HERO SECTION RULES:
- The hero is the most important section — it must immediately communicate the core value proposition
- Structure: eyebrow label → main headline (h1) → subheading → primary CTA → optional trust indicators
- HEADLINE AND SUBHEADING CLASS NAMES — REQUIRED, EXACT NAMES: The h1 must carry the class "hero-headline" in addition to any other classes, and the subheading paragraph immediately following it must carry the class "hero-subhead". (e.g. `<h1 class="hero-headline">...</h1>` and `<p class="hero-subhead">...</p>`.) The platform's landing-base.css applies a responsive max-width to elements with these exact class names — using a different or missing class name means that rule never applies. This is unrelated to and does not conflict with the HERO HEADING LAYOUT CONSTRAINT below — that rule governs the `.hero__head` wrapper's own width/centering, while these two classes live on the h1 and subheading paragraph themselves, one layer deeper.
- Eyebrow: small uppercase pill badge above the headline (e.g. "LIMITED TIME OFFER")
- Headline: bold, benefit-driven, emotionally compelling — the single most important copy on the page
- Subheading: 1–2 sentences expanding on the headline promise
- Primary CTA: large <a> tag with btn btn--primary btn--pulse classes, Font Awesome arrow icon
- CTA NOTE CLASS NAME — REQUIRED, EXACT NAME: If you include a short single-line note directly below the primary CTA (e.g. "87% OFF Special Launch Price · 30-Day Money-Back Guarantee"), it must carry the exact class "hero-note" — not "hero-trust-note", "cta-note", or any other variant. Per DO NOT DOUBLE UP THE GAP BETWEEN A BUTTON AND TEXT DIRECTLY BELOW IT in non_negotiable_rules.md, never give this element its own margin-top — the button's own margin-bottom already creates the gap. EXCEPTION: if the primary CTA itself is left-aligned (not centered/full-width), do not include this note at all — see the BUTTON ITSELF IS LEFT-ALIGNED exception under TEXT IMMEDIATELY UNDER A BUTTON MUST BE CENTERED AND BALANCED in non_negotiable_rules.md.
- Trust indicators below CTA: small icons + text (e.g. "✓ No credit card required", "✓ 30-day guarantee")
- Background: gradient or CSS pattern ONLY — NEVER a background image or placeholder

HERO LAYOUT STYLES — MUST BE INLINE <STYLE> BLOCK:
The hero's layout container styles (.hero__inner and .hero__head) MUST be placed in an inline <style> block immediately after the opening <section class="hero"> tag, NOT in the separate css field. This is an exception to the general output rule (all CSS goes in the css field) and follows the same GrapesJS-reliability pattern as inline scripts. 

Place this exact <style> block right after <section class="hero" id="hero"> and before the .hero__inner div:
<style>
.hero__inner { width: 100%; max-width: 100%; display: flex; flex-direction: column; align-items: center; gap: var(--space-xl); }
.hero__head { max-width: 1080px; margin: 0 auto; text-align: center; }
.hero__inner--split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-lg); align-items: start; } /* max-width:1200px + centering now platform-owned, do not add here */
@media (max-width: 767px) {
  .hero__inner--split { grid-template-columns: 1fr; }
}
</style>

Then use clean HTML without inline style= attributes — the <style> block above handles all layout.

HERO HEADING LAYOUT CONSTRAINT — NON-NEGOTIABLE: 
The width constraint and centering for the heading/eyebrow/subheading group is handled by the `.hero__head` CSS rule in the inline <style> block above (max-width: 1080px; margin: 0 auto; text-align: center). Do NOT generate any additional CSS rules like `.hero-headline { max-width: ... }` or `h1 { max-width: ... }` or any similar rule that constrains heading width — the heading element itself must remain unconstrained in your css field output. The .hero__head wrapper class handles all heading positioning; the h1 inside it is unstyled for width.

HERO HEADING FONT-SIZE — NON-NEGOTIABLE:
(A) Centered full-width hero: the 80px desktop / 68px tablet / 43px mobile values below are the ABSOLUTE MAXIMUM ceiling, only usable when your headline is short enough per the HERO HEADLINE FONT-SIZE — HARD CAPS BY CHARACTER COUNT table further down — that table's bracket for your actual headline length is the real cap you must use, which may be smaller than these maximums:
    font-size: clamp(35px, 7vw, 80px) — HARD CEILING at 80px desktop, 68px tablet, 43px mobile.
    Use @media (max-width:1024px) { h1 { font-size: clamp(35px, 6vw, 68px); } }
    Use @media (max-width:767px) { h1 { font-size: clamp(28px, 9vw, 43px); } }
