
/* ── Tokens ─────────────────────────────────────────────────────────────────────────────────
   TWO THEMES, TWO SELECTORS.

   :root                       the light values, and what every visitor gets until they say otherwise
   :root[data-theme="dark"]    dark, and ONLY on an explicit choice

   THE OS PREFERENCE IS DELIBERATELY NOT CONSULTED. It used to be a prefers-color-scheme: dark
   block handed a dark page to every visitor whose machine is set that way, which is most phones
   after sunset. This is a marketing page rather than an app: it is the first thing anyone sees of
   the product, the photography and the mascot were drawn against the light ground, and half the
   audience arriving to a different page than the other half is not a feature. Dark stays one click
   away and is remembered; it is just not assumed.

   One accent, spent on exactly one thing per screen: the primary action. Same rule as the app.
   --care is reserved for the floor and nothing else; in this register the mark IS the green — a
   note in the accent's own hue means "we stopped you". */
:root {
  
  --ink: #F7F6F2;
  --panel: #FFFFFF;
  --raised: #FFFFFF;
  --line: #D3D0C9;
  --line-strong: #E7E5E0;
  --text: #17191C;
  --muted: #6A6F76;
  --faint: #6F747B;
  --dim: #6A6F76;
  --accent: #1E6B3C;
  --accent-ink: #FFFFFF;
  --good: #1E6B3C;
  --warn: #A35A00;
  --bad: #B3261E;
  --care: #2F6FB0;
  --wash-mid: #E6F1EA;
  --wash-deep: #E7E5E0;
  color-scheme: light;

  --sans: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, Helvetica, Arial, sans-serif;
  --display: "Montserrat", var(--sans);
  /* The tracked-cap label family is the muted tier — Register P has one green and it is the
     action, so labels stopped being green with the register. */
  --label: #6A6F76;
  /* The quiet grounds inside cards: the page's own bg under the white panels, per §5. */
  --mini: #F7F6F2;
  /* The text-button hover — the register's own accent tint. */
  --tint: #E6F1EA;
  /* The softer of the two separators — card borders and section seams, where --line rings a control. */
  --hairline: #E7E5E0;

  /* The macro chips' ink-on-tint pairs — the direction's §5 set, shared with the app. Deliberately
     not the verdict hues: protein's red must never read as "over". Saturated fat wears fat's. */
  --macro-kcal: #17191C; --macro-kcal-tint: #EEEDE9;
  --macro-protein: #D9483F; --macro-protein-tint: #FBE6E4;
  --macro-carbs: #D48A1C; --macro-carbs-tint: #FBEFD9;
  --macro-fat: #3A74D0; --macro-fat-tint: #E3ECFA;

  --wrap: 70rem;
  --gutter: clamp(1.25rem, 5vw, 3rem);
}

:root[data-theme="dark"] {
  --label: #A4A8AD;
  --mini: #101214;
  /* No dark tint is named: the accent at low alpha over the surface is what a tint is there. */
  --tint: rgb(91 179 126 / .14);
  --hairline: #2A2E33;
  /* The direction's dark macro pairs — same chips, night register. */
  --macro-kcal: #F2F2EF; --macro-kcal-tint: #26292D;
  --macro-protein: #F07A72; --macro-protein-tint: #3A2221;
  --macro-carbs: #E9A94A; --macro-carbs-tint: #3A2E1A;
  --macro-fat: #7FA6EC; --macro-fat-tint: #1E2A3D;
}

:root[data-theme="dark"] { 
  --ink: #101214;
  --panel: #191C1F;
  --raised: #282828;
  --line: #2F3334;
  --line-strong: #2A2E33;
  --text: #F2F2EF;
  --muted: #A4A8AD;
  --faint: #A3A3A3;
  --dim: #A4A8AD;
  --accent: #5BB37E;
  --accent-ink: #08170A;
  --good: #5BB37E;
  --warn: #FFC53D;
  --bad: #F87171;
  --care: #5AA9FF;
  --wash-mid: #3FC551;
  --wash-deep: #1E8C3E;
  color-scheme: dark;
 }

/* ── The one typeface this page owns ────────────────────────────────────────────────────── */
/* Montserrat, ONE family for display and text — Register P §3 chose it over the pair that wore
   this role before, precisely because the product ships Russian and Vietnamese and neither of
   those faces has Cyrillic. Google's own subsetting, five unicode-range blocks, all SELF-HOSTED
   from this workspace's fonts/ directory — same-origin under font-src self, the OFL beside them. */
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-cyrillic-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-cyrillic.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-vietnamese.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* The display cut of the same family: headings, ordinals, figures and quotes — 600/700 with the
   register's tracking, where the body setting is 400/500. */
h1, h2, h3, .wordmark, .num, .faq-q {
  font-family: var(--display);
  letter-spacing: -0.02em;
}

/* ── Reset ──────────────────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p, ul, ol, figure, dl, dd { margin: 0; }
ul { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Text selection in the register's quiet accent ground. Small, and met by anybody who drags a
   cursor through the copy. */
::selection { background: var(--tint); }

