/* The home hero's composer and its one door (mockups 18 and 19, 2026-10-19; creative.md §15.859; the picked composer,
   2026-10-20: desktop `final.png`, phone `v1` "Fit"). hero-ask.js is the card's behaviour, waitlist-form.js
   `door: 'one'` the markup under it: ONE white door and "more ways to sign up" side by side in one compact row, with
   the terms row under them, and the link opening the whole stack (waitlist.css) in place. The `door` experiment's arm
   `two` (2026-10-20) adds the first provider the stack would draw as a second door above the phone door, on this
   sheet's 600px line only. The card is two rows on a desktop width (field over the hairline, then the "+", the four
   starters and the send) and ONE row on a phone (owner, 2026-10-20), where only the field and the send remain: the
   pill's shape, with the typed example in the field.

   Look plan:
   - palette: site.css tokens only. Ground --bg #000000 (the page) turning to --card #0d0d0d (the app's ground) at the
     press; the card and the press ground --card; hairline --line #262626 (the card's edge, and on a desktop width the
     rule between its two rows); the row's controls --raised #181818, one step off the card so they read as targets;
     ink --fg #ececec; quiet ink --muted #b3b3b3 (the field's placeholder); the door --door-fill #ffffff with --door-ink #1f1f1f and
     --door-line #747775 (Google's light-theme button, kept white on the dark ground; the paper theme re-points only
     its hover).
   - accent: exactly one, the send button's --storm-action ramp (site.css .sb-btn, --cta-bg), plus the focus ring
     (--accent). Nothing else on the hero is chromatic; the four-colour G is Google's own mark.
   - type: --font-ui for the card, the starters, the link and the phone door; Google Sans Medium 14/20 on the Google
     door alone (brand-mandated; the same stack and font-face as waitlist.css .wl-pv).
   - radius: two. --r-surface on the card; --r-pill on the starters and the door. The round "+" and the send button are
     50%, the circles the plan always allowed.
   - the one bold thing: the card itself, wider than the sign-in column it holds, with the live typed example on its
     first row and the storm send button as its single accent mark. The door, the link and the terms stay quiet under it.
   No numeric literal here but 0, 1px hairlines, 50% and unitless counts named where they sit; every length is a site.css
   token. Motion is always on (.cosmos/rules/motion-always-on.mdc): Rise is the desktop's send curve, one exit, the
   typed example its own loop, no guard. */

/* ---- the card ---- */
.hero-ask {
  display: grid; gap: 0; width: min(100%, var(--content)); margin: var(--sp-6) auto 0; padding: 0;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-surface);
}
/* row one: the field, with the typed example over it while the box is empty. The overlay is a decoration (aria-hidden);
   the field keeps its own label and placeholder, which the overlay only covers while it is running. */
.hero-ask-field { position: relative; display: flex; align-items: center; min-height: var(--control-h); padding: 0 var(--sp-6); }
.hero-ask-in {
  flex: 1; min-width: 0; align-self: stretch; padding: 0; background: none; border: 0; border-radius: 0;
  color: var(--fg); font: inherit; font-size: var(--fs-base); line-height: var(--lh-base);
}
.hero-ask-in::placeholder { color: var(--muted); }
.hero-ask-type { display: none; }
/* data-typed is hero-ask.js: 'on' while the example runs over an empty, unfocused box, 'off' while the box has text or
   focus (the decoration steps aside and the real placeholder shows again) */
