/* ========================================
   Binnie home (getbinnie.app/, /nl/, /ja/)
   The store deck's story as a page: the hero with its six source cards, the share
   sheet, two sticky-phone acts, the watch pair, what is free. Loaded by index only.
   ======================================== */

/* 🔴 Nothing here hides content until home.js has run and set `html.story-on`, the
   lesson style.css records for `.fade-in`: a page whose reveal depends on a script is
   a blank page whenever that script does not run. Every chapter is fully visible at
   rest, and every chapter carries its own inline screenshot for narrow screens. */

/* 🔴 THE PICKER THEMES THE WHOLE PAGE (founder 2026-10-18: "When user presses Green Kiwi
   or switches to dark, the entire page should switch"). Six palettes (pink, kiwi, golden x
   light, dark), mirrored from the app's own assets/config/colors*.json, keyed on
   html[data-pal] and html[data-mode], which the inline theme boot sets before first paint
   (tool/site-theme-params.json: ?palette= / ?mode= from the app, then the visitor's own
   choice, then the OS). Golden has no button; it comes only from an app link. With no
   script the page follows the OS in pink, which is why pink dark alone is written twice:
   under the media query guarded by :not([data-mode]) and on [data-mode="dark"]. Only the
   act-1 phone's captures follow the picker; every other screenshot stays as shot (founder:
   "too much work for a gimmick"). Every colour on this page is one of these tokens: a
   literal pink left in a rule stays pink on a green page. */
body.home {
  --h-paper: #FFF4F7;
  --h-paper-2: #FFE4EC;
  --h-card: #FFFFFF;
  --h-ink: #2B1620;
  --h-ink-2: #5E4853;
  --h-melon: #D6245F;

  --h-melon-ink: #B81E52;
  --h-melon-soft: #F7B8CC;
  --h-rind: #5E9E2E;
  --h-rind-soft: #DDEFCB;
  --h-line: #F1CAD7;
  --h-shape: #FBD3DF;
  --h-bezel: #1C1116;
  --h-strap: #EBB2C4;
  --h-case: #17171A;
  --h-case-hi: #5B5B61;
  --h-crown: #8A8A91;
  /* Fills that carry white text (badges, buttons, the pitch band, the price pill): the
     same in light and dark, as the app's buttonFill is. */
  --h-fill: #D6245F;
  --h-band: #AF1D4E;
  --h-band-a: #FFD66E;
  --h-band-b: #B4F0A0;
  --h-wm-b: #D6245F;
  --h-tag: #765667;
  --h-nav: rgba(255, 255, 255, 0.92);
  --h-shadow: rgb(80 10 40 / 0.55);
  /* The site-wide stylesheet's tokens (nav, buttons, footer) follow the home palette. */
  --primary: var(--h-fill);
  --primary-dark: var(--h-band);
  --primary-light: var(--h-melon-soft);
  --primary-lighter: var(--h-paper-2);
  --text-primary: var(--h-ink);
  --text-secondary: var(--h-ink-2);
  --bg-light: var(--h-paper);
  --border: var(--h-line);
  background: var(--h-paper);
  color: var(--h-ink);
}
/* Watermelon, dark (assets/config/colors_dark_pink.json family). */
@media (prefers-color-scheme: dark) {
  :root:not([data-mode]) body.home {
    --h-paper: #1A0F14; --h-paper-2: #24131B; --h-card: #2B1820; --h-ink: #FBEAF0; --h-ink-2: #C9AAB7;
    --h-melon: #FF5E8F; --h-melon-ink: #FF7AA3; --h-melon-soft: #6E2440; --h-rind: #9CCC65; --h-rind-soft: #2C3A1E;
    --h-line: #47232F; --h-shape: #33171F; --h-bezel: #050304; --h-strap: #5E2B3D; --h-case: #0A0A0C;
    --h-case-hi: #6E6E75; --h-crown: #9A9AA2; --h-wm-b: #FF5E8F; --h-tag: #C9AAB7;
    --h-nav: rgba(26, 15, 20, 0.9); --h-shadow: rgb(0 0 0 / 0.6);
    color-scheme: dark;
  }
}
:root[data-mode="dark"] body.home {
  --h-paper: #1A0F14; --h-paper-2: #24131B; --h-card: #2B1820; --h-ink: #FBEAF0; --h-ink-2: #C9AAB7;
  --h-melon: #FF5E8F; --h-melon-ink: #FF7AA3; --h-melon-soft: #6E2440; --h-rind: #9CCC65; --h-rind-soft: #2C3A1E;
  --h-line: #47232F; --h-shape: #33171F; --h-bezel: #050304; --h-strap: #5E2B3D; --h-case: #0A0A0C;
  --h-case-hi: #6E6E75; --h-crown: #9A9AA2; --h-wm-b: #FF5E8F; --h-tag: #C9AAB7;
  --h-nav: rgba(26, 15, 20, 0.9); --h-shadow: rgb(0 0 0 / 0.6);
  color-scheme: dark;
}
/* Kiwi green, light (assets/config/colors.json). The wordmark's b takes the app's
   wordmarkAccent: the olive primary sits too close to the near-black ink for a
   two-tone logo. */
:root[data-pal="kiwi"] body.home {
  --h-paper: #F6FAEE; --h-paper-2: #EAF3D6; --h-card: #FFFFFF; --h-ink: #212121; --h-ink-2: #4A5043;
  --h-melon: #557B2C; --h-melon-ink: #44661F; --h-melon-soft: #CFE3B0; --h-rind: #388E3C; --h-rind-soft: #DDEFCB;
  --h-line: #D0E2B8; --h-shape: #DDEBC6; --h-strap: #C5DBA5; --h-bezel: #10160C;
  --h-fill: #557B2C; --h-band: #3F5E1F; --h-band-a: #FFD66E; --h-band-b: #E3F5C6; --h-wm-b: #7CB342;
  --h-tag: #5A6350; --h-nav: rgba(246, 250, 238, 0.92); --h-shadow: rgb(30 50 10 / 0.5);
  color-scheme: light;
}
/* Kiwi green, dark (assets/config/colors_dark.json). No media-query twin: a palette only
   exists where the theme boot ran, and the boot always sets data-mode. */
:root[data-pal="kiwi"][data-mode="dark"] body.home {
  --h-paper: #0E1A12; --h-paper-2: #13241A; --h-card: #1A2E22; --h-ink: #E8F0E2; --h-ink-2: #B8C4B0;
  --h-melon: #8BC34A; --h-melon-ink: #9CCC65; --h-melon-soft: #2E4A1E; --h-rind: #9CCC65; --h-rind-soft: #22381A;
  --h-line: #1F3528; --h-shape: #1A2E22; --h-strap: #2E4A1E; --h-bezel: #050805;
  --h-fill: #557B2C; --h-band: #2F4A17; --h-wm-b: #8BC34A; --h-tag: #B8C4B0;
  --h-nav: rgba(14, 26, 18, 0.9); --h-shadow: rgb(0 0 0 / 0.6);
  color-scheme: dark;
}
/* Kiwi golden, light (assets/config/colors_golden.json): the app's unlockable palette.
   The picker never offers it; it arrives only as ?palette=golden from the app (founder
   2026-10-20). The wordmark's b takes the app's wordmarkAccent, as kiwi's does. */
:root[data-pal="golden"] body.home {
  --h-paper: #FFFCF2; --h-paper-2: #FFF3D1; --h-card: #FFFFFF; --h-ink: #3E2723; --h-ink-2: #5D4037;
  --h-melon: #8F6C10; --h-melon-ink: #7A5800; --h-melon-soft: #F5E6A0; --h-rind: #8B4513; --h-rind-soft: #F3E3CC;
  --h-line: #E8D9B0; --h-shape: #F5E8C4; --h-strap: #E6D29A; --h-bezel: #17120A;
  --h-fill: #8F6C10; --h-band: #6E520A; --h-band-a: #FFD66E; --h-band-b: #FFF1C2; --h-wm-b: #D69A00;
  --h-tag: #6B5A44; --h-nav: rgba(255, 252, 242, 0.92); --h-shadow: rgb(60 40 0 / 0.5);
  color-scheme: light;
}
/* Kiwi golden, dark (assets/config/colors_dark_golden.json). */
:root[data-pal="golden"][data-mode="dark"] body.home {
  --h-paper: #2A1F18; --h-paper-2: #33271F; --h-card: #36291F; --h-ink: #E8DCC8; --h-ink-2: #C4B5A0;
  --h-melon: #E0AE1F; --h-melon-ink: #E8BC3C; --h-melon-soft: #5A4512; --h-rind: #D7A86E; --h-rind-soft: #3D2E25;
  --h-line: #4A3A2E; --h-shape: #3D2E25; --h-strap: #5D4A2A; --h-bezel: #0A0705;
  --h-fill: #8F6C10; --h-band: #5C450A; --h-wm-b: #E0AE1F; --h-tag: #C4B5A0;
  --h-nav: rgba(42, 31, 24, 0.9); --h-shadow: rgb(0 0 0 / 0.6);
  color-scheme: dark;
}
body.home .nav { background: var(--h-nav); }
body.home .nav-brand span, body.home .nav-link { color: var(--h-ink); }
body.home .footer { background: var(--h-paper-2); }
body.home .footer-links a, body.home .footer-brand span { color: var(--h-ink); }
body.home .footer-copyright, body.home .footer-trademarks { color: var(--h-ink-2); }
/* The inline wordmarks carry fill="#D6245F" on their b; any CSS beats a presentation
   attribute. :where() keeps this at (0,1,0) so a band that whitens its wordmarks
   (.h-uvp .wm-b) still wins. */