/* Every number on this page is tabular and set in the display face, the way the app sets its
   metrics: the product's claim is that it hands you a figure you can act on, and a figure that
   reflows as it changes does not read like one. */
.num { font-variant-numeric: tabular-nums; }
/* The macro chip — icons.ts draws the tinted circle and the glyph from the --macro-* tokens; this
   is only its size and how it sits in a line of text (the boards' 1.6em chip, baseline-aligned). */
.mico { width: 1.6em; height: 1.6em; flex: none; vertical-align: -0.45em; display: inline-block; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }

/* ── Section marker ─────────────────────────────────────────────────────────────────────── */
/* The boards' label: tracked capitals in the label green, the way _landing_hero and every .lab
   set them — 12px rather than the board's 11, which is under this page's floor. --label and not
   --accent: the accent stays spent on the one action, and this is the hue the boards pair with it. */
.eyebrow {
  font-size: .75rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--label); margin-bottom: .5rem;
}

.section { padding: 4.5rem 0; }
.section + .section { border-top: 1px solid var(--hairline); }
/* Every board draws the head above the content, left-aligned, in one full-width column — no
   running margin. The eyebrow sits directly on the title (the board's 8px), and the content
   follows the head by the board's ~26px. */
.section-head { max-width: 52ch; margin-bottom: 1.625rem; }
.section-title {
  font-size: 1.75rem; font-weight: 700;
  line-height: 1.1; text-wrap: balance; max-width: 18ch;
}

/* ── Masthead ───────────────────────────────────────────────────────────────────────────── */
/* The boards' _landing_nav: a 60px bar over a bottom hairline — the wordmark, the section doors,
   then the app's door and the theme toggle pushed right. Privacy and Support left for the footer,
   which is where the page always kept them anyway. */
.masthead { border-bottom: 1px solid var(--line); }
.masthead-row { display: flex; align-items: center; gap: .875rem; min-height: 3.75rem; }
/* The signature — the resting face at 20px beside the name; Register P shrinks him to a mark. */
.wordmark {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: 1.125rem; font-weight: 800; letter-spacing: -0.02em; text-decoration: none;
}
.masthead .spud { width: 1.25rem; height: 1.25rem; flex: none; }
.masthead-links { display: flex; gap: .125rem; margin-left: .375rem; }
.masthead-links a {
  padding: .4375rem .6875rem; border-radius: .625rem;
  /* The boards' .lnav draws the nav in ink; the muted tier under it measured 4.36:1. */
  font-weight: 500; font-size: .8125rem; color: var(--text); text-decoration: none;
}
.masthead-links a:hover { background: var(--mini); }
.masthead-side { margin-left: auto; display: flex; align-items: center; gap: .75rem; }
/* The theme toggle. A 36px target with a mark that is a filled disc on light and a crescent on
   dark — one element and a box-shadow, because an icon swap needs either two SVGs or a script that
   writes markup, and this needs neither. currentColor throughout, so it follows --muted. */
.theme-toggle {
  display: inline-grid; place-items: center;
  width: 2.25rem; height: 2.25rem; padding: 0;
  border: 1px solid var(--line-strong); border-radius: .625rem;
  background: transparent; color: var(--muted); cursor: pointer;
}
.theme-toggle:hover { color: var(--text); border-color: var(--text); }
.theme-toggle-mark { width: .875rem; height: .875rem; border-radius: 50%; background: currentColor; }
/* Pressed means the page is dark, so the mark becomes a crescent: a ring with an offset shadow
   biting a piece out of it. */
.theme-toggle[aria-pressed="true"] .theme-toggle-mark {
  background: transparent;
  box-shadow: inset -.3125rem -.125rem 0 0 currentColor;
}

/* The door into the product, in the top bar (#426). Register P's treatment: a text button —
   accent ink on quiet, the tint ground only under hover, because one green now means "the action"
   and this door is one. */
.masthead-app {
  color: var(--accent);
  font-weight: 500; font-size: .8125rem; padding: .5625rem .875rem;
  border-radius: .625rem; text-decoration: none;
}
.masthead-app:hover { background: var(--tint); }
/* The store badge beside the door — Apple's own artwork at 32px, drawn only where the bar has
   room for a second door: at and above the two-column breakpoint. Hidden by default rather than
   in the phone media, so a bar without the listing draws nothing either way. */
.masthead-store { display: none; text-decoration: none; }
@media (min-width: 62rem) { .masthead-store { display: inline-flex; } }
.masthead-store .cta-badge { height: 2rem; width: auto; }
/* The GitHub button — the boards' .ghb: a 32px lozenge split by a hairline, "Star" and the mark
   on the left, the stargazer count on the right when the build carried one. One drawing serves
   the masthead, the Open source card's .gh-slot and the footer's bottom row. */