.hero-ask[data-typed] .hero-ask-type {
  position: absolute; inset: 0; display: flex; align-items: center; padding: inherit;
  overflow: hidden; white-space: pre; pointer-events: none;
  color: var(--fg); font: inherit; font-size: var(--fs-base); line-height: var(--lh-base);
}
.hero-ask[data-typed="off"] .hero-ask-type { display: none; }
.hero-ask[data-typed="on"] .hero-ask-in::placeholder { color: transparent; }
.hero-ask-caret {
  flex: none; width: 1px; height: var(--sp-5); margin-left: 1px; background: currentColor;
  animation: hero-ask-caret var(--dur-5) step-end infinite; /* deliberate */
}
@keyframes hero-ask-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
/* the box carries the focus state, not the field inside it (site.css gives a bare field its own ring) */
.hero-ask .hero-ask-in:focus-visible { outline: none; border-color: transparent; box-shadow: none; }
.hero-ask:has(.hero-ask-in:focus-visible) { outline: var(--focus-w) solid var(--accent); outline-offset: var(--focus-w); }
/* row two, under the hairline: the "+", the four starters, the send arrow */
.hero-ask-row { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2); border-top: 1px solid var(--line); }
.hero-ask-plus, .hero-ask-mode {
  background: var(--raised); color: var(--fg); border: 0; cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-std), transform var(--dur-2) var(--ease-std);
}
.hero-ask-plus { flex: none; display: inline-flex; align-items: center; justify-content: center; width: var(--target); height: var(--target); padding: 0; border-radius: 50%; }
.hero-ask-plus svg { width: var(--sp-4); height: var(--sp-4); }
/* wrap is the last resort of the tightest card (320px, where four 44px targets and their gaps do not share one line);
   min-width keeps every starter on the touch floor's width as well as its height */
.hero-ask-modes { display: flex; flex: 1; flex-wrap: wrap; min-width: 0; gap: var(--sp-2); }
.hero-ask-mode {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1);
  min-width: var(--target); height: var(--target); padding: 0 var(--sp-3); border-radius: var(--r-pill);
  font: inherit; font-size: var(--fs-sm); line-height: var(--lh-sm); white-space: nowrap;
}
.hero-ask-mode svg { flex: none; width: var(--sp-4); height: var(--sp-4); }
.hero-ask-plus:active, .hero-ask-mode:active { transform: scale(var(--press-scale)); }
@media (hover: hover) { .hero-ask-plus:hover, .hero-ask-mode:hover { background: var(--line); } }
/* the send button: .sb-btn's storm ramp as a circle, a white arrow on it (the paper theme's ramp is ink, the arrow still white) */
.hero-ask-go { flex: none; width: var(--target); height: var(--target); min-height: 0; padding: 0; border-radius: 50%; color: var(--door-fill); }
.hero-ask-go svg { width: var(--sp-5); height: var(--sp-5); }
/* the phone card is ONE row (owner, 2026-10-20: "keep mobile to just the 1 row for composer, looked better before"):
   the field with its typed example over it, the round send at its right, in the old phone pill's shape. The plus and
   the four starters step aside and take the hairline and the row's own padding with them, so the row itself goes
   display: contents and the send becomes the card's second item, inline after the field; nothing in the row is left to
   place. A phone on its side (a 874px window, 280px tall) takes this too, because a second row does not fit there
   either. Desktop above 600px keeps the two-row card exactly. */
@media (max-width: 600px), (orientation: landscape) and (max-height: 500px) {
  .hero-ask {
    display: flex; align-items: center; gap: var(--sp-2); min-height: var(--control-h);
    padding: var(--sp-1) var(--sp-1) var(--sp-1) var(--sp-4);
  }
  .hero-ask-field { flex: 1; min-width: 0; padding: 0; min-height: var(--target); }
  .hero-ask-row { display: contents; }
  .hero-ask-plus, .hero-ask-modes { display: none; }
}
/* the sign-up sits close under the card, whichever hero arm lays out the column */
.hero .hero-ask + .hero-cta { margin-top: var(--sp-3); }
/* a 320x568 phone (the tightest upright fold): the hero above the composer takes the last step down (hero.css's own
   portrait tiers stop at the mark's 96px and --sp-2 of padding) so the sign-up stack "more ways to sign up" opens
   still lands its email field above the fold. The phone card's one row gave back the second row's height, so the tier
   now leaves that air above the fold rather than buying it back */
@media (max-width: 400px) and (max-height: 700px) {
  .hero:has(.hero-ask) { padding-top: 0; gap: var(--sp-2); }
  .hero .hero-ask { margin-top: var(--sp-2); }
  .hero:has(.hero-ask) .sb-lockup { gap: var(--sp-1); }
  .hero:has(.hero-ask) .sb-glitch { width: calc(var(--sp-12) * 1.5); height: calc(var(--sp-12) * 1.5); }
}
@media (max-width: 400px) and (max-height: 620px) {
  .hero:has(.hero-ask) .sb-glitch { width: var(--sp-12); height: var(--sp-12); }
}
/* a phone on its side has 280px of height under the toolbars (874x280): the card's one row takes the touch floor and
   the two gaps around it take the hairline's step, so the door row and the primary still land in the first viewport */