:where(body.home) .wm-b { fill: var(--h-wm-b); }
/* The claim's swoosh carries stroke="#D6245F" from the deck's own SVG; it is the accent. */
:where(body.home) .swoosh-ink path { stroke: var(--h-melon); }

.home main { padding-top: 64px; overflow-x: clip; }
.home h1, .home h2, .home h3 { font-weight: 800; letter-spacing: -0.015em; text-wrap: balance; color: var(--h-ink); }
/* Small melon text uses --h-melon-ink (5.25:1 on --h-paper-2 where --h-melon is 4.11); the
   brand melon stays for large type, fills and marks. */
.home .eyebrow { font-weight: 800; font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--h-melon-ink); }
.home .pay { display: block; color: var(--h-melon); }
/* The wordmark keeps its own two colours inside an accent payoff line, as the app
   draws it everywhere: the b in the accent, the rest in the text ink (textPrimary). */
.home .pay .wm-r { fill: var(--h-ink); }
/* Same in a melon eyebrow (founder 2026-10-21, "ONLY IN binnie" on the Health band): on the
   light paper the all-melon mark read as part of the label; the regular two-colour mark reads
   as the brand. */
.home .eyebrow .wm-r, .home .hl-vs-us small .wm-r, .home .hl-em .wm-r { fill: var(--h-ink); }
.home .lockup { font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 800; white-space: nowrap; }
/* In a HEADLINE the lockup is a mention, not a second headline (founder 2026-10-18, the nl share
   payoff "... en THE binnie GRADE."): at 0.8em of a headline the wordmark stood taller than the
   claim's own words. */
.home h1 .lockup, .home h2 .lockup { font-size: 0.62em; }
/* On the baseline like every inline wordmark: its bottom never below the words around it. */
.home .lockup .wm { height: 1.2em !important; vertical-align: baseline !important; margin-inline: 0.1em; }
.home .nav-right { gap: 20px; }

/* ---------- shared device frames ---------- */
/* A thin, even bezel around a screen that has the CAPTURE'S OWN shape (Pixel 1080 x 2424),
   so `cover` never crops the bottom of a screenshot. A 2 px rim gives the metal edge. */
.home .phone { position: relative; z-index: 2; width: min(290px, 70vw); border-radius: 40px; background: #17121A; padding: 7px;
  box-shadow: 0 0 0 1.5px #3A2F37, 0 40px 70px -30px var(--h-shadow); }
.home .scr { position: relative; width: 100%; aspect-ratio: 1080 / 2424; border-radius: 33px; overflow: hidden; background: var(--h-paper-2); }
.home .scr picture, .home .scr img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.home .layer { position: absolute; inset: 0; opacity: 0; transition: opacity 0.45s ease; }
.home .layer.on { opacity: 1; }
.home .slice { position: absolute; width: min(600px, 125%); aspect-ratio: 1; z-index: 0; pointer-events: none; }
.home .slice .s-rind { fill: var(--h-rind-soft); }
.home .slice .s-pith { fill: var(--h-paper); }
.home .slice .s-flesh { fill: var(--h-shape); }

/* ---------- hero: the deck hero's cards at the deck's phone coordinates
   (build-binnie-deck.cjs heroLayout, device 196 x 427 design px) ---------- */
.h-hero { padding-block: 32px 72px; }
.h-hero-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 40px; align-items: center; }
.h-hero-copy { display: grid; gap: 16px; min-width: 0; }
/* The brand lockup, as the branding composes it: mark, wordmark, category line. */
.h-lockup { display: flex; align-items: center; gap: 16px; }
.h-lockup img { width: 72px; height: 72px; flex: none; }
.h-lockup-text { display: grid; gap: 4px; }
.h-lockup-name { font-size: 2.6rem; line-height: 1; color: var(--h-ink); }
.h-lockup-name svg:not(.wm) { display: block; }
.h-lockup-tag { font-weight: 800; font-size: 1.1rem; color: var(--h-tag); letter-spacing: 0.01em; }
/* On a phone the stage comes first and the nav right above it already carries the mark
   and the name, so the hero lockup would only repeat them, and on an iPhone it landed
   half under Safari's toolbar (founder 2026-10-17). Keep only the tagline, as the
   headline's eyebrow. */
@media (max-width: 979px) {
  .h-lockup img, .h-lockup-name { display: none; }
  .h-lockup-tag { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--h-melon-ink); }
  .h-hero-copy { gap: 14px; }
}
.h-hero-copy h1 { font-size: clamp(2.3rem, 4.6vw, 4.1rem); line-height: 1.02; padding-bottom: 0.14em; overflow-wrap: break-word; hyphens: auto; }
/* Dutch opens on one long compound (Voedingswaarden, 8.27em in Nunito 800), and a
   hyphen splitting the headline's first word reads as broken. Never hyphenate it;
   size the line so the word fits the column instead (8.6em of the 48px-gutter column
   down to a 320px phone; the two-column layout above 860px already has room). */
/* "For free." (deck google.claimSuffix), its own line as on the Android welcome screen
   (authWelcomeNutritionKickerFree), in the claim's ink, never swooshed. Inline, it pushed
   the swoosh word onto a middle line and the swoosh ink (down to 1.48em) struck the
   next line's capitals; the margin clears it. */
.h-claim-free { display: block; margin-top: 0.28em; white-space: nowrap; }
/* nl underlines "écht", which never lands on the claim's last line ("vertrouwen." follows it),
   so the margin that clears the stroke would only open a gap above "Gratis." */
:lang(nl) .h-claim-free { margin-top: 0.06em; }
:lang(nl) .h-hero-copy h1 { hyphens: manual; font-size: min(clamp(2.3rem, 4.6vw, 4.1rem), calc((100vw - 48px) / 8.6)); }
@media (min-width: 980px) { :lang(nl) .h-hero-copy h1 { font-size: clamp(2.3rem, 4.6vw, 4.1rem); } }
/* Japanese: phrase-aware line breaks (never 「リ／ール」), and air between heading lines so
   the swoosh under 信頼 sits in the gap rather than across the next line. */
/* Japanese headings break at phrase boundaries, never inside a word (グ / レード).
   auto-phrase is Chrome-only; Safari ignored it and broke between any two kana, so
   keep-all (breaks at 、。, spaces and script changes) is the floor everywhere, with
   overflow-wrap as the last resort for a run that cannot fit. */
:lang(ja) .home h1, :lang(ja) .home h2, :lang(ja) .home h3, :lang(ja) .home .h-sub, :lang(ja) .h-uvp p, :lang(ja) .h-4in1 { word-break: keep-all; overflow-wrap: anywhere; }
@supports (word-break: auto-phrase) { :lang(ja) .home h1, :lang(ja) .home h2, :lang(ja) .home h3, :lang(ja) .home .h-sub, :lang(ja) .h-uvp p, :lang(ja) .h-4in1 { word-break: auto-phrase; } }
:lang(ja) .h-hero-copy h1 { line-height: 1.45; }
:lang(ja) .home h2, :lang(ja) .home h3 { line-height: 1.3; }
/* ONE subhead under the H1 (founder 2026-10-19: a second pink headline and an
   ellipsis-split sentence read as two competing headlines). Pink belongs to the
   H1's underline alone. */
.h-sub { margin: 0; max-width: 36ch; color: var(--h-ink-2); font-size: clamp(1.15rem, 1.7vw, 1.35rem); font-weight: 500; line-height: 1.45; text-wrap: pretty; }
.h-hero-stage { position: relative; display: grid; place-items: center; min-width: 0; }
/* also capped by HEIGHT: the whole composition (about 2.66x its width, cards included)
   must sit in the first viewport; svh = the toolbar-expanded mobile height. */
