/* ============================================================
   BULKBITE - styles.css
   Mobile-first. Bold typography, big numbers, high contrast.
   ============================================================ */

/* ------------------------------------------------------------
   Metric-matched fallbacks for the display font.
   Anton loads asynchronously, so headings first paint in a system
   font and reflow when it arrives - that reflow is Cumulative
   Layout Shift, a Core Web Vitals ranking signal.
   The size-adjust values below were measured against Anton in the
   browser (Impact renders 99.2% of Anton's width at the same size,
   Arial Narrow 91.2%), so the swap is visually near-invisible.
   Re-measure if the display font ever changes.
   ------------------------------------------------------------ */
@font-face {
  font-family: 'Anton Fallback';
  src: local('Impact');
  size-adjust: 99.2%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Anton Fallback Narrow';
  src: local('Arial Narrow');
  font-weight: 700;
  size-adjust: 91.2%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

/* ---------- tokens ---------- */
:root {
  --ink:        #101010;
  --ink-2:      #1b1b1b;
  --ink-3:      #2b2b2b;
  --paper:      #f5f0e6;
  --paper-2:    #ece5d6;
  --white:      #ffffff;
  --accent:     #ff5a1f;
  --accent-dk:  #e14709;
  --accent-text:#c53a00;
  --amber:      #ffc53d;
  --muted:      #6d6a64;
  --muted-dark: rgba(255, 255, 255, .62);
  --line:       rgba(16, 16, 16, .14);
  --line-dark:  rgba(255, 255, 255, .16);

  --display: 'Anton', 'Anton Fallback', 'Anton Fallback Narrow', Impact, 'Arial Narrow', sans-serif;
  --body: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

  --wrap: 1140px;
  --radius: 14px;
  --pad: clamp(1.15rem, 5vw, 2rem);
  --sect-y: clamp(3.6rem, 9vw, 7rem);
  --shadow: 0 18px 40px -22px rgba(16, 16, 16, .45);
}

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

/* ------------------------------------------------------------
   The `hidden` attribute must win.
   ------------------------------------------------------------
   Every panel, modal, banner and view on this site is opened and
   closed by setting `hidden` from JavaScript. The browser
   implements that with `[hidden] { display: none }` in its OWN
   stylesheet - and any author rule that sets `display` beats a
   user-agent rule outright, whatever its specificity. So a single
   line like `.lead-panel { display: flex }` silently turns
   `hidden` into a no-op: the element is marked closed, reports
   itself as closed, and stays on the screen with nothing in it.

   `!important` is right here and nowhere else in this file.
   `hidden` is a statement about whether the element exists for the
   user, not a style, and it must not be overridable by accident.
   ------------------------------------------------------------ */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 76px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
body {
  margin: 0;
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, svg { max-width: 100%; display: block; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4 { margin: 0 0 .5em; line-height: 1.02; }
p { margin: 0 0 1em; }
ul, ol { margin: 0; padding: 0; list-style: none; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--accent); color: var(--ink); padding: .8rem 1.2rem; font-weight: 700;
}
.skip-link:focus { left: .5rem; top: .5rem; }

/* ---------- layout ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--pad); }
.wrap.narrow { max-width: 760px; }

.section { padding-block: var(--sect-y); position: relative; }

.section-title {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.1rem, 8vw, 3.6rem);
  letter-spacing: -.005em;
  text-transform: uppercase;
  margin-bottom: .45em;
}
.section-title.huge { font-size: clamp(2.4rem, 10vw, 4.6rem); }
.section-lede {
  font-size: clamp(1.02rem, 2.4vw, 1.18rem);
  color: var(--muted);
  max-width: 62ch;
  margin-bottom: 2.2rem;
}
.section-lede.center { text-align: center; margin-inline: auto; }

.eyebrow {
  font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-text); margin-bottom: 1.1rem;
}
.section-ink .eyebrow, .section-cta .eyebrow { color: var(--accent); }
/* .82, not .65: this label only ever sits on the accent orange, where ink at
   65% measures 3.4:1 against #ff5a1f and it is 12.5px text, not large text.
   .82 measures 4.9:1 and still reads as a recessed eyebrow. */
.eyebrow-dark { color: var(--ink); opacity: .82; }

.fineprint { font-size: .875rem; color: var(--muted); }
.fineprint.center { text-align: center; }
.section-ink .fineprint, .section-cta .fineprint { color: rgba(255, 255, 255, .68); }

/* Reveal-on-scroll.
   Sections are VISIBLE by default and only hidden once JS has taken
   responsibility for revealing them (.reveal-init). If JS never runs,
   fails, or is blocked, the page still renders in full. */
.section { transition: opacity .55s ease, transform .55s ease; }
.section.reveal-init { opacity: 0; transform: translateY(14px); }
.section.reveal-init.is-in { opacity: 1; transform: none; }

/* ---------- colour blocks ---------- */
.section-paper { background: var(--paper); }
.section-ink   { background: var(--ink); color: var(--white); }
.section-ink .section-lede { color: var(--muted-dark); }
.section-accent { background: var(--accent); color: var(--ink); }
/* Amber is reserved for OFFERS - the promo bar, the founding section and the
   capacity band - so a discount never reads as just another orange block. */
.section-amber { background: var(--amber); color: var(--ink); }
.section-cta { background: var(--ink); color: var(--white); }
.section-cta .section-lede { color: var(--muted-dark); }
/* The site grey measures 2.3:1 on orange and 1.9:1 on amber. Both fail, so
   the lede on a coloured band runs at ink-2 (>4.5:1) and relies on size
   rather than tone to read as secondary. */
.section-accent .section-lede,
.section-amber .section-lede { color: var(--ink-2); }
.section-amber .fineprint { color: var(--ink-2); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  padding: .85rem 1.4rem; border: 2px solid transparent; border-radius: 999px;
  font-weight: 800; font-size: .95rem; letter-spacing: .01em; text-decoration: none;
  cursor: pointer; transition: transform .16s ease, background .16s ease, color .16s ease, box-shadow .16s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:active { transform: translateY(1px) scale(.995); }
.btn-accent { background: var(--accent); color: var(--ink); box-shadow: 0 10px 24px -12px rgba(255, 90, 31, .9); }
.btn-accent:hover { background: var(--accent-dk); }
.btn-ghost { background: transparent; border-color: currentColor; }
.btn-ghost:hover { background: rgba(255, 255, 255, .1); }
.section:not(.section-ink):not(.section-cta) .btn-ghost:hover { background: rgba(16, 16, 16, .07); }
/* Solid dark button - the only readable "primary" on an accent background,
   where .btn-accent would be orange on orange. */
.btn-ink { background: var(--ink); color: #fff; }
.btn-ink:hover { background: var(--ink-3); }
.btn-lg { padding: 1.05rem 1.9rem; font-size: 1.05rem; }
.btn-sm { padding: .6rem 1.05rem; font-size: .85rem; }
.btn-block { width: 100%; }

/* ---------- promo bar (referral promotion) ----------
   Sits ABOVE the sticky header and scrolls away with the page, so the
   promotion gets the first impression without permanently eating vertical
   space on a phone. */
.promo-bar {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: .25rem .7rem;
  background: var(--amber); color: var(--ink); text-decoration: none;
  padding: .6rem var(--pad); min-height: 44px;
  font-size: .88rem; font-weight: 600; text-align: center;
  border-bottom: 1px solid rgba(16, 16, 16, .18);
}
.promo-bar:hover { background: #ffcf5c; }
.promo-tag {
  background: var(--ink); color: #fff; border-radius: 999px;
  padding: .16rem .6rem; font-size: .68rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; white-space: nowrap;
}
.promo-text strong { font-weight: 800; }
.promo-more { font-weight: 800; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
/* One line of message is plenty on a narrow phone - the arrow is a
   duplicate affordance, the whole bar is already the link. */
@media (max-width: 560px) { .promo-more { display: none; } }

/* ---------- header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 90;
  background: rgba(255, 255, 255, .88);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.site-header.is-stuck { border-bottom-color: var(--line); box-shadow: 0 8px 24px -20px rgba(0, 0, 0, .6); }
.header-inner { display: flex; align-items: center; gap: 1rem; min-height: 62px; }

.logo { display: inline-flex; align-items: center; text-decoration: none; margin-right: auto; }
.logo-lockup { display: block; width: auto; height: 36px; }
.logo-lockup-404 { height: clamp(34px, 10vw, 46px); }

.header-nav { display: none; gap: 1.5rem; font-size: .92rem; font-weight: 600; }
.header-nav a { text-decoration: none; opacity: .75; }
.header-nav a:hover { opacity: 1; color: var(--accent); }
.header-cta { display: none; }

@media (min-width: 800px) {
  .header-nav { display: flex; }
  .header-cta { display: inline-flex; }
}

/* ---------- hero ---------- */
.hero {
  background: var(--ink); color: var(--white);
  padding-top: clamp(2.6rem, 8vw, 4.5rem); padding-bottom: 0;
  position: relative; overflow: hidden;
}
.hero::before {
  content: ''; position: absolute; inset: auto -20% -30% auto;
  width: 70vw; height: 70vw; max-width: 700px; max-height: 700px;
  background: radial-gradient(circle, rgba(255, 90, 31, .30), transparent 62%);
  pointer-events: none;
}
.hero .wrap { position: relative; padding-bottom: clamp(2.6rem, 7vw, 4rem); }
.hero-copy { position: relative; z-index: 1; }

/* Three short lines ("LUNCH AND / DINNER. / HANDLED."), so this can run
   larger than a headline built from long words. The vw factor drops at
   900px because that is where the hero splits into two columns and the
   text stops getting the full viewport - scaling on vw past that point
   overflows the copy column. Re-measure both clamps if the headline
   changes; the binding line here is "LUNCH AND". */
.hero-title {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2.6rem, 13vw, 4.8rem);
  letter-spacing: -.01em; text-transform: uppercase; margin-bottom: .32em;
}
.hero-title .hl { color: var(--accent); }
.hero-sub { font-size: clamp(1.05rem, 3.2vw, 1.32rem); color: rgba(255, 255, 255, .82); max-width: 36ch; }
.hero-sub strong { color: #fff; }

.hero-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin: 1.8rem 0 1.2rem; }
.hero-actions .btn { flex: 1 1 auto; min-width: 190px; }

/* The proof line under the CTA. Three facts, no adjectives - it exists
   to answer "what am I actually buying" in the half-second after the
   headline, without starting an argument about grams. */
.hero-proof {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1.15rem;
  margin: 0 0 1.4rem; font-weight: 700; font-size: .95rem;
  color: rgba(255, 255, 255, .78);
}
.hero-proof li { position: relative; }
.hero-proof li + li::before {
  content: '·'; position: absolute; left: -.7rem; color: var(--accent); font-weight: 800;
}
.hero-proof span { font-family: var(--display); font-size: 1.15em; color: #fff; }

.hero-foot { font-size: .92rem; color: rgba(255, 255, 255, .6); max-width: 46ch; margin: 0; }

.hero-visual {
  position: relative; display: block; margin: 2.2rem 0 0;
  aspect-ratio: 16 / 10;
  border-radius: calc(var(--radius) + 8px); overflow: hidden;
  background: #171717; border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: 18px 18px 0 rgba(255, 90, 31, .16);
}
.hero-visual img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  object-position: 68% center;
}

@media (min-width: 900px) {
  .hero .wrap {
    display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(360px, .9fr);
    gap: clamp(2.5rem, 5vw, 5rem); align-items: center;
  }
  .hero-title { font-size: clamp(3rem, 6vw, 5.4rem); }
  .hero-sub { font-size: 1.35rem; }
  .hero-actions .btn { flex: 0 0 auto; }
  .hero-visual { margin: 0; aspect-ratio: 4 / 5; }
  .hero-visual img { object-position: 72% center; }
}

/* ticker */
.ticker {
  border-top: 1px solid var(--line-dark); border-bottom: 1px solid var(--line-dark);
  background: var(--accent); color: var(--ink);
  overflow: hidden; white-space: nowrap; padding-block: .55rem;
}
.ticker-track {
  display: inline-flex; gap: 1.4rem; align-items: center;
  font-family: var(--display); font-size: .95rem; letter-spacing: .06em;
  animation: ticker 26s linear infinite; will-change: transform;
}
@keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ticker-track { animation: none; } }

/* ---------- shared: the pull quote ---------- */
.pull {
  border-left: 5px solid var(--accent); padding: .3rem 0 .3rem 1.3rem;
  font-size: clamp(1.1rem, 3vw, 1.4rem); line-height: 1.35;
}
.pull p:last-child { margin-bottom: 0; }
.pull-dark { margin: 2rem 0; }
.pull-dark strong { color: var(--accent); }
/* The line the section is remembered by, set in display type so it reads
   as a signature rather than as another sentence. */
.pull-sign {
  font-family: var(--display); text-transform: uppercase; line-height: 1.05;
  font-size: clamp(1.35rem, 5vw, 2.1rem); margin-top: .8rem;
}

/* ---------- section 2: recognition ----------
   Four cards that all end the same way. The repetition IS the argument -
   the answer is identical because the point is that it is always the same
   answer, whatever went wrong with the day. Do not vary the second line. */
.scenarios { display: grid; gap: .8rem; margin: 0 0 2.4rem; }
@media (min-width: 640px) { .scenarios { grid-template-columns: repeat(2, 1fr); } }
.scenario {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  border-left: 5px solid var(--accent); padding: 1.35rem 1.3rem;
}
.scenario-q {
  font-size: clamp(1.05rem, 2.8vw, 1.18rem); font-weight: 700; color: var(--ink);
  margin-bottom: .3rem;
}
.scenario-a {
  font-family: var(--display); text-transform: uppercase; line-height: 1.05;
  font-size: clamp(1.4rem, 5vw, 1.85rem); color: var(--accent-text); margin: 0;
}

/* ---------- section 3: the second dinner ---------- */
.second-lead { font-size: 1.05rem; color: var(--muted-dark); margin-top: 1.6rem; }
.receipt {
  display: grid; gap: 0; margin: 0; border-top: 1px solid var(--line-dark);
  max-width: 34rem;
}
.receipt li {
  display: flex; align-items: baseline; gap: .8rem;
  padding: .7rem 0; border-bottom: 1px solid var(--line-dark);
  font-size: 1.02rem; color: rgba(255, 255, 255, .88);
}
.receipt li::before {
  content: '+'; font-family: var(--display); color: var(--accent);
  font-size: 1.1rem; line-height: 1;
}
.second-note { color: var(--muted-dark); max-width: 56ch; }
.second-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.8rem; }

/* ---------- section 4: the portion ladder ----------
   Bar widths are percentages of the LARGEST serving, written into the
   markup as inline styles. If a serving size changes in js/config.js,
   change the widths in index.html to match - the token substitution
   updates the labels but cannot resize a bar. */
.ladder { display: grid; gap: 1.15rem; margin: 0 0 2.2rem; }
.ladder-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  margin-bottom: .4rem;
}
.ladder-name {
  font-family: var(--display); text-transform: uppercase;
  font-size: clamp(1.2rem, 4vw, 1.5rem);
}
.ladder-grams {
  font-family: var(--display); font-size: clamp(1.4rem, 5vw, 1.9rem); color: var(--accent-text);
}
.ladder-bar {
  height: 14px; border-radius: 999px; background: rgba(16, 16, 16, .1); overflow: hidden;
}
.ladder-bar span {
  display: block; height: 100%; border-radius: 999px; background: var(--ink);
}
.ladder-step-anchor .ladder-bar span { background: var(--accent); }
.ladder-step-anchor .ladder-name { color: var(--accent-text); }
.ladder-note { font-size: .92rem; color: var(--muted); margin: .45rem 0 0; }

/* The Full plan as arithmetic. Three steps, each one derived from the
   last, so the 33.6 kg lands as a consequence rather than as a boast. */
.maths { border-top: 2px solid var(--line); padding-top: 1.5rem; }
.maths-kicker {
  font-size: .76rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); margin-bottom: .9rem;
}
.maths-chain { display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem 1.6rem; margin: 0 0 1rem; }
.maths-chain li { display: flex; flex-direction: column; position: relative; }
.maths-chain li + li::before {
  content: '→'; position: absolute; left: -1.1rem; top: .3em;
  color: var(--accent); font-weight: 800; font-size: .9rem;
}
.maths-num { font-family: var(--display); font-size: clamp(1.8rem, 7vw, 2.6rem); line-height: 1; }
.maths-chain li:last-child .maths-num { color: var(--accent-text); }
.maths-lbl { font-size: .82rem; color: var(--muted); }
.maths-foot { font-size: .92rem; color: var(--muted); margin: 0; }

/* ---------- section 5: the loaf comparison ----------
   ONE reference object. The bars underneath carry the actual comparison;
   the drawings are only there so the numbers have something to sit on.
   Resist adding a third item - see the note in index.html. */
.weighin {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: end;
  gap: 1rem; margin-bottom: 1.2rem;
}
/* The drawings inherit currentColor: ours is orange to tie it to the
   orange bar beneath it, the reference object is a neutral grey so the
   comparison reads as "us against a known thing", not as two products. */
.weighin-item { margin: 0; text-align: center; color: var(--accent); }
.weighin-item-ref { color: var(--muted); }
.weighin-illo { width: 100%; max-width: 190px; height: auto; margin: 0 auto .8rem; }
.weighin-weight {
  display: block; font-family: var(--display); line-height: 1;
  font-size: clamp(2rem, 9vw, 3rem); color: var(--accent-text);
}
.weighin-item-ref .weighin-weight { color: var(--ink); }
.weighin-name { display: block; font-size: .88rem; color: var(--muted); margin-top: .25rem; }
.weighin-vs {
  font-family: var(--display); text-transform: uppercase; font-size: 1.1rem;
  color: var(--muted); margin: 0 0 3.2rem;
}
.weighin-bars { display: grid; gap: .45rem; margin-bottom: 1.4rem; }
.weighin-bar { height: 12px; border-radius: 999px; background: rgba(16, 16, 16, .1); overflow: hidden; }
.weighin-fill { display: block; height: 100%; border-radius: 999px; background: var(--ink); }
.weighin-fill-us { background: var(--accent); }
.weighin-line {
  font-size: clamp(1.05rem, 2.8vw, 1.25rem); line-height: 1.45; max-width: 46ch; margin-bottom: .6rem;
}
.weighin-line strong { font-family: var(--display); font-weight: 400; text-transform: uppercase; }

/* ---------- section 6: what disappears ----------
   The more persuasive half of the convenience argument, so it gets its
   own slab rather than a bullet list under the steps. */
.disappear {
  margin-top: 2.4rem; background: var(--ink); color: #fff; border-radius: var(--radius);
  padding: clamp(1.5rem, 5vw, 2.4rem);
}
.disappear-title {
  font-family: var(--display); text-transform: uppercase; font-size: 1.25rem;
  letter-spacing: .06em; color: var(--accent); margin-bottom: 1.1rem;
}
.disappear-list { display: grid; gap: .55rem; margin-bottom: 1.6rem; }
@media (min-width: 720px) { .disappear-list { grid-template-columns: repeat(2, 1fr); gap: .55rem 2rem; } }
.disappear-list li {
  position: relative; padding-left: 2.1rem; font-size: 1.02rem;
  color: rgba(255, 255, 255, .82);
}
/* A struck-through cross, because these are things that stop happening. */
.disappear-list li::before {
  content: '×'; position: absolute; left: 0; top: -.06em;
  font-family: var(--display); font-size: 1.4rem; line-height: 1.1; color: var(--accent);
}
.disappear-foot {
  margin: 0; padding-top: 1.4rem; border-top: 1px solid var(--line-dark);
  font-family: var(--display); text-transform: uppercase; line-height: 1.05;
  font-size: clamp(1.4rem, 5vw, 2.1rem);
}

/* ---------- section 8: the plans ----------
   Ascending order, equal columns. The anchor is the LAST card, because
   the page has already argued for the big portion by the time a reader
   gets here - it is the conclusion of the ladder, not an upsell. */
.plans { display: grid; gap: 1rem; margin-bottom: 2rem; }
@media (min-width: 900px) {
  .plans { grid-template-columns: repeat(3, 1fr); gap: 1.1rem; align-items: stretch; }
}
.plan {
  border: 1px solid var(--line-dark); border-radius: var(--radius);
  background: rgba(255, 255, 255, .04);
  padding: 1.5rem 1.3rem; display: flex; flex-direction: column;
}
/* The anchor card is distinguished by colour, not by size. It used to
   carry extra padding from when it was the wide first card; in an
   equal-column row that only left its button 8px above the other two. */
.plan-anchor {
  border-color: var(--accent); background: rgba(255, 90, 31, .1);
  box-shadow: 0 24px 50px -30px rgba(255, 90, 31, .8);
}

.plan-flag {
  font-size: .7rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted-dark); margin: 0 0 .9rem;
}
.plan-flag-anchor {
  display: inline-block; align-self: flex-start;
  background: var(--accent); color: var(--ink); border-radius: 999px; padding: .28rem .8rem;
}
/* The recommended tier. Amber rather than orange so it reads as a
   recommendation next to the anchor card rather than competing with it. */