@media (orientation: landscape) and (max-height: 500px) {
  .hero .hero-ask { margin-top: var(--sp-2); }
  .hero-ask-field { min-height: var(--target-touch); }
  .hero .hero-ask + .hero-cta { margin-top: var(--sp-1); }
}
/* an iPhone on its side with the toolbars out shows 280px (874x280): the hero's own air and the card's padding take the
   last step, so the door row and the terms line still end inside the first viewport */
@media (orientation: landscape) and (max-height: 320px) {
  .hero:has(.hero-ask) { padding-top: var(--sp-1); gap: var(--sp-1); }
  .hero .hero-ask { margin-top: 0; padding-left: var(--sp-3); }
  .hero .hero-ask + .hero-cta { margin-top: 0; }
}
/* a short phone held upright (hero.css 728's tier): the row under the card takes the next step down with the hero's own
   rhythm, so the door experiment's arm two clears the tab bar at 390x664 (ga-audit 2026-10-20) */
@media (orientation: portrait) and (max-height: 760px) {
  .hero .hero-ask + .hero-cta { margin-top: var(--sp-2); }
}

/* ---- the press (hero-ask.js) ----
   The typed words leave the box: the box's own text steps aside at once and a copy of the words, at the same place, goes
   out on Rise, the desktop's send curve (opacity 1 to 0 while it travels up --sp-2, over --rise-ms on the spring the
   script sets as --ghost-ease). The app carries the same exit on from where it stands when its first frame paints. The
   ground is the target shell's own, so the hop never steps between two blacks: the desktop's is --card #0d0d0d; the
   phone's boot page is #000000, the page's own dark ground, so a phone press changes nothing. The copy is the box's
   content area, the words left-aligned and centred in it, clipped to it (the app paints its half the same way). */
.hero-ask[data-sent] .hero-ask-in { color: transparent; caret-color: transparent; }
html[data-handoff="desktop"] body { background: var(--card); }
.hero-ask-ghost {
  position: fixed; z-index: var(--z-handoff); left: var(--ghost-x); top: var(--ghost-y); width: var(--ghost-w); height: var(--ghost-h);
  display: flex; align-items: center; margin: 0; overflow: hidden; white-space: pre; pointer-events: none;
  color: var(--fg); font: var(--ghost-font);
  animation: hero-ask-rise var(--rise-ms) var(--ghost-ease) both;
}
@keyframes hero-ask-rise { to { opacity: 0; transform: translateY(calc(-1 * var(--sp-2))); } }

/* ---- the one door: what shows ----
   data-door on the .wl slot is the switch (waitlist-form.js): 'one' the door, 'phone' / 'email' that door opened onto its
   row, 'all' the whole stack. Only the first step (data-state email) is cut down; the code step and "you're in." show as
   they always do, whatever the door was. */
.wl[data-door="one"][data-state="email"] > :not(.wl-one, .wl-more, .wl-terms),
.wl[data-door="two"][data-state="email"] > :not(.wl-one, .wl-more, .wl-terms) { display: none; }
.wl[data-door="phone"][data-state="email"] > :not(.wl-one, .wl-msg, .wl-phone, .wl-rates, .wl-more, .wl-terms) { display: none; }
.wl[data-door="email"][data-state="email"] > :not(.wl-one, .wl-msg, [data-wl-email], .wl-more, .wl-terms) { display: none; }
.wl[data-door]:not([data-state="email"]) > :is(.wl-one, .wl-more) { display: none; }
.wl[data-door]:not([data-door="one"]):not([data-door="two"]) .wl-door { display: none; }
.wl[data-door="all"] > .wl-more { display: none; }
.wl[data-door] > .wl-more { order: 1; }
.wl[data-door] > .wl-terms { order: 2; }

