@import url("/noodl-tokens.css");

/* /v6 — fixed 1122px pixel-match skin for the painted reference mockup.
   Everything lives on a 1122x1897 stage and is absolutely positioned in
   reference-image coordinates, so the render overlays reference.png 1:1 —
   down to y=690, where the painted "How Noodl works" block used to be. That
   block was replaced on 2026-08-03 by the ten-card "Everything you need" grid,
   which has no painted counterpart, so nothing below y=690 traces the plate any
   more. The same day the two painted sections that followed the grid — the
   flexibility evolution and the badge shelf — were cut; the CTA banner is the
   only block left below the grid, hung 60px under the last card row rather than
   at its reference y. Scoped under body.v6 so it cannot leak into the other
   landing versions.

   Since 2026-08-03 the 1122x1897 stage described above is only served to
   /v6-full, the frozen complete page. The homepage adds `v6-hero` to the body
   and stops at 720px — nav + hero, one screen, no scroll — so every rule below
   the hero still exists but nothing on / matches it. Nothing here may be
   deleted for being unused by the homepage; /v6-full is what it is for. */

body.v6 {
  --v6-cream: var(--noodl-palettes-landing-cream);
  --v6-card: var(--noodl-palettes-landing-card);
  --v6-card-line: var(--noodl-palettes-landing-card-line);
  --v6-beige: var(--noodl-palettes-landing-beige);
  /* Named for the badge shelf's locked card, which was cut on 2026-08-03; the
     pair outlived it as the waitlist dialog's error colours. */
  --v6-locked-bg: var(--noodl-palettes-landing-locked-bg);
  --v6-locked-line: var(--noodl-palettes-landing-locked-line);
  --v6-lavender: var(--noodl-palettes-landing-lavender);
  --v6-lavender-line: var(--noodl-palettes-landing-lavender-line);
  --v6-orange: var(--noodl-palettes-landing-orange);
  --v6-orange-action: var(--noodl-palettes-landing-orange-action);
  --v6-orange-l: var(--noodl-palettes-landing-orange-l);
  --v6-green: var(--noodl-palettes-landing-green);
  --v6-body: var(--noodl-palettes-landing-body);
  --v6-muted: var(--noodl-palettes-landing-muted);
  --v6-navlink: var(--noodl-palettes-landing-navlink);
  /* The ink outline of the dialog cards and the trailer frame. Not in
     tokens.json yet; one name here instead of a literal in every rule. */
  --v6-outline: #2B2A26;
  --v6-sans: "Avenir Next Condensed", "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;

  margin: 0;
  background: var(--v6-cream);
  color: var(--v6-body);
  font-family: var(--v6-sans);
  -webkit-font-smoothing: antialiased;
}

body.v6 h1, body.v6 h2, body.v6 h3, body.v6 p, body.v6 ol, body.v6 ul, body.v6 dl,
body.v6 dt, body.v6 dd, body.v6 figure, body.v6 figcaption {
  margin: 0; padding: 0;
}
body.v6 ol, body.v6 ul { list-style: none; }
body.v6 img { display: block; max-width: none; }
body.v6 a { text-decoration: none; }

body.v6 .v6-skip {
  position: absolute; left: -9999px; top: 0; z-index: 90;
  background: var(--v6-green); color: #fff; padding: 10px 16px; border-radius: 0 0 10px 0;
  font: 600 15px/1 var(--v6-sans);
}
body.v6 .v6-skip:focus { left: 0; }

/* The stage: a fixed 1122x1897 canvas, centered. */
body.v6 .v6-stage {
  position: relative;
  width: 1122px;
  height: 1897px;
  margin: 0 auto;
  overflow: visible;   /* the hero scene deliberately bleeds past the stage */
  background: var(--v6-cream);
}
/* Hero-only homepage (2026-08-03). Same stage, cut off under the hero: 720 =
   the 68px nav band + the 668px painted scene, which is where the page now
   ends. Nothing else changes — the grid and banner rules below are still
   served in full to /v6-full, which keeps body class `v6` without this one.

   720 is not an arbitrary crop: the `@media (min-width: 1000px)` zoom rule
   already keys its height term to the same 720px (it was written to keep the
   hero above the fold on the long page). With the stage *being* 720px, that
   term now sizes the whole page. Change one number and the other has to change
   with it.

   Which of the zoom's two terms binds still depends on the window: at 1440x900
   (1.6) the height term wins and the scene fills the screen edge to edge, but
   on a window proportionally taller than the hero's 1122:720 — 1122x800, say —
   the width term wins and a band of page cream is left under the scene. That is
   the deliberate trade: `min()` never scales past the width, because scaling to
   cover would push the headline and the store badges off the sides on a tall
   narrow window. Cream under a hero is quiet; a cut-off headline is not.

   The clip is what makes "no scroll" true rather than nearly true. The phone
   deck's cream wash (.v6-phones::before) is a 700px-tall radial centred at
   y528, so it reaches stage y878 — 158px past the end of a 720px stage, which
   is enough to give the document a scrollbar with nothing in it. Clipping it
   costs nothing visually: below the painted scene the wash is page cream on
   page cream. Only the vertical axis is clipped — the hero scene's 300px bleed
   past each edge is the design, and body's overflow-x: hidden is what handles
   that. (Longhands, not the `visible clip` shorthand: a browser that does not
   know `clip` then drops one declaration instead of both.) */
body.v6-hero .v6-stage {
  height: 720px;
  overflow-x: visible;
  overflow-y: clip;
}

body.v6 .v6-stage main,
body.v6 .v6-stage section,
body.v6 .v6-stage header { display: block; }