(B) Two-column hero with h1 in left column: font-size: clamp(35px, 4vw, 45px) — FLAT 45px CAP REGARDLESS OF CHARACTER COUNT, NEVER the large centered-hero ceiling or its bracket table. The two-column layout's left column is inherently narrower than the full-width centered hero, so this cap stays fixed at 45px desktop no matter how short the headline is — it does not scale up for a short headline the way pattern (A) does.
NEVER use var(--text-hero) unconstrained — the clamp values above are the required sizes. Include these @media rules in your css field (NOT in the inline <style> block).

HERO HEADING LINE COUNT — NON-NEGOTIABLE, OVERRIDES THE CLAMP ABOVE WHEN NEEDED: The hero headline (desktop/tablet) must fit within 3 lines maximum. The clamp() values above are a ceiling based on viewport width alone — they say nothing about how many lines your specific headline text will actually wrap into, and a long headline rendered at or near that 65px ceiling can easily wrap to 4, 5, or more lines, which is a separate failure even when the font-size itself is technically within the cap. A confirmed real-world failure, recurring more than once: a long multi-sentence headline ("Most AI Hustlers Are Broke. You Don't Have To Be — Join The New Wave Of AI Automation Rebels" — 16 words, ~95 characters) rendered at a size close to the 65px ceiling and wrapped to 4 full lines, producing a visually overwhelming wall of oversized text that overflowed past the intended hero area.

HERO HEADLINE FONT-SIZE — HARD CAPS BY CHARACTER COUNT, NON-NEGOTIABLE: Do not estimate line wrap mentally — count the total characters in your headline (including spaces and punctuation) and use the EXACT hard cap below for that bracket. These are caps, not starting points or suggestions — never exceed the cap for your bracket, even if you think the headline "looks like it could handle" a larger size. If your clamp() or font-size value resolves above the cap at any breakpoint, lower it until it doesn't.
  THESE BRACKETS APPLY ONLY TO THE CENTERED, FULL-WIDTH HERO (pattern A below) — if the hero uses the two-column/split layout with the h1 in the left column (pattern B below), skip this table entirely and use the flat 45px cap specified under HERO HEADING FONT-SIZE pattern (B) instead, regardless of character count.
  - 0–20 characters: desktop cap 80px, tablet cap 70px, mobile cap 44px. Use clamp(40px, 8vw, 80px) desktop, clamp(38px, 7vw, 70px) tablet, clamp(30px, 9vw, 44px) mobile.
  - 21–35 characters: desktop cap 72px, tablet cap 62px, mobile cap 40px. Use clamp(36px, 7.5vw, 72px) desktop, clamp(34px, 6.5vw, 62px) tablet, clamp(28px, 8.5vw, 40px) mobile.
  - 36–50 characters: desktop cap 64px, tablet cap 56px, mobile cap 37px. Use clamp(34px, 6.5vw, 64px) desktop, clamp(32px, 5.5vw, 56px) tablet, clamp(27px, 8vw, 37px) mobile.
  - 51–65 characters: desktop cap 58px, tablet cap 50px, mobile cap 35px. Use clamp(32px, 6vw, 58px) desktop, clamp(30px, 5vw, 50px) tablet, clamp(26px, 7.5vw, 35px) mobile.
  - 66–80 characters: desktop cap 52px, tablet cap 46px, mobile cap 32px. Use clamp(30px, 5.5vw, 52px) desktop, clamp(28px, 4.5vw, 46px) tablet, clamp(24px, 7vw, 32px) mobile.
  - 81–100 characters: desktop cap 50px, tablet cap 44px, mobile cap 30px. Use clamp(28px, 5vw, 50px) desktop, clamp(26px, 4vw, 44px) tablet, clamp(22px, 6.5vw, 30px) mobile.
  - Over 100 characters: desktop cap 42px, tablet cap 36px, mobile cap 26px. Use clamp(26px, 4vw, 42px) desktop, clamp(24px, 3vw, 36px) tablet, clamp(20px, 5.5vw, 26px) mobile. A headline this long is also a copywriting problem, not just a sizing problem — strongly prefer shortening the copy itself over relying on this smallest bracket; hero headlines read better punchy and short regardless of how the font-size math works out.
  A CONFIRMED REAL-WORLD FAILURE MATCHING THE 100+ BRACKET EXACTLY: the headline "Stop Making Cool AI Clips Nobody Pays For. Start Running a Real AI Automation Agency That Prints $1,500 Checks." is 111 characters — squarely in the 100+ bracket, which caps desktop at 42px. It was instead rendered at roughly the SHORTEST bracket's size (closer to 70-80px), spanning 4 full lines and badly overflowing the hero — both the character-count cap above and the separate 3-line maximum in HERO HEADING LINE COUNT were violated simultaneously. This is exactly the failure mode this table exists to prevent: defaulting to a large, "looks impressive" font-size without first counting the headline's actual characters and checking which bracket it falls into. At 111 characters, even the correct 42px cap would likely still need the headline split across headline + subhead, or shortened outright — do not treat hitting the bracket's cap as sufficient on its own if the copy is this long; re-read REFERENCE MATH below and verify 3 lines actually holds at the bracket's cap before finalizing.
  Reference math: at the 80px desktop cap (shortest bracket) with the 1080px max-width constraint on `.hero__head`, each line holds roughly 14-18 characters at this bold weight and size — this number grows as font-size decreases through the brackets, which is why the math is bracket-specific rather than one fixed per-line character count. Count your headline's characters BEFORE writing any font-size value, find its bracket, and use that bracket's exact caps at every breakpoint — never default to a larger bracket's caps without first checking your specific headline's length against this table.
  A SECOND CONFIRMED REAL-WORLD FAILURE OF THIS EXACT RULE: the headline "Stop Making AI Content Nobody Pays For. Start Running the Agency That Gets Paid $1,500 a Project." is 97 characters — the 81–100 bracket, 50px desktop cap. It instead rendered at roughly 70-80px and spanned 4 lines, the same category of failure as the first confirmed example above, just with different copy. Two separate real generations have now defaulted to a large font-size without first counting the headline's characters, despite this exact table existing to prevent it — treat this as a high-risk step, not a formality to skim past.
  MANDATORY WRITTEN CHARACTER COUNT — NOT OPTIONAL, NOT SKIPPABLE: Immediately above your hero headline's font-size declaration in your css field, write a literal CSS comment stating the exact character count you counted and the bracket it maps to, in this exact format: `/* headline length: [N] chars → [bracket] bracket → [X]px desktop cap */` — for example `/* headline length: 97 chars → 81-100 bracket → 50px desktop cap */`. This comment must reflect a count you actually performed on your specific headline text, not a copy-pasted example. If you cannot honestly produce this comment because you skipped counting, go back and count before writing the font-size value. This step exists specifically because two prior real generations defaulted to an oversized font without counting first — writing the count down forces the check to actually happen rather than being silently skipped under the assumption that "this headline looks short enough."