.rig { --rw: min(290px, 54vw, calc((100svh - 150px) / 2.7)); position: relative; width: var(--rw); container-type: inline-size; margin: calc(var(--rw) * 0.46) 0 calc(var(--rw) * 0.2); }
.rig .phone { width: 100%; }
.card { position: absolute; z-index: 3; }
.card .face { position: absolute; inset: 0; background: #fff; border-radius: 7cqw; box-shadow: 0 3cqw 7cqw -3cqw rgb(60 10 30 / 0.45); overflow: hidden; }
.card .face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bdg { position: absolute; width: 14.3cqw; height: 14.3cqw; border-radius: 50%; display: grid; place-items: center; background: var(--h-fill); color: #fff;
  border: 1cqw solid #fff; box-sizing: border-box; box-shadow: 0 1.5cqw 4cqw -1cqw rgb(30 5 12 / 0.45); }
.bdg svg:not(.wm) { width: 46%; height: 46%; }
.disc { position: absolute; width: 13.3cqw; height: 13.3cqw; border-radius: 50%; display: grid; place-items: center; background: #fff; box-shadow: 0 1cqw 3cqw -1cqw rgb(30 5 12 / 0.4); }
.disc svg:not(.wm) { width: 66%; height: 66%; }
.c-plate { left: -27%; top: -15.5%; width: 53.1%; aspect-ratio: 104 / 74; rotate: -7deg; }
.c-plate .face { padding: 2.2cqw; } .c-plate .face img { border-radius: 5cqw; }
.c-web { left: -30.1%; top: 26%; width: 36.7%; aspect-ratio: 72 / 100; rotate: -5deg; }
.c-web .face { display: grid; grid-template-rows: auto 1fr auto; }
.c-web .bar { height: 9cqw; background: #F1E7EB; display: flex; align-items: center; gap: 1.4cqw; padding-left: 2.5cqw; }
.c-web .bar i { width: 2.2cqw; height: 2.2cqw; border-radius: 50%; background: #D9C3CC; }
.c-web .lines { padding: 2.5cqw; display: grid; gap: 1.6cqw; }
.c-web .lines i { height: 1.8cqw; border-radius: 1cqw; background: #EADCE2; } .c-web .lines i:last-child { width: 60%; }
.c-video { left: 86.2%; top: -17.8%; width: 36.7%; aspect-ratio: 72 / 126; rotate: 6deg; }
.c-video .play { position: absolute; inset: 0; display: grid; place-items: center; }
.c-video .play svg:not(.wm) { width: 30%; fill: #fff; filter: drop-shadow(0 1cqw 2cqw rgb(0 0 0 / 0.5)); }
/* ja names no TikTok anywhere (deck Round 5: logos follow the copy), and the rest close up. */
[data-tiktok="hide"] .d-tiktok { display: none; }
[data-tiktok="hide"] .d-ig { left: 2.8% !important; }
[data-tiktok="hide"] .d-yt { left: 29.2% !important; }
.c-barcode { left: 79%; top: 32.1%; width: 56.1%; aspect-ratio: 110 / 72; rotate: 5deg; }
.c-barcode .face, .ov-barcode .face { display: grid; grid-template-rows: auto auto; align-content: center; place-items: center; row-gap: 4%; padding: 11% 13% 7%; }
/* Heights in cqw, not a 1fr row: measured 2026-10-17, the SVG (64px in a 45px row) and
   the digit line (16px in a 9px row) both overflowed their grid rows on a small hero, so
   the digits printed over the bars. The hero card's cqw is the RIG's (the card is not a
   size container): the card is 56.1cqw wide and 36.7 tall, less 10.1 of padding and the
   4.3 digit line. The story overlay IS its own container: 65.5 tall, less 18 and 7.4. */
.c-barcode .bars, .ov-barcode .bars { width: 100%; }
.c-barcode .bars { height: 21cqw; }
.ov-barcode .bars { height: 37cqw; }
.c-barcode .digits { font: 500 3.6cqw/1.2 ui-monospace, Menlo, monospace; color: #222; letter-spacing: 0.08em; }
.digits a, .digits a[href^="tel"] { color: inherit; text-decoration: none; pointer-events: none; }
.c-note { left: 81.6%; top: 70.3%; width: 52%; aspect-ratio: 1; rotate: -4deg; }
.c-note .face { background: #FFE883; border-radius: 2cqw; padding: 7cqw 5.5cqw; font: 600 6.9cqw/1.15 "Bradley Hand", "Segoe Print", "Comic Sans MS", cursive; color: #3B3226; white-space: pre-line; hyphens: auto; overflow-wrap: break-word; }
.c-apple { left: -27%; top: 77.3%; width: 32.7%; aspect-ratio: 1; rotate: 8deg; }
.c-apple .face { border-radius: 50%; display: grid; place-items: center; } .c-apple .face svg:not(.wm) { width: 62%; }

/* ---------- official store badges: unmodified, App Store first, matched height ---------- */
.stores { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.stores a { display: block; line-height: 0; border-radius: 10px; }
.store-apple img { height: 52px; width: auto; }
/* One Apple badge at a time: the Mac App Store one on a Mac (html.is-mac, set in <head>
   before first paint, so nothing swaps in view), the App Store one everywhere else. */
.stores .store-mac { display: none; }
/* Shown on a Mac only, so its link is the macappstore:// scheme: it opens the App Store app
   from any browser instead of the web listing (founder 2026-10-21). */
.is-mac .stores .store-mac { display: block; }
.is-mac .stores .store-apple { display: none; }
.store-mac img { height: 52px; width: auto; }
/* Google's badge PNGs are trimmed to the visible badge at build time (their padding differs
   per locale: en pads all four sides, nl and ja only top and bottom), so no crop here. */
.store-google img { height: 52px; width: auto; max-width: none; }

/* ---------- share sheet ---------- */
.h-share { background: var(--h-paper-2); padding-block: 80px; }
.h-share-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.h-share-copy { display: grid; gap: 18px; min-width: 0; }
/* Capped so the claim holds one line in every core locale (founder 2026-10-18,
   "Share a TikTok recipe." / "Deel een TikTok-recept."): measured in the half-width
   column, Dutch keeps one line at 46px from 1280px and 44px at 1100px, English at 50px. */
.h-share-copy h2 { font-size: clamp(2.1rem, 4vw, 2.85rem); line-height: 1.04; }
.home .h-proof { font-size: 1.15rem; color: var(--h-ink-2); max-width: 44ch; }
.h-src { display: flex; gap: 14px; align-items: center; font-size: 1.15rem; font-weight: 700; color: var(--h-ink); }
.h-src > span:last-child { min-width: 0; }
/* A row of overlapping white discs: the share sources, and the hero's four apps. */
.disc-row { display: flex; flex: none; }
.disc-row > span { width: 40px; height: 40px; border-radius: 50%; background: #fff; display: grid; place-items: center; box-shadow: 0 3px 10px -4px rgb(30 5 12 / 0.45); }
.disc-row > span + span { margin-left: -8px; }
.disc-row svg:not(.wm) { width: 64%; height: 64%; }
/* The share sources as two interlocking rows (founder 2026-10-21): the social apps above, the
   three browsers below, the lower row set half a disc in so the six sit like a honeycomb. With
   TikTok hidden (data-tiktok) the two rows centre on each other, two over three. */
.disc-stack { display: grid; flex: none; justify-items: center; }
.disc-stack > .disc-row + .disc-row { margin-top: -7px; }
.disc-stack > .disc-row:first-child { position: relative; z-index: 1; margin-inline-end: 16px; }
.disc-stack > .disc-row:last-child { margin-inline-start: 16px; }
[data-tiktok="hide"] .disc-stack > .disc-row { margin-inline: 0; }
.h-4in1 { display: grid; gap: 12px; width: fit-content; max-width: 100%; }
.h-4in1-n { margin: 0; color: var(--h-ink); font-weight: 800; font-size: 1.1rem; }
.h-4in1-t { display: grid; gap: 1px; color: var(--h-ink); font-weight: 700; }
.h-4in1-sub { font-size: 0.82em; font-weight: 500; line-height: 1.3; color: color-mix(in oklab, var(--h-ink-2) 80%, transparent); }
.fi .fi-link { grid-column: 2; justify-self: start; margin-top: 8px; padding-bottom: 0.3em; color: var(--h-ink); font-weight: 700; font-size: 0.92rem; }
.fi .fi-link span { color: inherit; font-size: inherit; }
/* The card links match the 4-in-1 line (founder 2026-10-21): ink text, the arrow in melon,
   underline on hover. The wave stays the hero's emphasis mark, not a link style. */
.fi .fi-link { text-decoration: none; }
.more-link { color: var(--h-ink); font-weight: 700; text-decoration: none; white-space: nowrap; }
.more-link .fi-arrow { color: var(--h-melon-ink); font-weight: 800; }
.more-link:hover { text-decoration: underline; text-decoration-color: var(--h-melon); text-underline-offset: 3px; }
.fi .fi-link .fi-arrow { color: var(--h-melon-ink); font-weight: 800; }
.fi .fi-link:hover { text-decoration: underline; text-decoration-color: var(--h-melon); text-underline-offset: 3px; }
.h-4in1-health { justify-self: center; text-align: center; text-wrap: balance; /* never sets the block's width: the four tiles do, so this centres under THEM */ width: 0; min-width: 100%; box-sizing: border-box; padding-inline: 1.4em; line-height: 1.5; margin-top: 4px; color: var(--h-ink); font-weight: 700; font-size: 0.98rem; text-decoration: none; }
/* The arrow hangs past the text: zero layout width, so the TEXT alone is centred under
   the tiles (founder 2026-10-21) and the arrow still shows after the last word. */
/* Japanese has no comma to balance on, so balance cut it into three short lines mid-phrase
   (founder 2026-10-21). Without the side padding and with pretty wrapping it spans the tiles
   and breaks at the sentence end, after 写真も。 */
:lang(ja) .h-4in1-health { padding-inline: 0; text-wrap: pretty; }
.h-4in1-health .h-4in1-arrow { color: var(--h-melon-ink); font-weight: 800; display: inline-block; width: 0; margin-inline-start: 0.3em; white-space: nowrap; overflow: visible; }
.h-4in1-health:hover { text-decoration: underline; text-decoration-color: var(--h-melon); text-underline-offset: 3px; }
.h-4in1-health:hover { color: var(--h-melon-ink, var(--h-ink)); }
.h-4in1-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, max-content); gap: 10px 32px; }
.h-4in1-grid li { display: flex; align-items: flex-start; gap: 10px; min-width: 0; color: var(--h-ink-2); font-size: 1rem; line-height: 1.25; font-weight: 600; }
.h-4in1-ic { flex: none; width: 38px; height: 38px; border-radius: 12px; background: color-mix(in oklab, var(--h-melon) 13%, transparent); display: grid; place-items: center; color: var(--h-melon); }
.h-4in1-ic svg:not(.wm) { width: 58%; height: 58%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* On a phone the four discs took ~40% of the row and squeezed the line into a column
   (five lines in Dutch): stack the discs above it so the line gets the full width. */
@media (max-width: 979px) { .h-4in1 { flex-direction: column; align-items: flex-start; gap: 8px; } }
[data-tiktok="hide"] .h-src .s-tt { display: none; }
.h-db { display: flex; gap: 10px; align-items: center; font-weight: 700; color: var(--h-ink); }
.h-db svg:not(.wm) { width: 22px; height: 22px; flex: none; fill: none; stroke: var(--h-rind); stroke-width: 2; }
.h-steps { margin: 0; padding: 0; list-style: none; counter-reset: s; display: grid; gap: 10px; }
.h-steps li { counter-increment: s; display: flex; gap: 12px; align-items: center; font-size: 1.05rem; }
/* --h-fill, not --h-melon: white on the dark sets' melon measured 2.05-2.90 (a11y review
   2026-10-20); the fill is the same in light and dark, 4.86-4.91 in all six sets. */
.h-steps li::before { content: counter(s); display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--h-fill); color: #fff; font-weight: 800; font-size: 0.85rem; flex: none; }
.h-share-stage { position: relative; display: grid; place-items: center; padding-bottom: 8%; }
.h-share-stage .phone { width: min(250px, 46vw); }
.h-share-stage .sx-back { rotate: -4deg; translate: -28% -4%; }
.h-share-stage .sx-front { position: absolute; rotate: 3deg; translate: 30% 8%; z-index: 3; }

/* ---------- the pitch ---------- */
/* A deeper melon than the brand #D6245F so every word on it clears WCAG 4.5:1, not just
   the 3:1 large-text floor (measured: white 6.76, 85% white 5.24, gold 4.86, green 5.12;
   on #D6245F the gold was 3.53). */
.h-uvp { background: var(--h-band); color: #fff; padding-block: 72px; }
.h-uvp .container { display: grid; gap: 10px; max-width: 900px; width: fit-content; }
/* fit-content: the block is as wide as its longest line, so the sign-off's "end" is that line's end. */
.h-uvp p { font-weight: 700; font-size: clamp(1.5rem, 3.4vw, 2.5rem); line-height: 1.15; color: rgb(255 255 255 / 0.85); }
.h-uvp p.big { color: #fff; font-weight: 800; font-size: clamp(1.9rem, 4.4vw, 3.4rem); text-wrap: balance; contain: inline-size; }
/* contain: inline-size keeps the big line out of the block's fit-content width, so the block (and the
   sign-off straddling its end) follows the two lines above while the big line wraps inside it. */
/* The argument's two sides: recipes in Kiwi golden, nutrition in Kiwi green, and
   "both" carrying the two. Pale tints, 3:1 or better on the band at this size. */
.h-uvp .t-r { color: var(--h-band-a); }
.h-uvp .t-n { color: var(--h-band-b); }
.h-uvp .t-b { color: var(--h-band-a); background: linear-gradient(90deg, var(--h-band-a) 15%, var(--h-band-b) 85%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.h-uvp .wm-b, .h-uvp .wm-r { fill: #fff; }

/* The language switcher follows the page theme (founder 2026-10-18: in dark mode the list
   opened white). Its base rules in style.css read the site-wide tokens, which the home page's
   palettes and dark mode never redefine, so on the home page it reads the --h-* tokens. */
.home .lang-toggle { color: var(--h-ink); border-color: color-mix(in oklab, var(--h-ink) 18%, transparent); }
.home .lang-toggle:hover { background: color-mix(in oklab, var(--h-melon) 10%, var(--h-card)); border-color: var(--h-melon); }
.home .lang-chevron { color: var(--h-ink-2); }
.home .lang-dropdown { background: var(--h-card); border-color: color-mix(in oklab, var(--h-ink) 14%, transparent); box-shadow: 0 16px 36px -14px rgb(0 0 0 / 0.45); }
.home .lang-option { color: var(--h-ink-2); }
.home .lang-option:hover { background: color-mix(in oklab, var(--h-melon) 12%, var(--h-card)); color: var(--h-ink); }
.home .lang-option.active { background: var(--h-melon-soft); color: var(--h-melon-ink); }

/* The Share glyph beside "tap Share" (founder 2026-10-18), drawn in the eyebrow's own
   colour and sized to its cap height. */
.eyebrow .share-glyph { display: inline-block; height: 1.25em; width: auto; vertical-align: -0.28em; margin-inline-start: 0.4em; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- the sticky-phone acts ---------- */
/* An ACT is a part of the story; a CHAPTER is one step inside it (founder 2026-10-18: "the
   chapters look the same as the act"). So the act head is a full-bleed band on the second
   paper tone, centred, with the largest type on the page after the hero, and the chapter
   titles sit a clear step below it. Full-bleed from inside .container: the negative margin
   reaches the viewport edges and the matching padding brings the text back to the column. */
.act-head { margin-inline: calc(50% - 50vw); padding: clamp(56px, 9vh, 104px) calc(50vw - 50%); background: var(--h-paper-2); display: grid; justify-items: center; text-align: center; gap: 14px; }
.act-head > * { max-width: 860px; }
.act-head .eyebrow { font-size: 0.95rem; }
.act-head h2 { font-size: clamp(2.5rem, 5.6vw, 4.4rem); line-height: 1.02; text-wrap: balance; }
.act-head p { color: var(--h-ink-2); font-size: clamp(1.1rem, 1.6vw, 1.3rem); max-width: 60ch; text-wrap: pretty; }
.story { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; position: relative; }
/* A chapter is the scroll distance one phone screen stays on. It needs about the phone's
   own height (633px at its 290px cap, plus the card over its top edge and the counter
   under it), never more: at 86svh alone a tall screen (founder 2026-10-18, a 2000px
   viewport) made every chapter ~1720px, mostly empty page. Laptops are unchanged. */
/* Every chapter is EXACTLY as tall as the pinned stage, with its text centred, so a chapter's
   text and the device it describes share one centre line while that chapter is on screen.
   🔴 Do not shorten the first or last chapter to trim the space around an act head: that was
   tried (2026-10-18) and it put the first device ~250px below its text, left the previous
   act's last device beside the next act's head, and paired the 5/5 screen with chapter 4. The
   act transition reads as a deliberate break through the act band instead. */
.chapter { min-height: min(calc(100vh - 64px), 820px); min-height: min(calc(100svh - 64px), 820px); display: grid; align-content: center; gap: 16px; padding-block: 24px; max-width: 520px; transition: opacity 0.35s ease; }
/* Inactive chapters fade only as far as their text stays WCAG AA (measured minimum 0.84
   light, 0.74 dark; it was 0.38, 1.81:1). */
html.story-on .chapter { opacity: 0.86; }
html.story-on .chapter.on { opacity: 1; }
.num { display: inline-grid; place-items: center; width: 52px; height: 52px; border-radius: 14px; background: var(--h-card); color: var(--h-melon); font-weight: 800; font-size: 1.35rem; box-shadow: 0 6px 18px -10px color-mix(in oklab, var(--h-shadow) 75%, transparent); }
.chapter h3 { font-size: clamp(1.75rem, 3.1vw, 2.6rem); line-height: 1.06; }
.inline-phone, .inline-watch { display: none; }
.stage { position: relative; }
/* The stage is as tall as a chapter, never taller, and while pinned it sits in the middle of the
   visible area (below the 64px nav). Uncapped (100svh - 64px) on a tall screen it centred the
   phone ~970px into a section whose 820px chapters centre their text ~410px in, so the phone
   sat far below its own text (founder 2026-10-18, the watch act on a 2000px window). Laptops
   are unchanged: there 100svh - 64px is under 820px and the top resolves to 64px. */
.stage-in { position: sticky; top: max(64px, calc((100vh - 756px) / 2)); top: max(64px, calc((100svh - 756px) / 2)); height: min(calc(100vh - 64px), 820px); height: min(calc(100svh - 64px), 820px); display: grid; place-items: center; align-content: center; gap: 14px; }
.rig2 { position: relative; z-index: 2; display: grid; place-items: center; }
/* The pinned story phone is 2.18x as tall as it is wide and sits under a 64px nav,
   with a card overlapping its top edge and the counter below it. At a fixed 290px it is
   633px tall, so a laptop under ~800px pushed the card into the nav. Cap it by height. */
.stage-in .rig2 .phone { width: min(290px, 70vw, calc((100svh - 264px) / 2.183)); }
.counter { position: relative; z-index: 2; display: grid; justify-items: center; gap: 2px; font: 800 1.2rem var(--font); font-variant-numeric: tabular-nums; color: var(--h-ink); background: none; border: 0; cursor: pointer; padding: 4px 10px; }
.counter svg:not(.wm) { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* chapter overlays, placed as the store frames place them */
.ov { position: absolute; z-index: 4; }
.stage .ov { opacity: 0; transition: opacity 0.45s ease; }
.stage .ov.on { opacity: 1; }
/* the barcode lifts over the phone's top-right corner, tilted like the hero's card */
.ov-barcode { right: -16%; top: -5%; width: 60%; aspect-ratio: 110 / 72; rotate: 5deg; container-type: inline-size; }
.ov-barcode .face { position: absolute; inset: 0; background: #fff; border-radius: 11cqw; box-shadow: 0 14px 30px -12px rgb(30 5 12 / 0.5); }
.ov-barcode .digits { font: 500 6.2cqw/1.2 ui-monospace, Menlo, monospace; color: #222; letter-spacing: 0.08em; }
.ov-barcode .bdg { width: 25cqw; height: 25cqw; border-width: 1.8cqw; left: 78%; top: -19%; }
.c-barcode .bdg-corner { left: 78.2%; top: -19.4%; }
.ov-watch { right: -20%; bottom: 7%; width: 46%; }
/* The snapped plate over the snap act's phone, as the store deck's snap frame carries it
   (founder 2026-10-17): the hero's own falafel photo, framed white, tilted, its camera
   badge on the corner. */
.ov-plate { right: -18%; top: -6%; width: 58%; aspect-ratio: 104 / 74; rotate: 6deg; container-type: inline-size; }
.ov-plate .face { position: absolute; inset: 0; background: #fff; border-radius: 9cqw; padding: 4cqw; box-shadow: 0 14px 30px -12px rgb(30 5 12 / 0.5); }
.ov-plate .face img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 6cqw; }
.ov-plate .bdg { width: 24cqw; height: 24cqw; border-width: 1.8cqw; left: 82%; top: 62%; }
.ov-la { left: -9%; right: -9%; bottom: 12%; border-radius: 22px; overflow: hidden; box-shadow: 0 24px 40px -16px rgb(20 0 10 / 0.6); }
.ov-la picture, .ov-la img { display: block; width: 100%; height: auto; }
/* One Live Activity card per walkthrough step; home.js shows the phone's step. The
   hit areas sit over the card's own speaker and Next step buttons (positions inline,
   from each card's height). */
.ov-la .la { display: none; position: relative; }
.ov-la .la.on { display: block; }
.ov-la .la-hit { position: absolute; padding: 0; border: 0; background: transparent; cursor: pointer; border-radius: 999px; }
.ov-la .la-hit:focus-visible { outline: 3px solid var(--h-melon); outline-offset: 2px; }

/* ---------- watches: a thin metal edge, black glass, then the display ---------- */
/* the circle centres on the watch pair, not on pair + counter */
.wrig { position: relative; display: grid; place-items: center; padding-block: 90px 70px; }
.wrig > .wpair { grid-area: 1 / 1; }
.wrig > .slice { left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(520px, 118%); }
.wpair { position: relative; z-index: 2; display: flex; gap: clamp(18px, 3vw, 40px); align-items: center; justify-content: center; }
.wfig { display: grid; justify-items: center; gap: 14px; margin: 0; }
.wbody { position: relative; display: grid; place-items: center; }
.wbody::before { content: ""; position: absolute; z-index: 0; left: 50%; translate: -50% 0; top: -32%; bottom: -32%; width: 66%; background: var(--h-strap); border-radius: 22px; }
.wcase { position: relative; z-index: 1; background: #000; box-shadow: 0 0 0 2px var(--h-case-hi), 0 0 0 4px var(--h-case), 0 24px 40px -18px rgb(60 10 30 / 0.55); }
.wcase .scr { position: relative; overflow: hidden; background: #000; width: 100%; border-radius: inherit; }
.wcase .scr picture, .wcase .scr img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.wcase::after { content: ""; position: absolute; background: linear-gradient(90deg, var(--h-crown), var(--h-case-hi)); }
/* The case wraps a screen with the capture's exact shape (374 x 446), never the other way round. */
.wcase.apple { width: clamp(124px, 13vw, 168px); border-radius: 26% / 22%; padding: 7%; }
.wcase.apple .scr { aspect-ratio: 374 / 446; border-radius: 19% / 16%; }
.wcase.apple::after { right: -6.5%; top: 24%; width: 4.4%; height: 15%; border-radius: 0 5px 5px 0; }
.wcase.wear { width: clamp(128px, 14vw, 176px); border-radius: 50%; padding: 6%; }
.wcase.wear .scr { aspect-ratio: 1; border-radius: 50%; }
.wcase.wear::after { right: -6%; top: 43%; width: 5%; height: 14%; border-radius: 0 6px 6px 0; }
.ov-watch .wcase.wear { width: 100%; }
.ov-watch .wcase.wear::after { right: -7%; }
/* the label and its platform mark travel as ONE pill, legible over the strap */
.wfig figcaption { position: relative; z-index: 2; }
.wlabel { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px 5px 10px; border-radius: 999px; background: var(--h-card); color: var(--h-ink-2);
  font-weight: 800; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; box-shadow: 0 4px 12px -6px rgb(60 10 30 / 0.35); }
.wlabel svg:not(.wm) { width: 14px; height: 14px; flex: none; }

/* ---------- what is free ---------- */
.h-free { margin-top: 110px; display: grid; gap: 26px; }
.h-free h2 { font-size: clamp(2rem, 4.4vw, 3.25rem); line-height: 1.05; }
.h-free .sub { color: var(--h-ink-2); font-size: 1.15rem; max-width: 60ch; }
.freegrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; grid-auto-flow: row dense; }
/* The two longest tiles (notifications, family) take two columns so the grid closes on full rows. */
.freegrid .fi-wide { grid-column: span 2; }
/* the lead tile spans the row and is centred as a whole (founder 2026-10-17): the check
   sits beside the title, the body line centred under both */
/* "Also free": the features that need no tile, as a two-column checklist; a short line
   only where the name alone does not explain it (protein quality, widgets, typed recipes). */
.freemore { margin-top: 22px; border-radius: 20px; padding: 22px 24px; background: var(--h-card); border: 1.5px solid var(--h-line); }
.freemore h3 { font-size: 1.1rem; font-weight: 800; margin: 0 0 12px; }
.freemore ul { margin: 0; padding: 0; list-style: none; columns: 2 280px; column-gap: 32px; }
.freemore li { break-inside: avoid; position: relative; padding: 0 0 10px 26px; color: var(--h-ink-2); font-size: 0.95rem; }
.freemore li::before { content: ""; position: absolute; left: 2px; top: 0.3em; width: 12px; height: 7px; border-left: 2.4px solid var(--h-rind); border-bottom: 2.4px solid var(--h-rind); transform: rotate(-45deg); }
.freemore li b { color: var(--h-ink); font-weight: 700; display: block; }
/* The lead centres only while it spans several cards; in the one-column
   layout it is a card like the rest. */
.freegrid .fi-lead { grid-column: 1 / -1; }
@media (min-width: 861px) {
  .freegrid .fi-lead { display: block; text-align: center; }
  .freegrid .fi-lead svg:not(.wm) { display: inline-block; vertical-align: -0.3em; margin-inline-end: 8px; }
  .freegrid .fi-lead > span { display: block; margin-top: 4px; }
}
@media (max-width: 860px) { .freegrid { grid-template-columns: minmax(0, 1fr); } .freegrid .fi-wide { grid-column: auto; } }
/* Content centred vertically: a row is as tall as its tallest card, so a short card (the wide
   "Filters" and "Notifications" cards beside a long one) read as mostly empty when its text
   hugged the top (founder 2026-10-18). */
.fi { background: var(--h-card); border-radius: 20px; padding: 18px 20px; border: 1.5px solid var(--h-line); display: grid; grid-template-columns: 28px 1fr; gap: 4px 12px; align-content: center; }
.fi svg:not(.wm) { width: 26px; height: 26px; grid-row: span 2; fill: none; stroke: var(--h-rind); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.fi b { font-weight: 800; }
.fi span { color: var(--h-ink-2); font-size: 0.95rem; }
/* a tile's footnote: the specifics behind its body line (founder 2026-10-17: the health
   conditions Binnie checks), under the body in the text column */
.fi .fi-note { grid-column: 2; margin-top: 6px; color: var(--h-ink-2); font-size: 0.82rem; line-height: 1.45; }
.tiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 14px; }
/* Tier cards: the price is the card's header, set off from the features by a rule
   (founder 2026-10-17: the price "doesn't look the best yet"). White like the free tiles;
   Pro+AI carries the melon outline as the upgrade path, no badge and no extra claim. */
.tierc { border-radius: 24px; padding: 26px 28px; background: var(--h-card); border: 1.5px solid var(--h-line); display: grid; gap: 0; align-content: start; }
.tierc.tierc-ai { border: 2px solid var(--h-melon); }
.tier-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 12px 20px; padding-bottom: 18px; margin-bottom: 18px; border-bottom: 1px solid var(--h-line); }
.tierc b { font-weight: 800; font-size: 1.25rem; padding-top: 6px; }
.tierc b .lockup { font-size: 0.92em; }
/* The price, top right: the per-month figure leads, the yearly charge under it, and the
   real saving against the monthly plan as the deal. Right-aligned while it sits beside the
   title; on a narrow card it wraps under the title and aligns left with it. */
.tier-price { display: grid; justify-items: end; text-align: end; gap: 6px; margin-inline-start: auto; }
/* The app's promo ribbon: an extra-bold headline over a lighter subtitle, in a soft pill. */
.tier-price .intro { display: grid; justify-items: inherit; gap: 1px; color: var(--h-ink); border: 1.5px solid var(--h-band); padding: 5px 12px; border-radius: 14px; line-height: 1.2; }
.tier-price .intro b { font-weight: 800; font-size: 0.82rem; letter-spacing: 0.01em; }
.tier-price .intro-sub { font-weight: 600; font-size: 0.74rem; color: var(--h-ink-2); }
.tier-price .line { display: flex; align-items: baseline; gap: 3px; }
.tier-price .amt { font-weight: 800; font-size: 2.75rem; line-height: 1; letter-spacing: -0.01em; color: var(--h-ink); }
.tier-price .per { font-weight: 700; font-size: 1.05rem; color: var(--h-ink-2); }
.tier-price .billed { font-size: 0.9rem; color: var(--h-ink-2); }
.tier-price .save { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 4px 8px; }
.tier-price .pill { background: var(--h-band); color: #fff; font-weight: 800; font-size: 0.82rem; letter-spacing: 0.02em; padding: 4px 10px; border-radius: 999px; }
.tier-price .vs { font-size: 0.82rem; color: var(--h-ink-2); }
@media (max-width: 520px) {
  .tier-price { justify-items: start; text-align: start; margin-inline-start: 0; }
  .tier-price .save { justify-content: flex-start; }
}
.price-note { font-size: 0.85rem; color: var(--h-ink-2); margin-top: 12px; }
/* Pro+AI opens with "Everything in binnie PRO, plus:" as a lead-in, not a bullet: it frames
   the list below as additions (founder 2026-10-17: start, with the wordmark). */
.tier-lead { margin: 0 0 12px; font-weight: 700; color: var(--h-ink); }
.tier-lead .lockup { font-size: 0.95em; }
.tierc ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
/* a block, not flex: as flex, a wordmark set into the line became its own item and
   the gap pushed "De binnie-assistent" apart */
.tierc li { color: var(--h-ink-2); font-size: 0.95rem; position: relative; padding-left: 17px; }
/* Founder 2026-10-20: the dot centres on the WHOLE item, so a bullet that breaks after
   its colon onto two lines has its dot between them, not beside the first line. */
.tierc li::before { content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 7px; height: 7px; border-radius: 50%; background: var(--h-melon); }

/* ---------- story teaser + closer ---------- */
.h-storyteaser { margin-top: 96px; display: grid; gap: 12px; max-width: 760px; }
.h-storyteaser h2 { font-size: clamp(1.8rem, 3.6vw, 2.6rem); line-height: 1.1; }
.h-storyteaser p { color: var(--h-ink-2); font-size: 1.1rem; }
.h-link { color: var(--h-melon); font-weight: 800; }
/* Out-specifies style.css's a:hover, which would take --primary-dark: on the home page that
   is --h-band, a DARK band colour, 1.77-2.77 on the dark pages. */
.h-link:hover { color: var(--h-melon-ink); }
.h-closing { margin-block: 96px 64px; display: grid; grid-template-columns: auto 1fr; gap: 28px; align-items: center; background: var(--h-card); border-radius: 32px; padding: 40px clamp(20px, 4vw, 48px); border: 1.5px solid var(--h-line); }
.h-closing h2 { font-size: clamp(1.75rem, 3.6vw, 2.6rem); line-height: 1.1; }
.h-closing p { color: var(--h-ink-2); margin-block: 8px 18px; max-width: 56ch; }

/* ---------- narrow screens: no sticky stage, each chapter carries its own screen ---------- */
/* The hero stacks below 980px, not 860px (2026-10-19): its card collage spills
   ~60px past the stage on purpose, and two columns under ~980px left no room
   for it on either side (clipped on the right, over the copy on the left). */
@media (max-width: 979px) {
  .h-hero-grid { grid-template-columns: 1fr; }
  /* Phone first screen (founder 2026-10-17: "It's not even clear what the app is about"):
     the headline comes FIRST, then the subhead and the download buttons, then the card
     collage, then the rest. The copy column dissolves into the hero grid
     (display: contents) so its children can be ordered around the stage. */
  .h-hero-grid { gap: 18px; }
  .h-hero-copy { display: contents; }
  .h-hero-copy > .h-lockup { display: none; }  /* the header says "Nutrition & Recipes" right above */
  .h-hero-copy > .h-sub.h-sub, .h-hero-copy > #get { order: 1; }  /* .h-sub twice: outranks the (0,2,1) order:3 rule */
  .h-hero-copy > h1 { order: 1; }
  .h-hero-stage { order: 2; margin-block: 4px; }
  .h-hero-copy > .h-4in1 { order: 3; }
  .h-hero-copy > :not(.h-lockup):not(h1) { order: 3; }
}
@media (max-width: 860px) {
  .h-share-grid { grid-template-columns: 1fr; }
  .h-share-stage { order: -1; }
  .rig { --rw: min(230px, 50vw, calc((100svh - 150px) / 2.7)); }
  .story { grid-template-columns: minmax(0, 1fr); }
  .chapter { min-width: 0; }
  .stage { display: none; }
  html.story-on .chapter { opacity: 1; }
  .chapter { min-height: 0; padding-block: 36px; }
  /* founder 2026-10-19: on a narrow screen the colour picker (and its joke) lands BELOW the
     screenshot it recolours, so a tap shows its result right above it */
  #ch-organized .inline-phone { order: 1; }
  #ch-organized .palpick { order: 2; margin-top: 4px; }
  .inline-phone { display: block; justify-self: center; margin-top: 8px; }
  .inline-phone .rig2 { margin-inline: 12%; }
  .inline-phone .phone, .h-share-stage .phone, .rig .phone { padding: 5px; border-radius: 30px; }
  .inline-phone .phone .scr, .h-share-stage .phone .scr, .rig .phone .scr { border-radius: 25px; }
  .inline-phone .phone { width: min(250px, 66vw); }
  .inline-watch { display: block; justify-self: center; margin-block: 34px 20px; }
  .inline-watch .wcase.apple { width: 118px; }
  .inline-watch .wcase.wear { width: 124px; }
  .h-closing { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .layer, .stage .ov, .chapter { transition: none; }
}
@media (max-width: 420px) { .h-4in1-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px 14px; } .h-4in1-grid li { font-size: 0.92rem; } }
/* Act 1's colour switcher: the four library captures stacked, one shown (home.js sets
   data-pal / data-mode). Every layer FILLS the screen, because a screenshot is sized by
   `.scr picture { position: absolute; inset: 0 }` against its nearest positioned box. */
.palset, .palset > .pal { position: absolute; inset: 0; }
.palset > .pal { opacity: 0; transition: opacity 0.35s ease; }
.palset[data-pal="pink"][data-mode="light"] > .pal-pink-light,
.palset[data-pal="pink"][data-mode="dark"] > .pal-pink-dark,
.palset[data-pal="kiwi"][data-mode="light"] > .pal-kiwi-light,
.palset[data-pal="kiwi"][data-mode="dark"] > .pal-kiwi-dark { opacity: 1; }
.palpick { display: none; gap: 10px; margin-top: 18px; }
.pal-on .palpick { display: grid; }
.palpick-row { display: flex; flex-wrap: wrap; gap: 8px; }
.palpick .pp { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 16px; border-radius: 999px; border: 1.5px solid var(--h-line); background: var(--h-card); color: var(--h-ink); font: inherit; font-weight: 700; font-size: 0.95rem; cursor: pointer; }
.palpick .pp[aria-pressed="true"] { border-color: var(--h-ink); box-shadow: inset 0 0 0 1px var(--h-ink); }
.palpick .pp:focus-visible { outline: 3px solid var(--h-melon-ink, var(--h-band)); outline-offset: 2px; }
.palpick .sw { width: 18px; height: 18px; border-radius: 50%; box-shadow: 0 0 0 2px #fff, 0 0 0 3px rgb(0 0 0 / 0.15); }
.palpick .pp svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.palpick-note { margin: 0; color: var(--h-ink-2); font-size: 0.95rem; }
.palpick-joke { margin: 0; color: var(--h-ink-2); font-size: 0.95rem; font-style: italic; max-width: 46ch; }
@media (prefers-reduced-motion: reduce) { .palset > .pal { transition: none; } }

/* See for yourself: the provenance walkthrough. Each state fills the screen; a sheet that
   scrolls carries its stitched body in .pf-body, scrolled inside the phone. Hotspots are
   real buttons on the app's own bounds. Screens use `.home .scr picture { absolute }`, so
   the body image opts back into flow. */
.pflow-sec { padding-block: 88px 24px; }
.pflow-in { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; align-items: center; }
.pflow-copy { display: grid; gap: 12px; max-width: 560px; }
.pflow-copy h2 { font-size: clamp(1.9rem, 4vw, 3rem); line-height: 1.05; }
.pflow-copy p { color: var(--h-ink-2); font-size: 1.1rem; }
.pflow-copy .pflow-note { font-size: 0.95rem; }
.pflow { position: relative; display: grid; justify-items: center; gap: 16px; }
.pflow .phone { width: min(320px, 74vw); }
.pf-scr { position: relative; }
.pf-st { position: absolute; inset: 0; display: none; }
.pf-st.on { display: block; animation: pf-in 0.22s ease; }
@keyframes pf-in { from { opacity: 0.4; } to { opacity: 1; } }
.pf-body { position: absolute; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
.pf-body::-webkit-scrollbar { display: none; }
.pf-bin { position: relative; }
.home .scr .pf-bin img { position: static; display: block; width: 100%; height: auto; }
.pf-hot { position: absolute; padding: 0; margin: 0; border: 0; background: transparent; border-radius: 10px; cursor: pointer; }
.pf-hot:hover { background: rgb(0 0 0 / 0.05); }
.pf-hot:focus-visible { outline: 3px solid var(--h-melon-ink, var(--h-band)); outline-offset: -3px; }
.pflow:not(.pf-on) .pf-hot { pointer-events: none; }
.pf-hint-ring { box-shadow: 0 0 0 0 color-mix(in srgb, var(--h-fill) 55%, transparent); animation: pf-ring 1.6s ease-out infinite; }
@keyframes pf-ring { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--h-fill) 55%, transparent); } 100% { box-shadow: 0 0 0 14px transparent; } }
.pf-ctl { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; }
.pf-ctl .pf-hint { width: 100%; text-align: center; color: var(--h-ink-2); font-weight: 700; }
.pflow:not(.pf-on) .pf-ctl { display: none; }
.pf-ctl .pp { min-height: 44px; padding: 8px 18px; border-radius: 999px; border: 1.5px solid var(--h-line); background: var(--h-card); color: var(--h-ink); font: inherit; font-weight: 700; cursor: pointer; }
.pf-ctl .pp:disabled { opacity: 0.45; cursor: default; }
.pf-ctl .pp:focus-visible { outline: 3px solid var(--h-melon-ink, var(--h-band)); outline-offset: 2px; }
/* Side by side, the words travel with the screen (founder 2026-10-18): the text column is
   pinned beside the 847px phone, roughly centred under the nav (sized for the tallest
   locale, ja at ~470px), and lets go when it reaches the bottom of its own white space, so
   heading and phone leave the view together. One column (below) keeps the plain flow. */
@media (min-width: 861px) {
  .pflow-copy { position: sticky; top: max(88px, calc(64px + (100vh - 534px) / 2)); top: max(88px, calc(64px + (100svh - 534px) / 2)); align-self: start; }
}
@media (max-width: 860px) { .pflow-in { grid-template-columns: minmax(0, 1fr); } .pflow-sec { padding-block: 56px 16px; } }
@media (prefers-reduced-motion: reduce) { .pf-st.on, .pf-hint-ring { animation: none; } }

/* Tappable, obviously (founder 2026-10-17: "make it more obvious that it is tappable").
   A "Try it" badge over the phone, a tap hand bobbing over the first tappable row until
   the first tap, and one shimmer across every tappable row when the phone first comes
   into view. All of it stops for reduced motion. */
.pf-try { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px; background: var(--h-fill); color: #fff; font-weight: 800; font-size: 0.95rem; box-shadow: 0 6px 16px -8px color-mix(in srgb, var(--h-fill) 80%, transparent); }
.pf-try::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: #fff; animation: pf-dot 1.4s ease-in-out infinite; }
@keyframes pf-dot { 50% { opacity: 0.25; } }
/* The guiding hand (founder 2026-10-18: "make it blatantly obvious"). It rests on the hinted
   row at 20% of the screen (was 15%), tapping, until the first tap; before that it FLIES there
   from the "Try it" pill, large, the first time the whole phone is in view (home.js). */
.pf-hand { position: absolute; width: 20%; aspect-ratio: 1; z-index: 6; pointer-events: none; filter: drop-shadow(0 4px 6px rgb(30 5 12 / 0.35)); animation: pf-tap 1.4s ease-in-out infinite; }
.pf-hand.pf-hand-wait { visibility: hidden; animation: none; }
.pf-flyer { position: absolute; left: 0; top: 0; z-index: 7; pointer-events: none; filter: drop-shadow(0 8px 14px rgb(30 5 12 / 0.4)); transform-origin: 30% 10%; }
.pf-flyer svg, .pf-hand svg { display: block; width: 100%; height: 100%; }
@keyframes pf-tap { 0%, 60%, 100% { transform: translate(0, 0) scale(1); } 75% { transform: translate(-4%, -10%) scale(1.06); } 88% { transform: translate(0, 2%) scale(0.88); } }
@keyframes pf-bob { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(-6%, -12%); } }
.pf-shimmer .pf-st.on .pf-hot { animation: pf-glow 1.1s ease-out both; animation-delay: calc(var(--i, 0) * 70ms); }
@keyframes pf-glow { 0% { background: transparent; } 35% { background: color-mix(in srgb, var(--h-fill) 16%, transparent); } 100% { background: transparent; } }
@media (prefers-reduced-motion: reduce) { .pf-try::before, .pf-hand, .pf-shimmer .pf-st.on .pf-hot { animation: none; } }

/* The read-aloud player (founder 2026-10-17): nine cook-mode captures stacked, one shown;
   a play badge over the phone and a Play button in the chapter, which reads each step in
   the app's voice and moves on. */
.cookset, .cookset > .ck { position: absolute; inset: 0; }
.cookset > .ck { opacity: 0; transition: opacity 0.35s ease; }
.cookset > .ck.on { opacity: 1; }
/* The step text, redrawn live over the capture's own (cover: the screen's flat ground,
   #FFEAF3) so it can be read aloud the way the app does: the app's 24 pt body at 1.6, in
   1080 px screen units via cqw. Spoken letters take the accent and a wave (the app's
   karaoke: 2.24 em period, +-0.056 em, centred on the line's foot). */
.cookset { touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.cookset > .ck { container-type: inline-size; }
.cookset img { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
.ck-tx { position: absolute; left: 3.704%; width: 92.593%; box-sizing: border-box; padding: 0 2.13% 3cqw; background: #FFEAF3; }
.ck-tx p { margin: 0; font: 400 var(--ck-fs, 5.833cqw)/1.6 var(--font); letter-spacing: 0.0365cqw; color: #2A1A22; }
/* Japanese: the app's own fallback order (Nunito, then its bundled NotoSansJP), and a line may
   break between any two characters, as the app's step text does. */
:lang(ja) .ck-tx p { font-family: 'Nunito', 'Noto Sans JP', sans-serif; line-break: loose; word-break: normal; }
.ck-tx .sp { color: #C2185B; padding-bottom: 0.31em; -webkit-box-decoration-break: clone; box-decoration-break: clone;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 140 12'%3E%3Cpath d='M0 6Q35-1 70 6T140 6' fill='none' stroke='%23D6245F' stroke-width='4' stroke-linecap='round'/%3E%3C/svg%3E") 0 100% / 2.24em 0.192em repeat-x; }
.ck-tx .sp .m { font-weight: 500; }
.ck-hit { position: absolute; top: 90.47%; height: 5.2%; width: 44.17%; z-index: 3; cursor: pointer; border-radius: 3cqw; }
.ck-hit-prev { left: 3.89%; }
.ck-hit-next { left: 51.94%; }
.ck-badge { position: absolute; left: 50%; top: 76%; width: 22%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: var(--h-fill); display: grid; place-items: center; box-shadow: 0 10px 24px -8px color-mix(in oklab, var(--h-fill) 70%, transparent); cursor: pointer; z-index: 3; animation: ck-pulse 1.8s ease-in-out infinite; }
.ck-badge svg { width: 46%; height: 46%; fill: #fff; translate: 6% 0; }
@keyframes ck-pulse { 50% { scale: 1.08; } }
.ck-playing .ck-badge { opacity: 0; pointer-events: none; transition: opacity 0.25s; }
.ck-ctl { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 14px; }
.ck-play { display: inline-flex; align-items: center; gap: 10px; min-height: 48px; padding: 10px 20px; border: 0; border-radius: 999px; background: var(--h-fill); color: #fff; font: inherit; font-weight: 800; font-size: 1.02rem; cursor: pointer; box-shadow: 0 8px 18px -10px color-mix(in oklab, var(--h-fill) 90%, transparent); }
.ck-play svg { width: 20px; height: 20px; fill: currentColor; }
.ck-play:focus-visible { outline: 3px solid var(--h-melon-ink, var(--h-band)); outline-offset: 3px; }
.ck-i-pause, .ck-l-pause, .ck-play[aria-pressed="true"] .ck-i-play, .ck-play[aria-pressed="true"] .ck-l-play { display: none; }
.ck-play[aria-pressed="true"] .ck-i-pause, .ck-play[aria-pressed="true"] .ck-l-pause { display: inline; }
.ck-step { display: inline-flex; gap: 6px; }
.ck-go { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 2px solid var(--h-fill); background: transparent; color: var(--h-fill); cursor: pointer; }
.ck-go svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.ck-go:focus-visible { outline: 3px solid var(--h-melon-ink, var(--h-band)); outline-offset: 3px; }
.ck-hint { color: var(--h-ink-2); font-size: 0.95rem; max-width: 40ch; }
.ck-now { width: 100%; color: var(--h-ink); font-weight: 700; font-size: 0.95rem; min-height: 1.2em; }
@media (prefers-reduced-motion: reduce) { .ck-badge { animation: none; } .cookset > .ck { transition: none; } }

/* On a phone the inline Snap phone sits right under the chapter's proof line, and the
   falafel card, which leans out above the phone's top edge, landed on that line (founder
   2026-10-17). The rig drops by the card's overhang so the card clears the text. */
@media (max-width: 860px) { .inline-phone .rig2:has(.ov-plate) { margin-top: clamp(28px, 11vw, 56px); } }


/* The two store badges: one height, one gap, aligned on their centres. */
.h-hero-copy .stores { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.h-hero-copy .stores img { display: block; height: 48px; width: auto; }
/* "Every screen here is a capture from the app." is a footnote. */
.pflow-note { font-style: italic; }

/* Hero rhythm (founder 2026-10-19: "something about the spacing"). The column used
   ONE uniform gap, so nothing grouped: the H1 crowded the lockup and the store
   badges read as a fifth list row. Space now groups: the H1 and its subhead are
   one idea; the four apps and the badges each get air of their own. */
.h-hero-copy { gap: 0; }
.h-hero-copy > .h-lockup { margin-bottom: 28px; }
.h-hero-copy > h1 { margin: 0; }
.h-hero-copy > .h-sub { margin-top: 14px; }
.h-hero-copy > .h-4in1 { margin-top: 36px; }
.h-hero-copy > #get { margin-top: 36px; }
.h-hero-copy .stores img { height: 44px; }
/* A 14" MacBook with the browser full screen is ~1512 x 865 px: the badges sat at the fold
   (founder 2026-10-21). On a short desktop viewport the hero's gaps tighten, so the
   badges clear it; nothing scales down and tall screens keep the roomier rhythm. */
@media (min-width: 980px) and (max-height: 960px) {
  .h-hero { padding-top: 14px; }
  .h-hero-copy > .h-lockup { margin-bottom: 16px; }
  .h-hero-copy > .h-4in1 { margin-top: 24px; }
  .h-hero-copy > #get { margin-top: 22px; }
}
/* A 13" MacBook Air (~1280 x 800): one step tighter. */
@media (min-width: 980px) and (max-height: 840px) {
  .h-hero-copy > .h-lockup { margin-bottom: 8px; }
  .h-hero-copy > .h-4in1 { margin-top: 16px; }
  .h-hero-copy > #get { margin-top: 16px; }
  .h-hero-copy > .h-sub { margin-top: 8px; }
}
@media (max-width: 979px) {
  .h-hero-copy > .h-sub { margin-top: 10px; }
  .h-hero-copy > #get { margin-top: 22px; margin-bottom: 8px; }
  .h-hero-copy > .h-4in1 { margin-top: 28px; }
}

/* Two columns from 980px: the collage still spills ~60px past the stage on the
   right until the container's outer margin can hold it (~1200px), so reserve it. */
@media (min-width: 980px) and (max-width: 1199px) { .h-hero-stage { margin-inline-end: 56px; } }

/* Stacked hero with room to spare (640-979px, founder 2026-10-19): the subhead is
   capped at a readable measure, which left a dead right half beside it while the
   store badges sat alone below. The badges move into that space, stacked, centred
   on the subhead. Below 640px they stay underneath (phones). */
@media (min-width: 640px) and (max-width: 979px) {
  .h-hero-grid { grid-template-columns: minmax(0, 1fr) auto; column-gap: 32px; }
  .h-hero-copy > h1, .h-hero-stage, .h-hero-copy > .h-4in1 { grid-column: 1 / -1; }
  .h-hero-copy > #get { grid-column: 2; align-self: center; margin-top: 10px; }
  .h-hero-copy .stores { flex-direction: column; align-items: flex-start; gap: 10px; }  /* a common LEFT edge: the badges differ in width */
}
/* Under the centred collage, the four apps centre AS A BLOCK; each item's text
   stays left-aligned beside its icon. */
@media (max-width: 979px) {
  .h-hero-copy > .h-4in1 { justify-self: center; justify-items: center; }
  .h-4in1-grid { justify-items: start; }
}

/* The hero ring follows the phone's HEIGHT cap too (2026-10-19). It was sized by the
   stage's WIDTH alone (min(600px, 125%)) while the phone rig is capped by the
   screen's height ((100svh - 150px) / 2.7), so on a wide, short window (a landscape
   tablet, a short laptop window) the phone shrank and the ring did not, and rose
   over the subhead and the store badges. 2.07 = the desktop ratio, 600 / 290. */
.h-hero-stage > .slice { width: min(600px, 125%, calc((100svh - 150px) / 2.7 * 2.07)); }