.ghb {
  display: inline-flex; align-items: stretch; height: 2rem; border-radius: .625rem;
  box-shadow: inset 0 0 0 1px var(--line); background: var(--panel);
  font-size: .8125rem; font-weight: 600; color: var(--text); text-decoration: none;
  overflow: hidden; flex: 0 0 auto; white-space: nowrap; width: fit-content;
}
.ghb .ghl { display: flex; align-items: center; gap: .375rem; padding: 0 .625rem; }
.ghb .ghn {
  display: flex; align-items: center; padding: 0 .625rem;
  box-shadow: inset 1px 0 0 var(--line); font-variant-numeric: tabular-nums;
}
.ghb svg { width: 1rem; height: 1rem; }
/* The phone masthead keeps the wordmark, the web door and the toggle — the nav links and the
   GitHub button leave it, the door pair moving to the footer's Company column instead. */
@media (max-width: 44rem) {
  .masthead-links { display: none; }
  .masthead-side .ghb { display: none; }
}

/* ── Hero ───────────────────────────────────────────────────────────────────────────────── */
/* The hero in Register P: the copy column on the paper — headline, sub, the dotted promise, the
   two doors — beside the drawn pair: our camera on the hero photograph, then the result the app
   computed on the same frame. On a phone the result phone leads alone, above the copy. */
.hero { padding: clamp(2rem, 5vw, 3.5rem) 0 0; }
.hero-grid { display: flex; flex-direction: column; gap: clamp(2rem, 5vw, 2.75rem); }
@media (min-width: 62rem) {
  .hero-grid {
    display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    align-items: center;
  }
}
/* The drawn pair: our camera on the hero photograph, the hand-drawn arrow, then the result the
   app computed on the same frame, dropped a step lower — the boards' sequence, read left to
   right. The phones wear #included's .inc-phone chrome; what fills the screens is the hero's. */
.pair { display: flex; align-items: flex-start; justify-content: center; gap: .75rem; }
/* The boards' .lph: the phone is 220px and everything on the result card is a fraction of it —
   the --w below is what the .pair-res overrides further down read. A breakpoint that narrows the
   phone narrows the card's text with it, so nothing on the card can clip at its right edge. */
.pair .inc-phone { --w: 13.75rem; width: var(--w); }
.pair-res { margin-top: 3.5rem; }
.pair-arrow { flex: none; width: 3.75rem; height: 4.375rem; margin-top: 6.5rem; color: var(--text); }
/* The camera: the photograph fills the whole screen under the finder chrome — the four corners,
   the shutter, the flash that fires once per lpw-* cycle. */