/* the door and the quiet link in ONE compact row under the card (desktop `final.png`, phone `v1`). No 'or' rule in the
   hero: waitlist-form.js still draws it for /download and the phone's sheet, and every other mount keeps waitlist.css's
   stack, so the rule only steps aside here. The door is a fully rounded pill at every width, the link beside it, the
   terms row under both; at 320px the row wraps the link under the door and nothing else moves. */
.wl-one { --font-google: "Google Sans", "Google Sans Label", "Google Label Medium", Roboto, var(--font-ui); display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--sp-2); width: auto; padding: 0; box-sizing: border-box; }
.hero .hero-cta .wl-one .wl-or { display: none; }
.hero .hero-cta .wl[data-door="one"][data-state="email"],
.hero .hero-cta .wl[data-door="two"][data-state="email"] {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  column-gap: var(--sp-4); row-gap: var(--sp-2);
}
/* the link rides on the door's row (its own order above the terms, waitlist.css 124-125); the terms take the next one */
.hero .hero-cta .wl[data-door="one"][data-state="email"] > .wl-terms,
.hero .hero-cta .wl[data-door="two"][data-state="email"] > .wl-terms { flex: 0 0 100%; }
.hero .hero-cta .wl-door { border-radius: var(--r-pill); }
.wl-door {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--google-gap);
  min-height: var(--target-touch); padding: 0 var(--sp-6); box-sizing: border-box;
  background: var(--door-fill); color: var(--door-ink); border: 1px solid var(--door-line);
  font: 600 var(--fs-base) / var(--lh-base) var(--font-ui); text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-std), transform var(--dur-2) var(--ease-std);
}
.wl-door[data-provider="google"] { font: 500 var(--fs-sm) / var(--lh-sm) var(--font-google); }
.wl-door-desk { border-radius: var(--r-pill); }
.wl-door-phone { border-radius: var(--r-control); }
.wl-door svg { width: var(--sp-5); height: var(--sp-5); flex: none; }
.wl-door:active { transform: scale(var(--press-scale)); }
@media (hover: hover) { .wl-door:hover { background: var(--door-hover); } }
/* the site's phone line (waitlist.css's 600px): the phone door takes the desktop door's place. In the hero's row it keeps
   its own width (the link rides beside it, phone `v1`) and the label takes the 14px step so the two fit one line at
   390px; every other mount keeps the full-width 52px door. */
@media (max-width: 600px) {
  .wl-door-desk { display: none; }
  .wl-door-phone { width: 100%; min-height: var(--control-h); }
  .hero .hero-cta .wl-one { gap: var(--sp-1); }
  /* arm two: the two doors take the row and the link wraps under them, so the row's height is the same at 320 and 390
     (the reserve in the lander's head is measured from it) */
  .hero .hero-cta .wl[data-door="two"] .wl-one { flex: 0 0 100%; }
  .hero .hero-cta .wl-door-phone { width: auto; min-height: var(--target-touch); padding: 0 var(--sp-4); font-size: var(--fs-sm); }
}
@media (min-width: 601px) { .wl-door-phone { display: none; } }
/* the `two` arm's provider door (waitlist-form.js oneDoorHtml): the first provider the stack would draw, above the phone
   door, sized and dressed as that door (--control-h, --r-control, full width). A desktop width never draws it: the
   desktop door above is already that provider. In the hero's row it keeps its own width like the phone door. */
.wl-door-prov { display: none; }
@media (max-width: 600px) {
  .wl-door-prov { display: inline-flex; width: 100%; min-height: var(--control-h); border-radius: var(--r-control); }
  .hero .hero-cta .wl-door-prov { width: auto; min-height: var(--target-touch); padding: 0 var(--sp-4); }
}

/* "more ways to sign up": a quiet underlined word, a button that opens the stack in place */
.wl-more { margin: 0; }
.wl-more-btn {
  display: inline-flex; align-items: center; min-height: var(--target); padding: 0; background: none; border: 0;
  color: var(--muted); font: inherit; font-size: var(--fs-sm); line-height: var(--lh-sm);
  text-decoration: underline; text-underline-offset: var(--sp-1); cursor: pointer;
}
@media (hover: hover) { .wl-more-btn:hover { color: var(--fg); } }
