/* Bite — public pages.
   Follows the app's own rules (Bite/CLAUDE.md, docs/brand-guide.md): hierarchy
   from size and weight, white paper and two inks, and space rather than lines —
   with one named exception, below.

   ── THE BRAND PASS, 2026-09-25 (analysis/brand/README.md, phase 6) ─────────
   The site follows the app onto paper and two inks. INK (#1C1C1E) is every
   line, all type and every button; CHERRY (#D9232E, --ink2; Sunflower until 2026-09-28) prints only
   under a drawing, or as a whole ground where a drawing stands on it (the
   teaser's close, the invite card). Cherry and cream are gone: the old
   --cherry* tokens became --ink/--ink-pressed/--on-ink, and the five stocks
   resolve to the neutral well, as they do in Theme.swift. The mark is the
   bitten b, generated into each page by analysis/brand/mark_export.py
   between <!-- generated:mark --> comments; never hand-edit those.

   ── THE 2026-09-17 PASS ────────────────────────────────────────────────────
   Nate: "this is simple text. it doesnt have to be expressive or anything, but
   lets make this a lot cleaner like someone actually took the time to make this
   look professional."

   It read as raw text for four specific reasons, and each is a drift rather
   than a taste:

   1. NO WEBFONT AT ALL. The stack was `-apple-system` alone, so a page opened
      on anything but an Apple device rendered in Segoe UI or Roboto — the two
      typefaces that most read as "unstyled document". Figtree Bold (Bricolage
      Grotesque until 2026-10-02) is the app's own display face, it is SIL
      OFL, and it is already in this repo at `Bite/Fonts/`. It is served from
      `/fonts/` now.

   2. THE PASTELS WERE DEAD TOKENS. `--butter`, `--lavender`, `--mint`,
      `--blush` and `--peach` were replaced one-for-one by the PAPER STOCKS on
      2026-09-16 (brand-guide §2) — cream, oat, kraft, sage, slate — because
      Nate read five hues tinted to one lightness as "ai generated ... doesnt
      feel intentional". The front page was still serving a butter card.

   3. NO ELEVATION. The app's idiom for an ask is a PAPER CARD: white on the
      white page, the resting `.card` shadow, and no stroke. This sheet had no
      shadow tokens at all, so every card was a flat grey rectangle — the exact
      "fill standing in for a picture" the paper-stock argument is about.

   4. NOTHING SET THE PAGE'S SHAPE. One column of 17px text from the top of the
      viewport to the bottom. The front page has a COVER now, which is the
      lockup `og.png` has always been (cream on full-bleed cherry), and the
      legal pages are DOCUMENTS with a repeating unit.

   ── THE ONE LINE THIS SHEET DRAWS ──────────────────────────────────────────
   `--hairline`, on the legal pages only, above each `h2`. The no-lines rule is
   real and `AppColors.hairline` is its one licensed exception, granted by Nate
   on 2026-09-15: "id be open to introducing lines to provide structure given we
   are intentional w it and not look like ai." Theme.swift's argument is that a
   REPEATING UNIT — same shape, an edge at each end — is the thing spacing alone
   cannot buy, and a twelve-section legal document is that argument's strongest
   case. Warm (#E4E2E0), never Apple's cool separator, at a full point so it
   reads as drawn. Above each section and never under the last.

   It does NOT appear on the front page, which has no repeating unit to build.

   ── SCOPED BY BODY CLASS, ON PURPOSE ───────────────────────────────────────
   `body.home`, `body.doc` and `body.invite` (api/plan.js) each get their own
   layout. That is what lets the front page go full-bleed without touching the
   invite page's padding, which it inherits from `body` and which broke the one
   time a layout change was made globally. A new page picks a class or gets the
   plain document shape. */

