
:root {
  /* Every surface here is an opaque hex, not white at n% over the background.
     Translucent layers stack: a chip inside a card inside a panel ends up a
     colour nobody chose, and edges show through each other. Flat values mean
     the palette is the palette. */

  /* Near-black with a blue cast rather than pure #000: the photos are warm,
     and a neutral black makes them look like stickers on a void. */
  --bg: #0A0D12;
  --surface: #12161D;
  --surface-2: #171C25;
  --hairline: #232A35;
  --hairline-strong: #39424F;

  --accent: #3E8BFF;
  --accent-quiet: #16233A;
  --protein: #9C8CF5;
  --carb: #F2B33D;
  --fat: #F2647B;

  --text: #F5F7FA;
  --text-2: #A2ACBC;
  /* Not darker than this. Every small label on the page is --text-3 — the macro
     row, the counts, the footer — and at 13px WCAG wants 4.5:1. Measured against
     all three surfaces: 5.35:1 on the page, 5.07:1 on a card, 4.79:1 on a card
     at its hover colour. The prettier grey two steps down lands at 4.2. */
  --text-3: #7F8697;

  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-2xl: 40px;

  /* Black only. A coloured shadow is a glow, and a blue halo under a blue
     button is the single clearest tell of a page nobody designed. */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow-md: 0 12px 32px -12px rgba(0,0,0,.7);
  --shadow-lg: 0 32px 64px -24px rgba(0,0,0,.85);

  /* One easing everywhere. Motion that all shares a curve reads as one system;
     mixing eases is the single loudest tell of a page assembled in parts. */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --gutter: clamp(20px, 5vw, 40px);
  --section-gap: clamp(72px, 11vw, 148px);
  --nav-h: 64px;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchors land below the fixed bar instead of under it. */
  scroll-padding-top: calc(var(--nav-h) + 24px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
               "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* One fixed layer: grain, nothing else. There were three soft blue radials
   behind this before and they were the loudest thing on the page — a coloured
   haze bleeding out of the corners is the look every generated landing page
   has. The background is one flat colour now; depth comes from the cards
   sitting on it, which is where depth belongs.

   The grain stays. It is texture, not light, and it is the whole difference
   between a flat dark page and one that looks like a surface. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .028;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

a { color: inherit; text-decoration: none; }

::selection { background: var(--accent); color: #fff; }

/* Focus: one visible ring, only for keyboard users, never clipped by a parent's
   overflow because it is drawn outside the box. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

.skip {
  position: absolute;
  left: 50%;
  top: 8px;
  transform: translate(-50%, -180%);
  z-index: 100;
  background: var(--accent);
  color: #fff;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  transition: transform .2s var(--ease);
}
.skip:focus { transform: translate(-50%, 0); }

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

/* ---------- Navigation ---------------------------------------------------- */

.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  /* Transparent over the hero — there is nothing behind it there but the page
     colour — and fully opaque once anything would scroll underneath. No blur:
     content sliding half-visible under a frosted bar is exactly the muddle
     this palette is meant to avoid. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
.nav.is-stuck {
  background: var(--bg);
  border-bottom-color: var(--hairline);
}
.nav-inner {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--text);
}
/* The app's own icon. */
.brand-mark {
  flex: 0 0 auto;
  width: 26px; height: 26px;
  border-radius: 7px;
  display: block;
  object-fit: cover;
}
/* One element, not two. "Cal" and "Snap" used to be separate children of the
   flex row, so the 10px gap meant for the icon landed between them as well and
   the wordmark read "Cal Snap". Der Name ist seit der Umbenennung ein Wort und
   einfarbig — die Regel bleibt trotzdem stehen, weil sie den Grund festhält,
   aus dem hier kein zweites Element auftauchen darf. */
.brand-word { white-space: nowrap; }

.nav-links { display: flex; align-items: center; gap: 4px; }
.nav-link {
  position: relative;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text-2);
  transition: color .2s var(--ease), background-color .2s var(--ease);
}
.nav-link:hover { color: var(--text); background: var(--surface-2); }
.nav-sep { width: 1px; height: 18px; background: var(--hairline); margin: 0 6px; }
.nav-lang {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  font-size: 13.5px; font-weight: 600;
  color: var(--text-2);
  transition: color .2s var(--ease), border-color .2s var(--ease),
              background-color .2s var(--ease);
}
.nav-lang:hover { color: var(--text); border-color: var(--hairline-strong); background: var(--surface); }

/* ---------- Buttons ------------------------------------------------------- */

.btn {
  --spot: 50%;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: 52px;
  padding: 0 26px;
  border-radius: 999px;
  border: 1px solid transparent;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.01em;
  cursor: pointer;
  white-space: nowrap;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease),
              background-color .25s var(--ease), border-color .25s var(--ease),
              opacity .25s var(--ease);
}
.btn:active { transform: scale(.975); }

/* Flat accent, black shadow. The gradient-plus-blue-halo version read as a
   button lit from inside by nothing. */
.btn-primary {
  color: #fff;
  background: var(--accent);
}
.btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
  background: #4F97FF;
  box-shadow: var(--shadow-md);
}
/* The download button has nowhere to point yet. It stays the visual anchor of
   the hero but is genuinely disabled, so a screen reader says so too rather
   than announcing a link that goes nowhere. */
