/* home.css — the herosite.com front door (Clarke 2026-07-25).

   One non-scrolling screen: the comic cityscape as backdrop, Captain Hero anchored
   bottom-left, and a single landscape billboard panel carrying the whole pitch — headline,
   lead, then two columns. Left column is the website builder (in the lab, with its
   notify-me signup); right column is the logo generator, which is live.

   THE FRAME IS CSS, NOT ARTWORK. The blue surround, the gold keyline and the cream
   interior are three nested boxes, so the panel grows with its copy instead of being
   pinned to an image's aspect ratio, and stays crisp at any size. (The old portrait
   coming-soon panel was a .webp, which is why its text had to be sized in cqi.)

   LAYOUT. The panel is centred in the SAME column as the top nav and the footer:
   --col-width, declared once in base.css. It is capped narrower than that column so
   it stays a readable measure, but it can never exceed the nav's width or fall out of
   line with it. Captain Hero sits behind it (z-index 1) rather than beside it, so the
   panel's position is never a function of how wide the hero happens to be. */

body.home {
    margin: 0;
    font-family: 'Archivo', system-ui, sans-serif;
    line-height: 1.65;                   /* airier default; headings set their own below */
    color: #1a1a1a;
}

.stage {
    position: relative;
    min-height: 100vh;
    min-height: 100svh;                  /* svh absorbs mobile browser chrome */
    overflow: hidden;
    box-sizing: border-box;
    display: grid;
    place-items: center;
    padding: 132px 0 2.2rem;             /* top pad clears the fixed nav; --col-width owns the sides */
    background: #bfe0f5 url('/images/cityscapes/city-main-2026-06.webp') center center / cover no-repeat;
}

/* ---------- The nav scrim on scroll ----------
   Home scrolls now, so the logo and the burger ended up sitting on top of whatever content
   happened to be passing under them. This is the SAME treatment the sky pages already use
   (.sky::before in sky.css) — a fixed white band under the nav that fades to nothing along
   its bottom edge, held at opacity 0 until the page is scrolled.

   topnav.js already toggles .nav-scrolled on the body for EVERY page; only the CSS was
   sky-only, so home needed the rule, not the plumbing. At the very top there is no band, so
   the cityscape stays clean and the nav floats over it exactly as before.

   z-index 46: above the billboard (2) and the hero (1), below the nav itself (50). */
body.home::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 150px;
    z-index: 46;
    pointer-events: none;
    opacity: 0;
    transition: opacity .25s ease;
    background: linear-gradient(to bottom, #fff 60%, rgba(255, 255, 255, 0));
}
body.home.nav-scrolled::before { opacity: 1; }

/* --- Captain Hero: bottom-left, bleeds off the corner --- */
.stage__hero {
    position: absolute;
    z-index: 1;                          /* behind the panel: the panel is the message */
    left: 0;
    bottom: 0;
    width: clamp(230px, 33vw, 760px);
    height: auto;
    pointer-events: none;
    user-select: none;
}

/* ---------- The billboard: a NINE-CELL IMAGE FRAME ----------
   tool-bg.webp is the surface for the whole panel, set on the GRID CONTAINER rather than
   on each cell: it is a 976x679 picture, not a tile, so nine independent copies would show
   nine different crops with a visible seam at every cell edge. One background on the
   container reads as a single continuous surface behind all nine cells — including the
   content cell — which is what "all nine have tool-bg" has to look like to work.

   The eight frame tiles are transparent 118x118 RGBA images, so they lay OVER that
   surface rather than hiding it.

   --frame is the single knob for frame thickness: the 118px you specified at desktop,
   stepping down on small screens because two 118px columns out of a 350px phone would
   leave only ~114px of usable width for the content. */
.billboard {
    --frame: 118px;
    position: relative;
    z-index: 2;
    box-sizing: border-box;
    /* Never wider than the nav/footer column, and never wider than a comfortable
       measure. --col-width already carries the 20px page gutters. */
    width: min(1080px, var(--col-width));
    margin-inline: auto;
    display: grid;
    grid-template-columns: var(--frame) 1fr var(--frame);
    grid-template-rows:    var(--frame) 1fr var(--frame);
    background: url('/images/assets/tool-bg.webp') center / cover no-repeat;
}

/* Each frame cell stretches its tile to fill the cell. For the four corners the cell is
   exactly 118x118, so that is 1:1 with no distortion; the four edges stretch along their
   long axis, as specified (stretched, not tiled). */