.pair-cam .inc-shot { inset: 0; height: 100%; }
.cam-corners { position: absolute; inset: 14% 10% 26%; }
.cam-corners i {
  position: absolute; width: 22%; height: 14%;
  border: 3px solid #fff; border-radius: .375rem;
}
.cam-corners i:nth-child(1) { left: 0; top: 0; border-right: 0; border-bottom: 0; }
.cam-corners i:nth-child(2) { right: 0; top: 0; border-left: 0; border-bottom: 0; }
.cam-corners i:nth-child(3) { left: 0; bottom: 0; border-right: 0; border-top: 0; }
.cam-corners i:nth-child(4) { right: 0; bottom: 0; border-left: 0; border-top: 0; }
.cam-shutter {
  position: absolute; left: 50%; bottom: 7%; width: 19%; aspect-ratio: 1;
  border-radius: 50%; background: #fff; box-shadow: 0 0 0 4px rgba(255,255,255,.4);
  transform: translateX(-50%);
}
.cam-flash { position: absolute; inset: 0; background: #fff; opacity: 0; }
/* The hero meal's items, called out on the photograph inside the result phone: a panel hairline
   chip with an ink dot, the item's name and its own kcal as a tabular figure. NO shadow — the
   hairline is enough lift on a photographic ground, and the bezel's is the only shadow here.
   Placement is persona.heroMeal.callouts, generated above — the offsets keep every chip inside
   the photograph's 60% and off the card. */
.pair-co {
  position: absolute; display: flex; align-items: center; gap: .1875rem;
  background: var(--panel); border: 1px solid var(--hairline); border-radius: .375rem;
  padding: .1875rem .375rem;
  font-size: calc(var(--w) * .043); font-weight: 600; color: var(--text); line-height: 1.45;
  white-space: nowrap;
  animation: lpw-co 7s cubic-bezier(.2, .7, .2, 1) infinite;
}
.pair-co::before {
  content: ""; width: .3125rem; height: .3125rem; border-radius: 50%;
  background: var(--text); flex: none;
}
.pair-co .num { color: var(--muted); font-weight: 500; }
/* The card on the result phone: the boards' .lph .card — padding .05w, the title and the row
   text .05w, the kcal figure .1w, the door .055w on a .15w line — so at every --w the card's
   content is inside the card. The shared .inc-card rules above size the #included phone, which
   keeps its own width and its own text. */
.pair-res .inc-card { padding: calc(var(--w) * .05); }
.pair-res .inc-card-name { font-size: calc(var(--w) * .05); }
.pair-res .inc-card-kcal .num { font-size: calc(var(--w) * .1); }
.pair-res .inc-macs { font-size: calc(var(--w) * .05); }
.pair-res .inc-vs .vline { font-size: calc(var(--w) * .05); }
.pair-res .inc-correct {
  min-height: calc(var(--w) * .15); margin-top: calc(var(--w) * .04);
  font-size: calc(var(--w) * .055);
}
.pair-co-1 { left: 6%; top: 45%; animation-name: lpw-co; }
.pair-co-2 { left: 20%; top: 13%; animation-name: lpw-co2; }
.pair-co-3 { right: 4%; top: 5%; animation-name: lpw-co3; }
/* The lpw-* loop: every cycle OPENS on the finished result — chips and card fully visible at
   first paint — then the shutter presses, the flash fires, and the result re-arrives. CSS only. */
.pair-cam .cam-shutter { animation: lpw-shut 7s cubic-bezier(.2, .7, .2, 1) infinite; }
.pair-cam .cam-flash { animation: lpw-flash 7s linear infinite; }
.pair-res .inc-card { animation: lpw-card 7s cubic-bezier(.2, .7, .2, 1) infinite; }
@keyframes lpw-shut {
  0%, 62% { transform: translateX(-50%) scale(1); }
  65% { transform: translateX(-50%) scale(.84); }
  69%, 100% { transform: translateX(-50%) scale(1); }
}
@keyframes lpw-flash { 0%, 63% { opacity: 0; } 65% { opacity: .85; } 70%, 100% { opacity: 0; } }
@keyframes lpw-co {
  0%, 58% { opacity: 1; transform: none; }
  62%, 68% { opacity: 0; transform: scale(.6); }
  72%, 100% { opacity: 1; transform: none; }
}
@keyframes lpw-co2 {
  0%, 58% { opacity: 1; transform: none; }
  62%, 70% { opacity: 0; transform: scale(.6); }
  74%, 100% { opacity: 1; transform: none; }
}
@keyframes lpw-co3 {
  0%, 58% { opacity: 1; transform: none; }
  62%, 72% { opacity: 0; transform: scale(.6); }
  76%, 100% { opacity: 1; transform: none; }
}
@keyframes lpw-card {
  0%, 58% { opacity: 1; transform: none; }
  62%, 74% { opacity: 0; transform: translateY(30%); }
  82%, 100% { opacity: 1; transform: none; }
}
/* Between the two-column breakpoint and the wrap's full width the column is narrower than the
   pair at full size — the phones and the arrow give ground rather than overflow into the copy. */
@media (min-width: 62rem) and (max-width: 71.99rem) {
  .pair .inc-phone { --w: 10.5rem; }
  .pair-arrow { width: 3rem; height: 3.5rem; margin-top: 4.5rem; }
}
@media (max-width: 61.99rem) {
  /* The pair collapses to the result phone alone, leading the copy — the camera and its arrow
     are the desktop composition, and a second phone at this width is the sideways scroll the
     page already shipped once. */
  .pair { order: -1; margin-bottom: 1.5rem; }
  .pair-cam, .pair-arrow { display: none; }
  .pair .inc-phone { --w: 15.625rem; }
  .pair-res { margin-top: 0; }
}

.hero-title {
  /* 34 on a phone, 52/700/−0.03em on a desktop — the reviewer's own deviation from the app scale. */
  font-size: clamp(2.125rem, 4.4vw, 3.25rem); font-weight: 700;
  letter-spacing: -0.03em; line-height: 1.1; text-wrap: balance; max-width: 15ch;
}
.hero-sub {
  margin-top: .875rem; font-size: 1.0625rem; line-height: 1.45;
  color: var(--muted); max-width: 30rem;
}

.cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem; margin-top: 1.625rem; }
.cta, .cta-alt {
  display: inline-flex; align-items: center; justify-content: center; gap: .625rem;
  font-size: .9375rem; font-weight: 600; letter-spacing: -0.02em; text-decoration: none;
  padding: .875rem 1.5rem; border: 1px solid transparent;
}
.cta {
  background: var(--accent); color: var(--accent-ink);
  border-radius: .875rem;
  transition: transform .18s ease;
}
.cta:hover { transform: translateY(-2px); }
.cta:active { transform: translateY(0); }
/* THE STORE ACTION IS APPLE'S BADGE (#693), so it wears none of the button above: their artwork is
   the whole control, and a pill under it would be our button with their badge glued on — the thing
   #688 shipped and this replaced. Height only; the width follows the viewBox, and the row's own
   1.25rem gap is more than the clear space Apple asks for around it. */
.cta-store { display: inline-flex; text-decoration: none; }
.cta-badge { display: block; height: 3.375rem; width: auto; }
/* The two variants Apple publishes, and the page picks by theme rather than shipping one of them
   onto a ground it was not drawn for: black on the light page, white on the dark one. The hairline
   is theirs and is neutral enough for both. */