.btn-primary:disabled { cursor: default; background: #2E6ABF; }
.btn-primary:disabled:hover { transform: none; box-shadow: none; }

.btn-soon {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  /* A darker blue pill rather than white-at-22%, which would pick up whatever
     the button underneath happens to be. */
  background: #1F4E92;
}

.btn-ghost {
  color: var(--text);
  background: var(--surface);
  border-color: var(--hairline);
}
.btn-ghost:hover {
  transform: translateY(-2px);
  background: var(--surface-2);
  border-color: var(--hairline-strong);
  box-shadow: var(--shadow-md);
}

.cta-note {
  margin: 16px 0 0;
  font-size: 13.5px;
  color: var(--text-3);
  max-width: 42ch;
}

/* ---------- Hero ---------------------------------------------------------- */

.hero {
  position: relative;
  padding: calc(var(--nav-h) + clamp(56px, 11vw, 116px)) 0 clamp(56px, 9vw, 104px);
}
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(40px, 6vw, 76px);
  align-items: center;
}

/* Nomi above the headline. No shadow and no glow behind it — the mascot is
   already the one round, bright thing on the page, and a halo under it would
   be exactly the generated look the rest of this stylesheet avoids. */
.nomi {
  width: clamp(88px, 8vw, 128px);
  aspect-ratio: 1;
  margin: 0 0 14px -6px;
}
.nomi video, .nomi img { display: block; width: 100%; height: 100%; }
.nomi .nomi-still { display: none; }

@media (prefers-reduced-motion: reduce) {
  /* A looping mascot is motion nobody asked for. The still says the same. */
  .nomi video { display: none; }
  .nomi .nomi-still { display: block; }
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 15px 7px 11px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  color: var(--text-2);
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -.005em;
}
.eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: #4ADE80;
}

h1.display {
  margin: 26px 0 0;
  font-size: clamp(42px, 6.4vw, 78px);
  line-height: 1.02;
  font-weight: 700;
  letter-spacing: -.038em;
  /* Solid white. The fade-to-grey version made the last line of the headline
     look like it had lost signal. */
  color: #FFFFFF;
  text-wrap: balance;
}
.hero-sub {
  margin: 22px 0 0;
  max-width: 46ch;
  font-size: clamp(17px, 1.35vw, 19px);
  line-height: 1.62;
  color: var(--text-2);
  text-wrap: pretty;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 36px;
}

/* The preview: real cards from the catalogue, in a glass frame, turned a few
   degrees. Enough to read as a product shot, not so much that the titles have
   to be guessed at. */
.preview {
  position: relative;
  perspective: 1600px;
}
/* There was a blurred blue radial behind this frame. It is gone: the frame is
   an opaque panel that stands on the page by its border and its shadow, the
   same way every other surface here does. */
.preview-frame {
  padding: 16px;
  border-radius: var(--r-2xl);
  border: 1px solid var(--hairline);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  transform: rotateY(-9deg) rotateX(3deg) scale(.97);
  transform-origin: 70% 50%;
  transition: transform .8s var(--ease);
}
.preview:hover .preview-frame { transform: rotateY(-4deg) rotateX(1.5deg) scale(1); }
.preview-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.preview .card-title { font-size: 14.5px; }
.preview .card-body { padding: 12px 13px 14px; }
.preview .meta { font-size: 11.5px; gap: 9px; }
.preview .meta svg { width: 12px; height: 12px; }