HERO INNER CONTAINER — NON-NEGOTIABLE:
The hero's inner container must span the full section width (width: 100%) unless using the split layout. Layout is handled by the inline <style> block — do NOT add additional width constraints or margins to .hero__inner in the css field. The inline <style> already contains the flex layout and alignment for centered single-column; use .hero__inner--split for side-by-side layouts.
DESKTOP MAX-WIDTH WHEN NOT USING 2 COLUMNS — NON-NEGOTIABLE: When the hero uses the centered single-column layout (pattern A below, NOT the split/two-column pattern B), `.hero__inner` itself must have `max-width: 1200px; margin: 0 auto;` on desktop — it is no longer simply `max-width: 100%` at this breakpoint. The `.hero__head` wrapper nested inside it keeps its own separate, narrower `max-width: 1080px` exactly as before — these are two distinct, intentionally nested caps (1200px outer, 1080px inner), not the same value applied twice. The split/two-column layout (`.hero__inner--split`) ALSO resolves to this same 1200px desktop cap, just via its own grid-based mechanism rather than this flex-based one — see THE SPLIT LAYOUT MUST STILL BE CAPPED AT 1200px ON DESKTOP under pattern (B) below for that case's exact CSS.
USE THE LITERAL CLASS NAME `hero__inner` — DOUBLE UNDERSCORE, EXACT SPELLING, NO SUBSTITUTES: A confirmed, recurring real-world failure: despite this rule explicitly requiring the class `hero__inner`, generated pages have repeatedly used a different, invented class instead — `hero-content`, `hero-inner` (single hyphen instead of double underscore), `hero-inner-wrap`, and similar variants. This is not a stylistic choice with equivalent results — it breaks TWO separate things at once: (1) the platform's landing-base.css applies its guaranteed mobile horizontal padding via the EXACT selector `.hero__inner` (no wildcard matching, because this exact name was supposed to be reliable), so any other name silently receives zero horizontal padding on mobile; and (2) the inline `<style>` block immediately below — which you are required to copy verbatim — defines its flex layout (`display:flex; flex-direction:column; align-items:center; gap:...`) against the exact selector `.hero__inner` too, so a differently-named wrapper gets none of that layout either, forcing you to informally reinvent the same layout from scratch with a different class name and losing the platform guarantee in the process. Before finalizing, check the literal class attribute on your hero's content wrapper div character-by-character against `hero__inner` — `hero-inner`, `heroinner`, `hero_inner`, and any other near-miss are all wrong. This is the single most impactful class name to get exactly right in the entire hero section, since two separate guarantees both depend on it being spelled correctly.