.plan-pick { border-color: rgba(255, 197, 61, .55); }
.plan-flag-pick {
  display: inline-block; align-self: flex-start;
  background: var(--amber); color: var(--ink); border-radius: 999px; padding: .28rem .8rem;
}
.plan-name {
  font-family: var(--display); text-transform: uppercase; line-height: 1;
  font-size: clamp(1.9rem, 7vw, 2.4rem); margin-bottom: .2rem;
}
/* The serving size, directly under the name: it is the only thing that
   actually differs between these three cards. */
.plan-portion {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .04em;
  font-size: 1.02rem; color: var(--accent); margin-bottom: .6rem;
}
.plan-voice { font-style: italic; color: var(--muted-dark); margin-bottom: 1.2rem; }

.plan-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: .45rem; margin-bottom: 1rem; }
.plan-amount { font-family: var(--display); font-size: clamp(2.2rem, 8vw, 2.7rem); line-height: 1; color: var(--amber); }
.plan-period { font-weight: 700; font-size: .95rem; color: rgba(255, 255, 255, .6); }

/* Price per meal, set larger than the monthly figure it is derived from.
   The monthly number is what a student commits to; the per-meal number is
   the only one they can compare to anything they already buy, so it is
   the number this card is built around. */
.plan-permeal {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  border: 1px solid var(--line-dark); border-radius: 10px;
  padding: .75rem .9rem; margin: 0 0 1.3rem;
  background: rgba(255, 255, 255, .05);
}
.plan-permeal-num {
  font-family: var(--display); font-size: clamp(2rem, 8vw, 2.5rem); line-height: 1; color: #fff;
}
.plan-permeal-lbl {
  font-size: .72rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted-dark);
}
.plan-permeal-anchor {
  border-color: var(--accent); background: rgba(255, 90, 31, .16);
}
.plan-permeal-anchor .plan-permeal-num { color: var(--accent); }