/* ---------- Section headers ---------------------------------------------- */

.section { padding-top: var(--section-gap); }
.section-head { max-width: 62ch; margin-bottom: clamp(28px, 3.4vw, 44px); }

h2.title {
  margin: 0;
  font-size: clamp(30px, 3.7vw, 46px);
  line-height: 1.1;
  font-weight: 700;
  letter-spacing: -.032em;
  text-wrap: balance;
}
.section-sub {
  margin: 14px 0 0;
  font-size: 17px;
  color: var(--text-2);
  max-width: 52ch;
  text-wrap: pretty;
}

.cat-head {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  margin: clamp(48px, 6vw, 88px) 0 26px;
}
.cat-emoji {
  flex: 0 0 auto;
  width: 52px; height: 52px;
  border-radius: var(--r-md);
  display: grid; place-items: center;
  font-size: 25px;
  line-height: 1;
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-sm);
}
.cat-text { min-width: 0; }
.cat-title {
  margin: 0;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 12px;
  font-size: clamp(22px, 2.5vw, 29px);
  font-weight: 650;
  letter-spacing: -.028em;
  line-height: 1.2;
}
.cat-count {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--text-3);
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  white-space: nowrap;
}
.cat-desc {
  margin: 8px 0 0;
  color: var(--text-2);
  font-size: 15.5px;
  max-width: 56ch;
  text-wrap: pretty;
}

.rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: var(--hairline);
}

/* ---------- Cards --------------------------------------------------------- */

.grid {
  display: grid;
  gap: clamp(14px, 1.6vw, 22px);
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  background: var(--surface);
  overflow: hidden;
  isolation: isolate;
  transition: transform .45s var(--ease), border-color .45s var(--ease),
              box-shadow .45s var(--ease), background-color .45s var(--ease);
}
.card:hover, .card:focus-visible {
  transform: translateY(-6px);
  border-color: var(--hairline-strong);
  background: var(--surface-2);
  box-shadow: var(--shadow-lg);
}

.card-media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #12161D;
}
/* Fixed box plus object-fit: every card is the same height whatever the photo
   measures, so nothing reflows as the images arrive. */
.card-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1.001);
  transition: transform .7s var(--ease);
}
.card:hover .card-media img { transform: scale(1.065); }
.card-media .emoji {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  font-size: clamp(40px, 6vw, 58px);
  background: #1A2029;
  transition: transform .7s var(--ease);
}
.card:hover .card-media .emoji { transform: scale(1.06); }
/* The photo settles into the card instead of ending on a hard edge. Fading to
   the card's own colour, not to a grey wash — anything else is a smudge that
   belongs to neither the picture nor the surface. */
.card-media::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 42%;
  background: linear-gradient(180deg, rgba(18,22,29,0), rgba(18,22,29,.85));
  pointer-events: none;
}

.card-body { padding: 15px 17px 17px; }
.card-title {
  margin: 0;
  font-size: 16.5px;
  font-weight: 600;
  letter-spacing: -.017em;
  line-height: 1.32;
  text-wrap: balance;
}

.meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 13px;
  margin-top: 11px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.meta span { display: inline-flex; align-items: center; gap: 5px; }