HERO LAYOUT — TWO VALID PATTERNS, SEPARATE CLASSES — NON-NEGOTIABLE: 
The hero must use exactly ONE of these two layouts, never a mix:
(A) CENTERED, SINGLE COLUMN — class `.hero__inner`: heading, subheading, and CTA are centered and stacked, full width up to the 1200px desktop cap above. An optional two-column row (e.g. image + content) may appear BELOW the centered heading/subheading, never replacing it. Use this for the typical centered hero.
(B) SPLIT, SIDE-BY-SIDE FROM THE TOP — class `.hero__inner hero__inner--split`: the headline/copy sits in one column and a form, image, or supporting content sits in the other, side by side from the very top. Use this class explicitly when choosing this layout; the inline <style> block's media query automatically handles responsive collapse to single column on mobile. NEVER apply grid/column styles to .hero__inner yourself to fake this layout — use the `--split` class so the platform's existing rules apply correctly. THE 1200px DESKTOP CAP AND CENTERING ARE NOW PLATFORM-OWNED FOR THIS CLASS — DO NOT WRITE YOUR OWN: `max-width: 1200px; margin-left: auto; margin-right: auto;` on `.hero__inner--split` is now guaranteed by landing-base.css, alongside the `display:grid`/`grid-template-columns`/`gap` it already owned. Do NOT write your own `max-width` or `margin` rule for this class at any breakpoint — this was previously a model-authored instruction that wasn't reliably followed, leading to a confirmed real-world failure where a split hero with no cap stretched its two columns edge-to-edge across a very wide desktop viewport, rendering an oversized, awkwardly-wrapping headline and an overly wide form column. It is now guaranteed regardless of what you write, so there's nothing for you to redeclare or get wrong here.
Whichever pattern you choose, the hero must contain AT MOST TWO columns total. NEVER split into 3 or 4 columns.

FORM-SIDE COLUMN MINIMUM WIDTH — NON-NEGOTIABLE: If the split layout's second column holds the lead-capture form (`.form-card`/`.capture-form-wrap`), that column must NEVER be narrower than 464px wide on desktop/tablet, whether you size it with a grid `1fr` track, a flex `flex-basis`, or a fixed pixel width. This number is not arbitrary: the form itself has a platform-owned `min-width: 400px` (see landing-base.css), and `.form-card` has its own `padding: 2rem` (32px each side = 64px total) — 400 + 64 = 464px is the absolute minimum the form-side column can be without forcing the form to overflow past the card's right edge. A CONFIRMED REAL-WORLD FAILURE: a split hero used a fixed-width form column (`flex: 0 0 440px; max-width: 440px;`) instead of the documented equal `1fr 1fr` grid columns — 440px is narrower than the required 464px floor, so the form's hard `min-width:400px` couldn't shrink to fit, and it overflowed the card, visually reading as "missing padding on the right." Prefer the documented equal `1fr 1fr` grid (which comfortably clears this floor on any normal desktop width) — but if you do choose a fixed-width or flex-basis column for the form side for design reasons, that value must be 464px or greater, never less.

SPLIT-HERO WITH A FORM COLUMN MUST COLLAPSE TO SINGLE COLUMN AT TABLET (max-width:1024px), NOT JUST MOBILE — NON-NEGOTIABLE: The documented mobile-only collapse (`@media (max-width:767px) { .hero__inner--split { grid-template-columns: 1fr; } }`) is NOT sufficient by itself whenever the second column holds the lead-capture form. The form-side column has a hard 464px width floor (see FORM-SIDE COLUMN MINIMUM WIDTH above), and a typical tablet viewport (768–1024px) does not have enough combined room for that 464px floor PLUS a usable width for the first column PLUS the gap between them — forcing two columns to stay side-by-side in that range causes the form to overflow/bleed off the side of the viewport rather than wrapping, since it physically cannot shrink below its floor. CONFIRMED REAL-WORLD FAILURE: a split hero's two columns remained side-by-side at tablet width because the only collapse breakpoint was the mobile one at 767px — the form-side column, unable to shrink below its 464px floor, bled off the right edge of the viewport instead of breaking to its own row. Fix: add `@media (max-width: 1024px) { .hero__inner--split { grid-template-columns: 1fr; } }` (or equivalent for whichever layout method you used) so the columns stack at the TABLET breakpoint, well before the 464px floor could ever cause an overflow — do not wait until the mobile breakpoint to collapse a layout containing a form column. Once stacked at this breakpoint, the form column must still be centered per the rule immediately below.

WHEN THE SPLIT-HERO COLUMNS STACK (ANY BREAKPOINT) — THE STACKED COLUMN MUST BE CENTERED, NOT LEFT FLUSH — NON-NEGOTIABLE: The documented mobile collapse (`@media (max-width:767px) { .hero__inner--split { grid-template-columns: 1fr; } }`) is not the only place this can happen — if you add your own intermediate tablet-range adjustment (e.g. narrowing the form-side column to a fixed width like 380px at max-width:1024px) and that adjustment results in a column narrower than the row it now occupies, that column will default to sitting flush against the left edge with empty space on its right — it does NOT center itself automatically just because the row became full-width. A CONFIRMED REAL-WORLD FAILURE: at the tablet breakpoint, a fixed-width form column (e.g. `.hero-right { max-width: 380px; }` with no centering override) rendered hugging the left side of a now much-wider stacked row, with a large empty gap to its right, instead of sitting centered in the available space. Whenever a column in this layout is narrower than its row — at any breakpoint, whether from the documented mobile collapse or your own added tablet rule — you MUST explicitly center it: `margin-left: auto; margin-right: auto;` if it's a block-level child with a fixed/max-width, or `justify-self: center` / `align-items: center` if the parent is a grid/flex container with that alignment property available. Never leave a narrower-than-row column to default to flush-left positioning.