/* z-index 4 puts every frame tile ABOVE the content cell, so the phone panel can bleed its
   white + its top rule underneath the left/right tiles and still read as framed.
   The 0.5px outset closes the HAIRLINE CRACKS Clarke caught on desktop: the grid's 1fr
   track lands on a fractional pixel, and at that seam the browser left a light line
   between the edge tile and the corner tile. Growing each tile a half pixel in every
   direction overlaps the seam without visibly moving the artwork. */
.billboard__cell {
    position: relative;
    z-index: 4;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    margin: -0.5px;
    padding: 0.5px;
    background-clip: border-box;
}
.billboard__cell--tl     { background-image: url('/images/assets/frame-tl.webp'); }
.billboard__cell--tr     { background-image: url('/images/assets/frame-tr.webp'); }
.billboard__cell--bl     { background-image: url('/images/assets/frame-bl.webp'); }
.billboard__cell--br     { background-image: url('/images/assets/frame-br.webp'); }
.billboard__cell--top    { background-image: url('/images/assets/frame-top.webp'); }
.billboard__cell--bottom { background-image: url('/images/assets/frame-bottom.webp'); }
.billboard__cell--left   { background-image: url('/images/assets/frame-left.webp'); }
.billboard__cell--right  { background-image: url('/images/assets/frame-right.webp'); }

/* The content cell. No border, no background, no padding — the frame is the inset now,
   and tool-bg shows through from the container. min-width:0 stops a long word forcing
   the middle column past its 1fr share. */
.billboard__inner {
    min-width: 0;
    padding: 0;
}

@media (max-width: 900px) { .billboard { --frame: 74px; } }
@media (max-width: 560px) { .billboard { --frame: 46px; } }

.billboard__title {
    margin: 0;
    font-family: 'Bangers', system-ui, cursive;
    font-weight: 400;
    color: var(--herosite-blue);
    line-height: .95;
    letter-spacing: .5px;
    text-align: center;
    font-size: clamp(1.75rem, 4.2vw, 3.3rem);
}
.billboard__lead {
    margin: .75em auto;                  /* see the note on .billboard__col p */
    max-width: 60ch;
    text-align: center;
    line-height: 1.65;
    font-size: clamp(.92rem, 1.3vw, 1.1rem);
    color: #222;
}

/* ---------- The two pitch columns ---------- */
.billboard__cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(1.2rem, 3.2vw, 2.8rem);
    margin-top: clamp(1.1rem, 2.4vw, 1.8rem);
}
/* ---------- THE PHONE TABS ----------
   Below 800px the two columns would stack, which buried the LIVE product (the logo
   generator) under a screenful of copy about one that hasn't launched. So on phones the
   two pitches become tabs — Logo open by default — and the whole page fits one screen.

   No JavaScript: the tabs are two radios plus their labels, so the open panel is real
   form state. It works with JS off, the browser gives arrow-key switching for free, and
   there is no flash of both panels before a script runs. `.pitch__radio` is offscreen
   rather than display:none so it stays focusable; the focus ring is drawn on the label. */
.pitch__radio {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
}
.pitch__strip { display: none; }