/* Shared orange pill button */
body.v6 .v6-btn {
  position: absolute;
  display: block;
  background: var(--v6-orange-action);
  color: #fff;
  border-radius: 999px;
  text-align: center;
  font-weight: 600;
  letter-spacing: .01em;
  transition: background .15s ease;
}
body.v6 .v6-btn:hover { background: #B94704; }

body.v6 .v6-accent { color: var(--v6-orange); }
body.v6 .v6-accent-l { color: var(--v6-orange-l); }

/* ============================== NAV ============================== */
body.v6 .v6-brand {
  position: absolute; left: 47px; top: 8px; z-index: 10;
  display: block; width: 148px;
  line-height: 0;
}
body.v6 .v6-brand-lockup {
  display: block;
  width: 100%;
  height: auto;
}
/* z-index matches .v6-brand above: the animated hero plate is hung at top:4px so
   it reaches up into the nav band, and the nav has to stay above it. */
body.v6 .v6-nav-links a {
  position: absolute; top: 29px; z-index: 10;
  font: 500 14.5px/14.5px var(--v6-sans);
  color: var(--v6-navlink); white-space: nowrap;
}
body.v6 .v6-nav-links a:hover { color: var(--v6-orange); }
/* Two links: "How it works" went with its section and Journey/Rewards went with
   theirs (both 2026-08-03). The 90px step from the four-link version is kept,
   but the pair is re-centred on the painted band's optical middle (x290..660,
   last label ending ~x598) instead of hugging its left edge, which would have
   left the whole right half of the band empty up to the CTA pill at x910. */
body.v6 .v6-nav-links a:nth-child(1) { left: 380px; }
body.v6 .v6-nav-links a:nth-child(2) { left: 470px; }

/* Anchored by its right edge (where the old 148px pill ended, x1048) and sized
   to its label, so a longer label grows leftward into the empty band. */
body.v6 .v6-nav-cta.v6-jelly {
  left: auto; right: 74px; top: 12px; width: auto; height: 32px; z-index: 10;
  padding: 6px 8px 4px;
  font-size: 12.5px;
  white-space: nowrap;
}
body.v6 .v6-nav-cta-short { display: none; }

/* ============================== HERO ============================== */
/* The painted scene is 1722px wide — 300px of generated extension on each side of
   the original 1122px crop — so it can cover the full viewport width while the
   stage is scaled to fit the hero's height. Centred on the stage, it bleeds
   300px past both edges; body's overflow-x: hidden clips it to the window. The
   original crop sits in the middle: its inner ~982px are the untouched reference
   pixels, and only its outermost 70px on each side are cross-faded into the
   generated extension (a hard join showed a seam, because the generator redraws
   the interior and matches its edges to that redraw, not to the original). */
body.v6 .v6-hero-scene { position: absolute; left: -300px; top: 52px; width: 1722px; height: 668px; }

/* PREVIEW (2026-07-29): the animated plate. It sits in exactly the same box as
   the still scene, so `zoom` on the stage scales it identically. Desktop only,
   and only when motion is welcome — everywhere else it stays display:none and
   the page behaves exactly as it did before this existed. The still plate is
   left in the flow underneath rather than removed, so it remains the LCP image
   and the fallback if the video fails to decode.

   No z-index: it must not create a stacking context, or it would paint above
   the hero copy (h1, lede, buttons), which are all z-index:auto. Instead the
   element sits immediately after the still <picture> in the DOM, so among the
   auto-z siblings it paints over the still and under everything declared after
   it. The phone deck keeps its own z-index 2/3 and stays on top.

   The clip is 716px tall, not 668: Noodl rises out of his side bend as he
   stretches and reaches 37px above the plate's top edge at the peak (measured
   across every 4th frame), so the frame carries 48px of headroom above y=0 and
   is hung at top:4px to keep plate y=0 landing on stage y=52. That headroom
   band is flat cream apart from his hand — median deviation from the page cream
   is 8/765 — so it reads as page background, not as a taller image. */
body.v6 .v6-hero-motion { display: none; }
/* Same (min-width: 1000px) and (min-aspect-ratio: 3/2) pair as the zoom block
   and the <picture>'s own source: the animated plate belongs to the painted
   fixed composition, and showing it while the layout has reflowed paints a
   second, differently-scaled copy of the scene over the copy. The three have to
   agree — they are one decision ("is this the desktop composition?") expressed
   in three places, because one of them is a markup attribute. */
@media (min-width: 1000px) and (min-aspect-ratio: 3/2) and (prefers-reduced-motion: no-preference) {
  body.v6 .v6-hero-motion {
    display: block;
    position: absolute; left: -300px; top: 4px; width: 1722px; height: 716px;
  }
}

/* ---- App screenshots ------------------------------------------
   Real simulator captures sit in CSS device frames above the illustrated scenes. */
/* The deck gets a box of its own so it can host the veil below. `inset: 0` makes
   it exactly the stage, so the phones' existing stage-space coordinates are
   unchanged; no transform is applied, so it does not become a stacking context
   and the phones keep painting at z-index 2/3 against the stage as before. */
body.v6 .v6-phones {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* The painted plaza is the same cream as the devices, so the deck had no edge to
   win on — it read as part of the painting rather than as the subject of it.
   This lifts a soft wash of page cream behind the phones: the scene keeps its
   detail at the edges and yields the middle, without repainting the plate.
   Sits at z-index auto, so it covers the plate and video (earlier siblings) but
   stays under the hero copy and the phones themselves. */
body.v6 .v6-phones::before {
  content: "";
  position: absolute;
  left: 544px;   /* deck centre — the phones span x 325–763, y 371–684 */
  top: 528px;
  width: 820px;
  height: 700px;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side,
    rgba(252, 244, 234, .90) 0%,
    rgba(252, 244, 234, .74) 40%,
    rgba(252, 244, 234, .34) 68%,
    rgba(252, 244, 234, 0) 100%);
}

/* The plate has no shadows under the phones (they were erased with them), so
   the layers carry their own — drop-shadow follows the cutout's alpha, and it
   scales with the stage because zoom scales lengths.

   Two shadows, not one: a tight contact shadow that plants the device on the
   plaza, and a wide ambient one that separates it from the scene behind. The
   single .20 shadow this replaces read as neither, which is why the phones
   looked painted into the plate instead of standing in front of it. */
body.v6 .v6-phone-wrap { position: absolute; }
body.v6 .v6-phone {
  display: block;
  width: 100%;
  height: auto;
  box-sizing: border-box;
  border: 3px solid #292B27;
  border-radius: 20px;
  background: #292B27;
  filter:
    drop-shadow(0 2px 3px rgba(94, 72, 43, .34))
    drop-shadow(0 16px 24px rgba(94, 72, 43, .20));
}
body.v6 .v6-phone-l { left: 325px; top: 365px; width: 144px; height: auto; z-index: 2; }
body.v6 .v6-phone-r { left: 617px; top: 361px; width: 146px; height: auto; z-index: 2; }
body.v6 .v6-phone-c { left: 469px; top: 365px; width: 153px; height: auto; z-index: 3; }


@media (prefers-reduced-motion: no-preference) {
  /* `translate` and `transform` are separate properties, so the scroll-driven
     parallax and the idle float compose without fighting for one declaration. */
  @keyframes v6-phone-float { from { transform: translateY(0); } to { transform: translateY(-9px); } }
  /* Only the centre phone floats. With all three drifting on their own timings,
     ambient motion was everywhere in the hero and therefore drew the eye nowhere;
     one moving device inside a still deck reads as the subject. */
  body.v6 .v6-phone-c { animation: v6-phone-float 4.6s ease-in-out infinite alternate; }

  /* Scroll parallax, only where the browser really supports scroll timelines —
     without the guard the keyframes would run once on the time timeline and
     leave the deck parked at its end state. This stays on all three: it is depth
     cueing tied to the scroll, not ambient motion competing for attention. */
  @supports (animation-timeline: scroll()) {
    @keyframes v6-phone-rise-far  { to { translate: 0 -34px; } }
    @keyframes v6-phone-rise-near { to { translate: 0 -58px; } }
    body.v6 .v6-phone-l,
    body.v6 .v6-phone-r {
      animation: v6-phone-rise-far linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 80vh;
    }
    body.v6 .v6-phone-c {
      animation: v6-phone-float 4.6s ease-in-out infinite alternate,
                 v6-phone-rise-near linear both;
      animation-timeline: auto, scroll(root block);
      animation-range: normal, 0 80vh;
    }
  }
}

/* "Sneak peek" screen: every so often each phone frosts over, turns white and
   says the app is not final, left to right, then clears back to its screenshot.
   It is a second phone laid over the first — same frame, same tilt, its own
   Dynamic Island — so the glass looks like it switched screens rather than
   something being stuck on top. Sized in em so each layout only sets a
   font-size, and one class deeper than the fluid layout's `position: static`
   reset so it keeps its place there too. */
body.v6 .v6-stage .v6-phone-wrap .v6-phone-note {
  --note-delay: 2.5s;
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .55em;
  box-sizing: border-box;
  padding: 0 .9em;
  font: 500 10.5px/1.2 var(--v6-sans);
  text-align: center;
  color: #1C1B18;
  background: #fff;
  border: 3px solid #292B27;
  border-radius: 20px;
  opacity: 0;
}
body.v6 .v6-phone-note::before {
  content: "";
  position: absolute;
  top: 2.6%;
  left: 50%;
  width: 30%;
  height: 3.6%;
  translate: -50% 0;
  border-radius: 99px;
  background: #111;
}
/* Noodl's logo with the CTAs' gold sparkle, still turning, perched on its
   top-right corner, over a quiet two-line lockup. Deep enough to outrank the
   fluid layout's `position: static` reset, like the note itself. */
body.v6 .v6-stage .v6-phone-wrap .v6-phone-note-brand {
  position: relative;
  margin-bottom: .2em;
}
body.v6 .v6-phone-note-logo {
  display: block;
  width: 7.2em;
  height: auto;
}
body.v6 .v6-phone-note .v6-cta-sparkle {
  position: absolute;
  top: -.6em;
  right: -1.1em;
  width: 1.5em;
  height: 1.5em;
}
body.v6 .v6-phone-note strong {
  font-size: 1.55em;
  font-weight: 600;
  letter-spacing: -.005em;
}
body.v6 .v6-phone-note small {
  font-size: .78em;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #8C8579;
}
body.v6 .v6-phone-l :is(.v6-phone, .v6-phone-note) { transform: rotate(-7deg); transform-origin: bottom right; }
body.v6 .v6-phone-r :is(.v6-phone, .v6-phone-note) { transform: rotate(7deg); transform-origin: bottom left; }
body.v6 .v6-stage .v6-phone-c .v6-phone-note { --note-delay: 2.8s; }
body.v6 .v6-stage .v6-phone-r .v6-phone-note { --note-delay: 3.1s; }

@media (prefers-reduced-motion: no-preference) {
  /* 10s loop, white for about 2.5s of it; the first wave starts 2.5s in, once
     the page has been seen as it is. The glass frosts before it goes white and
     frosts again on the way back, and the words rise in once the screen has
     settled and leave before it clears. */
  @keyframes v6-phone-note {
    0%, 32%, 100% { opacity: 0; background-color: rgb(255 255 255 / 0); backdrop-filter: blur(0); }
    3%, 29%       { opacity: 1; background-color: rgb(255 255 255 / .55); backdrop-filter: blur(6px); }
    7%, 25%       { opacity: 1; background-color: rgb(255 255 255 / 1); backdrop-filter: blur(6px); }
  }
  @keyframes v6-phone-note-words {
    0%, 6%, 27%, 100% { opacity: 0; translate: 0 .5em; filter: blur(2px); }
    10%, 24%          { opacity: 1; translate: 0 0; filter: blur(0); }
  }
  body.v6 .v6-stage .v6-phone-wrap .v6-phone-note {
    animation: v6-phone-note 10s ease-in-out var(--note-delay) infinite;
  }
  body.v6 .v6-stage .v6-phone-wrap .v6-phone-note :is(.v6-phone-note-logo, strong, small) {
    animation: v6-phone-note-words 10s cubic-bezier(.2, .7, .2, 1) var(--note-delay) infinite;
  }
  body.v6 .v6-stage .v6-phone-wrap .v6-phone-note strong { animation-delay: calc(var(--note-delay) + .08s); }
  body.v6 .v6-stage .v6-phone-wrap .v6-phone-note small { animation-delay: calc(var(--note-delay) + .16s); }
  /* The sparkle arrives with the words and keeps the CTAs' idle turn. */
  body.v6 .v6-stage .v6-phone-wrap .v6-phone-note .v6-cta-sparkle {
    animation: v6-phone-note-words 10s cubic-bezier(.2, .7, .2, 1) calc(var(--note-delay) - .08s) infinite,
               noodl-sparkle-idle 6.8s linear infinite;
  }
}

body.v6 .v6-h1 {
  position: absolute; left: 48px; top: 103px;
  font: 600 65px/62.5px var(--v6-sans);
  color: var(--v6-green);
  letter-spacing: .038em;
}

body.v6 .v6-lede {
  position: absolute; left: 52px; top: 240px;
  font: 500 16.3px/20px var(--v6-sans);
  color: var(--v6-body);
  letter-spacing: -.012em;
}

/* CUT 2026-07-31, both in the same pass: the painted "Start stretching" pill
   (left:52 top:293, 154x33) and the "Watch how it works" play link beside it
   (left:220 top:294, with a 32px ring and a 10x12.5 triangle). The pill was a
   duplicate of the App Store badge — both opened the waitlist — and the play
   link promised a video the page does not have. Desktop keeps the badges in
   that space; the separately art-directed mobile layout restores a primary CTA. */

/* App-store badges, directly under the lede. NOTE: these are CSS recreations,
   not Apple's / Google's official artwork — both require their own assets and
   have brand rules, so swap them in (and use real store URLs) at launch. */
body.v6 .v6-stores {
  position: absolute; left: 51px; top: 296px;
  display: flex; align-items: center; gap: 8px;
  z-index: 4;
}
/* The orange pill is display:none everywhere as of 2026-09-07 (Martin's call).
   It was the primary action on every composition below the desktop canvas, and
   on the poster it was also what pushed the badges down onto the phone deck.
   Desktop never had it — the nav pill is its primary action — so removing it
   leaves the badges below the canvas. Element and styles stay: this rule is the
   only thing switching the mobile action off, and the compositions that used to
   place it are in the blocks below, one revert away. */
body.v6 .v6-mobile-action { display: none; }
body.v6 .v6-mobile-cta {
  position: relative;
  min-width: min(250px, 100%);
  min-height: 50px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 0 17px 0 20px;
  box-sizing: border-box;
  background: var(--v6-orange-action);
  color: #fff;
  border-radius: 999px;
  font: 600 16px/1 var(--v6-sans);
  letter-spacing: .01em;
  white-space: nowrap;
  box-shadow: 0 3px 0 rgba(15, 42, 27, .20);
  transition: background .15s ease, transform .12s ease, box-shadow .12s ease;
}
body.v6 .v6-mobile-cta:hover { background: #B94704; }
body.v6 .v6-mobile-cta:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 rgba(15, 42, 27, .20);
}
body.v6 .v6-mobile-cta:focus-visible {
  outline: 2.5px solid var(--v6-green);
  outline-offset: 3px;
}

/* The shared jelly appearance and motion live in public/noodl-button.css. */
body.v6 .v6-store {
  display: flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 11px;
  background: #16281B; color: #FFF9F0;
  border-radius: 9px;
  transition: background .15s ease, transform .15s ease;
}
body.v6 .v6-store:hover { background: #0C1A10; transform: translateY(-1px); }
body.v6 .v6-store small {
  display: block; font: 500 7.4px/9px var(--v6-sans);
  letter-spacing: .06em; text-transform: uppercase; opacity: .82;
}
body.v6 .v6-store strong { display: block; font: 600 13px/14px var(--v6-sans); letter-spacing: .005em; }
/* ============================ HEADINGS ============================ */
body.v6 .v6-h2 {
  position: absolute;
  color: var(--v6-green);
  font-weight: 600;
  letter-spacing: -.005em;
}
/* The one heading left, and it was never a left-rail label off the painted
   plate: it spans the stage and centres over the card grid, so it is set in the
   wider face the banner headline uses rather than the condensed one. */
body.v6 .v6-feat-h {
  left: 0; top: 752px; width: 1122px; text-align: center;
  font: 600 27px/34px "Avenir Next", var(--v6-sans);
}

/* ======================= EVERYTHING YOU NEED =======================
   Ten cards, five columns of 192px on a 206px pitch, which leaves the same
   53px of cream on both edges of the stage. Only the boxes are placed in stage
   coordinates: nothing in this section traces reference.png, so inside a card
   the content is ordinary flow and the card is tall enough for the longest of
   the ten bodies rather than measured off a plate. */
body.v6 .v6-featcard {
  position: absolute; width: 192px; height: 400px;
  background: var(--v6-card);
  border: 1px solid var(--v6-card-line);
  border-radius: 14px;
  overflow: hidden;
  box-sizing: border-box;
}
/* Column lefts repeat between the two rows, so they are grouped by column. */
body.v6 .v6-featcard-1, body.v6 .v6-featcard-6  { left: 53px; }
body.v6 .v6-featcard-2, body.v6 .v6-featcard-7  { left: 259px; }
body.v6 .v6-featcard-3, body.v6 .v6-featcard-8  { left: 465px; }
body.v6 .v6-featcard-4, body.v6 .v6-featcard-9  { left: 671px; }
body.v6 .v6-featcard-5, body.v6 .v6-featcard-10 { left: 877px; }
body.v6 .v6-featcard:nth-child(-n+5) { top: 840px; }
body.v6 .v6-featcard:nth-child(n+6)  { top: 1258px; }

/* Same painted-circle treatment as the old step numbers — highlight and halo,
   not a flat fill — in the page's dark green rather than terracotta, so ten of
   them in a row do not turn the grid orange. */
body.v6 .v6-feat-num {
  position: absolute; left: 14px; top: 12px; width: 28px; height: 28px;
  background: radial-gradient(circle at 32% 28%, #2E5B3E 0%, #1E4230 55%, #142E21 100%);
  box-shadow: 0 1px 3px rgba(15, 42, 27, .25);
  color: #fff; border-radius: 50%;
  font: 700 14px/28px var(--v6-sans); text-align: center;
}
/* The PNGs are transparent-background with the subject centred, so the art sits
   on the card's own cream; the top margin clears the number chip. */
body.v6 .v6-feat-art {
  margin: 44px auto 0; width: 140px; height: 180px;
  object-fit: contain;
}
body.v6 .v6-featcard h3 {
  margin: 14px 16px 0;
  font: 600 15.5px/19px "Avenir Next", var(--v6-sans);
  color: var(--v6-green);
}
body.v6 .v6-featcard > p {
  margin: 7px 16px 0;
  font: 400 12.3px/16.5px var(--v6-sans);
  color: var(--v6-body);
}

/* CUT 2026-08-03: "Your flexibility evolution" (the beige band, the five Noodl
   stages with their arrows and captions, and the bendiest-Noodl figure) and
   "Collect progress. Unlock joy." (the four unlocked badges, the locked card and
   the lounging Noodl) were both removed at Martin's call. The page ends on the
   feature grid and its CTA now. Their art is still in app/assets/images/v6/. */

/* ============================ CTA BANNER ============================ */
/* The whole block moved up 275px on 2026-08-03, when the evolution and badge
   sections between it and the feature grid were cut. Every coordinate below is
   its painted offset minus 275, so the banner's internal composition is
   untouched; it lands 60px under the grid's second row (which ends at y1658). */
body.v6 .v6-cta-band {
  position: absolute; left: 49px; top: 1718px; width: 1024px; height: 160px;
  /* Sampled from reference.png: the painted band averages (230,223,242) under the
     top border and lifts to about (233,226,244) near the bottom edge. */
  background: linear-gradient(180deg, #E6DFF2 0%, #E9E2F4 100%);
  border: 1.5px solid var(--v6-lavender-line);
  border-radius: 16px;
  box-sizing: border-box;
}
body.v6 .v6-cta-left { position: absolute; left: 49px; top: 1717px; width: 294px; height: 163px; z-index: 2; }
body.v6 .v6-cta-bird { position: absolute; left: 866px; top: 1742px; width: 208px; height: 139px; z-index: 2; }

body.v6 .v6-cta-h {
  position: absolute; left: 300.5px; top: 1738px; width: 501px;
  text-align: center; z-index: 3;
  /* The painted banner headline is set in a wider face than the condensed one
     used elsewhere: at the reference's 318px line-1 width its cap-to-baseline is
     only ~25px, which the condensed face cannot hit without heavy tracking. */
  font: 600 32px/36.5px "Avenir Next", var(--v6-sans);
  color: var(--v6-green); letter-spacing: 0;
}
/* Line 1 is tracked wider than line 2 in the painted reference (318px vs 204px),
   so each line keeps its own tracking. */
body.v6 .v6-cta-line1 { letter-spacing: 0; }
body.v6 .v6-cta-line2 { letter-spacing: -.037em; }
body.v6 .v6-cta-spark-l { position: absolute; left: 411px; top: 1776px; width: 27px; height: 35px; z-index: 3; }
body.v6 .v6-cta-spark-r { position: absolute; left: 663px; top: 1776px; width: 27px; height: 35px; z-index: 3; }

body.v6 .v6-cta-btn {
  left: 439px; top: 1820px; width: 216px; height: 34px; z-index: 3;
  font: 600 17px/38px var(--v6-sans); letter-spacing: .02em;
}
body.v6 .v6-cta-foot {
  position: absolute; left: 291px; top: 1862px; width: 499px; text-align: center; z-index: 3;
  font: 500 11px/12px var(--v6-sans); color: #3B443A;
}

/* Sticky note. The element itself is the BACK sheet; ::before paints the front
   sheet on top of it (a negative z-index child would still paint above the
   parent background, so the sheets are ordered this way instead). Every text
   offset below is therefore measured from the back sheet's box. */
body.v6 .v6-note {
  position: absolute; left: 765px; top: 1747px; width: 150px; height: 121px;
  background: #F6E1C8;
  border: 2px solid #2B2A26;
  border-radius: 3px;
  transform: rotate(-2.75deg);
  box-sizing: border-box;
  z-index: 6;
}
body.v6 .v6-note::before {
  content: ""; position: absolute; left: 5.5px; top: -7.5px; width: 150px; height: 121px;
  background: #FBEBD5; border: 2px solid #2B2A26; border-radius: 3px;
  box-sizing: border-box;
}
/* The two clips are painted upright in the reference, so they sit in stage
   coordinates outside the rotated note (sliced straight from reference.png). */
body.v6 .v6-note-clip { position: absolute; z-index: 7; }
body.v6 .v6-note-clip-l { left: 779px; top: 1738px; width: 10px; height: 16px; }
body.v6 .v6-note-clip-r { left: 852px; top: 1733px; width: 12px; height: 15px; }
body.v6 .v6-note-title {
  position: absolute; left: 0.5px; top: 8.5px; width: 100%; text-align: center;
  font: 600 11px/14px var(--v6-sans); color: #40403A;
  letter-spacing: .013em;
}
body.v6 .v6-note-body {
  position: absolute; left: 29.5px; top: 32px;
  /* Same wider face as the banner headline: the painted note lines are 89px and
     69px wide but only 10px tall, which the condensed face renders far too tall. */
  font: 600 10px/17px "Avenir Next", var(--v6-sans); color: #4A4A3E;
  letter-spacing: -.012em;
}
/* 20x17 heart, placed so it lands on the painted one (stage x886..906, y1831..1848)
   once the note's -2.75deg rotation is applied. */
body.v6 .v6-note-heart {
  position: absolute; left: 117.4px; top: 84.6px; width: 20px; height: 17px;
}

/* ============================== RESPONSIVE ==============================
   The stage is a fixed 1122x1897 canvas, so at any viewport other than exactly
   1122px it either leaves cream margins or does not fit. Down to 1000px the
   whole canvas is scaled instead of reflowed, which keeps the painted
   composition intact; below that, scaling would push the 10-12px caption text
   under 9px, so the layout reflows into a real fluid one instead.

   Every reflow rule repeats the stage class (`.v6-stage.v6-stage`). The fixed
   layout above reaches specificity (0,3,2) — `.v6-nav-links a:nth-child(1)` —
   and the reflow has to outrank it. Repeating one class is the least invasive
   way to do that: the alternative is gating 300 lines of pixel-matched CSS
   behind a media query and restating every colour, border and font under it. */

/* Scale the canvas to exactly fill the viewport width, at every width — so the
   design never sits in a column with cream margins beside it, and a wide screen
   gets a big hero rather than a small one floating in the middle.

   `zoom` is what makes this work at all: it scales layout (unlike `transform`,
   which would leave the page's height measured at the unscaled 1897px). The
   factor has to be a plain number, and CSS cannot divide a length by a length
   portably — `tan(atan2(a, b))` is the standard way to type-cast a ratio of two
   lengths into a unitless number, and is supported everywhere trig functions
   are. At exactly 1122px this evaluates to 1, so the pixel match is untouched. */
/* The canvas is only scaled while the window is at least as wide-shouldered as
   the hero itself (3/2 — see the note on the reflow block below). Narrower than
   that and there is no scale factor that both fills the screen and keeps the
   copy on it, so the fluid layout takes over instead. */
@media (min-width: 1000px) and (min-aspect-ratio: 3/2) {
  /* Fill the width, but never so much that the hero (nav + scene = 720px of the
     design) grows past the fold — whichever constraint binds first wins. On a
     window wider than the hero's 1122:720 aspect the height term binds, the
     stage is then narrower than the window, and the scene's 300px of extension
     on each side covers the difference. Everything below the hero is cream on a
     cream page, so a narrower stage leaves no visible edge there. */
  body.v6 .v6-stage {
    zoom: min(tan(atan2(100vw, 1122px)), tan(atan2(100svh, 720px)));
  }

  /* The hero-only page has nothing below the fold, so the same "narrower stage"
     that is invisible on /v6-full shows there as a band of cream under the
     scene — 12px on a 1512x982 laptop, and growing every time the window is
     narrowed. The fix is to let the height term win a little sooner: measuring
     the width against 1080px rather than the full 1122px canvas lets the stage
     run up to 3.9% wider than the window, which is exactly enough for the height
     term to bind at every aspect down to 3/2, where the reflow takes over.
     What the overflow costs: `margin: 0 auto` resolves to 0 once there is no
     free space, so the excess is cut from the right edge only, and the
     right-most thing on the canvas is the nav pill, which ends at x1056 — 94.1%
     of 1122, clear of the 96.1% where the cut starts. Everything past it is
     painted scenery and the scene's own bleed. */
  body.v6-hero .v6-stage {
    zoom: min(tan(atan2(100vw, 1080px)), tan(atan2(100svh, 720px)));
  }
}

/* 100vw counts the classic scrollbar that Windows/Linux reserve, which would
   leave the scaled canvas a scrollbar-width too wide. Clipping that is
   invisible; a permanent horizontal scrollbar would not be. */
body.v6 { overflow-x: hidden; }

/* Two triggers, and together with the query above they tile the whole space of
   window shapes — exactly one layout is always in force.

   The width trigger is the original one: under 1000px, scaling the canvas would
   push the 10-12px caption text below 9px.

   The aspect trigger (added 2026-08-03) is about the *shape* of the window, not
   its size. Dragging a laptop window narrower lowers the aspect until the
   canvas is being scaled to fit the width, which leaves it shorter than the
   window — harmless on a page that scrolls, but on the hero-only homepage it is
   a band of cream under the painting that grows as you drag. Below 3/2 no scale
   factor fixes that (covering the height would carry the headline off the side),
   so the fluid layout takes the job: it has no fixed height to run out of. */
@media (max-width: 999px), (max-aspect-ratio: 3/2) {

  body.v6 .v6-stage.v6-stage {
    width: auto; height: auto; overflow: visible;
    max-width: 860px; margin: 0 auto;
    padding: 0 20px 40px;
    box-sizing: border-box;
    /* Both aspect features are inclusive, so at exactly 3/2 the canvas query
       above matches too and its `zoom` would scale this fluid layout — a page
       1.39x bigger than the window. This block is later and one class more
       specific, so putting the reset here hands the tie to the fluid layout and
       makes the overlap harmless instead of load-bearing. */
    zoom: 1;
  }

  /* The hero-only page's 720px is a desktop-zoom device — it only means "one
     screen" while the stage is still the fixed canvas being scaled to fit.
     Here the layout is static and fluid, so a fixed height would either clip
     the scene or strand a band of cream under it. The rule above already
     resets height, but it ties with this selector on specificity, so state it
     explicitly rather than leave the hero page depending on source order.
     Mobile is allowed to scroll: it is one screen by intent, not by height. */
  body.v6-hero .v6-stage.v6-stage { height: auto; }

  /* Drop the whole fixed-stage coordinate system in one pass. */
  body.v6 .v6-stage.v6-stage :is(header, section, div, ol, ul, dl, li, figure,
                                 figcaption, aside, h1, h2, h3, p, dt, dd, a, span, img) {
    position: static;
    left: auto; top: auto; right: auto; bottom: auto;
    width: auto; height: auto;
  }
  body.v6 .v6-stage.v6-stage img { max-width: 100%; height: auto; }

  /* Decorative marks with nowhere to sit once the art is fluid. */
  body.v6 .v6-stage.v6-stage .v6-phones { display: none; }

  body.v6 .v6-stage.v6-stage :is(.v6-cta-spark-l, .v6-cta-spark-r,
                                 .v6-note-clip, .v6-cta-bird) { display: none; }

  /* Padding-sized rather than a fixed height + matching line-height: at 320px
     the label would wrap and spill straight out of the pill. */
  body.v6 .v6-stage.v6-stage .v6-btn {
    display: inline-block;
    padding: 12px 24px;
    height: auto;
    font-size: 15px; line-height: 1.15;
    letter-spacing: .02em;
    white-space: nowrap;
  }

  /* -------------------------------- nav -------------------------------- */
  body.v6 .v6-stage.v6-stage .v6-nav {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 10px 16px;
    padding: 20px 0 6px;
  }
  body.v6 .v6-stage.v6-stage .v6-nav-links {
    order: 3; width: 100%;
    display: flex; flex-wrap: wrap; gap: 6px 20px;
    padding-top: 2px;
  }
  body.v6 .v6-stage.v6-stage .v6-nav-links a { font-size: 14.5px; }
  body.v6 .v6-stage.v6-stage .v6-brand {
    flex: 0 0 auto;
    display: block; width: 134px;
  }
  body.v6 .v6-stage.v6-stage .v6-brand-lockup { width: 100%; }
  /* Never let the pill shrink under its own label — if the row runs out of
     room it wraps to its own line instead of clipping the text. */
  body.v6 .v6-stage.v6-stage .v6-nav-cta { flex: 0 0 auto; white-space: nowrap; }

  /* ------------------------------- hero -------------------------------- */
  /* The hero owns the first screen: copy at the top, painted scene pinned to
     the bottom edge, so above the fold is the whole hero and nothing else. */
  /* Grid rather than flex-wrap, so the copy stays packed on rows 1-3 and the
     scene has a row of its own. */
  body.v6 .v6-stage.v6-stage .v6-hero {
    display: grid;
    grid-template-columns: auto auto;
    grid-template-rows: auto auto auto auto;
    justify-content: start; align-items: center;
    column-gap: 18px; row-gap: 14px;
    padding-top: 22px;
  }
  body.v6 .v6-stage.v6-stage .v6-h1 {
    grid-area: 1 / 1 / 2 / -1;
    font-size: clamp(34px, 8.4vw, 54px);
    line-height: 1.06;
    letter-spacing: .01em;
  }
  body.v6 .v6-stage.v6-stage .v6-lede {
    grid-area: 2 / 1 / 3 / -1;
    font-size: 16px; line-height: 22px;
  }
  body.v6 .v6-stage.v6-stage .v6-lede br { display: none; }
  /* Row 3 is the store availability row: the pill and the play link that used to
     hold rows 3 and 4 were both cut on 2026-07-31. */
  body.v6 .v6-stage.v6-stage .v6-stores {
    grid-area: 3 / 1 / 4 / -1;
    position: static; gap: 8px; flex-wrap: wrap; padding-top: 2px;
  }
  /* the blanket reset above zeroes their height, which squashes the badges */
  body.v6 .v6-stage.v6-stage .v6-store { height: 42px; padding: 0 13px; }
  body.v6 .v6-stage.v6-stage .v6-store small { font-size: 8px; line-height: 10px; }
  body.v6 .v6-stage.v6-stage .v6-store strong { font-size: 14px; line-height: 15px; }
  body.v6 .v6-stage.v6-stage .v6-stores svg { width: 15px; height: 15px; }
  body.v6 .v6-stage.v6-stage .v6-hero-scene {
    grid-area: 4 / 1 / 5 / -1;
    width: calc(100% + 40px); max-width: none;
    margin: 12px -20px 0;
  }

  /* ------------------------- everything you need ------------------------ */
  body.v6 .v6-stage.v6-stage .v6-feat { padding-top: 34px; }
  body.v6 .v6-stage.v6-stage .v6-h2 {
    font-size: clamp(23px, 5.4vw, 28px); line-height: 1.14; letter-spacing: 0;
  }
  /* The five stage columns are far too narrow to survive here, so the cards go
     back to being cards: as many per row as 240px allows, each as tall as its
     own copy. */
  body.v6 .v6-stage.v6-stage .v6-feats {
    display: grid; gap: 16px;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    margin-top: 20px;
  }
  /* Relative, not static: the number chip is still absolute and would otherwise
     anchor to the stage. */
  body.v6 .v6-stage.v6-stage .v6-featcard { position: relative; padding-bottom: 18px; }
  body.v6 .v6-stage.v6-stage .v6-feat-num {
    position: absolute; left: 14px; top: 12px;
    width: 28px; height: 28px;
  }
  /* The art keeps its `auto` side margins from the fixed layout, so it stays
     centred at whatever width the card lands on. */
  body.v6 .v6-stage.v6-stage .v6-feat-art { width: 140px; margin-top: 36px; }
  body.v6 .v6-stage.v6-stage .v6-featcard h3 { font-size: 16px; line-height: 20px; }
  body.v6 .v6-stage.v6-stage .v6-featcard > p { font-size: 13.5px; line-height: 18px; margin-top: 6px; }

  /* ----------------------------- CTA banner ----------------------------- */
  body.v6 .v6-stage.v6-stage .v6-cta {
    position: relative;
    margin-top: 44px;
    padding: 28px 20px 30px;
    text-align: center;
  }
  body.v6 .v6-stage.v6-stage .v6-cta-band {
    display: block;
    position: absolute; inset: 0;
    width: auto; height: auto;
  }
  body.v6 .v6-stage.v6-stage .v6-cta > *:not(.v6-cta-band) { position: relative; z-index: 2; }

  /* This crop's own background is the page cream (on the stage it straddles the
     band's edge), so it needs blending to sit inside the lavender on mobile. */
  body.v6 .v6-stage.v6-stage .v6-cta-left {
    width: 160px; margin: 0 auto 4px;
    mix-blend-mode: multiply;
  }
  body.v6 .v6-stage.v6-stage .v6-cta-h {
    width: auto; font-size: clamp(24px, 6vw, 34px); line-height: 1.18;
  }
  body.v6 .v6-stage.v6-stage .v6-cta-btn { margin-top: 18px; }
  body.v6 .v6-stage.v6-stage .v6-cta-foot { font-size: 12.5px; line-height: 16px; margin-top: 12px; }

  body.v6 .v6-stage.v6-stage .v6-note {
    width: min(250px, 100%); height: auto;
    margin: 26px auto 0;
    padding: 14px 16px 16px;
    text-align: center;
  }
  /* ::before is the front sheet and paints over static children, so the note's
     own content has to be lifted back above it. */
  body.v6 .v6-stage.v6-stage .v6-note > * { position: relative; z-index: 1; }
  body.v6 .v6-stage.v6-stage .v6-note::before { left: 6px; top: -7px; width: 100%; height: 100%; }
  body.v6 .v6-stage.v6-stage .v6-note-title { font-size: 13px; line-height: 17px; }
  body.v6 .v6-stage.v6-stage .v6-note-body { font-size: 12.5px; line-height: 19px; margin-top: 4px; }
  body.v6 .v6-stage.v6-stage .v6-note-heart { display: block; width: 20px; margin: 8px auto 0; }
}

/* ---- The hero-only page below the stage breakpoint -------------------------
   The reflowed page has no grid and no banner under the hero any more, so it
   ends wherever the badges and the art happen to end — on a phone that left a
   ~260px band of empty cream under the scene, which is exactly the failure the
   659px block above was written to get rid of the first time.

   The fix the old `min-height: 100svh - 104px` could not manage: give the art a
   *definite* box to fill instead of asking an intrinsically-sized <img> to
   stretch. The stage is a flex column of at least one screen, main and the hero
   pass the leftover height down, and the hero's last grid row takes it as 1fr;
   the <picture> stretches into that row and the image fills it with `cover`,
   bottom-anchored so the plaza and the phone deck are what survives the crop.
   No magic numbers: the nav can change height and this still lands on the
   viewport's bottom edge.

   Deliberately AFTER the 659/389px blocks, not inside the 999px one: their
   `.v6-hero-scene` rules match at the same specificity, so only source order
   puts this last. Scoped to body.v6-hero, so /v6-full — which has a whole page
   below its hero and wants none of this — is untouched.

   Mobile is not held to the desktop no-scroll rule; it just has to end on the
   painting rather than on a band of cream. Same trigger pair as the reflow
   block: a narrowed laptop window lands here too, and it is the reason it does
   — this is what actually fills the screen once the canvas has given up. */
@media (max-width: 999px), (max-aspect-ratio: 3/2) {
  body.v6-hero .v6-stage.v6-stage {
    display: flex; flex-direction: column;
    min-height: 100svh;
    padding-bottom: 0;
  }
  body.v6-hero .v6-stage.v6-stage main {
    flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
  }
  body.v6-hero .v6-stage.v6-stage .v6-hero {
    flex: 1 1 auto; min-height: 0;
    grid-template-rows: auto auto auto 1fr;
  }
  /* `picture` is the grid item here — it is not in the reflow's blanket reset,
     and the image is its content. It has to stretch before the image can. */
  body.v6-hero .v6-stage.v6-stage .v6-hero .v6-scene {
    display: block;
    grid-area: 4 / 1 / 5 / -1;
    align-self: stretch;
    min-height: 0;
  }
  /* The stage's 860px cap is a reading measure, and it is right for the copy —
     but this block now also catches a laptop window dragged narrow, where an
     860px column would stop the painting short of both edges and leave the
     cream at the sides that the block exists to remove. So the hero page drops
     the cap and holds the measure on the copy instead; the scene's -20px
     margins then reach the window's edges on their own, because the stage is
     the window. */
  body.v6-hero .v6-stage.v6-stage { max-width: none; }
  body.v6-hero .v6-stage.v6-stage :is(.v6-h1, .v6-lede) { max-width: 640px; }

  body.v6-hero .v6-stage.v6-stage .v6-hero-scene {
    height: 100%; min-height: 0;
    margin: 0 -20px;              /* full-bleed past the stage's side padding */
    object-fit: cover;
    object-position: 50% 100%;
  }
}

/* Portrait phones use a separate, text-free 941x1672 plate derived from the
   approved mobile composition. Live HTML is positioned in the plate's original
   UI coordinates, preserving accessible copy and controls while matching the
   reference art exactly. Every length below is proportional to the plate width,
   so the composition scales as one piece from 320px through 659px. */
@media (max-width: 659px) and (orientation: portrait) {
  body.v6 { --v6-cream: #FCF4EA; }
  body.v6-hero .v6-stage.v6-stage {
    position: relative;
    display: block;
    width: 100%;
    height: 177.68vw;
    min-height: 177.68vw;
    max-width: none;
    padding: 0;
    overflow: hidden;
  }
  body.v6-hero .v6-stage.v6-stage main {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
  }
  /* A zero-height bar along the top, not an `inset: 0` sheet: the brand hangs
     off it absolutely, and a full-stage nav at z-index 3 sat over the hero CTA
     and swallowed every tap on it. */
  body.v6-hero .v6-stage.v6-stage .v6-nav {
    position: absolute;
    inset: 0 0 auto;
    z-index: 3;
    display: block;
    padding: 0;
  }
  body.v6-hero .v6-stage.v6-stage .v6-brand {
    position: absolute;
    left: 5.1vw;
    top: max(2.4vw, env(safe-area-inset-top));
    width: 25.1vw;
  }
  body.v6-hero .v6-stage.v6-stage .v6-brand-lockup { width: 100%; }
  body.v6-hero .v6-stage.v6-stage .v6-hero {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
  }
  body.v6-hero .v6-stage.v6-stage .v6-hero .v6-scene {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: block;
    width: 100vw;
    max-width: 100vw;
    height: 177.68vw;
    margin: 0;
    overflow: hidden;
  }
  body.v6-hero .v6-stage.v6-stage .v6-hero-scene {
    position: static;
    width: 100vw;
    height: 177.68vw;
    min-height: 0;
    margin: 0;
    object-fit: fill;
    object-position: 50% 0;
  }
  body.v6-hero .v6-stage.v6-stage .v6-h1 {
    position: absolute;
    left: 5vw;
    top: 19.7vw;
    z-index: 2;
    width: 57vw;
    max-width: none;
    font-family: "Avenir Next", var(--v6-sans);
    font-size: clamp(32px, 8.4vw, 54px);
    line-height: .99;
    letter-spacing: -.012em;
    text-wrap: nowrap;
  }
  body.v6-hero .v6-stage.v6-stage .v6-lede {
    position: absolute;
    left: 5.4vw;
    top: 40.3vw;
    z-index: 2;
    width: 48vw;
    max-width: none;
    font-size: clamp(13px, 3.05vw, 18px);
    line-height: 1.25;
    letter-spacing: -.012em;
    text-wrap: nowrap;
  }
  body.v6-hero .v6-stage.v6-stage .v6-lede br { display: block; }
  body.v6-hero .v6-stage.v6-stage .v6-stores {
    position: absolute;
    left: 5.1vw;
    /* 61.6vw while the orange pill sat between this row and the lede. With the
       pill gone that left a hole; 51vw restores the lede's original gap to
       whatever follows it (~2vw) rather than inheriting the pill's slot. */
    top: 51vw;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 3px;
    width: auto;
    padding: 0;
  }
  body.v6-hero .v6-stage.v6-stage .v6-store {
    height: clamp(25px, 6.4vw, 42px);
    min-width: 0;
    justify-content: center;
    gap: 3px;
    padding: 0 4px;
    box-sizing: border-box;
    border-radius: 7px;
  }
  body.v6-hero .v6-stage.v6-stage .v6-store:nth-child(1),
  body.v6-hero .v6-stage.v6-stage .v6-store:nth-child(2) { width: 15.2vw; }
  body.v6-hero .v6-stage.v6-stage .v6-store:nth-child(3) { width: 12.7vw; }
  body.v6-hero .v6-stage.v6-stage .v6-store small {
    display: block;
    font-size: clamp(5px, 1vw, 6.5px);
    line-height: 1.1;
    letter-spacing: .025em;
  }
  body.v6-hero .v6-stage.v6-stage .v6-store strong {
    font-size: clamp(9px, 1.8vw, 11.5px);
    line-height: 1;
    letter-spacing: 0;
    white-space: nowrap;
  }
  body.v6-hero .v6-stage.v6-stage .v6-store svg {
    flex: 0 0 auto;
    width: clamp(10px, 2.4vw, 15px);
    height: clamp(10px, 2.4vw, 15px);
  }
}

/* ============================ THE POSTER ============================
   Between the phone plates and the desktop canvas sits everything else:
   tablets in both orientations, and any laptop window whose shape has made
   the fixed canvas give up (see the 3/2 note above). They all get the same
   composition — a centred proposition on clean cream, with the painted world
   rising full-bleed underneath it and running off the bottom edge.

   The hero is a flex column and the plate is its last item, so the band is
   simply whatever height is left under the copy. That is the whole trick: no
   magic top offset to keep in sync with the type scale, and no way for the
   badges to end up sitting on the painting, at any window shape.

   Trigger: everything from 660px up that the desktop canvas does not take —
   under 1000px by width, and above it by shape. The short-but-wide windows
   past 1200px used to fall through to the generic reflow and land on its
   left-aligned mobile stack, marooned in a screenful of cream; they belong
   here, so the block is bounded by the canvas' own condition rather than by
   a second, narrower width.

   `min-height: 521px` hands a big phone on its side straight back to the
   landscape block below, which is written against the generic reflow and only
   patches a few of its rules — overlapping the two produced a hybrid that
   clipped the headline. The second clause needs no such guard: at 1000px wide
   and 3/2 or squarer, the window is at least 667px tall by construction. */
@media (min-width: 660px) and (max-width: 999px) and (min-height: 521px),
       (min-width: 1000px) and (max-aspect-ratio: 3/2) {
  body.v6-hero .v6-stage.v6-stage {
    position: relative;
    display: block;
    width: 100%;
    /* One screen, and a floor under it so the composition stays intact rather
       than collapsing on a short window. 560px is the copy stack plus a band
       worth looking at; anything shorter than that in landscape is a phone,
       and the block below has it. */
    height: max(560px, 100svh);
    min-height: 560px;
    max-width: none;
    padding: 0;
    overflow: hidden;
  }
  body.v6-hero .v6-stage.v6-stage main {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    min-height: 0;
    box-sizing: border-box;
  }

  /* ------------------------------- nav -------------------------------- */
  body.v6-hero .v6-stage.v6-stage .v6-nav {
    position: absolute;
    inset: 0 0 auto;
    z-index: 4;
    display: flex;
    padding: clamp(16px, 2.4vh, 34px) clamp(26px, 3.6vw, 54px);
    box-sizing: border-box;
  }
  body.v6-hero .v6-stage.v6-stage .v6-brand {
    width: clamp(140px, 15.5vw, 210px);
  }
  body.v6-hero .v6-stage.v6-stage .v6-brand-lockup { width: 100%; }

  /* ---------------------------- the plate ------------------------------ */
  /* Full-bleed behind everything, not a band under the copy. That is the whole
     composition in one line: the plate keeps a well of its own cream across the
     middle of its upper half, the headline and the actions sit in that well,
     and the trees on one side and the building on the other rise past them. The
     copy is *in* the picture rather than stacked above it, which is what stops
     a tablet reading as two panels — a paragraph, then a photograph. */
  body.v6-hero .v6-stage.v6-stage .v6-hero .v6-scene {
    /* The reflow above hands the plate a grid area, and an absolutely
       positioned grid child is inset against *that area* rather than against
       the grid's padding box — which pinned the whole painting inside the row
       the badges happen to occupy. Give the area back before taking it out of
       flow. */
    grid-area: auto;
    position: absolute;
    inset: 0;
    z-index: 0;
    display: block;
    width: 100%;
    height: 100%;
    min-height: 0;
    margin: 0;
    overflow: hidden;
  }
  body.v6-hero .v6-stage.v6-stage .v6-hero-scene {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    min-height: 0;
    margin: 0;
    object-fit: cover;
    /* Anchored to the bottom, so what a crop takes is the cream overhead on a
       wide window and the outer planting on a tall one — never the plaza. */
    object-position: 50% 100%;
  }
  /* Both clips are desktop-weight assets built for the fixed canvas, where they
     are absolutely placed. Here the blanket reflow reset makes them static, so
     the phones clip took 650px out of the flow and pushed the entire
     proposition clean off the bottom edge of a landscape tablet — the headline,
     the lede and every action, gone. The still is the LCP image and the thing
     this composition is built around; 3MB of video is not what a tablet wants
     from it either. Same call as under 1000px, for the same two reasons. The
     block far below puts the clip back on a laptop, where it belongs. */
  body.v6-hero .v6-stage.v6-stage .v6-hero-motion {
    display: none;
  }

  /* ----------------------------- the copy ------------------------------ */
  /* Four rows packed at the top of the well. Every gap is a margin on the piece
     that owns it, so the stack keeps its rhythm as the type resizes. */
  body.v6-hero .v6-stage.v6-stage .v6-hero {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: grid;
    grid-template-columns: 100%;
    grid-template-rows: auto auto auto;
    /* Centred in the well, not pinned to the top of it. `safe` so a window too
       short for the stack pushes it down rather than off the top edge. */
    align-content: safe center;
    /* The reflow above sets a row-gap for its own two-column stack; inheriting
       it here would add 14px to all four seams. */
    gap: 0;
    width: 100%;
    height: 100%;
    min-height: 0;
    /* The floor of the well — where the painting starts — held back as padding,
       so the copy centres in the cream above it and can never reach the art.
       A real measurement rather than a guess: see --v6-plate-floor below. */
    padding: clamp(58px, 8.6vh, 124px) 0 var(--v6-plate-floor, 48svh);
    box-sizing: border-box;
    text-align: center;
  }
  body.v6-hero .v6-stage.v6-stage :is(.v6-h1, .v6-lede, .v6-stores) {
    position: relative;
    z-index: 2;
  }
  body.v6-hero .v6-stage.v6-stage .v6-h1 {
    grid-row: 1;
    width: min(94vw, 1000px);
    max-width: none;
    margin: 0 auto;
    font-family: "Avenir Next", var(--v6-sans);
    /* Sized off whichever of the two runs out first: width sets it on a tall
       tablet, height on a short laptop window, and the pair is what keeps the
       headline the same size *relative to the picture* across both. */
    font-size: clamp(42px, min(7.1vw, 10.3vh), 96px);
    line-height: 1.0;
    letter-spacing: -.02em;
    text-wrap: nowrap;
  }
  body.v6-hero .v6-stage.v6-stage .v6-lede {
    grid-row: 2;
    width: min(84vw, 660px);
    max-width: none;
    margin: clamp(12px, 2.2vh, 28px) auto 0;
    font-size: clamp(15px, min(1.85vw, 2.7vh), 22px);
    line-height: 1.35;
    text-wrap: pretty;
  }
  body.v6-hero .v6-stage.v6-stage .v6-lede br { display: none; }
  body.v6-hero .v6-stage.v6-stage .v6-stores {
    grid-row: 3;
    position: static;
    display: flex;
    justify-content: center;
    width: auto;
    margin: clamp(12px, 2.2vh, 28px) auto 0;
    padding: 0;
    gap: clamp(7px, .9vw, 12px);
    flex-wrap: nowrap;
  }
  body.v6-hero .v6-stage.v6-stage .v6-store {
    height: clamp(38px, 4.4vw, 56px);
    padding: 0 clamp(10px, 1.2vw, 16px);
    gap: clamp(6px, .8vw, 10px);
  }
  body.v6-hero .v6-stage.v6-stage .v6-store small {
    font-size: clamp(7px, .78vw, 10px);
    line-height: 1.2;
  }
  body.v6-hero .v6-stage.v6-stage .v6-store strong {
    font-size: clamp(12px, 1.32vw, 17px);
    line-height: 1.1;
  }
  body.v6-hero .v6-stage.v6-stage .v6-stores svg {
    width: clamp(14px, 1.5vw, 20px);
    height: clamp(14px, 1.5vw, 20px);
  }
}

/* ---- Where the painting starts -------------------------------------------
   Each plate keeps a well of cream across its upper half and begins the drawing
   at a known fraction of its own height — the landscape plate at 52%, the
   portrait one at 34%, where the tree canopies and the building's roof come up
   either side of the copy. Reserving that fraction as padding-bottom is what
   lets the copy centre in the cream above it and never reach the art.

   The landscape plate is 3:2, the widest shape the poster is ever served to
   (past 3/2 the desktop canvas takes over). Being at least as wide as every box
   it lands in, it can only ever be cropped at the SIDES, so its height always
   maps 1:1 onto the screen and the floor is simply 48svh. That is the whole
   reason it is 3:2 and not the 4:3 it started as: cropping the top pulled the
   phone deck up the screen as the window widened while the copy kept growing
   with it, and the two met at 1440x960 with the badges 63px inside the deck.

   The portrait plate is 3:4, not wide enough to make the same promise — from
   3:4 up to square it is cropped at the top instead — so it needs both
   readings. `max()` takes whichever is actually cropping, because the other
   always yields the smaller reserve:

     cropped at the sides   the plate's height IS the screen's height: 43svh.
     cropped at the top     the plate is scaled to the screen's WIDTH, so the
                            floor is measured up from the bottom edge: 56vw.

   The portrait pair is deliberately larger than its 34% art line needs. Sized
   to that line the copy rode too high on the screen; the flanking planting is
   scenery the copy is horizontally clear of anyway, so the extra reserve costs
   nothing and buys the headline a place lower in the frame (Martin, 2026-09-07).

   The landscape floor carries 4 units more than the geometry strictly needs:
   the bare figure puts the last badge exactly on the deck's top edge, which is
   correct and still reads as a collision. The portrait one needs no such margin
   — what its floor holds back is the flanking planting, which the copy is
   horizontally clear of anyway; the deck itself is far below at 73%. */
@media (max-aspect-ratio: 1/1) {
  body.v6-hero .v6-stage.v6-stage .v6-hero { --v6-plate-floor: max(43svh, 56vw); }
}
@media (min-aspect-ratio: 1/1) {
  body.v6-hero .v6-stage.v6-stage .v6-hero { --v6-plate-floor: 52svh; }
}

/* A phone turned sideways has too little height for the portrait stack. Treat
   the illustration as the second half of the composition instead: the message
   remains fully readable on the left and the product stays visible on the right,
   without requiring a scroll just to discover what Noodl looks like.

   The width goes to 999px, not 659px, because a big phone on its side is well
   past 660: an iPhone Pro Max lands at 932x430, which is wide enough to be
   taken for a tablet and only 430px tall. `max-height: 520px` is the condition
   doing the real work — no tablet is that short in either orientation — and
   this block sits after the poster so it wins that overlap outright, which is
   what keeps a 620px composition off a 430px screen. */
@media (max-width: 999px) and (orientation: landscape) and (max-height: 520px) {
  body.v6-hero .v6-stage.v6-stage .v6-nav {
    padding-top: max(12px, env(safe-area-inset-top));
    padding-bottom: 0;
  }
  body.v6-hero .v6-stage.v6-stage .v6-brand { width: 110px; }
  body.v6-hero .v6-stage.v6-stage .v6-brand-lockup { width: 100%; }
  body.v6-hero .v6-stage.v6-stage .v6-hero {
    grid-template-columns: minmax(280px, .9fr) minmax(0, 1.1fr);
    grid-template-rows: auto auto 1fr;
    align-items: start;
    column-gap: 22px;
    row-gap: 10px;
    padding-top: 8px;
  }
  body.v6-hero .v6-stage.v6-stage .v6-h1 {
    grid-area: 1 / 1 / 2 / 2;
    font-size: clamp(36px, 5.7vw, 46px);
    line-height: 1.02;
    letter-spacing: -.012em;
  }
  body.v6-hero .v6-stage.v6-stage .v6-lede {
    grid-area: 2 / 1 / 3 / 2;
    font-size: 15px;
    line-height: 20px;
    max-width: 36ch;
  }
  /* The badges are this layout's only action since the orange pill went, so
     unlike the rest of the reflow it keeps them — laid out along the foot of
     the copy column rather than under it, where there is no room. */
  body.v6-hero .v6-stage.v6-stage .v6-stores {
    grid-row: 3;
    display: flex;
    justify-content: start;
    gap: 6px;
    margin-top: 4px;
    align-self: start;
  }
  body.v6-hero .v6-stage.v6-stage .v6-store { height: 34px; padding: 0 8px; gap: 5px; }
  body.v6-hero .v6-stage.v6-stage .v6-store small { font-size: 6.5px; line-height: 8px; }
  body.v6-hero .v6-stage.v6-stage .v6-store strong { font-size: 11px; line-height: 12px; }
  body.v6-hero .v6-stage.v6-stage .v6-stores svg { width: 13px; height: 13px; }
  body.v6-hero .v6-stage.v6-stage .v6-hero .v6-scene {
    grid-area: 1 / 2 / 4 / 3;
    height: 100%;
    min-height: 0;
  }
  body.v6-hero .v6-stage.v6-stage .v6-hero-scene {
    width: calc(100% + 20px);
    height: 100%;
    margin: 0 -20px 0 0;
    object-fit: cover;
    object-position: 53% 100%;
  }
}

/* The screenshot plane uses the same cover scale and bottom anchor as its
   background. Container units keep the devices attached to the plaza even
   when the scene is cropped by a tablet or a landscape phone. */
@media (max-width: 999px), (max-aspect-ratio: 3/2) {
  body.v6-hero .v6-stage.v6-stage .v6-hero .v6-scene {
    position: relative;
    container-type: size;
  }
  body.v6-hero .v6-stage.v6-stage .v6-phones {
    display: block;
    position: absolute;
    inset: auto auto 0 50%;
    width: max(100cqw, 150cqh);
    height: auto;
    aspect-ratio: 3 / 2;
    transform: translateX(-50%);
    overflow: clip;
    pointer-events: none;
  }
  /* A lighter version of the desktop cream wash separates the devices from
     the illustration. Its proportions follow the screenshot plane. */
  body.v6-hero .v6-stage.v6-stage .v6-phones::before {
    display: block;
    left: 49%;
    top: 74%;
    width: 74%;
    height: 76%;
    background: radial-gradient(closest-side,
      rgba(252, 244, 234, .78) 0%,
      rgba(252, 244, 234, .56) 40%,
      rgba(252, 244, 234, .22) 68%,
      rgba(252, 244, 234, 0) 100%);
  }
  body.v6-hero .v6-stage.v6-stage .v6-phone-wrap {
    position: absolute;
    height: auto;
  }
  body.v6-hero .v6-stage.v6-stage .v6-phone { width: 100%; height: auto; }
  body.v6-hero .v6-stage.v6-stage :is(.v6-phone, .v6-phone-note) {
    border-width: clamp(1px, .25cqw, 3px);
    border-radius: 13% / 6%;
  }
  body.v6-hero .v6-stage.v6-stage .v6-phone-l { left: 31%; top: 54%; width: 12.8%; }
  body.v6-hero .v6-stage.v6-stage .v6-phone-r { left: 56%; top: 53.3%; width: 12.7%; }
  body.v6-hero .v6-stage.v6-stage .v6-phone-c { left: 42.8%; top: 52.2%; width: 13.4%; }
  body.v6 .v6-stage .v6-phone-wrap .v6-phone-note { font-size: clamp(6px, .9cqw, 10px); }
}

@media (min-width: 660px) and (max-aspect-ratio: 1/1) {
  body.v6-hero .v6-stage.v6-stage .v6-phones {
    width: max(100cqw, 75cqh);
    aspect-ratio: 1254 / 1672;
  }
  body.v6-hero .v6-stage.v6-stage .v6-phones::before {
    left: 46%; top: 84%; width: 78%; height: 46%;
  }
  body.v6-hero .v6-stage.v6-stage .v6-phone-l { left: 26.5%; top: 74.1%; width: 13%; }
  body.v6-hero .v6-stage.v6-stage .v6-phone-r { left: 52.7%; top: 73.8%; width: 13%; }
  body.v6-hero .v6-stage.v6-stage .v6-phone-c { left: 39.1%; top: 73.1%; width: 14.1%; }
}

@media (max-width: 659px) and (orientation: portrait) {
  body.v6-hero .v6-stage.v6-stage .v6-phones {
    width: 100cqw;
    aspect-ratio: 941 / 1672;
  }
  body.v6-hero .v6-stage.v6-stage .v6-phones::before {
    left: 49%; top: 67%; width: 126%; height: 68%;
  }
  body.v6-hero .v6-stage.v6-stage .v6-phone-l { left: 12%; top: 52.5%; width: 27%; }
  body.v6-hero .v6-stage.v6-stage .v6-phone-r { left: 61.5%; top: 52.5%; width: 26%; }
  body.v6-hero .v6-stage.v6-stage .v6-phone-c { left: 35.5%; top: 50%; width: 28.5%; }
  body.v6 .v6-stage .v6-phone-wrap .v6-phone-note { font-size: clamp(7px, 2cqw, 10px); }
}

/* Full-screen plates remain absolute; the short landscape layout uses the
   scene's grid cell instead. Both establish the container used above. */
@media (max-width: 659px) and (orientation: portrait),
       (min-width: 660px) and (max-width: 999px) and (min-height: 521px),
       (min-width: 1000px) and (max-aspect-ratio: 3/2) {
  body.v6-hero .v6-stage.v6-stage .v6-hero .v6-scene { position: absolute; }
}

/* ============================ PAYMENTS PAUSED ============================
   The notice shown while checkout is paused (FoundingMember.checkout_paused?).
   Fixed, like the music toggle: top centre on desktop, in the sky between the
   logo and the music button; a bottom sheet edge on phones, where the logo
   fills the top. Same warning colours as the cards' alert flash. */
body.v6 .v6-paused {
  position: fixed;
  top: 14px; left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  width: max-content; max-width: min(560px, calc(100vw - 200px));
  margin: 0;
  padding: 9px 16px;
  border: 1.5px solid var(--v6-locked-line);
  border-radius: 12px;
  background: var(--v6-locked-bg);
  box-shadow: 0 6px 18px rgb(15 42 27 / .12);
  color: #7A3406;
  font: 500 13.5px/18px var(--v6-sans);
  text-align: center;
  text-wrap: balance;
}
body.v6 .v6-paused strong { font-weight: 700; }
@media (max-width: 999px), (max-aspect-ratio: 3/2) {
  body.v6 .v6-paused {
    top: auto; bottom: max(16px, env(safe-area-inset-bottom));
    left: 16px; right: 16px;
    transform: none;
    width: auto; max-width: none;
  }
}

/* ============================= MUSIC TOGGLE =============================
   A viewport-fixed control, deliberately outside .v6-stage. Inside the stage it
   would inherit `zoom` (so its hit target would shrink and grow with the window),
   scroll away with the nav, and get flattened to `position: static` by the mobile
   reflow's blanket rule. Fixed and stage-independent, it is in the corner and
   reachable at every width and every scroll position.

   The shared Cream button stylesheet supplies the face, outline, and press motion. */
body.v6 .v6-music {
  position: fixed;
  top: 14px; right: 12px;
  z-index: 60;
  width: 38px; height: 38px;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
body.v6 .v6-music.v6-jelly { padding: 0; border-radius: 50%; }
body.v6 .v6-music-icon { display: block; line-height: 0; }

/* Off state: the horn is an empty outline, waves hidden, a small x beside it.
   On state: the horn fills with the button ink and the waves take the x's place. */
body.v6 .v6-music .v6-music-wave { opacity: 0; }
body.v6 .v6-music .v6-music-off  { opacity: .75; }
body.v6 .v6-music[aria-pressed="true"] .v6-music-horn { fill: currentColor; }
body.v6 .v6-music[aria-pressed="true"] .v6-music-wave { opacity: 1; }
body.v6 .v6-music[aria-pressed="true"] .v6-music-off  { opacity: 0; }

/* Screen-reader-only state text, so the button announces a change and not just
   a pressed flag. */
body.v6 .v6-music-sr {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* The waves breathe outward while the track plays — the same "something is
   quietly alive" register as the phone screens, at the same slow tempo. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes v6-music-wave { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
  body.v6 .v6-music[aria-pressed="true"] .v6-music-wave-1 {
    animation: v6-music-wave 1.8s ease-in-out infinite;
  }
  body.v6 .v6-music[aria-pressed="true"] .v6-music-wave-2 {
    animation: v6-music-wave 1.8s ease-in-out .45s infinite;
  }
}

/* The hero can extend beyond the viewport near its desktop reflow threshold.
   Reserve space for the fixed music control while both buttons are visible. */
@media (min-width: 1000px) and (min-aspect-ratio: 3/2) and (max-aspect-ratio: 8/5) {
  body.v6-hero .v6-nav-cta.v6-jelly { right: 98px; }
}

/* Keep the icon compact where the gap beside the CTA narrows. */
@media (min-width: 1000px) and (max-width: 1199px) {
  body.v6 .v6-music { right: 8px; }
  body.v6 .v6-music svg { width: 18px; height: 18px; }
}

/* Match the desktop CTA's height and top offset after stage scaling. */
@media (min-width: 1000px) and (min-aspect-ratio: 3/2) {
  body.v6 .v6-music {
    width: min(calc(100vw * 32 / 1122), calc(100svh * 32 / 720));
    height: min(calc(100vw * 32 / 1122), calc(100svh * 32 / 720));
    top: min(calc(100vw * 12 / 1122), calc(100svh * 12 / 720));
  }
  body.v6-hero .v6-music {
    width: min(calc(100vw * 32 / 1080), calc(100svh * 32 / 720));
    height: min(calc(100vw * 32 / 1080), calc(100svh * 32 / 720));
    top: min(calc(100vw * 12 / 1080), calc(100svh * 12 / 720));
  }
}

/* The fluid layout hides the desktop nav CTA, leaving the top-right corner free
   for the music control. Keeping it in the header makes the control predictable
   and stops it floating over the illustrated product UI at the bottom. */
@media (max-width: 999px), (max-aspect-ratio: 3/2) {
  body.v6 .v6-music {
    top: max(12px, env(safe-area-inset-top));
    right: max(16px, env(safe-area-inset-right));
    bottom: auto;
    width: 44px; height: 44px;
  }
}

/* ============================ WAITLIST MODAL ============================
   The painted plate has no room for an email field, so every CTA opens this
   instead. Same reasoning as the music button: it sits outside .v6-stage, so
   none of the stage's `zoom` or its mobile reflow rules reach it — and a
   showModal()'d dialog is promoted to the top layer, above both.

   Chrome is the page's own vocabulary: cream paper, 2px ink outline, the
   letterpress offset shadow, and 3D button treatment. The second sheet behind the card
   (::before) is the same trick the pinned note in the CTA banner uses. */
/* Opening a modal <dialog> locks the document's scroll, which on any machine with
   classic (non-overlay) scrollbars — a Mac with a mouse attached, or Windows —
   makes the scrollbar disappear. The viewport widens by its width and everything
   centred, the dialog included, jumps sideways at the moment of the click.
   Reserving the gutter permanently keeps the page still. */
html:has(.v6-wait) { scrollbar-gutter: stable; }

body.v6 .v6-wait {
  padding: 0;
  border: 0;
  background: none;
  overflow: visible;
  /* application.css opens with `* { margin: 0 }`, which beats the UA stylesheet's
     `dialog { margin: auto }` — without this the modal pins to the top-left. */
  margin: auto;
  max-width: min(430px, calc(100vw - 32px));
  max-height: calc(100vh - 40px);
  color: var(--v6-body);
}
body.v6 .v6-wait::backdrop {
  background: rgba(28, 34, 26, .58);
  backdrop-filter: blur(2px);
}

/* No-JS / no-showModal path: an anchor to #waitlist still opens the card. The
   dialog is not in the top layer here, so it has to place itself.

   Scoped to documents WITHOUT the v6-js class (set in the head before paint):
   with JS, showModal owns the dialog, and a live :target rule would re-show the
   card as an inline block the instant it was closed — `history.replaceState`
   takes the hash out of the URL but browsers do not recompute :target from it. */
html:not(.v6-js) body.v6 .v6-wait:not([open]):target {
  display: block;
  position: fixed;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 100;
}

body.v6 .v6-wait-card {
  position: relative;
  background: var(--v6-card);
  border: 2px solid var(--v6-outline);
  border-radius: 14px;
  box-shadow: 0 6px 0 rgba(15, 42, 27, .17), 0 24px 48px rgba(15, 42, 27, .22);
  overflow: hidden;   /* clips the art band into the card's rounded corners */
}
/* The sheet of paper underneath, peeking out at a slight angle. It hangs off the
   dialog rather than the card: the card clips its own overflow, which would cut
   the second sheet off at exactly the edges where it is supposed to show. */
body.v6 .v6-wait::before {
  content: "";
  position: absolute; inset: 0;
  background: var(--v6-beige);
  border: 2px solid var(--v6-outline);
  border-radius: 14px;
  transform: rotate(-1.5deg) translate(-7px, 6px);
  z-index: -1;
}

body.v6 .v6-wait-x.v6-jelly {
  --button-face: #fff6e6;
  --button-edge: #a58c65;
  --button-base: #e3c798;
  --button-ink: #483b2b;
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 36px; height: 36px;
  display: grid; place-items: center;
  padding: 0;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
  border-radius: 50%;
}

/* Noodl on his deckchair, sitting straight on the card.

   The crop used to carry its own painted paper, which is not flat — it drifts
   from rgb(252,239,223) to rgb(253,242,230) across one 210px crop, and the 2x
   variant is warmer still — so against any single backdrop colour it read as two
   tones. It has true alpha now (art/v6/tools/alpha-key.py --flood, originals in
   versions/), so the card's cream is the only paper in the card. */
body.v6 .v6-wait-art {
  padding: 20px 0 0;
  display: grid; place-items: center;
  background: var(--v6-card);
}
body.v6 .v6-wait-miso {
  /* Locked to the source's 210x178: the @2x webp is 420 wide, so anything larger
     upscales a painted plate on a retina screen. */
  width: 210px; height: 178px;
}

body.v6 .v6-wait-body { padding: 20px 26px 24px; text-align: center; }

body.v6 .v6-wait-h {
  font: 700 25px/29px "Avenir Next", var(--v6-sans);
  letter-spacing: -.018em;
  color: var(--v6-green);
}
body.v6 .v6-wait-lede {
  margin-top: 8px;
  font: 500 14.5px/20px var(--v6-sans);
  color: var(--v6-muted);
}

body.v6 .v6-wait-form { margin-top: 16px; display: grid; gap: 9px; }
body.v6 .v6-wait-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

body.v6 .v6-wait-field {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 16px;
  background: #FFFDF8;
  min-height: 48px;
  border: 1.8px solid var(--v6-outline);
  border-radius: var(--noodl-radii-sm);   /* the button's radius: field and button read as one pair */
  font: 500 var(--noodl-type-sizes-body)/1.2 var(--v6-sans);
  color: var(--v6-body);
  -webkit-appearance: none; appearance: none;
}
body.v6 .v6-wait-field::placeholder { color: #94907F; }
body.v6 .v6-wait-field:focus-visible { outline: 2.5px solid var(--v6-orange); outline-offset: 2px; }
body.v6 .v6-wait-field-bad { border-color: var(--v6-orange); background: #FFF6EC; }

body.v6 .v6-wait-btn {
  width: 100%;
  min-height: 44px;
  padding: 10px 16px 8px;
  background: var(--button-face);
  color: var(--button-ink);
  border: 2px solid var(--button-edge);
  border-radius: 11px;
  box-shadow: 0 4px 0 var(--button-base), 0 6px 0 var(--button-edge), 0 10px 0 #e8dbc750;
  font: 600 14px/1.2 "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: -.25px;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
  transition: transform 160ms ease-out, box-shadow 160ms ease-out;
}

body.v6 .v6-wait-flash {
  margin-top: 12px;
  padding: 9px 14px;
  border-radius: 10px;
  border: 1.5px solid;
  font: 500 13.5px/18px var(--v6-sans);
}
body.v6 .v6-wait-ok  { background: #EAF1E4; border-color: #6F7A62; color: #24361F; }
body.v6 .v6-wait-bad { background: var(--v6-locked-bg); border-color: var(--v6-locked-line); color: #7A3406; }

/* Success state. Its button is a direct child of the body, not a row of
   .v6-wait-form, so it carries none of the form's spacing and would otherwise sit
   flush against the line above it. Same rhythm as the form: a clear step down from
   the message, then the action. */
body.v6 .v6-wait-ok + .v6-wait-lede { margin-top: 10px; }
body.v6 .v6-wait-body > .v6-wait-btn { margin-top: 18px; }

/* The card lands like a page being put down — never on the success state, where
   the movement would read as the message arriving twice. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes v6-wait-in {
    from { opacity: 0; transform: translateY(10px) scale(.975); }
    to   { opacity: 1; transform: none; }
  }
  body.v6 .v6-wait[open] .v6-wait-card { animation: v6-wait-in .26s cubic-bezier(.2, .9, .3, 1.1); }
}

@media (max-width: 420px) {
  /* The plate shrinks, and the frame shrinks with it — height has to stay on the
     image alone, or a fixed band height clips it into the headline below. */
  body.v6 .v6-wait-art { padding: 18px 0 2px; }
  body.v6 .v6-wait-miso { width: 178px; height: 151px; }
  body.v6 .v6-wait-body { padding: 16px 18px 20px; }
  body.v6 .v6-wait-h { font-size: 22px; line-height: 26px; }
  body.v6 .v6-wait-x { width: 44px; height: 44px; top: 10px; right: 10px; }
}

/* ========================= FOUNDING MEMBER MODAL =========================
   The waitlist card with an offer in it: same paper, outline, second sheet,
   close button and 3D button, all inherited from the .v6-wait-* rules above.
   What follows is only what the offer adds — a badge, a looping video in place
   of the painted plate, a perk list and a secondary "later" link. */
/* Wider than the waitlist card: the trailer wants room, and the checks and the
   two panels sit in rows at this width (they stack again under 640px). */
body.v6 .v6-found {
  max-width: min(720px, 100vw - 32px);
  /* The one deliberate step off the shared type scale (tokens.json typeSizes,
     h1 = 31px): the offer headline is the card's display line at 720px wide. */
  --v6-found-display: 34px;
  --v6-found-display-lh: 38px;
  /* Everything in the card but the trailer, plus the 40px the card keeps off
     the viewport's edges: measured at 1280x900, with a few px to spare. */
  --v6-found-rest: 615px;
}
/* Taller than the waitlist card, so on a short viewport it scrolls inside its
   frame instead of being clipped by the card's overflow:hidden. */
body.v6 .v6-found .v6-wait-card {
  max-height: calc(100vh - 40px);
  overflow: hidden auto;   /* never sideways; down only when the viewport is shorter than the card */
  overscroll-behavior: contain;
}

/* Transparent so the corner garden underneath shows through (.v6-wait-art
   paints the card cream by default). */
body.v6 .v6-found-art { position: relative; padding: 18px 36px 0; gap: 14px; background: transparent; }
body.v6 .v6-found .v6-wait-body { padding: 20px 36px 22px; }

/* The badge wears the system's raised yellow: the rounded 3D button's face,
   edge and solid base (tokens.json buttons.yellow), at the smaller depth the
   Expo Tile3D uses (3px base + 1.5px edge) because it is a label, not a
   control — no hover lift, no press. */
body.v6 .v6-found-badge {
  position: relative;
  display: inline-block;
  margin: 4px 0 5px;   /* the 4.5px base sits below the pill; keep it off the video */
  padding: 8px 22px 7px;
  border: 2px solid var(--noodl-buttons-yellow-edge);
  border-radius: var(--noodl-radii-pill);
  background: var(--noodl-buttons-yellow-face);
  box-shadow: 0 3px 0 var(--noodl-buttons-yellow-base), 0 4.5px 0 var(--noodl-buttons-yellow-edge);
  color: var(--noodl-buttons-yellow-ink);
  font: 600 var(--noodl-type-sizes-cap)/1 "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
}
/* A laurel sprig off each end of the badge, stroked in the yellow button edge
   (#B48C43, --noodl-buttons-yellow-edge; a data URI cannot read a variable). */
body.v6 .v6-found-badge::before,
body.v6 .v6-found-badge::after {
  content: "";
  position: absolute; top: 50%; left: -34px;
  width: 26px; height: 30px; margin-top: -15px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 30' fill='none' stroke='%23B48C43' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 27C14 22 12 15 15 3'/%3E%3Cpath d='M15.5 9c-3 0-5-1.5-6-4 3 0 5.5 1.5 6 4Zm-.5 6c-3 .5-5.5-1-7-3.5 3-.5 6 .5 7 3.5Zm1 6c-3 1-6-.5-7.5-3 3-1 6 0 7.5 3Zm-.5-12c2.5-1.5 3-4 2-6.5-2 1.5-3 4-2 6.5Zm.5 6c2.5-1 3.5-3.5 3-6-2.5 1-3.5 3.5-3 6Zm1 6c2.5-.5 4-3 4-5.5-2.5.5-4 3-4 5.5Z'/%3E%3C/svg%3E") no-repeat center / contain;
}
body.v6 .v6-found-badge::after { left: auto; right: -34px; transform: scaleX(-1); }

/* The corner garden. Sits on the card, under the content; the hills are two
   soft sage blobs peeking in at the bottom corners, the cut-outs hang over the
   card's edges a little so they read as tucked in rather than pasted on. */
/* No z-index on the garden itself: its pieces then sit in the card's own
   stacking order, under the content — except the sprig, which curls over the
   video frame's corner. */
/* overflow: hidden on the garden is what keeps the hills and the plants, which
   hang past the card's edges on purpose, from becoming scrollbars on the card. */
body.v6 .v6-found-garden { position: absolute; inset: 0; pointer-events: none; overflow: hidden; border-radius: calc(var(--noodl-radii-md) - 2px); }  /* the card's radius inside its 2px outline */
body.v6 .v6-found-art, body.v6 .v6-found .v6-wait-body { position: relative; z-index: 1; }
body.v6 .v6-found-hill {
  position: absolute; bottom: -40px;
  width: 260px; height: min(150px, 16vh);
  border-radius: 50%;
  background: var(--noodl-palettes-onboarding-sage-soft);
}
body.v6 .v6-found-hill-l { left: -70px; }
body.v6 .v6-found-hill-r { right: -70px; }
body.v6 .v6-found-corner { position: absolute; width: auto; }
/* Placed as in the reference: the sprig up the left edge past the video's
   corner, a plant in each bottom corner on its hill — the right one mirrored
   so it grows in from the edge. */
body.v6 .v6-found-corner-tl { left: 6px;   top: 70px;    height: 150px; transform: rotate(8deg); z-index: 2; }
body.v6 .v6-found-corner-bl { left: 14px;  bottom: 6px;  height: min(118px, 12vh); }
body.v6 .v6-found-corner-br { right: 8px;  bottom: 6px;  height: min(114px, 11.5vh); transform: scaleX(-1); }

body.v6 .v6-found-cta-wrap { position: relative; display: inline-block; max-width: 100%; margin-top: 18px; }

/* The trailer, framed like the card itself: 16:9, ink outline, rounded, and
   never cropped — the box is the clip's own ratio and the clip is letterboxed
   inside it if a browser rounds differently. The logo end card sits over it in
   the same box and takes over on `ended`, and the frame goes with the footage,
   so the logo ends up straight on the card's paper rather than inside a box. */
body.v6 .v6-found-stage {
  position: relative;
  /* The frame gives up width, never ratio, on short viewports: the trailer
     takes the height the rest of the card (--v6-found-rest, measured) leaves
     it, down to a 240px-wide floor (a 800px-tall laptop), below which the
     card scrolls instead. */
  width: min(100%, max(240px, calc((100vh - var(--v6-found-rest)) * 16 / 9)));
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  border: 2px solid var(--v6-outline);
  border-radius: var(--noodl-radii-md);
  overflow: hidden;
  background: var(--v6-outline);
  isolation: isolate;
  transition: border-color .8s ease, background-color .8s ease;
}
body.v6 .v6-found-video {
  display: block;
  width: 100%; height: 100%;
  object-fit: contain;
  transition: opacity .8s ease;
}
body.v6 .v6-found-end {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .8s ease;
}
body.v6 .v6-found-end-logo { width: 52%; height: auto; }
body.v6 .v6-found-ended { border-color: transparent; background-color: transparent; }
body.v6 .v6-found-ended .v6-found-video { opacity: 0; }
body.v6 .v6-found-ended .v6-found-end   { opacity: 1; }
/* The welcome flight: Noodl straight on the card's paper, no trailer frame.
   768x1120 source with Noodl (cape and bolts) in its middle half; cover keeps
   the middle 270px and the mask fades the frame's edges so H.264 paper never
   shows a faint rectangle. Swoop and hover loop share the box (swap `hidden`). */
body.v6 .v6-found-flight {
  width: auto; aspect-ratio: auto;
  border: 0; border-radius: 0;
  background: transparent;
  overflow: visible;
}
body.v6 .v6-found-flight .v6-found-video {
  width: 240px; height: 270px; margin: 0 auto;
  object-fit: cover;
  -webkit-mask-image: radial-gradient(ellipse 58% 60% at 50% 50%, #000 76%, transparent 100%);
          mask-image: radial-gradient(ellipse 58% 60% at 50% 50%, #000 76%, transparent 100%);
}
body.v6 .v6-found-flight .v6-found-video[hidden] { display: none; }
/* What's next, under the welcome lede. */
body.v6 .v6-found-next { margin-top: 14px; }
/* The maker's sign-off, in Caveat: a hand-written thank-you under what happens next. */
@font-face {
  font-family: "Caveat";
  src: url("/fonts/caveat.ttf") format("truetype");
  font-weight: 400 700;
  font-display: swap;
  /* Only the glyphs this TTF has and the WOFF2 subset lacks, so a character
     neither has (U+2011 in "one‑time") never downloads it for nothing. */
  unicode-range: U+292, U+2C7, U+2C9, U+2D8-2D9, U+2DB, U+2DD, U+3BC, U+400-45F, U+462-463, U+46A-46B,
    U+472-475, U+48A-4A5, U+4A8-4FF, U+510-513, U+51A-51D, U+524-529, U+52E-52F, U+2070,
    U+2074-2079, U+2080-2089, U+2153-2154, U+215B-215E, U+2219, U+2248, U+2260, U+2264-2265,
    U+27E8-27E9, U+F6C3, U+FB00-FB04;
}
/* Latin subset (WOFF2), declared after the full TTF so it wins for the
   characters it covers; the TTF only downloads for anything outside it.
   Same pair as Rubik in noodl-button.css. */
@font-face {
  font-family: "Caveat";
  src: url("/fonts/caveat.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-024F, U+0259, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-036F, U+1E00-1EFF, U+2000-206F, U+20A0-20CF, U+2100-2152, U+2190-2199, U+2212, U+2215, U+25CF, U+2713, U+FEFF, U+FFFD;
}
body.v6 .v6-found-sign {
  margin-top: 10px;
  font: 600 22px/1.1 "Caveat", "Bradley Hand", cursive;
  color: var(--v6-body);
}

/* ---- The welcome, polished. The flight gets a warm halo that breathes and
   one confetti burst as the swoop starts; the badge takes the price's gold
   glint; the copy rises in behind the swoop, one line after another. Every
   open replays it (the closed dialog is display:none). Reduced motion keeps
   the halo and the gold, still, and shows everything at once. ---- */
body.v6 .v6-found-flight { position: relative; isolation: isolate; }
/* multiply: the clip's paper-coloured background would otherwise sit on the
   halo as a flat cream disc; multiplied, it takes the glow and only Noodl reads. */
body.v6 .v6-found-flight .v6-found-video { position: relative; z-index: 1; mix-blend-mode: multiply; }
body.v6 .v6-found-halo {
  position: absolute; z-index: 0;
  left: 50%; top: 50%;
  width: 300px; height: 300px;
  margin: -150px 0 0 -150px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 214, 120, .55) 0%, rgba(255, 214, 120, .22) 40%, rgba(255, 214, 120, 0) 68%);
  pointer-events: none;
}
body.v6 .v6-found-confetti {
  position: absolute; z-index: 2;
  left: 50%; top: 46%;
  width: 0; height: 0;
  pointer-events: none;
}
body.v6 .v6-found-confetti i {
  position: absolute; left: 0; top: 0;
  width: var(--w); height: calc(var(--w) * 1.5);
  border-radius: 2px;
  background: var(--c);
  opacity: 0;
}
body.v6 .v6-found-confetti i:nth-child(3n) { border-radius: 50%; height: var(--w); }
/* Both founding badges ("Founding 50" on the offer, "Founding member #N" on the
   welcome) are gold: a glint crosses them on the 4.5s beat the panels use. */
body.v6 .v6-found-badge-gold {
  background:
    linear-gradient(100deg, transparent 38%, rgba(255, 253, 240, .95) 50%, transparent 62%) 100% 0 / 250% 100% no-repeat,
    var(--noodl-buttons-yellow-face);
}
@media (max-width: 640px) {
  body.v6 .v6-found-halo { width: 240px; height: 240px; margin: -120px 0 0 -120px; }
}
@media (prefers-reduced-motion: no-preference) {
  @keyframes v6-found-halo-breathe {
    0%, 100% { transform: scale(.92); opacity: .8; }
    50%      { transform: scale(1.06); opacity: 1; }
  }
  @keyframes v6-found-confetti-burst {
    0%   { opacity: 0; transform: translate(-50%, -50%) scale(.3); }
    8%   { opacity: 1; }
    55%  { opacity: 1; transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) rotate(var(--r)) scale(1); }
    100% { opacity: 0; transform: translate(calc(-50% + var(--x) * 1.12), calc(-50% + var(--y) + 70px)) rotate(calc(var(--r) * 2)) scale(.9); }
  }
  @keyframes v6-found-rise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
  @keyframes v6-found-badge-glint {
    0%        { background-position: 100% 0, 0 0; }
    22%, 100% { background-position: 0 0, 0 0; }
  }
  body.v6 .v6-found[open] .v6-found-halo { animation: v6-found-halo-breathe 4.5s ease-in-out infinite; }
  body.v6 .v6-found[open] .v6-found-confetti i {
    animation: v6-found-confetti-burst 1.7s cubic-bezier(.15, .7, .35, 1) var(--d) both;
  }
  body.v6 .v6-found[open] .v6-found-rise {
    animation: v6-found-rise .6s cubic-bezier(.2, .8, .3, 1) calc(.3s + var(--i) * .09s) both;
  }
  body.v6 .v6-found[open] .v6-found-badge-gold {
    animation: v6-found-badge-glint 4.5s ease-in-out 1s infinite;
  }
  body.v6 .v6-found[open] .v6-found-badge-gold.v6-found-rise {
    animation:
      v6-found-rise .6s cubic-bezier(.2, .8, .3, 1) .3s both,
      v6-found-badge-glint 4.5s ease-in-out 1s infinite;
  }
}
@media (max-width: 640px) {
  body.v6 .v6-found-flight .v6-found-video { width: 200px; height: 225px; }
  /* "Founding member #12" is wider than "Founding 50": its laurels would run
     into the close button on a phone. */
  body.v6 .v6-found-badge-member::before,
  body.v6 .v6-found-badge-member::after { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  body.v6 .v6-found-stage, body.v6 .v6-found-video, body.v6 .v6-found-end { transition: none; }
}

body.v6 .v6-found .v6-wait-h {
  font-size: var(--v6-found-display); line-height: var(--v6-found-display-lh);
  letter-spacing: -.022em;
  text-wrap: balance;   /* two even lines, never "payment." on its own */
}
/* A partner reader's card has the discount strip too (58px with its margin):
   the trailer gives up that much height so the card still fits the screen. */
body.v6 .v6-found:has(.v6-found-deal) { --v6-found-rest: 673px; }
/* The struck price and the new one never part across a line break. */
body.v6 .v6-found-prices { white-space: nowrap; }
/* "Noodl" in the heading, as the nav's lockup: sized so the handwritten name
   matches the heading's letters, with Noodl's raised arms and feet allowed to
   hang past the line (the negative margins) instead of spacing the lines out. */
body.v6 .v6-found-h-logo {
  display: inline-block;
  height: 2.1em; width: auto;
  margin: -.3em .04em -.2em 0;
  vertical-align: -.44em;   /* the name's baseline sits at 79% of the image */
}
/* The price: the brand orange deepened into amber, a gold glint that crosses
   it on the panels' 4.5s loop (just ahead of their sheen), and a brushed
   yellow swash that draws in under it once when the card opens. Without
   motion it is the gradient and the finished swash, still. */
body.v6 .v6-found-price {
  position: relative;
  display: inline-block;
  isolation: isolate;
  color: var(--v6-orange);
}
body.v6 .v6-found-price-num {
  background: linear-gradient(100deg,
      #C64B03 0%, #DD5605 38%, #FFC56B 50%, #DD5605 62%, #C64B03 100%)
    0 0 / 250% 100% no-repeat;
  background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
body.v6 .v6-found-price-swash {
  position: absolute; z-index: -1;
  left: -4%; right: -4%; bottom: .02em;
  width: 108%; height: .32em;
  overflow: visible;
}
body.v6 .v6-found-price-swash path {
  fill: none;
  stroke: var(--noodl-buttons-yellow-base);
  stroke-width: 5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  opacity: .85;
}
@media (prefers-reduced-motion: no-preference) {
  @keyframes v6-found-price-glint {
    0%        { background-position: 100% 0; }
    22%, 100% { background-position: 0 0; }
  }
  @keyframes v6-found-swash-draw {
    from { stroke-dashoffset: 1; }
    to   { stroke-dashoffset: 0; }
  }
  body.v6 .v6-found[open] .v6-found-price-num {
    animation: v6-found-price-glint 4.5s ease-in-out .5s infinite backwards;
  }
  body.v6 .v6-found[open] .v6-found-price-swash path {
    stroke-dasharray: 1;
    animation: v6-found-swash-draw .6s cubic-bezier(.6, 0, .3, 1) .35s both;
  }
}
body.v6 .v6-found-lede { margin-top: 10px; font-size: var(--noodl-type-sizes-h3); line-height: 24px; color: var(--v6-body); }

/* Three checks in a row, hairlines between them; a column under 640px. */
body.v6 .v6-found-checks {
  margin-top: 16px;
  display: flex; justify-content: center; flex-wrap: wrap;
}
body.v6 .v6-found-checks li {
  display: flex; align-items: center; gap: 11px;
  padding: 4px 20px;
  font: 600 var(--noodl-type-sizes-body)/20px var(--v6-sans);
  color: var(--v6-body);
}
body.v6 .v6-found-checks li + li { border-left: 1.5px solid var(--v6-card-line); }
body.v6 .v6-found-checks li::before {
  content: "";
  flex: 0 0 auto;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--noodl-palettes-onboarding-sage) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFDF8' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 12.5l4 4 8-9'/%3E%3C/svg%3E") no-repeat center / 16px;
}

/* The two panels side by side: bonus (yellow) and guarantee (sage). Same
   outline weight as the card, a shade darker than each panel's fill. */
body.v6 .v6-found-panels {
  margin-top: 16px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
}
body.v6 .v6-found-box {
  padding: 14px 16px 14px 12px;
  display: flex; align-items: center; gap: 12px;
  border: 1.5px solid;
  border-radius: var(--noodl-radii-md);
  text-align: left;
}
/* Fills and edges derived from tokens: the bonus is the everyday yellow let
   down into the card paper, the guarantee edge is the sage accent let down
   into the everyday sage fill. */
body.v6 .v6-found-box-bonus {
  background: color-mix(in srgb, var(--noodl-palettes-everyday-yellow) 55%, var(--v6-card));
  border-color: var(--noodl-buttons-yellow-base);
}
body.v6 .v6-found-box-guarantee {
  background: var(--noodl-palettes-everyday-sage);
  border-color: color-mix(in srgb, var(--noodl-palettes-onboarding-sage) 30%, var(--noodl-palettes-everyday-sage));
}

/* The panel icons. */
body.v6 .v6-found-box-icon {
  position: relative;
  flex: 0 0 auto;
  width: 62px; height: 62px;
  margin: 0 6px;   /* symmetric, so the icon sits centred between panel edge and text */
  align-self: center;
  display: grid; place-items: center;
}
/* Pinned to the slot: as a grid item the image sized from its width and its
   tall shield ran 17px past the slot's bottom, so it sat low. Absolute inset 0
   plus contain fits either shape inside the slot, centred both ways. */
body.v6 .v6-found-box-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* The cap and t-shirt are a product pair, not a glyph: a bigger slot, and
   a touch of bleed past the panel's padding so they read as product, not icon. */
body.v6 .v6-found-box-icon-merch { width: 88px; height: 84px; margin: -10px 4px -10px -2px; }
/* ...and a magnifier over them: a zoom-in cursor, a frame marking the spot
   being looked at (only while the card is up), and the card itself. The
   script in landing/show sets the frame's box and the card's --fx/--fy, how
   far across and down the picture the spot sits, 0 to 1. */
body.v6 button.v6-found-box-icon-merch {
  padding: 0; border: 0; background: none; font: inherit; color: inherit;
  cursor: zoom-in;
  touch-action: none;   /* a drag on the thumbnail pans the card, not the page */
  -webkit-tap-highlight-color: transparent;
}
body.v6 button.v6-found-box-icon-merch:focus-visible { outline: 2.5px solid var(--v6-orange); outline-offset: 2px; border-radius: 10px; }
body.v6 .v6-merch-lens {
  position: absolute; z-index: 1;
  border: 1.5px solid var(--v6-card);
  border-radius: 4px;
  background: rgba(255, 253, 248, .22);
  box-shadow: 0 0 0 1px rgba(15, 42, 27, .55), 0 2px 6px rgba(15, 42, 27, .25);
  opacity: 0;
  pointer-events: none;
}
body.v6 button:has(+ .v6-merch-peek:popover-open) .v6-merch-lens { opacity: 1; }

/* The card: a window onto the picture at --zoom, in the offer's paper and
   outline, placed just above the thumbnail by the script (--peek-x/--peek-y).
   Only something to look at, so the pointer passes through it. It grows from
   the thumbnail (--peek-origin). */
body.v6 .v6-merch-peek {
  --zoom: 2.5;
  position: fixed; inset: auto;
  left: var(--peek-x, 0); top: var(--peek-y, 0);
  box-sizing: border-box;
  margin: 0; padding: 0;
  width: min(250px, 100vw - 24px);
  aspect-ratio: 969 / 852;
  overflow: hidden;
  background: var(--v6-card);
  border: 2px solid var(--v6-outline);
  border-radius: 12px;
  box-shadow: 0 4px 0 rgba(15, 42, 27, .17), 0 18px 36px rgba(15, 42, 27, .24);
  pointer-events: none;
  transform-origin: var(--peek-origin, bottom left);
}
/* Translate percentages are of the image itself, which is --zoom times the
   window: moving it by fx * (1/zoom - 1) of its width keeps the spot at fx
   in view, from the left edge (0) to the right edge (1). */
body.v6 .v6-merch-peek-img {
  display: block;
  width: calc(var(--zoom) * 100%); max-width: none; height: auto;
  transform: translate(calc(var(--fx, .5) * (1 / var(--zoom) - 1) * 100%),
                       calc(var(--fy, .5) * (1 / var(--zoom) - 1) * 100%));
}
/* The mock-up notice, a band along the bottom of the card. */
body.v6 .v6-merch-peek-note {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 4px 8px 5px;
  background: color-mix(in srgb, var(--v6-card) 88%, transparent);
  border-top: 1px solid var(--v6-card-line);
  font: 500 11px/14px "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: .02em;
  text-align: center;
  color: var(--noodl-palettes-onboarding-ink-soft);
}
/* The thumbnail stops its hop while magnified, so frame and card agree. */
body.v6 .v6-found[open] .v6-found-box-bonus button:has(+ .v6-merch-peek:popover-open) .v6-found-box-img { animation: none; }
@media (prefers-reduced-motion: no-preference) {
  body.v6 .v6-merch-peek {
    transition: opacity .16s ease-out, transform .22s cubic-bezier(.3, 1.3, .5, 1),
                display .16s allow-discrete, overlay .16s allow-discrete;
  }
  body.v6 .v6-merch-peek:not(:popover-open) { opacity: 0; transform: scale(.6); }
  @starting-style {
    body.v6 .v6-merch-peek:popover-open { opacity: 0; transform: scale(.6); }
  }
  /* A short glide after the pointer, so the view follows rather than jitters. */
  body.v6 .v6-merch-peek-img { transition: transform .12s ease-out; }
  body.v6 .v6-merch-lens { transition: opacity .16s ease-out, left .12s ease-out, top .12s ease-out; }
}

/* Panel motion, all one-shot on open so the offer feels made rather than busy:
   the panels rise in just behind the card (which takes .26s), each icon pops
   with a small overshoot, then a soft sheen crosses each panel like light
   over foil, every 4.5s (bonus first, guarantee just behind). Hover (fine pointers) lifts the panel and tips the seal (not the merch, which
   is a magnifier and wants holding still). The
   dialog's closed state is display:none, so every open replays it. */
body.v6 .v6-found-box { position: relative; overflow: hidden; isolation: isolate; }
body.v6 .v6-found-box::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgba(255, 253, 248, .7) 50%, transparent 65%);
  transform: translateX(-110%);
}
@media (prefers-reduced-motion: no-preference) {
  @keyframes v6-found-box-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
  }
  @keyframes v6-found-icon-pop {
    0%   { opacity: 0; transform: scale(.6) rotate(-8deg); }
    60%  { opacity: 1; transform: scale(1.08) rotate(2deg); }
    100% { opacity: 1; transform: none; }
  }
  /* A 1.1s sweep, then the light rests off-panel for the rest of the 4.5s loop. */
  @keyframes v6-found-sheen {
    0%        { transform: translateX(-110%); }
    25%, 100% { transform: translateX(110%); }
  }
  body.v6 .v6-found[open] .v6-found-box {
    animation: v6-found-box-in .5s cubic-bezier(.2, .8, .3, 1) .14s both;
    transition: transform .2s ease-out, box-shadow .2s ease-out;
  }
  body.v6 .v6-found[open] .v6-found-box-guarantee { animation-delay: .22s; }
  body.v6 .v6-found[open] .v6-found-box-icon {
    animation: v6-found-icon-pop .55s cubic-bezier(.3, 1.4, .5, 1) .32s both;
    transition: transform .25s cubic-bezier(.3, 1.4, .5, 1);
  }
  body.v6 .v6-found[open] .v6-found-box-guarantee .v6-found-box-icon { animation-delay: .4s; }
  body.v6 .v6-found[open] .v6-found-box::after {
    animation: v6-found-sheen 4.5s ease-in-out .75s infinite backwards;
  }
  body.v6 .v6-found[open] .v6-found-box-guarantee::after { animation-delay: .9s; }
  /* The seal gives a small wiggle as the sheen crosses it, on the same 4.5s
     loop and delay, so the two read as one beat. On the image, not its slot,
     so it doesn't fight the slot's pop-in and hover tilt. A wiggle, not a
     shake: a guarantee should look steady, not alarmed. */
  @keyframes v6-found-seal-wiggle {
    0%, 8%    { transform: none; }
    10%       { transform: rotate(-7deg); }
    12%       { transform: rotate(6deg); }
    14%       { transform: rotate(-3deg); }
    16%       { transform: rotate(1.5deg); }
    18%, 100% { transform: none; }
  }
  body.v6 .v6-found[open] .v6-found-box-guarantee .v6-found-box-img {
    animation: v6-found-seal-wiggle 4.5s ease-in-out .9s infinite;
  }
  /* The merch hops (a present being nudged) as the bonus panel's sheen
     crosses it, on the same loop, so it lands a beat before the seal's wiggle. */
  @keyframes v6-found-merch-hop {
    0%, 8%    { transform: none; }
    11%       { transform: translateY(-3px) rotate(-3deg); }
    14%       { transform: translateY(0) rotate(1deg); }
    16%       { transform: translateY(-1px); }
    18%, 100% { transform: none; }
  }
  body.v6 .v6-found[open] .v6-found-box-bonus .v6-found-box-img {
    animation: v6-found-merch-hop 4.5s ease-in-out .75s infinite;
  }

  @media (hover: hover) and (pointer: fine) {
    body.v6 .v6-found-box:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 14px -8px rgba(15, 42, 27, .28);
    }
    body.v6 .v6-found-box-guarantee:hover .v6-found-box-icon { transform: rotate(8deg) scale(1.06); }
  }
}

body.v6 .v6-found-box-h {
  font: 700 var(--noodl-type-sizes-h3)/22px "Avenir Next", var(--v6-sans);
  letter-spacing: -.012em;
  color: var(--v6-green);
}
body.v6 .v6-found-box-h-caps {
  font: 700 var(--noodl-type-sizes-cap)/18px "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: .05em;
  white-space: nowrap;
  text-transform: uppercase;
  color: var(--noodl-buttons-yellow-ink);
}
body.v6 .v6-found-box-p {
  margin-top: 4px;
  font: 500 var(--noodl-type-sizes-body)/20px var(--v6-sans);   /* the checks' size: 13.5px read small in the condensed face */
  color: var(--v6-muted);
}

/* Button labels in both dialogs are set like the Expo app's caps buttons
   (PathButton capsLabel: Fredoka SemiBold, 16px, 1px tracking, uppercase).
   Fredoka is the variable face already in public/fonts. */
@font-face {
  font-family: "Fredoka";
  src: url("/fonts/fredoka.ttf") format("truetype");
  font-weight: 300 700;
  font-display: swap;
  /* Only the glyphs this TTF has and the WOFF2 subset lacks, so a character
     neither has (U+2011 in "one‑time") never downloads it for nothing. */
  unicode-range: U+2C7, U+2D8-2D9, U+2DB, U+2DD, U+5B0-5BC, U+5BE-5BF, U+5C1-5C2, U+5C7, U+5D0-5EA,
    U+5F3-5F4, U+FB01-FB02, U+FB2A-FB36, U+FB38-FB3C, U+FB3E, U+FB40-FB41, U+FB43-FB44,
    U+FB46-FB4B;
}
/* Latin subset (WOFF2), both axes kept; the TTF above covers the rest. */
@font-face {
  font-family: "Fredoka";
  src: url("/fonts/fredoka.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
  unicode-range: U+0000-024F, U+0259, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-036F, U+1E00-1EFF, U+2000-206F, U+20A0-20CF, U+2100-2152, U+2190-2199, U+2212, U+2215, U+25CF, U+2713, U+FEFF, U+FFFD;
}
body.v6 .v6-wait-btn.v6-jelly {
  min-height: 50px;
  font: 600 15px/1.2 "Fredoka", "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: 1px;
  text-transform: uppercase;
}

/* The CTA is the landing page's primary button, as in the nav's "Start
   stretching": the shared yellow raised button, the gold sparkle, the arrow and
   the gentle pulse (all from noodl-button.css), with the caps label above. .v6-jelly is doubled in because noodl-button.css loads
   after this file at equal specificity. */
body.v6 .v6-found-cta.v6-jelly {
  gap: 10px;
  min-height: 58px;
  width: 500px; max-width: 100%;
  margin-top: 0 !important;
  font: 600 16px/1.2 "Fredoka", "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: 1px;
  text-transform: uppercase;
}
body.v6 .v6-found-cta :is(.v6-cta-sparkle, .v6-cta-arrow) { width: 18px; height: 18px; }

/* The page CTAs that open this dialog take its button's caps label, so the
   page CTA and the card's read as one action.
   Sizes stay each button's own. */
body.v6 :is(.v6-hero-cta, .v6-mobile-cta).v6-jelly {
  font-family: "Fredoka", "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
}
/* The hero CTA sits in the store badges' row and takes each composition's
   badge height from .v6-store; these undo the badge-only bits (a fixed width
   in one composition, the tight badge padding) so the label sets its width. */
body.v6 .v6-stage .v6-stores .v6-hero-cta.v6-jelly {
  width: auto; min-width: 0;
  height: auto; min-height: 40px;   /* the phone badges shrink to 25px; a tap target can't */
  padding: 4px 14px 2px;
  gap: 8px;
  font-size: 12.5px;   /* the nav pill's size; 14px caps shouted over the lede */
  white-space: nowrap;
}

/* "2 of 50 spots claimed", just above the CTA: small caps in the price's
   orange, the social proof right where the decision is made. */
body.v6 .v6-found-spots {
  margin-top: 18px;
  display: flex; justify-content: center; align-items: center; gap: 8px;
  font: 600 var(--noodl-type-sizes-cap)/16px "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--noodl-palettes-landing-orange-action);
}
body.v6 .v6-found-spots strong { font-weight: 700; }
body.v6 .v6-found-spots + .v6-found-cta-wrap { margin-top: 10px; }
body.v6 .v6-found-spots-out { color: var(--v6-muted); }

/* A partner reader's discount (PartnerOffer): the list price struck through
   before the new one, a torn-ticket strip above the CTA with the code, and a
   tilted "$10 off" sticker on the hero's "Claim" button. */
body.v6 .v6-found-price-was {
  color: var(--v6-muted);
  font-size: .72em;
  text-decoration-thickness: 2px;
}
body.v6 .v6-found-deal {
  margin-top: 10px;
  padding: 8px 8px 8px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1.5px dashed var(--noodl-buttons-yellow-edge);
  border-radius: var(--noodl-radii-md);
  background: color-mix(in srgb, var(--noodl-palettes-everyday-yellow) 40%, var(--v6-card));
  text-align: left;
}
body.v6 .v6-found-deal-p {
  font: 500 var(--noodl-type-sizes-body)/1.3 var(--v6-sans);
  color: var(--v6-body);
}
body.v6 .v6-found-deal-p strong { font-weight: 700; }
/* A partner's wordmark, set in the line like a word, a little taller than the
   text so its lettering reads at the same size. Through .v6-stage.v6-stage for
   the hero's welcome line, whose stage sizes and places every img in it. */
body.v6 .v6-partner-logo,
body.v6 .v6-stage.v6-stage .v6-partner-logo {
  position: static;
  display: inline-block;
  width: auto; max-width: none;
  height: 1.4em;
  margin: 0;
  vertical-align: -.36em;
}
/* On the orange sticker the dark wordmark turns white, like the sticker's text. */
body.v6 .v6-stage.v6-stage .v6-cta-deal .v6-partner-logo {
  height: 1.5em;
  vertical-align: -.42em;
  filter: brightness(0) invert(1);
}
body.v6 .v6-found-deal-code {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 11px;
  border: 1.5px solid var(--noodl-buttons-yellow-edge);
  border-radius: var(--noodl-radii-sm);
  background: var(--v6-card);
  font: 700 13px/1 "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: .08em;
  color: var(--v6-orange-action);
  cursor: pointer;
  transition: transform .15s ease, background .15s ease;
}
body.v6 .v6-found-deal-code:hover { background: var(--noodl-palettes-everyday-yellow); }
body.v6 .v6-found-deal-code:active { transform: scale(.96); }
body.v6 .v6-found-deal-code:focus-visible { outline: 2px solid var(--v6-green); outline-offset: 2px; }
/* "Copied!" floats up out of the code for a moment. */
body.v6 .v6-found-deal-copied {
  position: absolute; left: 50%; bottom: 100%;
  translate: -50% -6px;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--v6-green); color: #fff;
  font: 600 11px/1.3 var(--v6-sans); letter-spacing: 0;
  white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity .2s ease, translate .2s ease;
}
body.v6 .v6-found-deal-copied:not(:empty) { opacity: 1; translate: -50% -10px; }
body.v6 .v6-found-deal + .v6-found-cta-wrap { margin-top: 12px; }

/* Through .v6-stage.v6-stage: the fluid layouts flatten every span and link in
   the stage to position: static, and the sticker must stay pinned. */
body.v6 .v6-stage.v6-stage :is(.v6-hero-cta, .v6-mobile-cta):has(.v6-cta-deal) { position: relative; }
body.v6 .v6-stage.v6-stage .v6-cta-deal {
  position: absolute; top: -12px; right: -14px; z-index: 1;
  padding: 3px 8px 2px;
  border-radius: 999px;
  background: var(--v6-orange-action); color: #fff;
  box-shadow: 0 2px 0 rgba(15, 42, 27, .18);
  font: 700 10.5px/1.2 "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: .04em;
  rotate: 6deg;
  white-space: nowrap;
  text-transform: none;
  pointer-events: none;
}
/* The list price, struck through before a partner reader's price. */
body.v6 .v6-cta-was { opacity: .55; text-decoration-thickness: 1.5px; }
body.v6 .v6-stage.v6-stage .v6-cta-deal-note {
  position: absolute; top: calc(100% + 10px); left: 50%;
  translate: -50% 0;
  padding: 4px 11px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--v6-card) 88%, transparent);
  box-shadow: 0 0 0 1px var(--v6-card-line);
  font: 600 12px/1.3 var(--v6-sans);
  letter-spacing: 0;
  text-transform: none;
  color: var(--v6-green);
  white-space: nowrap;
  pointer-events: none;
}
@media (max-width: 659px) {
  /* The phone's CTA is left-aligned: the note lines up under it, not centred. */
  body.v6 .v6-stage.v6-stage .v6-cta-deal-note {
    left: 0; translate: none;
    width: max-content; max-width: 100%;
    white-space: normal;
    border-radius: 12px;
  }
  /* Tucked into the corner: the lede sits right above the phone's CTA. */
  body.v6 .v6-stage.v6-stage .v6-cta-deal { top: -9px; right: -6px; rotate: 3deg; }
}
@media (max-width: 640px) {
  body.v6 .v6-found-deal { margin-top: 0; padding: 8px 8px 8px 12px; }
  body.v6 .v6-found-deal-p { font-size: 14px; }
}
body.v6 .v6-found-flash { margin-top: 16px; }

/* The fine-print line under the CTA ("Early preview: screens may change…").
   18px clears the button's 10px raised shadow with room to spare. */
body.v6 .v6-found-fine {
  margin-top: 18px;
  font: 500 var(--noodl-type-sizes-cap)/16px "Rubik", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: .02em;
  color: var(--noodl-palettes-onboarding-ink-soft);
}
/* The line runs wide enough to reach the corner garden's sage hills; a pill of
   the card's paper keeps it legible over them without moving anything. */
body.v6 .v6-found-fine {
  position: relative; z-index: 1;
  width: fit-content;
  margin-inline: auto;
  margin-top: 14px;   /* the pill's 4px out of the 18px above, so nothing moves */
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--v6-card);
}
body.v6 .v6-found-fine-refund {
  font-weight: 700;
  color: var(--v6-green);
}
body.v6 .v6-found-fine-short { display: none; }
@media (max-width: 640px) {
  /* No garden on a phone, so no pill: its padding would only add height. */
  body.v6 .v6-found-fine { padding: 0; }
  body.v6 .v6-found-fine-long { display: none; }
  body.v6 .v6-found-fine-short { display: inline; }
}

/* "Not ready? Join the waitlist", just under the fine print, which now takes
   most of the room this margin used to hold for it (the old 36px); the link
   swaps this dialog for the waitlist one. */
body.v6 .v6-found-later {
  margin-top: 6px;
  padding: 4px 6px;
  font: 500 var(--noodl-type-sizes-body)/1.2 var(--v6-sans);
  color: var(--v6-muted);
}
body.v6 .v6-found-later a {
  font-weight: 600;
  color: var(--v6-green);
  text-decoration: underline; text-underline-offset: 3px;
}
body.v6 .v6-found-later a:hover { color: var(--v6-orange); }
body.v6 .v6-found-later a:focus-visible { outline: 2.5px solid var(--v6-orange); outline-offset: 2px; border-radius: 6px; }

@media (max-width: 640px) {
  body.v6 .v6-found-art { padding: 16px 18px 0; }
  body.v6 .v6-found .v6-wait-body { padding: 18px 18px 20px; }
  body.v6 .v6-found-garden { display: none; }
  body.v6 .v6-found { --v6-found-display: 26px; --v6-found-display-lh: 30px; }
  body.v6 .v6-found-checks { flex-direction: column; align-items: center; gap: 8px; }
  body.v6 .v6-found-checks li { padding: 0; }
  body.v6 .v6-found-checks li + li { border-left: 0; }
  body.v6 .v6-found-panels { grid-template-columns: 1fr; gap: 12px; }
  body.v6 .v6-found-box { padding: 14px 14px 14px 10px; gap: 10px; }
  body.v6 .v6-found-box-icon { width: 50px; height: 50px; margin: 0 6px; }
  body.v6 .v6-found-box-icon-merch { width: 72px; height: 68px; margin: -6px 6px -6px 0; }
  body.v6 .v6-found-cta.v6-jelly { font-size: 15px; letter-spacing: .6px; min-height: 52px; }
}

/* On a phone the offer stops being a card over the page and becomes the page:
   edge to edge and exactly the visible height (dvh leaves Safari's toolbars
   out), the trailer full-bleed along the top, and the decision
   (.v6-found-buy) pinned to the bottom edge. The $99 button is on screen from
   the first frame on any phone; what doesn't fit above it scrolls behind it. */
@media (max-width: 640px) {
  body.v6 .v6-found {
    width: 100%; height: 100vh; height: 100dvh;
    max-width: none; max-height: none;
    margin: 0;
  }
  body.v6 .v6-found::before { display: none; }   /* no second sheet under a page */
  /* Paper, not a dimmed page: Safari tints the status bar from what is under
     it, and a grey band over a full-screen sheet reads as a broken edge. */
  body.v6 .v6-found::backdrop { background: var(--v6-card); backdrop-filter: none; }
  body.v6 .v6-found .v6-wait-card {
    display: flex; flex-direction: column;
    height: 100%; max-height: none;
    border: 0; border-radius: 0; box-shadow: none;
  }
  body.v6 .v6-found .v6-wait-x { top: max(12px, env(safe-area-inset-top)); right: 12px; }
  body.v6 .v6-found .v6-wait-art { padding-top: max(16px, env(safe-area-inset-top)); }

  /* The offer's trailer runs the full width with Noodl's badge tucked over its
     bottom edge. The welcome's flight keeps its own framing. */
  body.v6 .v6-found-art:has(> .v6-found-stage:not(.v6-found-flight)) { padding: 0; gap: 0; }
  /* 2:1 rather than the clip's 16:9, trimming a sliver off the top and bottom:
     25px back for the offer, which is what lets it fit a phone unscrolled. */
  body.v6 .v6-found-stage:not(.v6-found-flight) {
    width: 100%;
    aspect-ratio: 2 / 1;
    border-width: 0 0 2px; border-radius: 0;
  }
  body.v6 .v6-found-stage:not(.v6-found-flight) .v6-found-video { object-fit: cover; }
  body.v6 .v6-found-art > .v6-found-badge:not(.v6-found-badge-member) {
    order: 1; z-index: 1;
    margin: -17px 0 0;
  }
  /* The pill alone on a phone: the laurels read as clutter on the trailer's edge. */
  body.v6 .v6-found .v6-found-badge::before,
  body.v6 .v6-found .v6-found-badge::after { display: none; }

  body.v6 .v6-found .v6-wait-body {
    flex: 1 0 auto;
    display: flex; flex-direction: column;
    padding: 14px 20px 0;
  }
  body.v6 .v6-found-lede { margin-top: 8px; font-size: 15.5px; line-height: 21px; }

  /* A wrapping row again (two lines on a phone instead of three), without the
     desktop's hairlines. */
  body.v6 .v6-found .v6-found-checks {
    flex-direction: row; align-items: center;
    margin-top: 10px; gap: 6px 16px;
  }
  body.v6 .v6-found-checks li { gap: 9px; font-size: 14.5px; line-height: 20px; }
  body.v6 .v6-found-checks li::before { width: 20px; height: 20px; background-size: 13px; }

  body.v6 .v6-found-panels { margin: 12px 0 10px; gap: 8px; }
  body.v6 .v6-found-box { padding: 9px 12px 9px 8px; }
  body.v6 .v6-found-box-icon { width: 42px; height: 42px; }
  body.v6 .v6-found-box-icon-merch { width: 58px; height: 54px; margin: -4px 4px -4px 0; }
  body.v6 .v6-found-box-p { margin-top: 1px; font-size: 14px; line-height: 18px; }

  body.v6 .v6-found-buy {
    position: sticky; bottom: 0; z-index: 2;
    margin: auto -20px 0;
    padding: 14px 20px max(10px, env(safe-area-inset-bottom));
    background: var(--v6-card);
    box-shadow: 0 -1px 0 var(--v6-card-line), 0 -10px 18px -8px rgba(15, 42, 27, .12);
  }
  body.v6 .v6-found-buy > :first-child { margin-top: 0; }
  body.v6 .v6-found-buy .v6-found-spots + .v6-found-cta-wrap { margin-top: 10px; }
  body.v6 .v6-found-buy .v6-found-cta-wrap { display: block; }
  body.v6 .v6-found-fine { margin-top: 12px; }
  body.v6 .v6-found-later { margin-top: 0; padding-bottom: 0; }

  /* The welcome, on the same sheet: a smaller flight so the thank-you fits,
     and "Back to Noodl" pinned where the $99 button was. The flight's fade
     reaches 100% at the box's edges: the desktop ellipse runs past them,
     which on the smaller box left a faint square around Noodl. */
  body.v6 .v6-found-flight .v6-found-video {
    width: 150px; height: 168px;
    -webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 72%, transparent 100%);
            mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 72%, transparent 100%);
  }
  body.v6 .v6-found-halo { width: 190px; height: 190px; margin: -95px 0 0 -95px; }
  body.v6 .v6-found .v6-found-next { margin-top: 10px; }
  body.v6 .v6-found-sign { margin: 8px 0 10px; font-size: 20px; }
  body.v6 .v6-found-buy > .v6-found-cta-wrap:only-child { padding-bottom: 4px; }
}

/* The waitlist card, brought in line with the offer: the same raised badge
   over the art, and a link back across to the offer. */
body.v6 .v6-wait-art { gap: 10px; }
body.v6 .v6-wait-badge { margin: 0; }
body.v6 .v6-wait-alt {
  margin-top: 18px;
  font: 500 var(--noodl-type-sizes-sub)/1.3 var(--v6-sans);
  color: var(--v6-muted);
}
body.v6 .v6-wait-alt a {
  font-weight: 600;
  color: var(--v6-green);
  text-decoration: underline; text-underline-offset: 3px;
}
body.v6 .v6-wait-alt a:hover { color: var(--v6-orange); }
body.v6 .v6-wait-alt a:focus-visible { outline: 2.5px solid var(--v6-orange); outline-offset: 2px; border-radius: 6px; }

@media (max-width: 999px), (max-aspect-ratio: 3/2) {
  body.v6 .v6-stage.v6-stage .v6-nav-cta { display: none; }
}

/* Keep the primary action reachable when the painted desktop nav is hidden.
   Outside the scaled stage, it stays clear of the fixed music control. */
body.v6 .v6-compact-cta.v6-jelly { display: none; }
@media (max-width: 999px), (max-aspect-ratio: 3/2) {
body.v6 .v6-compact-cta.v6-jelly {
    display: inline-flex;
    position: fixed;
    z-index: 60;
    top: max(12px, env(safe-area-inset-top));
    right: calc(max(16px, env(safe-area-inset-right)) + 60px);
    width: auto;
    min-height: 44px;
    padding: 8px 10px;
    font-size: 13px;
    white-space: nowrap;
  }
}

/* ======================= PHONE: PINNED CLAIM BUTTON =======================
   On a phone held upright the "Claim" CTA leaves the painted stage and pins to
   the bottom of the screen, in the same paper bar as the offer card's pinned
   buy block (.v6-found-buy): always under the thumb, whatever is scrolled.
   The stage's zoom and transforms don't apply at this width, so `fixed` is
   against the viewport. The body keeps the bar's height free at its foot so
   the bottom of the painting can still be scrolled into view. */
@media (max-width: 659px) and (orientation: portrait) {
  body.v6-hero { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
  body.v6-hero .v6-stage.v6-stage .v6-stores {
    position: fixed;
    inset: auto 0 0;
    z-index: 50;
    display: block;
    padding: 14px 20px max(12px, env(safe-area-inset-bottom));
    background: var(--v6-card);
    box-shadow: 0 -1px 0 var(--v6-card-line), 0 -10px 18px -8px rgba(15, 42, 27, .12);
  }
  body.v6-hero .v6-stage.v6-stage .v6-stores .v6-hero-cta.v6-jelly {
    width: 100%;
    min-height: 50px;
    justify-content: center;
    font-size: 14px;
  }
  /* The bar has no room under the button; the sticker and the struck price
     already say it. */
  body.v6-hero .v6-stage.v6-stage .v6-stores .v6-cta-deal-note { display: none; }
  body.v6-hero .v6-stage.v6-stage .v6-stores .v6-cta-deal { right: -4px; }
  /* The payments-paused notice sits just above the bar, not over it. */
  body.v6-hero .v6-paused { bottom: calc(76px + 10px + env(safe-area-inset-bottom)); }
}