/* The founding price, flagged on the card it discounts. */
.plan-founding {
  display: grid; gap: .4rem; justify-items: start;
  background: rgba(255, 197, 61, .12); border: 1px solid rgba(255, 197, 61, .5);
  border-radius: 10px; padding: .8rem .9rem; margin: 0 0 1.1rem;
  font-size: .88rem; color: rgba(255, 255, 255, .88);
}
.plan-founding-tag {
  background: var(--amber); color: var(--ink); border-radius: 999px;
  padding: .12rem .6rem; font-size: .66rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
}
.plan-founding s { color: rgba(255, 255, 255, .5); text-decoration-thickness: 2px; }
.plan-founding strong { color: var(--amber); font-size: 1.08em; }
.plan-founding a { color: var(--amber); }

/* Inline links inside a sentence are the one place this page can fall below
   a 44px touch target. Padding grows the hit area; the matching negative
   margin keeps the line box - and so the sentence around it - unmoved. */
.plan-founding a, .fineprint a {
  display: inline-block; padding-block: .78rem; margin-block: -.78rem;
  text-underline-offset: 3px;
}

.plan-spec { display: grid; gap: .55rem; margin: 0 0 1.5rem; padding-top: 1.1rem; border-top: 1px solid var(--line-dark); }
.plan-spec > div { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.plan-spec dt { font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-dark); }
.plan-spec dd { margin: 0; font-weight: 700; font-size: .96rem; text-align: right; }