/* ── The display face ──────────────────────────────────────────────────────
   ONE WEIGHT, AND ONLY ON TITLES (ExtraBold is the word "bite" alone). The
   app confines its cover face, Figtree, to `coverTitle`
   and reversed three attempts to spread it onto main screens — but that rule
   governs app SCREENS, and brand-guide §9 scopes this site as "outside the
   app". The precedent is the portfolio case study, which uses it as its
   display face and is live at rev 5. Body copy stays the system stack, exactly
   as in the app.

   `swap`, so the page renders in the fallback immediately and reflows once —
   a title is the one thing worth a reflow, and 23 KB should never hold up a
   privacy policy somebody opened to read. */
@font-face {
  font-family: "Figtree";
  src: url("/fonts/Figtree-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Figtree";
  src: url("/fonts/Figtree-ExtraBold.woff") format("woff");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* LIGHT ONLY, like the app. There used to be a prefers-color-scheme: dark
     block here that inverted everything and invented a salmon cherry and a
     brown cream that exist nowhere in Theme.swift. api/plan.js had already
     re-pinned light for the invite page on exactly that argument; the static
     pages just never caught up (2026-09-07). */
  color-scheme: light;

  --ground:  #FFFFFF;
  --surface: #F3F2F1;   /* AppColors.surfaceSecondary, the well */

  /* THE SECOND INK. Under a drawing, or a poster's whole ground under one.
     Never text, never a panel, never a button. */
  --ink2:    #D9232E;

  /* THE RETIRED STOCKS resolve to the well, as AppGround's do in the app.
     Kept as names because the teaser's made faces and .card.<stock> read
     them; nothing new should. */
  --cream:  #F3F2F1;
  --warm:   #F3F2F1;
  --oat:    #F3F2F1;
  --kraft:  #F3F2F1;
  --sage:   #F3F2F1;
  --slate:  #F3F2F1;

  --ink:     #1C1C1E;
  --ink-2:   #6B6B6F;   /* AppColors.textSecondary */
  /* The one grey with no app twin. It is 3.66:1 on white, which clears the
     3:1 large-text floor and misses the 4.5:1 body floor — so it is used only
     where type is DECORATIVE or oversized. */
  --ink-3:   #8A857E;
  /* Muted copy on the well. It was a warm brown for cream; on the neutral
     well the app's own secondary passes (4.9:1). */
  --warm-ink:#6B6B6F;

  /* The one fill for the one affirmative action: ink, white label. */
  --ink-pressed: #3A3A3C;   /* brandPrimaryPressed */
  --on-ink:  #FFFFFF;

  /* AppColors.hairline. See the header for the whole of its licence. */
  --hairline: #E4E2E0;

  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --display: "Figtree", var(--sans);

  /* AppShadow, the app's two rungs and no third, re-tuned for a screen you sit
     back from: the app's single 12/4 blur at 6% disappears at desktop distance,
     so each rung is a contact shadow plus a soft one. Same opacities, same
     intent. These are the portfolio case study's values, which are downstream
     of Theme.swift and already judged. */
  --shadow-card:   0 1px 2px rgba(28, 28, 30, 0.06), 0 8px 24px rgba(28, 28, 30, 0.10);
  --shadow-raised: 0 2px 4px rgba(28, 28, 30, 0.08), 0 18px 48px rgba(28, 28, 30, 0.16);

  /* AppRadius. `xl` is the postcard and door-card radius. */
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-sheet: 28px;
  --r-pill: 100px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding: 0 16px 96px;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.wrap { max-width: 680px; margin: 0 auto; }

/* The rhythm is the app's: 32 between blocks about different things, 16
   between items inside one, 4 for a label and its value. */
header.masthead {
  padding: 40px 0 8px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* THE LOCKUP: the mark beside the word, one rule for every page. The mark is
   the bitten b, a stroke in currentColor, as tall as the word and as wide as
   its own viewBox says. */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.2px;
  color: var(--ink);
  text-decoration: none;
}
.mark { height: 22px; width: auto; color: var(--ink); display: block; }

h1 {
  font-family: var(--display);
  font-size: clamp(32px, 5.2vw, 44px);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.06;
  margin: 0;
  text-wrap: balance;
}

h2 {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.3px;
  margin: 32px 0 0;
  text-wrap: balance;
}

h3 {
  font-size: 17px;
  font-weight: 600;
  margin: 24px 0 0;
}

p, ul { margin: 12px 0 0; }
ul { padding-left: 20px; }
li { margin-top: 4px; color: var(--ink-2); }
li strong { color: var(--ink); font-weight: 600; }
p { color: var(--ink-2); }
p.lede { font-size: 20px; line-height: 1.55; color: var(--ink-2); margin-top: 16px; }
.stamp { font-size: 13px; color: var(--ink-2); margin-top: 8px; }

a { color: var(--ink); text-underline-offset: 2px; }
a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── Cards ────────────────────────────────────────────────────────────────
   A CARD IS PAPER BY DEFAULT. brand-guide §2: "An ASK is a PAPER card: white
   on the white page with the resting card shadow and no stroke — because a
   pastel with nothing of yours in it is a fill standing in for a picture."
   Every card on this site is an ask or a summary, so paper is the default and
   a stock is the thing you have to choose. */
.card {
  background: var(--ground);
  border-radius: var(--r-xl);
  padding: 24px;
  margin-top: 24px;
  box-shadow: var(--shadow-card);
}
.card p:first-child { margin-top: 0; }
.card p { color: var(--ink-2); }
.card strong { color: var(--ink); font-weight: 600; }

/* A stock is named, never derived. Ink passes on all five (11.9:1+); the muted
   grey does not, so copy on a stock is ink or the warm muted, never ink-2. */
.card.cream, .card.warm { background: var(--cream); box-shadow: none; }
.card.cream p, .card.warm p, .card.cream li, .card.warm li { color: var(--warm-ink); }
.card.oat   { background: var(--oat);   box-shadow: none; }
.card.kraft { background: var(--kraft); box-shadow: none; }
.card.sage  { background: var(--sage);  box-shadow: none; }
.card.slate { background: var(--slate); box-shadow: none; }
.card.oat p, .card.kraft p, .card.sage p, .card.slate p,
.card.oat li, .card.kraft li, .card.sage li, .card.slate li { color: var(--ink); }
.card.cream strong, .card.warm strong, .card.oat strong,
.card.kraft strong, .card.sage strong, .card.slate strong { color: var(--ink); }

/* AppControl.primaryHeight: the pill, ink, one per page. */
.cta {
  display: inline-block;
  background: var(--ink);
  color: var(--on-ink);
  font-size: 17px;
  font-weight: 600;
  text-decoration: none;
  padding: 15px 28px;
  border-radius: var(--r-pill);
  margin-top: 8px;
}
.cta:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

footer {
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  font-size: 13px;
}
footer a { color: var(--ink-2); text-decoration: none; }
footer a:hover { color: var(--ink); text-decoration: underline; }

/* ══ body.doc — privacy and terms ═════════════════════════════════════════
   A DOCUMENT, NOT A POSTER — which is api/plan.js's own distinction, read the
   other way round. What these two pages needed was not decoration but a
   repeating unit: twelve sections of one shape, each with an edge, so the eye
   can find the section it came for. See the header for the hairline's licence.

   The rule sits ABOVE each section and never under the last, which is
   AboutProfileSheet's rule applied to a page instead of a sheet. */
body.doc header.masthead { padding-bottom: 0; }

body.doc h2 {
  margin-top: 44px;
  padding-top: 28px;
  border-top: 1px solid var(--hairline);
}
/* A sub-section belongs to the section above it and takes no rule of its own:
   a rule between `h3`s would make seven of them read as seven sections. */
body.doc h3 { margin-top: 28px; }

/* The lede and the summary card belong to the masthead, so the first rule
   falls under them rather than between the title and its own summary. */
body.doc .card { margin-top: 28px; }