RECOMMENDED STRUCTURE — CENTERED SINGLE-COLUMN:
<section class="hero" id="hero">
  <style>
  .hero__inner { width: 100%; max-width: 1200px; margin: 0 auto; display: flex; flex-direction: column; align-items: center; gap: var(--space-xl); }
  .hero__head { max-width: 1080px; margin: 0 auto; text-align: center; }
  </style>
  <div class="hero__inner">
    <div class="hero__head">
      [eyebrow badge] [h1 headline] [subheading] [CTA with icon] [trust indicators]
    </div>
    [optional: two-column image + text row below centered content]
  </div>
</section>

RECOMMENDED STRUCTURE — SPLIT SIDE-BY-SIDE:
<section class="hero" id="hero">
  <style>
  .hero__inner--split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-lg); align-items: start; } /* max-width:1200px + centering now platform-owned, do not add here */
  @media (max-width: 1024px) {
    .hero__inner--split { grid-template-columns: 1fr; }
  }
  @media (max-width: 767px) {
    .hero__inner--split { grid-template-columns: 1fr; }
  }
  </style>
  <div class="hero__inner hero__inner--split">
    <div class="hero__content">
      [eyebrow] [h1] [subheading] [benefits list] [CTA]
    </div>
    <div class="hero__form-col">
      [form card, image, or other supporting content]
    </div>
  </div>
</section>

LOGO IN HERO — NARROW EXCEPTION ONLY:
The hero is one of only three permitted locations for the site logo (alongside nav/header and footer), but this is a narrow exception. The logo may ONLY appear as a small, secondary badge-style element (e.g. "As seen with [logo]" near trust indicators) — never as the hero's primary visual. It must NEVER be inside a generic content-image wrapper (`.hero-image-wrap`, `.hero-img`, `.hero-visual`), NEVER set to `loading="eager"`, and NEVER unconstrained in width. Max-width: 300px. The hero's actual primary visual (product mockup, screenshot, illustration) MUST use a placehold.co placeholder with exact pixel dimensions as text (e.g. `?text=800x600`) — NEVER the logo URL. Do not add a logo to the hero unless it serves the partner-badge purpose above — most heroes don't need one since nav already displays it.

HERO PADDING AND DIVIDERS:
- Bottom padding: ALWAYS exactly 0px at every breakpoint, no exceptions — NON-NEGOTIABLE. This is not conditional on whether a divider follows; per NO DIVIDER AFTER THE HERO below, no divider element is ever placed between the hero and the second section, so padding-bottom:0 is simply the hero's permanent bottom-padding value, every time, on every page. Do NOT write a non-zero bottom padding value (100px, 75px, or anything else) on the hero — the hero's content must end and the next section must begin with zero gap between them, so the color-match described in HERO BACKGROUND below reads as one continuous surface rather than two blocks with a visible gap.
- NO DIVIDER AFTER THE HERO — NON-NEGOTIABLE, NO EXCEPTIONS: The transition between the hero and the second section on the page is ALWAYS a hard cut with NO divider element of any kind — no SVG `.section-divider`, no `<hr>`, no clip-path/diagonal edge, regardless of the divider style selected for the rest of the page. This is true even if every other transition on the page uses dividers. The hero ends, the second section begins, with nothing visually inserted between them — the seam must be invisible because the colors match exactly (see HERO BACKGROUND below), not because a divider is disguising a mismatch.
- Top padding: must be explicitly set on the hero section to clear any navigation bar or provide appropriate spacing from page top. Include this in your css field output. If there IS a nav/header: use the exact pre-computed totals from NAV/HEADER CLEARANCE below (130px desktop/tablet, 114px mobile) — do not calculate nav-height-plus-gap yourself. If there is NO nav/header on the page: use padding-top: 60px desktop/tablet, 40px mobile — a smaller breathing-room value, not the nav-clearance totals and not the section's 100px/75px standard vertical padding (the hero never gets that, per THE HERO NEVER GETS THE STANDARD 75PX MOBILE SECTION PADDING below). Never leave hero top padding unset or default to 0 just because there's no nav — the hero still needs this smaller standalone breathing-room value when no nav is present.
- THE HERO NEVER GETS THE STANDARD 75PX MOBILE SECTION PADDING — NON-NEGOTIABLE: The universal 75px mobile section padding (from non_negotiable_rules.md's SECTION VERTICAL PADDING IS PLATFORM-OWNED rule) explicitly excludes the hero — it is platform-applied to every other section automatically, but never to `.hero`/`[class*="hero"]`. A confirmed real-world failure: on mobile only, a generated hero showed an unwanted extra gap stacked on top of its own nav-clearance padding — the model had applied the standard 75px mobile section padding to the hero's own wrapper IN ADDITION TO the 114px mobile nav-clearance total from the rule below, producing roughly 189px of combined top padding instead of just the 114px nav-clearance total alone. The hero's only top padding should come from the NAV/HEADER CLEARANCE rule immediately below (or 0 if there's no nav) — never the generic 75px mobile section value, and never both stacked together. If you find yourself writing `padding-top: 75px` (or `padding: 75px ...`) anywhere inside your hero's own CSS at the mobile breakpoint, that is almost certainly this exact mistake — remove it and rely solely on the nav-clearance total.
- HORIZONTAL PADDING ON MOBILE IS STILL YOUR RESPONSIBILITY HERE TOO: Every padding rule above discusses top/bottom only — that is not an exception to the universal MOBILE HORIZONTAL SPACING / outermost-div-exactly-10px rule in non_negotiable_rules.md, which still applies to the hero's own outermost div like every other section. A confirmed real-world failure: a hero section's headline and eyebrow badge rendered with 0px (or near-0px) left/right padding on mobile, extending almost to the literal screen edges — because every hero-specific padding rule the model was focused on (nav clearance, bottom spacing, line-count font sizing) only ever mentions padding-top/padding-bottom, and horizontal padding got dropped entirely as a result. Since the hero is the one section where you write your own padding CSS from scratch (every other section omits padding and relies on the platform), it is your responsibility — not the platform's — to also include padding-left: 10px; padding-right: 10px on the hero's outermost div at the mobile breakpoint. Do not let writing custom top/bottom values cause you to forget the horizontal value the universal rule still requires.