.meta svg { width: 13px; height: 13px; flex: 0 0 auto; }
.meta .m-kcal svg { color: #F2934D; }
.meta .m-prot { color: var(--protein); }
.meta .m-prot svg { color: var(--protein); }

/* ---------- FAQ ----------------------------------------------------------- */

.faq { display: grid; gap: 10px; max-width: 820px; }
.qa {
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}
.qa:hover { border-color: var(--hairline-strong); background: var(--surface-2); }
.qa[open] { border-color: var(--hairline-strong); }
.qa summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 19px 22px;
  cursor: pointer;
  font-size: 16.5px;
  font-weight: 550;
  letter-spacing: -.014em;
  list-style: none;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after {
  content: "";
  flex: 0 0 auto;
  width: 10px; height: 10px;
  border-right: 1.8px solid var(--text-3);
  border-bottom: 1.8px solid var(--text-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .35s var(--ease), border-color .35s var(--ease);
}
.qa[open] summary::after {
  transform: rotate(225deg) translate(-2px, -2px);
  border-color: var(--accent);
}
.qa p {
  margin: 0;
  padding: 0 22px 21px;
  color: var(--text-2);
  font-size: 15.5px;
  max-width: 68ch;
}

/* ---------- Detail page --------------------------------------------------- */

.back {
  display: inline-flex; align-items: center; gap: 8px;
  margin-bottom: 30px;
  font-size: 14.5px; font-weight: 550;
  color: var(--text-2);
  transition: color .2s var(--ease), gap .25s var(--ease);
}
.back:hover { color: var(--text); gap: 11px; }

.detail { padding-top: calc(var(--nav-h) + clamp(34px, 5vw, 60px)); }

.detail-media {
  position: relative;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--hairline);
  background: #12161D;
  box-shadow: var(--shadow-lg);
  aspect-ratio: 16 / 9;
}
.detail-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.detail-media .emoji {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  font-size: clamp(64px, 12vw, 120px);
  background: #1A2029;
}

h1.detail-title {
  margin: 34px 0 0;
  font-size: clamp(32px, 4.4vw, 52px);
  line-height: 1.07;
  font-weight: 700;
  letter-spacing: -.034em;
  text-wrap: balance;
}
.detail-sub {
  margin: 16px 0 0;
  font-size: 18px;
  color: var(--text-2);
  max-width: 58ch;
  text-wrap: pretty;
}

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 10px;
  margin: 32px 0 12px;
}
.stat {
  padding: 15px 17px;
  border-radius: var(--r-md);
  border: 1px solid var(--hairline);
  background: var(--surface);
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}
.stat:hover { border-color: var(--hairline-strong); background: var(--surface-2); }
.stat .k {
  font-size: 11.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-3);
}
.stat .v {
  margin-top: 4px;
  font-size: 23px; font-weight: 650;
  letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
}
.v.p { color: var(--protein); } .v.c { color: var(--carb); } .v.f { color: var(--fat); }
.per { margin: 0; color: var(--text-3); font-size: 13.5px; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.chip {
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  color: var(--text-2);
  font-size: 13.5px;
  font-weight: 500;
}

.panel {
  margin: 22px 0 0;
  padding: 26px 28px;
  border-radius: var(--r-xl);
  border: 1px solid var(--hairline);
  background: var(--surface);
}
.panel h2 {
  margin: 0 0 18px;
  font-size: 20px; font-weight: 650;
  letter-spacing: -.022em;
}
ul.ing { list-style: none; margin: 0; padding: 0; }
ul.ing li {
  display: flex; justify-content: space-between; gap: 20px;
  padding: 12px 0;
  border-bottom: 1px solid var(--hairline);
}
ul.ing li:last-child { border-bottom: 0; padding-bottom: 0; }
ul.ing li:first-child { padding-top: 0; }
ul.ing .amt { color: var(--text-2); font-weight: 550; white-space: nowrap;
              font-variant-numeric: tabular-nums; }

ol.steps { margin: 0; padding: 0; list-style: none; counter-reset: s; }
ol.steps li {
  position: relative;
  counter-increment: s;
  padding: 0 0 20px 46px;
  color: var(--text-2);
}
ol.steps li:last-child { padding-bottom: 0; }
ol.steps li::before {
  content: counter(s);
  position: absolute;
  left: 0; top: -1px;
  width: 28px; height: 28px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 650;
  color: var(--accent);
  background: var(--accent-quiet);
  border: 1px solid #294B7A;
}
/* The thread down the left, so a long method reads as one sequence. */
ol.steps li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 13.5px; top: 32px; bottom: 12px;
  width: 1px;
  background: var(--hairline);
}

.tip {
  margin: 0;
  padding-left: 18px;
  border-left: 2px solid var(--accent);
  color: var(--text-2);
}

.cta {
  display: flex; align-items: center; gap: 18px;
  margin: 34px 0 0;
  padding: 24px 26px;
  border-radius: var(--r-xl);
  border: 1px solid var(--hairline);
  background: var(--surface);
}
.cta .dot {
  flex: 0 0 auto;
  width: 48px; height: 48px;
  border-radius: 15px;
  display: grid; place-items: center;
  font-size: 23px;
  background: var(--accent);
}
.cta p { margin: 0; color: var(--text-2); font-size: 15.5px; max-width: 52ch; }