/* Push the button to the bottom so the three cards line up even when the
   copy above them is different lengths. */
.plan .btn { margin-top: auto; }

.plans-foot {
  border-top: 1px solid var(--line-dark); padding-top: 1.6rem; margin: 0;
  color: var(--muted-dark); max-width: 66ch;
}
.plans-foot strong { color: #fff; }

/* ---------- section 4: one decision ---------- */
.statement {
  font-family: var(--display); text-transform: uppercase; line-height: 1.05;
  font-size: clamp(1.5rem, 5.5vw, 2.2rem); margin-bottom: .3rem;
}
/* :last-of-type would match the plain paragraph that follows, not the
   last .statement - the sibling selector is what actually separates the
   two-line hook from the explanation under it. */
.statement + :not(.statement) { margin-top: 1.5rem; }
.statement strong { font-weight: 400; }

/* ---------- split sections ---------- */
.split { display: grid; gap: 2rem; align-items: center; }
@media (min-width: 880px) {
  .split { grid-template-columns: 1.05fr .95fr; gap: 3.5rem; }
  .split-reverse .split-text { order: 2; }
  .split-reverse .split-media { order: 1; }
}
.split-media { margin: 0; }

.photo-slot {
  position: relative; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--paper); overflow: hidden;
  box-shadow: 0 18px 44px -34px rgba(0, 0, 0, .55);
}
.section-paper .photo-slot { background: var(--white); }
.photo-slot figcaption {
  padding: .85rem 1rem .95rem; font-size: .78rem; color: var(--muted); text-align: left;
}
/* <picture> is inline by default, so it builds a line box and leaves a few px
   of descender gap under the photo inside the bordered figure. */
.photo-slot picture { display: block; }
.site-photo { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }

/* ---------- section 5: steps ---------- */
.steps { display: grid; gap: 1rem; counter-reset: step; }
@media (min-width: 720px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .steps { grid-template-columns: repeat(5, 1fr); gap: .8rem; } }
.step {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.3rem 1.15rem; position: relative;
}
.step h3 { font-size: 1.06rem; margin-bottom: .35rem; }
.step p { font-size: .92rem; color: var(--muted); margin: 0; }
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.2rem; height: 2.2rem; border-radius: 999px; background: var(--ink); color: #fff;
  font-family: var(--display); font-size: 1.1rem; margin-bottom: .8rem;
}
.step:first-child .step-num { background: var(--accent); }