NAV/HEADER CLEARANCE — NO CONTENT MAY BE HIDDEN BEHIND THE NAV:
If the page has a fixed or sticky navigation bar or header, check whatever content sits at the very top of the page (typically the hero section, or the first element inside <main>) and confirm it is not rendering underneath, overlapping, or partially obscured by that nav/header. The nav is fixed/sticky and removed from normal document flow, so the page's top content does not automatically clear it on its own — you must verify this yourself rather than assume default flow handles it.
USE THESE EXACT PRE-COMPUTED TOTALS — DO NOT CALCULATE NAV-HEIGHT-PLUS-GAP YOURSELF: The hero's padding-top must equal the nav's height plus a 50px clearance gap below it. Rather than doing that arithmetic yourself each time (a confirmed source of error — values like 160px have appeared that match neither the nav height nor the intended 50px gap), use these exact totals based on the nav heights specified in navigation.md (80px desktop, 64px mobile):
  - Desktop/tablet (nav height 80px): padding-top: 130px
  - Mobile (max-width:767px, nav height 64px): padding-top: 114px
A CONFIRMED REAL-WORLD FAILURE — WRITING ONLY THE DESKTOP VALUE, NO MOBILE OVERRIDE: A generated hero wrote `#hero { padding-top: 130px; ... }` with no `@media (max-width:767px)` rule anywhere overriding it to 114px. Since CSS values cascade down to narrower breakpoints unless explicitly overridden, that 130px applied completely unchanged at mobile width too — a 16px excess gap, pushing the hero's content down further than the mobile nav actually requires. Writing the 130px desktop value is NOT sufficient on its own; you MUST also write a separate, explicit `@media (max-width:767px) { #hero { padding-top: 114px; } }` (or equivalent) rule — these are two different values for two different breakpoints, and omitting the second one is a confirmed, recurring mistake. Before finalizing, check that your hero's CSS contains BOTH the 130px declaration AND a distinct 114px declaration inside a max-width:767px media query — if you only find one number anywhere in your hero's padding-top declarations, you have not finished this rule.
If there is no nav/header on the page, do NOT use either of these values — use the smaller no-nav fallback (padding-top: 60px desktop/tablet, 40px mobile) specified in HERO PADDING AND DIVIDERS above instead.

THE ACTUAL VISIBLE GAP IS WHAT MATTERS, NOT JUST THE PADDING-TOP DECLARATION — NON-NEGOTIABLE: Writing the correct padding-top value (130px/114px) is necessary but NOT sufficient — you must also confirm the hero's actual rendered layout doesn't add extra invisible space on top of it. The total visible gap between the bottom edge of the nav and the top edge of the hero's first visible content (the eyebrow badge, headline, or whatever renders first) must NEVER exceed 50px beyond the nav's own height — i.e. it must match the padding-top total above, not exceed it. A CONFIRMED REAL-WORLD FAILURE: a hero used `min-height: 100vh` (or similar) combined with `display:flex; align-items:center` (or `justify-content:center`) to vertically center its content block within that tall viewport-height container. The padding-top value was technically correct, but centering the content inside a much-taller-than-needed container pushed the actual first-visible-content far below where the padding-top alone would have placed it — producing a visible gap of 250px+ between the nav and the headline, several times larger than intended. If your hero sets a `min-height` taller than its natural content height AND vertically centers that content, you are almost certainly causing this exact failure. Either: (a) do not vertically center hero content when using a tall `min-height` — let it sit at the top, directly after the padding-top, with extra space falling below the content instead of being split above/below it via centering; or (b) do not use a `min-height` taller than the content needs in the first place. Before finalizing, mentally trace the rendered distance from the nav's bottom edge to the first visible content element — if anything in your CSS (min-height, vertical centering, an extra wrapper margin) would push that distance past the padding-top total, fix it.