/* ---------- Footer -------------------------------------------------------- */

footer {
  margin-top: var(--section-gap);
  padding: 34px 0 46px;
  border-top: 1px solid var(--hairline);
  color: var(--text-3);
  font-size: 13.5px;
}
.foot-inner {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 14px;
}
.foot-links { display: flex; gap: 20px; }
.foot-links a { color: var(--text-3); transition: color .2s var(--ease); }
.foot-links a:hover { color: var(--text-2); }

/* ---------- Scroll reveal ------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .75s var(--ease), transform .75s var(--ease);
  transition-delay: calc(var(--i, 0) * 55ms);
  will-change: opacity, transform;
}
.reveal.in { opacity: 1; transform: none; }
/* Nothing stays invisible if the observer never runs. */
.no-js .reveal { opacity: 1; transform: none; }

/* ---------- Responsive ---------------------------------------------------- */

@media (max-width: 1000px) {
  .hero-grid { grid-template-columns: 1fr; gap: 44px; }
  .preview-frame { transform: none; }
  .preview:hover .preview-frame { transform: none; }
  .preview::before { inset: 10% 0 -6% 0; }
}

@media (max-width: 640px) {
  :root { --nav-h: 58px; }
  body { font-size: 16.5px; }
  .hero { padding-top: calc(var(--nav-h) + 40px); padding-bottom: 48px; }
  h1.display { font-size: clamp(35px, 10vw, 46px); }
  .hero-sub { margin-top: 18px; font-size: 16.5px; }
  .hero-actions { margin-top: 28px; }
  /* Full-width buttons: a 52px pill that spans the column is the easiest
     target on the page, and two of them stacked read as a clear order. */
  .btn { width: 100%; height: 54px; }
  .grid { grid-template-columns: 1fr; }
  .preview-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .preview-frame { padding: 10px; border-radius: var(--r-xl); }
  /* Two cards, not four: the preview is a taste of the catalogue, and a 2x2
     grid of 4:3 photos pushes the first real section a whole screen down on a
     phone — which is the opposite of a compact hero. */
  .preview-grid > :nth-child(n+3) { display: none; }
  /* The narrow card cannot hold three figures on one line, and a meta row that
     wraps reads as a mistake. Calories and protein are the two that matter. */
  .preview .m-time { display: none; }
  .nav-links .nav-link { padding: 8px 11px; font-size: 14px; }
  .cat-head { gap: 14px; }
  .cat-emoji { width: 44px; height: 44px; font-size: 21px; }
  .panel { padding: 22px 20px; border-radius: var(--r-lg); }
  .cta { flex-direction: column; align-items: flex-start; gap: 14px; }
  .qa summary { padding: 17px 18px; font-size: 15.5px; }
  .qa p { padding: 0 18px 18px; }
}

/* Two cards fit a phone once the column is narrow enough to be worth it. */
@media (min-width: 421px) and (max-width: 640px) {
  .grid { grid-template-columns: 1fr 1fr; }
  .card-title { font-size: 15px; }
  .meta { gap: 10px; font-size: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .preview-frame { transform: none; }
}

/* A recipe is the one page on the web people still print and take to a
   worktop. Ink on white, nothing hidden behind a scroll observer, and the
   chrome that means nothing on paper left off. */
@media print {
  body { background: #fff; color: #000; }
  body::before, body::after { display: none; }
  .nav, .skip, .cta, footer, .back { display: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .detail { padding-top: 0; }
  .detail-media { max-height: 8cm; box-shadow: none; border: 0; }
  .panel, .stat, .chip {
    border-color: #ccc;
    background: transparent;
    break-inside: avoid;
  }
  .panel { padding: 0; margin: 16px 0 0; border: 0; }
  h1.detail-title, .panel h2 { color: #000; }
  .detail-sub, .per, ul.ing .amt, ol.steps li, .chip, .tip { color: #333; }
  ol.steps li::before { color: #000; background: #eee; border-color: #ccc; }
  ol.steps li:not(:last-child)::after { display: none; }
  a[href]::after { content: ""; }
}