/* ---------- section 10: the economics ---------- */
.section-accent .prose { font-size: clamp(1.02rem, 2.6vw, 1.16rem); max-width: 60ch; }
.section-accent .prose strong { background: var(--ink); color: #fff; padding: .05em .35em; border-radius: 4px; }
.prose-note {
  margin-top: 0; padding-top: 1.3rem; border-top: 2px solid rgba(16, 16, 16, .22);
  font-weight: 600;
}

/* What the price is NOT paying for. The lead-in of each line is the cost
   that was removed; the rest is why that is possible. Runs at --ink-2 rather
   than --muted: the site grey measures 2.3:1 on orange, ink-2 measures 4.9:1
   - the same rule as .refer-terms in the referral section. */
.system-list { display: grid; gap: .7rem; margin: 1.6rem 0 2rem; max-width: 62ch; }
.system-list li {
  position: relative; padding-left: 1.9rem; font-size: 1.02rem; color: var(--ink-2);
}
.system-list li::before {
  content: ''; position: absolute; left: 0; top: .5em;
  width: 1.05rem; height: 3px; background: var(--ink); border-radius: 2px;
}
.system-list span {
  font-weight: 800; color: var(--ink);
}

/* ---------- cards ---------- */
.cards { display: grid; gap: .9rem; grid-template-columns: 1fr; }
@media (min-width: 620px) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .cards { grid-template-columns: repeat(3, 1fr); } }
.card {
  border: 1px solid var(--line); border-radius: var(--radius); padding: 1.4rem 1.25rem;
  background: var(--white); transition: transform .18s ease, box-shadow .18s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.card-icon { width: 30px; height: 30px; color: var(--accent); margin-bottom: .9rem; }
.card-title { font-family: var(--display); font-size: 1.3rem; text-transform: uppercase; margin-bottom: .3rem; }
.card-body { font-size: .95rem; color: var(--muted); margin: 0; }
.section-paper .card { background: var(--white); }

/* ---------- section 7: the four-week rotation ----------
   One card per week. Framed as "a new BulkBite every week" rather than
   "the same meal for seven days", because the second is the same fact
   told in the way that loses the sale.

   PHOTOGRAPHY: .meal-thumb is a placeholder tile, not a design choice.
   Each card is sized to take a real 4:3 photograph of the dish - swap
   the <div> for a <picture> and delete the gradient rules below. A meal
   service is judged on its food photos and these four cards are where
   that judgement happens. */
.meals { display: grid; gap: 1rem; margin-bottom: 2.6rem; }
@media (min-width: 640px) { .meals { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .meals { grid-template-columns: repeat(4, 1fr); gap: .9rem; } }

.meal {
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
  background: var(--white); display: flex; flex-direction: column;
  transition: transform .18s ease, box-shadow .18s ease;
}
.meal:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.meal-now { border-color: var(--accent); box-shadow: 0 18px 40px -28px rgba(255, 90, 31, .9); }

.meal-thumb {
  aspect-ratio: 4 / 3; display: grid; place-items: center;
  font-size: clamp(2.6rem, 9vw, 3.4rem); line-height: 1;
  border-bottom: 1px solid var(--line);
}
.meal-thumb span { filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .25)); }
.meal-thumb-1 { background: linear-gradient(140deg, #f7d7c2, #e8a97e); }
.meal-thumb-2 { background: linear-gradient(140deg, #f3c9b6, #d87a5a); }
.meal-thumb-3 { background: linear-gradient(140deg, #f6e2be, #e0b174); }
.meal-thumb-4 { background: linear-gradient(140deg, #f6e6b4, #d9ab4e); }

.meal-week {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .1em;
  font-size: .85rem; color: var(--accent-text); margin: 1.1rem 1.1rem .3rem;
}
.meal-now .meal-week::after { content: ' · cooking now'; }
.meal-name {
  font-family: var(--display); text-transform: uppercase; line-height: 1.02;
  font-size: 1.28rem; margin: 0 1.1rem .4rem;
}
.meal-desc { font-size: .93rem; color: var(--muted); margin: 0 1.1rem 1.2rem; }

/* ---------- section 9: the drop ----------
   A product release, not a cafeteria board. The dish gets its own
   dark slab; the rotation below it is deliberately quieter. */
.drop {
  background: var(--ink); color: #fff; border-radius: var(--radius);
  padding: clamp(1.5rem, 5vw, 2.6rem); margin-bottom: 2.6rem;
  box-shadow: 0 24px 50px -30px rgba(0, 0, 0, .85);
  border-left: 6px solid var(--accent);
}
.drop-kicker {
  font-size: .74rem; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .7rem;
}
.drop-name {
  font-family: var(--display); text-transform: uppercase; line-height: 1;
  font-size: clamp(2rem, 8vw, 3.4rem); margin-bottom: .35em;
}
.drop-desc { font-size: clamp(1.02rem, 2.6vw, 1.18rem); color: rgba(255, 255, 255, .8); max-width: 46ch; }
.drop-when {
  display: inline-block; margin: .4rem 0 0; padding: .35rem 1rem; border-radius: 999px;
  background: rgba(255, 255, 255, .08); border: 1px solid var(--line-dark);
  font-size: .85rem; font-weight: 700;
}
.subhead {
  font-family: var(--display); text-transform: uppercase; font-size: 1.15rem;
  letter-spacing: .04em; color: var(--muted); margin-bottom: 1rem;
}

/* ---------- section 12: the weekly load ----------
   One card per plan: what that student physically carries home each
   Sunday. Rendered by renderWeek() in js/main.js, so the weights can
   never drift from the plans. The container COUNT is the promise; how
   the week is split between them is operational and stays off the page.

   Styled for a LIGHT section. If these cards are ever moved back onto
   an ink band, the borders and label colours need the dark treatment. */
.containers {
  display: grid; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  margin-top: 2.6rem;
}
.container-card {
  border: 1px solid var(--line); border-radius: var(--radius); padding: 1.4rem 1rem;
  text-align: center; background: var(--paper);
  display: flex; flex-direction: column; align-items: center; gap: .3rem;
}
.container-card-anchor { border-color: var(--accent); background: rgba(255, 90, 31, .08); }
.container-illo { width: 74px; height: auto; margin-bottom: .5rem; }
.container-illo rect { fill: none; stroke: var(--ink); stroke-width: 2.4; }
.container-illo path { stroke: rgba(16, 16, 16, .35); stroke-width: 2.4; stroke-linecap: round; }
.container-card-anchor .container-illo rect { stroke: var(--accent); }
.container-name {
  font-size: .72rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted);
}
.container-card-anchor .container-name { color: var(--accent-text); }
.container-kg { font-family: var(--display); font-size: 2.2rem; line-height: 1; color: var(--ink); }
.container-card-anchor .container-kg { color: var(--accent-text); }
.container-lbl { font-size: .82rem; color: var(--muted); }

/* ---------- section 12: storage note ----------
   A .wrap inside a .wrap: the collection block above it runs the full
   width, this holding message does not want to. */
.storage-note { padding-inline: 0; margin-top: 2.4rem; }
.storage-note .subhead { margin-bottom: .8rem; }

/* ---------- section 14: social proof ----------
   The empty state is a real design element, not a gap waiting to be
   filled with something invented. See the note in index.html. */
.reviews-empty {
  border: 2px dashed var(--line); border-radius: var(--radius);
  padding: clamp(1.4rem, 5vw, 2.2rem); color: var(--muted);
  font-size: clamp(1rem, 2.5vw, 1.1rem);
}
.reviews-empty p:last-child { margin-bottom: 0; }
.reviews-empty-foot { color: var(--ink); font-weight: 600; }

/* Ready for real quotes - see the commented grid in index.html. */
.reviews { display: grid; gap: 1rem; }
@media (min-width: 720px) { .reviews { grid-template-columns: repeat(2, 1fr); } }
.review {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  border-left: 5px solid var(--accent); padding: 1.4rem 1.3rem;
}
.review blockquote { margin: 0 0 .8rem; font-size: 1.06rem; line-height: 1.5; }
.review blockquote p { margin: 0; }
.review-by {
  margin: 0; font-size: .82rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}

/* ---------- section 13: referral promotion ----------
   On the accent (orange) background, so every value here is a dark ink
   tone - var(--muted) and the white card treatments used elsewhere both
   fail contrast against orange. */
.refer-grid { display: grid; gap: 1.6rem; align-items: center; margin-bottom: 2.4rem; }
@media (min-width: 860px) { .refer-grid { grid-template-columns: 1.15fr .85fr; gap: 3rem; } }

.refer-lede { font-size: clamp(1.05rem, 2.8vw, 1.24rem); line-height: 1.5; }
.refer-lede strong { background: var(--ink); color: #fff; padding: .05em .35em; border-radius: 4px; }
.refer-copy p:last-child { margin-bottom: 0; }

.refer-price {
  background: var(--ink); color: #fff; border-radius: var(--radius);
  padding: 1.5rem 1.4rem; display: grid; gap: .2rem; justify-items: center;
  text-align: center; box-shadow: 0 20px 44px -26px rgba(0, 0, 0, .8);
}
.refer-was { font-size: .9rem; color: rgba(255, 255, 255, .6); }
.refer-was s { text-decoration-thickness: 2px; }
.refer-now {
  font-family: var(--display); font-size: clamp(3.2rem, 14vw, 4.6rem); line-height: 1;
  color: var(--amber);
}
.refer-sub { font-size: .9rem; color: rgba(255, 255, 255, .7); }
.refer-save {
  margin-top: .7rem; background: var(--accent); color: var(--ink);
  border-radius: 999px; padding: .35rem 1rem; font-size: .85rem; font-weight: 800;
}

/* The founding offer reuses .refer-grid / .refer-price, and adds a spec
   list. Ticks rather than bullets: this is what you get, not a summary. */
.found-specs { display: grid; gap: .45rem; margin: 0 0 1.2rem; font-size: 1.02rem; }
.found-specs li { position: relative; padding-left: 1.7rem; }
.found-specs li::before {
  content: ''; position: absolute; left: .1rem; top: .42em;
  width: .7rem; height: .38rem; border: 2px solid var(--ink);
  border-top: 0; border-right: 0; transform: rotate(-45deg);
}
.found-specs strong {
  background: var(--ink); color: #fff; padding: .05em .35em; border-radius: 4px;
}

.refer-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-bottom: 1.6rem; }
.refer-actions .btn { flex: 1 1 auto; min-width: 200px; }
@media (min-width: 620px) { .refer-actions .btn { flex: 0 0 auto; } }

/* --ink-2, not --muted: the site grey measures 2.3:1 on orange. Size alone
   is what makes this read as fine print here. */
.refer-terms { font-size: .84rem; color: var(--ink-2); max-width: 68ch; margin: 0; }

/* ---------- deflist / notice ---------- */
.deflist { margin: 0 0 1.5rem; display: grid; gap: .9rem; }
.deflist > div { display: grid; gap: .1rem; padding-bottom: .9rem; border-bottom: 1px solid var(--line); }
.deflist > div:last-child { border-bottom: 0; padding-bottom: 0; }
.deflist dt {
  font-size: .76rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--accent-text);
}
.deflist dd { margin: 0; font-size: 1.02rem; }
.notice {
  background: var(--ink); color: #fff; padding: 1.1rem 1.25rem; border-radius: var(--radius);
  font-size: .96rem; margin: 0;
}
.section-ink .notice { background: rgba(255, 255, 255, .07); }

/* ---------- trust ---------- */
.trust-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; }
@media (min-width: 720px) { .trust-grid { grid-template-columns: repeat(4, 1fr); } }
.trust-item {
  border: 1px solid var(--line-dark); border-radius: 10px; padding: .95rem 1rem;
  display: flex; flex-direction: column; gap: .15rem;
}
.trust-label { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted-dark); }
/* Clamped, not fixed: the price range is the longest value here
   ("R1,699.95–R2,799.95") and it has to survive a 360px phone. */
.trust-value {
  font-family: var(--display); font-size: clamp(1.05rem, 3.6vw, 1.35rem);
  overflow-wrap: anywhere;
}

/* ---------- FAQ ---------- */
.faq { border-top: 1px solid var(--line); }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-q {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.15rem .2rem; cursor: pointer; font-weight: 700; font-size: 1.03rem;
  list-style: none;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-chev { width: 20px; height: 20px; flex: none; color: var(--accent); transition: transform .2s ease; }
.faq-item[open] .faq-chev { transform: rotate(180deg); }
.faq-a { padding: 0 .2rem 1.25rem; color: var(--muted); margin: 0; max-width: 62ch; }

/* ---------- launch capacity band ----------
   Deliberately not a .section: it is a thin bridge between the FAQ and
   the form, and it should not get the reveal-on-scroll treatment that
   would make a capacity claim feel like a marketing flourish. */
.capacity { background: var(--amber); color: var(--ink); padding-block: clamp(2.2rem, 6vw, 3.2rem); }
.capacity-inner { text-align: center; }
.capacity-kicker {
  font-size: .76rem; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  margin-bottom: .4rem; opacity: .75;
}
.capacity-title {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .06em;
  font-size: clamp(1.3rem, 5vw, 1.9rem); margin-bottom: .8rem; line-height: 1.1;
}
.capacity-num {
  display: block; font-size: clamp(4rem, 20vw, 7rem); line-height: .9; letter-spacing: 0;
}
.capacity-body { max-width: 54ch; margin: 0 auto; font-size: .98rem; color: var(--ink-2); }

/* ---------- form ---------- */
.cta-price {
  font-family: var(--display); font-size: clamp(2.6rem, 12vw, 4rem); line-height: 1;
  color: var(--amber); margin: 1rem 0 .4rem;
}
.cta-price-from {
  font-family: var(--body); font-size: .8rem; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255, 255, 255, .5); vertical-align: .5em;
}
.cta-price-period { font-family: var(--body); font-size: 1rem; font-weight: 700; color: rgba(255, 255, 255, .65); }
.cta-support { color: var(--muted-dark); margin-bottom: 2.2rem; }

.form {
  background: rgba(255, 255, 255, .05); border: 1px solid var(--line-dark);
  border-radius: 18px; padding: clamp(1.15rem, 4vw, 2rem);
}
.field { margin-bottom: 1.15rem; border: 0; padding: 0; min-width: 0; }
.field-row { display: grid; gap: 0; }
@media (min-width: 640px) { .field-row { grid-template-columns: 1fr 1fr; gap: 0 1rem; } }

/* Direct children only. The chip/radio pills are labels nested inside
   .chips / .radios - a plain `.field label` selector outranks `.chip`
   on specificity and would flatten them back into block labels. */
.field > label, .field > legend {
  display: block; font-size: .84rem; font-weight: 700; letter-spacing: .02em;
  margin-bottom: .45rem; color: rgba(255, 255, 255, .9); padding: 0;
}
.req { color: var(--accent); }
.opt { font-weight: 500; color: rgba(255, 255, 255, .68); }

.field input[type="text"], .field input[type="tel"], .field input[type="email"],
.field select, .field textarea {
  width: 100%; padding: .85rem .95rem; border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, .22); background: rgba(0, 0, 0, .35); color: #fff;
  transition: border-color .16s ease, background .16s ease;
}
.field textarea { resize: vertical; }
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .8rem center; background-size: 18px;
  padding-right: 2.4rem;
}
.field select option { color: #111; background: #fff; }
.field input::placeholder, .field textarea::placeholder { color: rgba(255, 255, 255, .38); }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--accent); background: rgba(0, 0, 0, .5); outline: none;
  box-shadow: 0 0 0 3px rgba(255, 90, 31, .28);
}
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: #ff6b6b; }

.err { color: #ff8a80; font-size: .82rem; margin: .35rem 0 0; min-height: 0; }
.err:empty { display: none; }

/* chips + radios */
.chips, .radios { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip, .radio {
  display: inline-flex; align-items: center; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .24); border-radius: 999px;
  /* .68rem keeps the pill at ~44px tall - the minimum comfortable
     touch target, and most of this traffic is phones. */
  padding: .68rem 1.15rem; min-height: 44px; font-size: .9rem; font-weight: 600; margin: 0;
  transition: background .16s ease, border-color .16s ease, color .16s ease;
  color: rgba(255, 255, 255, .85);
}
.chip input, .radio input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip:hover, .radio:hover { border-color: rgba(255, 255, 255, .55); }
.chip:has(input:checked), .radio:has(input:checked) {
  background: var(--accent); border-color: var(--accent); color: var(--ink);
}
.chip:has(input:focus-visible), .radio:has(input:focus-visible) {
  box-shadow: 0 0 0 3px rgba(255, 197, 61, .5);
}
fieldset.has-error .chips, fieldset.has-error .radios { padding: .3rem; border-radius: 12px; box-shadow: 0 0 0 1px #ff6b6b; }

/* Plan radios carry a price under the name, so they are stacked blocks
   rather than pills - a two-line pill is not a pill. */
.radios-plans { display: grid; gap: .5rem; }
@media (min-width: 620px) { .radios-plans { grid-template-columns: repeat(2, 1fr); } }
.radio-plan {
  flex-direction: column; align-items: flex-start; justify-content: center;
  border-radius: 12px; padding: .8rem 1.1rem; gap: .1rem;
}
.radio-main { font-weight: 700; }
.radio-sub { font-size: .8rem; opacity: .7; font-weight: 500; }
.radio-plan:has(input:checked) .radio-sub { opacity: .9; }

/* consent */
.consent .check { display: flex; align-items: flex-start; gap: .7rem; font-weight: 500; font-size: .95rem; cursor: pointer; }
.consent .check input {
  appearance: none; width: 1.35rem; height: 1.35rem; flex: none; margin-top: .1rem;
  border: 2px solid rgba(255, 255, 255, .4); border-radius: 6px; cursor: pointer;
  background: rgba(0, 0, 0, .3); transition: background .15s ease, border-color .15s ease;
}
.consent .check input:checked {
  background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4 10-11'/%3E%3C/svg%3E") center/70% no-repeat;
  border-color: var(--accent);
}

/* honeypot */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* submit states */
#submit-btn { margin-top: .6rem; position: relative; }
.spinner { display: none; width: 1.05rem; height: 1.05rem; border-radius: 50%;
  border: 2.5px solid rgba(255, 255, 255, .4); border-top-color: #fff; animation: spin .7s linear infinite; }
#submit-btn.is-loading .spinner { display: inline-block; }
#submit-btn.is-loading .btn-label { opacity: .8; }
@keyframes spin { to { transform: rotate(360deg); } }

.form-status { margin: .9rem 0 0; font-size: .92rem; text-align: center; color: var(--muted-dark); }
.form-status.is-error { color: #ff8a80; font-weight: 600; }
.form-status:empty { display: none; }

.setup-banner {
  background: rgba(255, 197, 61, .14); border: 1px solid var(--amber); color: var(--amber);
  padding: .85rem 1rem; border-radius: 10px; font-size: .86rem; margin-bottom: 1.4rem;
}
.setup-banner code { background: rgba(0, 0, 0, .35); padding: .1em .35em; border-radius: 4px; }

/* ---------- success ---------- */
.success { text-align: center; }
.success:focus { outline: none; }
.success-mark {
  width: 76px; height: 76px; margin: 0 auto 1.4rem; border-radius: 50%;
  background: var(--accent); color: #fff; display: grid; place-items: center;
  animation: pop .45s cubic-bezier(.2, 1.4, .5, 1) both;
}
.success-mark svg { width: 42px; height: 42px; }
@keyframes pop { from { transform: scale(.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.success .section-lede { margin-inline: auto; }
.success-list {
  display: inline-grid; gap: .55rem; text-align: left; margin: 0 auto 2rem; padding: 0;
}
.success-list li { position: relative; padding-left: 1.8rem; color: rgba(255, 255, 255, .82); }
.success-list li::before {
  content: ''; position: absolute; left: 0; top: .42em; width: .75rem; height: .75rem;
  border-radius: 50%; background: var(--amber);
}
.success-refer {
  max-width: 52ch; margin: 0 auto 1.8rem; padding: 1rem 1.2rem;
  border: 1px solid var(--amber); border-radius: var(--radius);
  background: rgba(255, 197, 61, .1); color: rgba(255, 255, 255, .88); font-size: .95rem;
}
.success-refer strong { color: var(--amber); }
.success-actions { display: flex; flex-wrap: wrap; gap: .7rem; justify-content: center; margin-bottom: 1.2rem; }

/* ---------- footer ---------- */
.site-footer { background: #0a0a0a; color: rgba(255, 255, 255, .75); padding-top: 3rem; }
.footer-inner { display: grid; gap: 2rem; padding-bottom: 2.4rem; }
@media (min-width: 820px) { .footer-inner { grid-template-columns: 1.4fr 1fr 1fr; } }
.logo-lockup-footer { height: 34px; margin-bottom: .7rem; }
.footer-tag { font-family: var(--display); text-transform: uppercase; color: var(--accent); margin-bottom: .6rem; }
.footer-meta { font-size: .88rem; color: rgba(255, 255, 255, .5); max-width: 40ch; margin: 0 0 .8rem; }
/* Real NAP block - local search cross-references this against the
   JSON-LD and your Google Business Profile, so keep all three identical. */
.footer-address { font-style: normal; font-size: .88rem; color: rgba(255, 255, 255, .5); line-height: 1.7; }
.footer-nav { display: grid; gap: .35rem; font-size: .92rem; }
/* Padding rather than gap: it grows the tappable area itself, not just
   the space between links. */
.footer-nav a, .footer-contact a {
  text-decoration: none; color: rgba(255, 255, 255, .72);
  padding-block: .3rem; display: inline-block;
}
.footer-nav a:hover, .footer-contact a:hover { color: var(--accent); }
.footer-contact { display: grid; gap: .35rem; font-size: .92rem; align-content: start; justify-items: start; }

.footer-bottom {
  border-top: 1px solid rgba(255, 255, 255, .1); padding-block: 1.3rem;
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; justify-content: space-between;
  font-size: .82rem; color: rgba(255, 255, 255, .68);
}
.footer-bottom p { margin: 0; }
.powered a { color: rgba(255, 255, 255, .78); text-decoration: underline; text-underline-offset: 3px; }
.powered a:hover { color: var(--accent); }

/* ---------- sticky CTA (mobile) ---------- */
.sticky-cta {
  position: fixed; left: .75rem; right: .75rem; bottom: calc(.75rem + env(safe-area-inset-bottom));
  z-index: 80; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  background: var(--accent); color: var(--ink); text-decoration: none; font-weight: 800;
  padding: .95rem 1.3rem; border-radius: 999px; box-shadow: 0 14px 34px -14px rgba(0, 0, 0, .85);
  transform: translateY(140%); transition: transform .28s cubic-bezier(.2, .8, .3, 1);
}
.sticky-cta.is-visible { transform: translateY(0); }
.sticky-price { font-family: var(--display); font-size: 1.15rem; white-space: nowrap; }
@media (min-width: 800px) { .sticky-cta { display: none; } }

/* ============================================================
   TERMS AND CONDITIONS (terms.html)
   ------------------------------------------------------------
   Long-form reading, so this block does the opposite of the rest
   of the site: narrower measure, smaller display type, more
   leading. A legal page nobody can read is not a legal page.
   ============================================================ */
.legal-head { padding-block: clamp(2.4rem, 7vw, 4.2rem) 0; }
.legal-head h1 {
  font-family: var(--display); font-size: clamp(2.3rem, 7vw, 3.6rem);
  text-transform: uppercase; letter-spacing: .01em;
}
.legal-version {
  font-size: .95rem; color: var(--muted); margin-bottom: 1.2rem;
  padding-bottom: 1.2rem; border-bottom: 1px solid var(--line);
}
.legal-intro { max-width: 62ch; font-size: 1.05rem; }

.legal-toc {
  max-width: 68ch; background: var(--paper); border-radius: var(--radius);
  padding: 1.2rem 1.4rem; margin-bottom: .5rem;
}
.legal-toc h2 {
  font-size: .72rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); font-family: var(--body); font-weight: 800; margin-bottom: .7rem;
}
.legal-toc ol { list-style: decimal; padding-left: 1.3rem; columns: 2; column-gap: 2rem; }
.legal-toc li { margin-bottom: .3rem; font-size: .92rem; break-inside: avoid; }
.legal-toc a { color: var(--ink); text-decoration: none; }
.legal-toc a:hover { color: var(--accent-text); text-decoration: underline; }
@media (max-width: 640px) { .legal-toc ol { columns: 1; } }

.legal { padding-block: clamp(2rem, 6vw, 3.4rem); }
.legal-body { max-width: 68ch; }
.legal-body h2 {
  font-family: var(--body); font-weight: 800; font-size: 1.18rem; line-height: 1.35;
  margin: 2.2rem 0 .7rem; scroll-margin-top: 84px;
}
.legal-body h2:first-child { margin-top: 0; }
.legal-body p { font-size: 1rem; line-height: 1.72; }
.legal-body a { color: var(--accent-text); }

.legal-ul, .legal-ol { margin: 0 0 1em; padding-left: 1.4rem; }
.legal-ul { list-style: disc; }
.legal-ol { list-style: decimal; }
.legal-ul li, .legal-ol li { margin-bottom: .45rem; line-height: 1.65; }

/* The clauses a customer is most likely to be surprised by later.
   Marked so they are found while skimming, which is the only way
   most people read terms at all. */
.legal-flag {
  border-left: 4px solid var(--accent); background: var(--paper);
  padding: .85rem 1rem; border-radius: 0 10px 10px 0; margin-bottom: 1.1rem;
}
.legal-foot {
  margin-top: 2.4rem; padding-top: 1.4rem; border-top: 1px solid var(--line);
  font-size: .92rem; color: var(--muted);
}

/* ============================================================
   ONBOARDING (onboarding.html)
   ------------------------------------------------------------
   A form somebody fills in once, on a phone, from an email link.
   Every control is at least 44px tall and every acknowledgement
   is its own card, so nothing important can be ticked by accident
   while scrolling past it.
   ============================================================ */
body.onboarding { background: var(--paper-2); }

.ob-header { background: var(--ink); color: #fff; }
.ob-header-inner { display: flex; align-items: center; gap: .9rem; min-height: 66px; flex-wrap: wrap; }
.ob-header .logo-lockup { width: 132px; height: auto; }
.ob-badge {
  font-size: .66rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
  background: var(--accent); color: var(--ink); padding: .3rem .6rem; border-radius: 999px;
}

.ob-wrap { max-width: 660px; padding-block: clamp(1.4rem, 5vw, 2.6rem) 3rem; }

.ob-card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: clamp(1.15rem, 4vw, 1.7rem); margin-bottom: 1rem;
}
.ob-card h1 {
  font-family: var(--display); font-size: clamp(1.7rem, 5.5vw, 2.3rem);
  text-transform: uppercase; line-height: 1.05;
}
.ob-lead { font-size: 1.03rem; }
.ob-meta { font-size: .87rem; color: var(--muted); margin-bottom: 0; }
.ob-help { font-size: .88rem; color: var(--muted); margin-bottom: .8rem; }
.ob-label { display: block; font-size: .85rem; font-weight: 700; margin: .9rem 0 .35rem; }
.ob-intro { border-left: 4px solid var(--accent); }

.ob-fieldset { border: 1px solid var(--line); margin: 0 0 1rem; }
.ob-fieldset legend {
  font-weight: 800; font-size: 1.06rem; line-height: 1.35; padding: 0;
  display: flex; align-items: baseline; gap: .55rem;
}
.ob-step {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.65rem; height: 1.65rem; border-radius: 999px;
  background: var(--ink); color: #fff; font-size: .8rem; font-weight: 800; flex: none;
}
.ob-fieldset.has-error { border-color: #e6796b; box-shadow: 0 0 0 3px rgba(230, 121, 107, .18); }
.ob-fieldset-risk { border-color: var(--amber); border-width: 2px; }

/* plan + week choices */
.ob-plans, .ob-weeks { display: grid; gap: .55rem; margin-top: .9rem; }
.ob-plan, .ob-week {
  display: flex; align-items: center; gap: .8rem; cursor: pointer;
  border: 1.5px solid var(--line); border-radius: 12px;
  padding: .9rem 1rem; min-height: 56px; background: #fbfaf7;
}
.ob-plan:hover, .ob-week:hover { border-color: rgba(255, 90, 31, .55); }
.ob-plan input, .ob-week input { width: 1.25rem; height: 1.25rem; flex: none; accent-color: var(--accent); }
.ob-plan:has(input:checked), .ob-week:has(input:checked) {
  border-color: var(--accent); background: #fff5f0;
}
.ob-plan:focus-within, .ob-week:focus-within { outline: 3px solid var(--accent); outline-offset: 2px; }

.ob-plan-body { display: grid; grid-template-columns: 1fr auto; gap: .1rem .8rem; width: 100%; align-items: baseline; }
.ob-plan-name { font-weight: 800; font-size: 1.05rem; }
.ob-plan-price { font-weight: 800; text-align: right; white-space: nowrap; }
.ob-plan-price s { color: var(--muted); font-weight: 400; }
.ob-plan-grams { font-size: .88rem; color: var(--muted); }
.ob-plan-promo {
  grid-column: 1 / -1; font-size: .75rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .07em; color: var(--accent-text);
}
.ob-week-note { display: block; font-size: .84rem; color: var(--muted); }

/* acknowledgement checkboxes - always unticked on load, one per card */
.ob-check {
  display: flex; gap: .75rem; align-items: flex-start; cursor: pointer;
  background: var(--paper); border-radius: 10px; padding: .85rem 1rem;
  margin-top: .9rem; min-height: 52px;
}
.ob-check input { width: 1.3rem; height: 1.3rem; flex: none; margin-top: .1rem; accent-color: var(--accent); }
.ob-check:focus-within { outline: 3px solid var(--accent); outline-offset: 2px; }
.ob-check span { font-size: .96rem; line-height: 1.5; }

.ob-form textarea {
  width: 100%; padding: .8rem .9rem; border: 1px solid var(--line); border-radius: 10px;
  background: #fbfaf7; font-family: inherit; resize: vertical; min-height: 100px;
}
.ob-form textarea:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px rgba(255, 90, 31, .2); }
.ob-form textarea:disabled { background: #f1efea; color: var(--muted); }

.ob-notice { border-radius: 10px; padding: .9rem 1rem; margin: .9rem 0; font-size: .95rem; line-height: 1.6; }
.ob-notice-amber { background: #fff8ed; border-left: 4px solid var(--amber); }
.ob-notice-risk { background: var(--paper); border-left: 4px solid var(--accent); }
.ob-notice p { margin: 0 0 .7rem; }
.ob-notice p:last-child { margin-bottom: 0; }

.ob-list { margin: .5rem 0 0; }
.ob-list li { position: relative; padding-left: 1.2rem; margin-bottom: .5rem; line-height: 1.6; }
.ob-list li::before { content: "\2022"; position: absolute; left: 0; color: var(--accent); font-weight: 800; }

.ob-err { color: #a5271a; font-size: .88rem; font-weight: 600; margin: .6rem 0 0; }
.ob-err:empty { display: none; }
.ob-status { margin: .8rem 0 0; font-size: .92rem; }
.ob-status.is-error { color: #a5271a; font-weight: 600; }

.ob-submit-card { position: sticky; bottom: .6rem; box-shadow: var(--shadow); }
.ob-submit-card .btn { min-height: 54px; }
.ob-submit-card .btn.is-loading .spinner { display: inline-block; }
.ob-submit-card .btn.is-loading .btn-label { opacity: .8; }

.ob-footer {
  background: var(--ink); color: rgba(255, 255, 255, .62);
  padding-block: 1.4rem; font-size: .85rem; text-align: center;
}
.ob-footer a { color: var(--amber); }
.ob-footer p { margin: 0; }