@media (max-width: 800px) {
    /* One column, and no gap — only one panel is ever on screen. */
    .billboard__cols {
        grid-template-columns: 1fr;
        gap: 0;
        margin-top: clamp(.9rem, 3vw, 1.4rem);
    }

    /* The strip. Tabs overlap by their 3px border (margin-right:-3px) so the two share
       one line rather than showing a 6px double rule between them. */
    .pitch__strip {
        display: flex;
        align-items: flex-end;
        padding-left: 6px;
    }
    .pitch__tab {
        font-family: 'Bangers', system-ui, cursive;
        font-size: clamp(1.45rem, 6.6vw, 2.1rem);
        line-height: 1;
        letter-spacing: .5px;
        color: #000;
        background: #cfcfcf;
        border: 3px solid #000;
        border-bottom: 0;
        border-radius: 14px 14px 0 0;
        padding: .42em .68em .3em;
        margin-right: -3px;
        cursor: pointer;
        position: relative;
        z-index: 1;
    }
    /* The open tab joins the white panel: it sits above it (z-index) and its -3px bottom
       margin covers the panel's top border, so the tab and the panel read as one shape. */
    #pitch-logo:checked ~ .pitch__strip .pitch__tab:first-of-type,
    #pitch-web:checked  ~ .pitch__strip .pitch__tab:last-of-type {
        background: #fff;
        z-index: 3;
        margin-bottom: -3px;
        padding-bottom: .42em;
    }
    #pitch-logo:focus-visible ~ .pitch__strip .pitch__tab:first-of-type,
    #pitch-web:focus-visible  ~ .pitch__strip .pitch__tab:last-of-type {
        outline: 3px solid var(--herosite-blue);
        outline-offset: 2px;
    }

    /* The panel. White, with the black rule along the top that the open tab breaks through.
       It bleeds a full --frame OUTWARD on both sides and pays the width back as padding,
       so the rule carries on UNDER the left/right frame tiles (cells 4 and 6) instead of
       stopping dead beside the tabs (Clarke's phone). The tiles are transparent PNGs laid
       over the container, so they need to paint ABOVE the panel for that to read as
       "under" — see the z-index on .billboard__cell. */
    .billboard__col {
        position: relative;
        z-index: 2;
        background: #fff;
        border-top: 3px solid #000;
        margin-inline: calc(var(--frame) * -1);
        margin-bottom: calc(var(--frame) * -1);
        padding: 1rem calc(var(--frame) + .45rem) calc(var(--frame) + 1.3rem);
    }
    #pitch-logo:checked ~ .billboard__col--web,
    #pitch-web:checked  ~ .billboard__col--logo { display: none; }

    /* One column on screen instead of two narrow ribbons, so the type can breathe. */
    .billboard__h2      { font-size: 1.12rem; }
    .billboard__col p   { font-size: 1rem; }
    .billboard__media   { min-height: 0; }
    /* The legal bar is position:fixed with a half-white background, so on a tall panel it
       floated over the last control in the panel — it swallowed "SIGN ME UP" on Clarke's
       phone. The panel now ends above it.
       Note the calc keeps the frame bleed below — this selector outranks the shorthand on
       .billboard__col, so dropping the var here would undo the white's run to the frame. */
    .billboard__col:last-child { padding-bottom: calc(var(--frame) + 3.4rem); }
    /* The action row's mobile rules live with .billboard-btn--lg further down — they have
       to come AFTER the base .billboard__actions rule to win, same specificity. */
}

/* Source order is logo-first (it is the live product). Desktop puts the website builder
   back on the left, so the two-column render is unchanged. */
@media (min-width: 801px) {
    .billboard__col--web { order: -1; }
}

/* Flex column so each side's action row can be pushed to the bottom with margin-top:auto,
   which keeps the two columns' buttons on the same line however the copy wraps. */
.billboard__col {
    min-width: 0;
    display: flex;
    flex-direction: column;
}
/* font-family is explicit: base.css sets headings to Bangers sitewide, and without
   this the column headings inherit the comic face instead of the flat block caps. */
.billboard__h2 {
    margin: 0 0 .7rem;
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .3px;
    line-height: 1.2;
    font-size: clamp(.98rem, 1.55vw, 1.24rem);
    color: #111;
}
/* SPACING NOTES — two things that make these numbers read oddly if you don't know:
   1. .em, not px. .75em is 12px against this rule's own 16px type, but because the
      font-size is a fluid clamp the gap now SCALES with the text instead of staying
      12px while the type shrinks. That keeps the rhythm even at small viewports.
      Use .75rem instead if you ever want a flat 12px regardless of type size.
   2. .billboard__col is a flex column, and flex items do NOT collapse margins — so
      top + bottom really is ~24px between paragraphs, not ~12px the way it would be
      in normal flow. That is deliberate (Clarke: "everything looks crowded"). */
.billboard__col p {
    margin: .75em 0;
    line-height: 1.65;
    font-size: clamp(.88rem, 1.22vw, 1rem);
    color: #222;
}

/* Reserved space in the right column for the artwork Clarke is adding. It holds its
   own height so the buttons already sit where they will sit once the images land. */
.billboard__media {
    flex: 1 1 auto;
    min-height: clamp(60px, 11vh, 140px);
}

/* ---------- Buttons ---------- */
.billboard__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .7rem;
    margin-top: auto;                    /* pin to the bottom of the column */
}
.billboard-btn {
    display: inline-block;
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 800;
    font-size: clamp(.78rem, 1.05vw, .94rem);
    letter-spacing: .3px;
    text-transform: uppercase;
    text-decoration: none;
    text-align: center;
    color: #000;
    background: #fff;
    border: 3px solid #000;
    border-radius: 12px;
    padding: .68rem 1.15rem;
    box-shadow: 4px 4px 0 #000;
    cursor: pointer;
    transition: transform .1s ease, box-shadow .1s ease;
}
.billboard-btn--yellow { background: var(--herosite-yellow); }
/* Size modifier for the logo column's pair. They are the page's primary action, so they
   sit larger than "Sign me up" — kept as a separate class so changing one never moves the
   other. Flat rem, not the base rule's fluid clamp: this is a fixed size on purpose. */