.badge-body { fill: #000; }
.badge-ink { fill: #fff; }
.badge-edge { fill: #a6a6a6; }
:root[data-theme="dark"] .badge-body { fill: #fff; }
:root[data-theme="dark"] .badge-ink { fill: #000; }
/* Register P's .landing-alt: the browser door as a text button beside Apple's badge — accent
   ink on quiet, the tint ground only under hover, still the same height as the badge beside it. */
.cta-alt {
  color: var(--accent); background: transparent; border-color: transparent;
  border-radius: .625rem; font-weight: 500; font-size: .9375rem;
  padding: .875rem 1.25rem; min-height: 3.375rem;
}
.cta-alt:hover { background: var(--tint); }
/* On a phone the door's own padding indents its text ~20px past the badge's left edge; it sits
   flush instead — here, AFTER the .cta-alt rules above, because the same override placed earlier
   in source order once lost to them at equal specificity. */
@media (max-width: 61.99rem) { .cta-alt { padding-inline: 0; } }

/* ── The verdict, as a dot and a line ──────────────────────────────────────────────────── */
/* Register P §5: the pill was the second-strongest "childish" signal after the mascot, so a
   verdict is now a 6px dot and a 13px/500 line of ink, one verdict per row. The dot carries the
   verdict's colour — good is the accent itself, because "on plan" IS the action colour — and the
   text of it stays ink. Drawn rather than screenshotted, so it cannot drift from the palette the
   app ships. */
.vline {
  display: flex; align-items: center; gap: .5rem;
  font-size: .8125rem; font-weight: 500; color: var(--text); line-height: 1.45;
}
.vdot { width: .375rem; height: .375rem; border-radius: 50%; flex: none; }
.v-good .vdot { background: var(--good); }
.v-warn .vdot { background: var(--warn); }
.v-bad  .vdot { background: var(--bad); }
/* ── The one arrival ────────────────────────────────────────────────────────────────────── */
/* One orchestrated moment on load and nothing else on the page moves: the question and its answer
   rise, in the order a reader takes them. The deal-and-resolve sequence went with the phone that
   was being dealt. Sections do not fade in as you scroll; cards do not lift on hover. */
.hero-title, .hero-sub { animation: rise .7s cubic-bezier(.2, .7, .2, 1) backwards; }
.hero-sub { animation-delay: 90ms; }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ── The card row ─────────────────────────────────────────────────────────────────────────── */
/* .landing-step from _landing_how: panel ground, the card radius and the hairline — the chrome
   Why eait's cards still ride. */
.landing-steps { display: flex; gap: 1.25rem; align-items: stretch; }
.landing-step {
  flex: 1; display: flex; flex-direction: column; gap: .625rem;
  background: var(--panel); border: 1px solid var(--hairline); border-radius: .75rem;
  padding: 1.25rem 1.375rem;
}
/* The boards' label — the same treatment .eyebrow wears, at card scale. */
.lab {
  font-size: .75rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--label);
}

/* On a phone the card rows stack. This block must follow the .landing-* rules above: same
   specificity, so an override declared earlier would lose to them. */
@media (max-width: 44rem) {
  .section { padding: 3rem 0; }
  .landing-steps { flex-direction: column; }
}
/* ── What's included / Why eait ────────────────────────────────────────────────────────── */
/* The boards' #included and #why, in this page's chrome: centred titles (the boards centre both),
   hairline cards rather than the snippet's ring shadows, and every colour a token so the dark
   register comes for free. No animations — the page's one orchestrated moment is the hero's. */
.section-head-center { max-width: none; text-align: center; }
.section-head-center .section-title { margin-inline: auto; }

/* #included: the result phone beside the four cards. Stacked and centred by default — the
   boards' phone layout — and side by side above the two-column breakpoint, like the hero. */
.inc { display: grid; gap: 1.5rem; justify-items: center; margin-top: 1.25rem; }
@media (min-width: 62rem) {
  .inc { grid-template-columns: auto 1fr; gap: 4.5rem; align-items: center; justify-items: stretch; margin-top: 2.25rem; }
}

/* The result phone: a black bezel around a screen clipped round, the frenchtoast photograph
   filling its top 60% and the app's own meal card over the rest. Drawn, not screenshotted —
   the card's numbers are persona.meal's. */
.inc-phone {
  width: 15.625rem; flex: 0 0 auto;
  border-radius: 2.625rem; background: #111; padding: .5rem;
  box-shadow: 0 1.125rem 2.5rem -1.125rem rgba(23, 25, 28, .45);
}
@media (min-width: 62rem) { .inc-phone { width: 16.25rem; } }
.inc-screen {
  position: relative; aspect-ratio: 9 / 19.2;
  border-radius: 2.125rem; overflow: hidden; background: var(--ink);
}
.inc-shot {
  position: absolute; inset: 0 0 40% 0; width: 100%; height: 60%;
  object-fit: cover;
}
.inc-card {
  position: absolute; left: 5%; right: 5%; bottom: 4%;
  background: var(--panel); border: 1px solid var(--hairline);
  border-radius: .875rem; padding: .875rem;
}
.inc-card-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.inc-card-name { font-size: .9375rem; font-weight: 600; }
.inc-card-kcal { display: inline-flex; align-items: center; gap: .3125rem; }
.inc-card-kcal .num { font-size: 1.375rem; font-weight: 700; letter-spacing: -0.02em; }
.inc-macs { display: flex; gap: .625rem; flex-wrap: nowrap; margin-top: .5rem; font-size: .8125rem; }
.inc-mac {
  display: inline-flex; align-items: center; gap: .1875rem;
  font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.inc-hr { height: 1px; background: var(--hairline); margin: .5rem 0; }
/* The verdicts side by side, wrapping — the boards' .vs row. */
.inc-vs { display: flex; flex-wrap: wrap; gap: .25rem .625rem; }
.inc-vs .vline { font-size: .75rem; }
/* "Correct this meal" — the boards' secondary button: panel ground, --line ring, no accent. */
.inc-correct {
  display: flex; align-items: center; justify-content: center; margin-top: .625rem;
  min-height: 2.25rem; border-radius: .625rem; padding: 0 .75rem;
  font-size: .8125rem; font-weight: 600;
  background: var(--panel); color: var(--text); border: 1px solid var(--line);
}

.inc-feats { display: flex; flex-direction: column; gap: .75rem; width: 100%; }
.inc-feat {
  background: var(--panel); border: 1px solid var(--hairline); border-radius: .75rem;
  padding: 1.125rem 1.25rem;
}
/* The boards' selected card: the ink ring, here as a border swap plus a 1px shadow so it reads
   thicker rather than doubled. */
.inc-feat-on { border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
.inc-feat-title { font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.01em; }
.inc-feat-body { margin-top: .375rem; color: var(--muted); font-size: .9375rem; line-height: 1.45; }

/* The plan card's figure — the boards' .fg inset panel around the drawn curve. */
.inc-fg {
  margin-top: .75rem; max-width: 22.5rem; padding: .75rem .875rem;
  border: 1px solid var(--hairline); border-radius: .625rem;
}
.inc-fg-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
/* The "eait analysis" tag — quiet text, not the boards' pill: §5 bans the shape outright, and
   the face it carried is spent twice over already (wordmark, transcript). */
.inc-tag { font-size: .75rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
.inc-pgraph { overflow: visible; margin-top: .625rem; }
.inc-pgraph text { font-size: .75rem; fill: var(--muted); }
.inc-pgraph-ln { fill: none; stroke: var(--good); stroke-width: 2.5; stroke-linecap: round; }
/* The "Target" chip is ink in both registers: its label takes the page's ground colour back. */
.inc-pgraph .inc-pgraph-target { fill: var(--ink); font-size: .875rem; font-weight: 700; }
.inc-pgraph .inc-pgraph-kg { fill: var(--text); font-weight: 600; }
.inc-est { margin-top: .5rem; font-size: .75rem; font-weight: 600; color: var(--muted); }

/* #why: three cards on the shared row chrome, each opening on a tinted line-icon disc. */
.why-cards { margin-top: 1.75rem; }
.why-card .why-ico { margin-bottom: .25rem; }
.why-ico {
  width: 2.75rem; height: 2.75rem; flex: 0 0 2.75rem; border-radius: 50%;
  background: var(--mini); display: flex; align-items: center; justify-content: center;
}
.why-ico svg {
  width: 1.375rem; height: 1.375rem;
  stroke: var(--label); stroke-width: 1.75; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}
.why-title { font-size: 1.0625rem; font-weight: 600; }
.why-body { color: var(--muted); font-size: .9375rem; line-height: 1.45; }
/* The Open source card's GitHub button mount — the .875rem offset; :empty stays the safety so
   a card never carries a phantom gap under its last line. */
.gh-slot { margin-top: .875rem; }
.gh-slot:empty { display: none; }

@media (max-width: 44rem) {
  .inc-feat-body { font-size: .875rem; }
}

/* ── The section photographs ───────────────────────────────────── */
/* One plate under three of the headlines, in the drawn treatment one notch quieter: the same
   radius family, a shallower shadow because these sit in the middle of the page rather than at the
   top of it, and no card over them — they are the room the argument happens in, not the argument.
   HEIGHT: AUTO, because the img states its own width and height so
   the box is reserved before the bytes land, and those attributes set the CSS height unless this
   says otherwise. The file is already 1400x788, so nothing is cropped here. */
/* ── FAQ ────────────────────────────────────────────────────────────────────────────────── */
/* The boards' .qa: one column centred at 760px under a centred head — the five landing
   questions, answers left-aligned inside the card rows. */
.faq { display: grid; gap: .75rem; align-items: start; max-width: 47.5rem; margin-inline: auto; text-align: left; }
.faq-item {
  background: var(--panel); border: 1px solid var(--hairline); border-radius: .75rem;
}
.faq-q {
  cursor: pointer; list-style: none; padding: 1rem 2.5rem 1rem 1.25rem; position: relative;
  font-size: 1.0625rem; font-weight: 600; line-height: 1.45; color: var(--text);
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q:hover { color: var(--accent); }
/* The chevron is DRAWN — a 1.75px border corner rotated, never a glyph: the direction's icon
   weight, and nothing a font can render differently. */
.faq-q::after {
  content: ""; position: absolute; right: 1.125rem; top: 1.35rem;
  width: .5rem; height: .5rem;
  border-right: 1.75px solid var(--muted); border-bottom: 1.75px solid var(--muted);
  transform: rotate(45deg); transform-origin: center;
  transition: transform .15s ease;
}
.faq-item[open] .faq-q::after { transform: rotate(-135deg); }
.faq-a { padding: 0 1.25rem 1.125rem; color: var(--muted); font-size: .9375rem; line-height: 1.45; max-width: 60ch; text-align: left; }

/* ── /faq — the nine questions on a page of their own ───────────────────────────────────── */
/* The board's .pg-faq: the h1 centred at its 44px (32 on the phone), the same 760px column the
   landing's Q&A draws, and the ask centred under the list. .faq-more is the door to it from
   the home section — a plain paragraph centring the cta-alt door it carries. */
.faq-page-title { font-size: clamp(2rem, 5vw, 2.75rem); }
.faq-page .cta-row { justify-content: center; margin-top: 3.5rem; }
.faq-more { margin-top: 1.5rem; text-align: center; }

/* ── What people say ────────────────────────────────────────────────────────────────────── */
/* The boards' .psay/.rv: the reviews slot's cards — a DASHED hairline rather than the card
   hairline, which is the board's own honest look for "the App Store has none yet". The section
   renders nothing while the reviews list is empty, so these rules meet no element until the
   first real review exists. */
.reviews { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.review { margin: 0; border: 1px dashed var(--line); border-radius: .75rem; padding: 1.375rem; }
.review-quote { margin: 0; font-style: italic; color: var(--muted); font-size: .9375rem; line-height: 1.5; }
.review-by { margin-top: .625rem; font-size: .8125rem; color: var(--muted); }

/* ── Spud ───────────────────────────────────────────────────────────────────────────────── */
/* Every appearance is a job he already does in the app — see the header of mascot.ts. Sized
   down deliberately: he is a voice beside a paragraph, not an illustration the section is built
   around. 4.5rem against the app's 50-point badge: the drawing occupies about 82 of its 120 viewBox
   units vertically, so the potato lands near 49px, the same optical weight beside body copy that
   the badge has beside caption text on a phone. */
.spud { width: 4.5rem; height: 4.5rem; flex: none; }
/* The blink. The app closes his eyes for 130ms every 4.2s on a timer; this is the same cadence as
   one keyframe cycle, and a scaleY squash instead of a path swap because a stylesheet cannot swap
   paths. transform-box makes the squash happen about the eye group's own centre. */
.spud-eyes { transform-box: fill-box; transform-origin: 50% 50%; animation: spud-blink 4.2s infinite; }
@keyframes spud-blink { 0%, 96.4% { transform: none; } 98.2% { transform: scaleY(.06); } 100% { transform: none; } }


/* ── Closing ────────────────────────────────────────────────────────────────────────────── */
/* The boards' .lpclose: the last ask as a split — the headline and the CTA pair on the left
   (42fr), the cake on the right (58fr) at 3:2 with the card radius. On a phone the plate leads,
   stacked above the copy. No scrim and no fade: the plate sits on the paper beside the ask. */
.closing { padding: 4.5rem 0 6.5rem; border-top: 1px solid var(--hairline); }
.closing-grid { display: grid; grid-template-columns: 42fr 58fr; gap: 3.5rem; align-items: center; }
.closing-title { margin: 0; font-size: clamp(1.875rem, 5vw, 3rem); font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; text-wrap: balance; }
.closing-plate {
  display: block; width: 100%; height: auto; aspect-ratio: 3 / 2;
  object-fit: cover; object-position: center; border-radius: .75rem;
  border: 1px solid var(--hairline); margin: 0;
}

/* On a phone the reviews stack to one column and the close stacks plate-first — here, AFTER
   the .reviews and .closing-* rules above, because the same override placed earlier in source
   order would lose to them at equal specificity. */
@media (max-width: 44rem) {
  .reviews { grid-template-columns: 1fr; }
  .closing-grid { grid-template-columns: 1fr; gap: 1.75rem; }
  .closing-plate { order: -1; }
}

/* ── Footer ─────────────────────────────────────────────────────────────────────────────── */
/* The boards' .ft: a wordmark column, then Download / Legal / Company on the 1.6fr split, and a
   bottom row over a hairline — the copyright line left, the GitHub button right. */
.footer { border-top: 1px solid var(--hairline); padding: 3rem 0 2.5rem; color: var(--muted); font-size: .875rem; line-height: 1.45; }
.footer .spud { width: 1.25rem; height: 1.25rem; flex: none; }
.footer-cols { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 2rem; }
.footer-col { display: flex; flex-direction: column; align-items: flex-start; gap: .625rem; }
.footer-col .lab { margin-bottom: .125rem; }
.footer-col a { color: var(--muted); text-decoration: none; width: fit-content; }
.footer-col a:hover { color: var(--text); }
/* .footer-col a is a class plus an element (0,1,1), so it outranks the lone classes on the two
   links that are NOT muted — the wordmark and .footer-acc — and both rendered grey without
   .footer-col-qualified colours of their own. */
.footer-col .wordmark { color: var(--text); }
/* The boards' .acc — accent ink at 600 — the web door under the Download column's badge. */
.footer-acc { color: var(--accent); font-weight: 600; }
.footer-col .footer-acc { color: var(--accent); }
/* The two doors the phone masthead drops move to the Company column there; on the desktop the
   bar already carries them, so they are drawn only under 44rem. */
.footer-door { display: none; }
.footer-store .cta-badge { height: 3rem; width: auto; }
.footer-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid var(--hairline);
  font-size: .8125rem;
}
.footer-note { max-width: 52ch; }
/* The boards' .scr .ft / .ftc / .ftr: one column, the phone-only doors on, the web door off, the
   bottom row stacked. AFTER the base rules — same specificity, so source order wins. */
@media (max-width: 44rem) {
  .footer-cols { grid-template-columns: 1fr; gap: 1.5rem; }
  .footer-door { display: block; }
  .footer-acc { display: none; }
  .footer-row { flex-direction: column; align-items: flex-start; }
}

/* Last in the sheet on purpose: every selector here ties on specificity with the rule it switches
   off, so source order is what makes it win. Placed above .spud-eyes it did not, and he blinked. */
@media (prefers-reduced-motion: reduce) {
  .hero-title, .hero-sub, .spud-eyes { animation: none; }
  /* The lpw-* loop goes still with the result COMPLETE — the keyframes open on it, so a frozen
     first frame is the finished answer, not a missing one. */
  .cam-shutter, .cam-flash, .pair-co, .pair-res .inc-card { animation: none; }
  .cta { transition: none; }
  .cta:hover { transform: none; }
}

/* ── /login, /subscription, /impressum — the utility pages (#871, stage 3c) ─────────── */
/* The boards' .pg column and .lcard card, drawn the register's way: the card is every card
   on the page — panel ground, a 1px hairline, the 12px radius, no shadow — and the centred
   column is the boards' 560px (the card 440px). */
.pagecol { max-width: 35rem; margin: 0 auto; text-align: center; }
.pagecol-title { font-size: clamp(2rem, 5vw, 2.75rem); }
/* The boards' .web .pg-sub2 h1: "Manage subscription" holds one line at desktop width rather
   than wrapping in the 35rem column; on the phone it may wrap, as the board allows. */
@media (min-width: 44.01rem) { .sub-title { white-space: nowrap; } }
.page-sub { margin-top: .875rem; color: var(--muted); }
.pagecard {
  max-width: 27.5rem; margin: 0 auto; padding: 2.5rem 2.25rem; text-align: center;
  background: var(--panel); border: 1px solid var(--hairline); border-radius: .75rem;
}
.pagecard-title { font-size: 2rem; }
.pagecard-empty { margin-top: 1.75rem; }
.pagecard-empty a, .fine a { color: var(--text); font-weight: 500; }
/* The provider doors — one per configured provider, then the email route when it exists. A
   hairline and the control radius on a panel ground: doors, so none of them spends the accent.
   Apple's keeps Apple's own black — white on the dark page — and Google its four-colour mark:
   brand artwork, the same exception the store badge already takes. */
.ssos { display: flex; flex-direction: column; gap: .75rem; margin-top: 1.75rem; }
.sso {
  display: flex; align-items: center; justify-content: center; gap: .625rem;
  min-height: 3.25rem; padding: 0 1rem;
  border: 1px solid var(--line); border-radius: .625rem;
  background: var(--panel); font-size: 1rem; font-weight: 600; text-decoration: none;
}
.sso:hover { border-color: var(--line-strong); }
.sso svg { flex: none; }
.sso-apple { background: #000; border-color: #000; color: #fff; }
:root[data-theme="dark"] .sso-apple { background: #fff; border-color: #fff; color: #000; }
/* The small print — the dim tier rather than --faint, which is the white-surface caption and
   reads under AA on the paper these pages sit on. */
.fine { margin-top: 1.25rem; font-size: .8125rem; color: var(--dim); line-height: 1.5; }
/* The email step on /subscription — one field, one Send, only when the route exists. */
.subform { margin-top: 1.75rem; text-align: left; }
.field-label { display: block; font-size: .8125rem; font-weight: 600; margin-bottom: .375rem; }
.field-input {
  width: 100%; height: 3.25rem; padding: 0 .875rem;
  border: 1px solid var(--line); border-radius: .625rem; background: var(--panel);
  font: inherit; font-size: 1rem; color: var(--text);
}
.field-input::placeholder { color: var(--dim); }
.subform-send { width: 100%; margin-top: .75rem; }
.sub-go { margin-top: 1.75rem; }
/* A postal address is contact data, so it is <address> — font-style reset, we don't set it in
   italics. */
.impressum-addr { margin-top: 1.75rem; font-style: normal; font-size: 1.0625rem; line-height: 1.6; }
@media (max-width: 44rem) { .pagecard { padding: 1.75rem 1.25rem; } }