HERO BACKGROUND:
- The hero's bottom edge background color must be a single flat hex so dividers can match it perfectly.
- THE BOTTOM EDGE MUST BE A SOLID COLOR — NON-NEGOTIABLE, REGARDLESS OF WHETHER THE HERO STARTS WITH A GRADIENT: Whether the hero's background starts as a flat color or a gradient, it must END at the bottom edge as a single solid, flat hex — never still actively transitioning, never a visible gradient band right at the seam. If using a gradient, flat-anchor it well before the bottom edge (e.g. by the 85–90% mark) so the last 10-15% of the section is already a fully solid, unchanging color by the time it reaches the bottom. The bottom edge is never the place a gradient is still blending — it must already have resolved to one flat value before it gets there.
- If using a gradient, flat-anchor it at the bottom: e.g. `linear-gradient(180deg, #1a1a2e 0%, #0d0d0d 88%, #0d0d0d 100%)`. The intent of flat-anchoring is a visual FADE — the gradient should ease into its final flat color well before the bottom edge (e.g. by the 85–90% mark), not cut off abruptly at the very edge, so the hero appears to gradually dissolve into the section below it rather than hitting a hard line.
- EFFECTS LAYERS MUST SIT ON A BACKGROUND MATCHING THE EXACT SAME COLOR — NON-NEGOTIABLE: If the hero includes any decorative effect layer (a particle canvas, floating shapes, an animated gradient overlay, a noise/texture layer, or any other visual effect rendered on top of or within the hero), the container that effect lives in must have its OWN background set to the exact same resolved color as the hero section's background at that point — never transparent-by-default-to-something-else, and never a different hex that would create a visible patch or seam where the effect's container sits. A confirmed real-world failure pattern: a particle-effect canvas element had no explicit background of its own, and depending on stacking/rendering order this could show through as a different shade than the hero's actual background, creating a visible rectangle or color discontinuity within the hero itself — not just at its edges. Any effect container must explicitly inherit or set `background: transparent` ONLY if it sits directly on top of the hero's own background with nothing between them, or otherwise must explicitly match the resolved hex of whatever it's layered against at that specific position. Never assume an effect layer defaults to invisible/transparent without verifying it.
- HERO-TO-NEXT-SECTION COLOR MATCH — NON-NEGOTIABLE, NO EXCEPTIONS: The hero's resolved bottom-edge hex MUST be the exact same hex as the next section's resolved top-edge color — character-for-character identical, not "close," not "a similar dark tone," not a different shade in the same palette. This applies regardless of whether the hero's background is a flat color or a gradient — if it's a gradient, the flat-anchored stop nearest the bottom edge (per GRADIENT FLAT-ANCHORING in non_negotiable_rules.md) is the value that must match. Per NO DIVIDER AFTER THE HERO above, no divider element ever appears at this seam — the two sections' touching edges must blend into one continuous color entirely through this color match, with nothing else disguising a mismatch. Combined with the fade-anchoring above, the goal is that a viewer scrolling past this seam should perceive one continuous surface gently fading from the hero's gradient into a flat color, never a visible boundary line or color jump. A confirmed real-world failure: the hero ended on a deep purple gradient stop while the section immediately below it opened on a completely different navy/black tone — with no divider to disguise the seam, the mismatch created a hard, visible color break exactly where the design intended a smooth transition. Before finalizing, explicitly compare the hero's resolved bottom hex against the next section's resolved top hex in your COLOR PLAN comment and confirm they are the same value — if they are not, change one of them (almost always easier to change the next section's background to match the hero's anchored bottom stop) so they align exactly.
- The flat bottom hex is what the next section must match.

OPTIONAL HERO IMAGE:
A foreground product image as `<img>` (NOT a background image) with class "hero-image" for entrance animation — only if the layout includes a visual element.