.billboard-btn--lg { font-size: 1.3rem; }
/* On a phone the pair has to fit ~210px of panel between them, so they hold one line and
   shrink with the viewport instead of wrapping. This block sits AFTER the base
   .billboard__actions rule on purpose: same specificity, so the later one wins.

   Below 346px the pair genuinely cannot fit — the panel is ~174px inside a 46px frame, and
   holding one line there would mean 8px type. Those phones get the honest stack instead. */
@media (min-width: 346px) and (max-width: 800px) {
    .billboard__actions { flex-wrap: nowrap; gap: .5rem; }
    /* nowrap on the LABEL as well as the row: without it a button that is a few pixels too
       narrow breaks its own words in half ("MORE / INFO") instead of the font stepping down. */
    .billboard-btn--lg  {
        font-size: clamp(.66rem, 2.9vw, 1.15rem);
        padding: .62rem .5rem;
        white-space: nowrap;
    }
}
@media (max-width: 345px) {
    .billboard-btn--lg { font-size: .95rem; padding: .58rem .8rem; }
}
/* Gated: on a touch screen :hover sticks after the tap, leaving the button
   stuck in its pressed state. Touch gets :active instead. */
@media (hover: hover) {
    .billboard-btn:hover { transform: translate(4px, 4px); box-shadow: 0 0 0 #000; }
}
.billboard-btn:active,
.billboard-btn:focus-visible { transform: translate(4px, 4px); box-shadow: 0 0 0 #000; }
.billboard-btn:disabled { opacity: .55; cursor: default; transform: translate(4px, 4px); box-shadow: 0 0 0 #000; }

/* ---------- The notify-me signup ---------- */
.notify {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    align-items: center;
    margin-top: auto;
}
.notify__email {
    flex: 1 1 170px;
    min-width: 0;
    box-sizing: border-box;
    font-family: inherit;
    font-size: 1rem;
    color: #111;
    background: #fff;
    border: 3px solid #000;
    border-radius: 12px;
    padding: .62rem .8rem;
}
.notify__email:focus-visible { outline: 3px solid var(--herosite-blue); outline-offset: 2px; }

/* The honeypot. Off-screen rather than display:none — some bots skip hidden inputs
   but happily fill anything they can find in the DOM. */
.notify__hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.notify__thanks {
    display: none;
    margin: 0;
    font-weight: 800;
    font-size: clamp(.92rem, 1.3vw, 1.05rem);
    color: #0a7d32;
}
.notify__error {
    flex: 1 1 100%;
    margin: 0;
    font-size: .85rem;
    font-weight: 700;
    color: #b3261e;
}

/* The swap, on success: field + button out, thank-you in. */
.notify.is-sent .notify__email,
.notify.is-sent .billboard-btn,
.notify.is-sent .notify__error { display: none; }
.notify.is-sent .notify__thanks { display: block; }

/* ---------- The live "by 9:47am" clock (comic-hero.js) ---------- */
.billboard__h2 [data-ready-by] { color: inherit; white-space: nowrap; }
.billboard__h2 [data-ready-by].is-ticking { animation: billboard-tick .45s ease; }
@keyframes billboard-tick {
    0%   { transform: translateY(-2px); opacity: .35; }
    100% { transform: translateY(0);    opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .billboard__h2 [data-ready-by].is-ticking { animation: none; }
}

/* ---------- Phones ----------
   The panel leads; below it the page SCROLLS into a deep run of cityscape that ends on
   Captain Hero (Clarke 2026-07-31). He is anchored to the bottom of .stage, so growing
   .stage with padding-bottom puts him at the end of the scroll as the payoff rather than
   half-hidden behind the panel — and it opens the room under the buttons where the
   "logos made by Herosite" slideshow will go.

   Below this width a two-column pitch would be two narrow ribbons, so .billboard__cols has
   already become the tabs (800px above) and the reserved image space shrinks away. */
@media (max-width: 640px) {
    .stage {
        padding: 118px 4vw 52vh;         /* the 52vh IS the scroll run down to the hero */
        align-items: start;
        min-height: 100svh;
    }
    /* Full opacity: at .9 he read as a ghost over the cityscape rather than standing in
       front of it (Clarke's phone). He is the payoff at the bottom now, so he is also
       bigger than the peek-in size he had when he only ever showed behind the panel. */
    .stage__hero { width: min(82vw, 420px); left: -6vw; opacity: 1; }
    .billboard__media { min-height: 0; }
    .tv { box-shadow: 6px 6px 0 rgba(0, 0, 0, .32); }
}