MOBILE HORIZONTAL SPACING REMINDER: This section is subject to the MOBILE HORIZONTAL SPACING rule in non_negotiable_rules.md — on mobile (max-width:767px), no element you write for this section (outer wrapper, inner container, cards, headings, paragraphs, buttons, icons, anything) may have padding-left, padding-right, margin-left, or margin-right greater than 10px, and this section's outermost div must have at least 10px. Check this section's mobile CSS against that rule before finalizing.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GRAPESJS MOBILE CHECKS — HERO
[GRAPESJS BUILDER ONLY — page generator: ignore this section]
Run these checks after adding or modifying the hero section in GrapesJS.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. PADDING-TOP 114px on mobile (not the 130px desktop value — this is the #1 recurring hero mobile failure):
   editor.Css.setRule('#hero, .hero', {'padding-top':'114px'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

2. SPLIT LAYOUT collapses at 1024px (not just 767px — form column can't fit beside text below 1024px):
   editor.addStyle('@media (max-width:1024px) { .hero__inner--split { grid-template-columns: 1fr !important; } }');

3. HERO INNER horizontal padding — 10px on mobile:
   editor.Css.setRule('.hero__inner', {'padding-left':'10px','padding-right':'10px'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

4. H1 FONT-SIZE — verify mobile value matches the char-count bracket (count headline chars, pick the mobile cap):
   0-20 chars=44px, 21-35=40px, 36-50=37px, 51-65=35px, 66-80=32px, 81-100=30px, 100+=26px
   editor.Css.setRule('h1.hero-headline, .hero-headline', {'font-size':'clamp(28px,9vw,43px)'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

5. CTA BUTTON centered and wraps on mobile:
   editor.addStyle('@media (max-width:767px) { .hero .btn, .hero a.btn { display: block; margin-left: auto; margin-right: auto; white-space: normal; text-wrap: balance; } }');

6. HERO-NOTE centered on mobile (trust line below CTA):
   editor.Css.setRule('.hero-note', {'text-align':'center','max-width':'100%'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

7. NO OVERFLOW — nothing in hero should extend past viewport edge:
   editor.Canvas.getDocument().querySelector('#hero')?.querySelectorAll('*').forEach(el => { if(el.scrollWidth > el.clientWidth + 2) console.warn('HERO OVERFLOW:', el.className || el.tagName); });

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GRAPESJS MOBILE CHECKS — HERO
[GRAPESJS BUILDER ONLY — page generator: ignore this section]
Run these checks after adding or modifying the hero section in GrapesJS.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

0. INLINE STYLE BLOCK PRESENT (run this FIRST — most common cause of "looks fine here, broken live"):
   Verify the hero section has an inline <style data-role="hero-layout"> as its first child.
   If missing, add it immediately — this is what provides display:grid for hero__inner--split on the live page:
   const _hero=editor.getWrapper().find('#hero,.hero,.optin-hero')[0];
   if(_hero){
     const _existing=_hero.find('style[data-role="hero-layout"]')[0];
     const _css='.hero__inner{width:100%;max-width:1200px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:var(--space-xl)}.hero__head{max-width:1080px;margin:0 auto;text-align:center}.hero__inner--split{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-lg);align-items:start}@media(max-width:1024px){.hero__inner--split{grid-template-columns:1fr}}@media(max-width:767px){.hero__inner--split{grid-template-columns:1fr}}';
     if(_existing){_existing.set('content',_css);}
     else{_hero.components().add({tagName:'style',attributes:{'data-role':'hero-layout'},content:_css},{at:0});}
     editor.store();
   }

1. PADDING-TOP 114px on mobile (not the 130px desktop value — this is the #1 recurring hero mobile failure):
   editor.Css.setRule('#hero, .hero', {'padding-top':'114px'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

2. SPLIT LAYOUT collapses at 1024px (not just 767px — form column can't fit beside text below 1024px):
   editor.addStyle('@media (max-width:1024px) { .hero__inner--split { grid-template-columns: 1fr !important; } }');

3. HERO INNER horizontal padding — 10px on mobile:
   editor.Css.setRule('.hero__inner', {'padding-left':'10px','padding-right':'10px'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

4. H1 FONT-SIZE — verify mobile value matches the char-count bracket (count headline chars, pick the mobile cap):
   0-20 chars=44px, 21-35=40px, 36-50=37px, 51-65=35px, 66-80=32px, 81-100=30px, 100+=26px
   editor.Css.setRule('h1.hero-headline, .hero-headline', {'font-size':'clamp(28px,9vw,43px)'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

5. CTA BUTTON centered and wraps on mobile:
   editor.addStyle('@media (max-width:767px) { .hero .btn, .hero a.btn { display: block; margin-left: auto; margin-right: auto; white-space: normal; text-wrap: balance; } }');

6. HERO-NOTE centered on mobile (trust line below CTA):
   editor.Css.setRule('.hero-note', {'text-align':'center','max-width':'100%'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

7. NO OVERFLOW — nothing in hero should extend past viewport edge:
   editor.Canvas.getDocument().querySelector('#hero')?.querySelectorAll('*').forEach(el => { if(el.scrollWidth > el.clientWidth + 2) console.warn('HERO OVERFLOW:', el.className || el.tagName); });
