/* ─────────────────────────────────────────────────────────────────────────────
   Gushi — the tokens. One palette, one type scale, read by every web surface.

   THIS FILE EXISTS BECAUSE THERE ARE NOW TWO WEB PRODUCTS. The marketing site
   (site.css) and the Teaching Platform (platform.css) are different designs
   with different jobs, and the one thing they must never disagree about is
   what colour anything is. `docs/brand.md` tracks this palette across the iOS
   app, the story-art brief and the web, and `GushiUITests/PaletteTests.swift`
   asserts ΔE2000 separation and WCAG AA contrast on the app's copy of it — so a
   second, drifting copy of these hexes on the web was the obvious way to make
   that test a liar.

   It was lifted verbatim out of site.css. Nothing was renamed and no value
   changed, so the site renders identically; the only new thing is the growth
   ramp at the bottom, which nothing on the marketing site uses.

   LINK IT FIRST. Both stylesheets are plain <link> elements rather than an
   @import chain, because @import costs a serial round trip before a single
   pixel can paint, and these pages are meant to be fast on a school's wifi.
   ──────────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Ink. The app's own ground. Absolute; never remapped. ──────────────── */
  --ink: #15140F;
  --ink-sunken: #1B1A14;
  --ink-card: #1F1D17;
  /* THE THIRD SURFACE. `Theme.swift:18 raised` — the step the app puts under a
     chip, a segmented control, a nav row that is selected and the track of a
     ring. It was missing here, so the Learning Platform had page and card and
     had to fake the third one with a hairline or a tint; docs/brand.md now
     lists this file as a consumer of it. */
  --ink-raised: #28251D;
  --ink-fg: #ECE6D8;
  --ink-fg-2: #A39B8B;
  --ink-muted: #948B7A;               /* was #6F685B — 3.34:1, failed AA on ink */
  --ink-hair: rgba(236, 230, 216, .12);
  --ink-seal-text: #E9A08F;           /* 8.68:1 — the accent as TEXT, not as fill */

  /* ── Paper. The warm light ground for reading. ─────────────────────────── */
  --paper: #F4F1E9;
  --paper-sunken: #EDE9DF;
  --paper-card: #FFFDF8;
  /* The same third surface on the light ground, where the ramp runs the other
     way: the card is the LIGHTEST thing on paper, so "raised" is a warm step
     back towards the page rather than away from it. A chip that is lighter than
     a near-white card is a chip nobody can see. */
  --paper-raised: #F1ECE0;
  --paper-fg: #1A1813;
  --paper-fg-2: #5B5546;
  --paper-muted: #6F685B;             /* was #8A8271 — 3.38:1, failed AA on paper */
  --paper-hair: rgba(26, 24, 19, .14);
  --paper-seal-text: #A83A25;         /* 5.64:1 — #C8452E as a link is 4.29:1 and fails */

  /* ── Seal red. One voltage colour, and it ignores the scheme by design.
        Twice per page at most: the 故事 chop, and the one primary button.
        Scarcity is what gives it weight — see docs/brand.md. ─────────────── */
  --seal: #C8452E;
  --seal-press: #D8512F;
  --seal-on: #FFFFFF;                 /* 4.84:1 on seal */
  --seal-soft: rgba(200, 69, 46, .12);

  /* ── The five tone colours. Fixed everywhere pinyin appears, in the app and
        here, because that consistency is the point of the system. ────────── */
  --t1: #D85C50;
  --t2: #E0A23C;
  --t3: #5FA86A;
  --t4: #5B8BC9;
  --t5: #8C857A;
  --jade: #5FA86A;
  --amber: #E0A23C;

  /* ── The two story-highlight hues that are not tones. ───────────────────
        A story wash has four categories and only two of them can borrow from
        the list above: the meaning takes warm gold (--amber) and the tone
        archetype takes the character's own tone. The other two need their own
        hue, and these are the app's, to the byte — `Highlight.base(tone:)` in
        GushiUI/Theme.swift. Kept here rather than in learn.css because
        docs/brand.md tracks one palette across four consumers and a hex that
        lives in two files drifts in one of them. */
  --violet: #9A7BD0;                  /* a building block you already know */
  --rose: #D9789E;                    /* the sound hook */

  /* ── Scheme: PAPER, always. ─────────────────────────────────────────────
        This used to follow prefers-color-scheme, which meant anyone with their
        OS in dark mode saw the ink version and never the design that was
        actually being worked on. The site is a light document; the app is the
        dark one. The ink tokens above stay because docs/brand.md tracks them
        as one palette across four consumers — nothing here resolves to them.
        Re-enabling dark is one @media block, kept at the bottom of this file. */
  --bg: var(--paper);
  --bg-sunken: var(--paper-sunken);
  --card: var(--paper-card);
  --fg: var(--paper-fg);
  --fg-2: var(--paper-fg-2);
  --muted: var(--paper-muted);
  --hair: var(--paper-hair);
  --raised: var(--paper-raised);
  --seal-text: var(--paper-seal-text);
  --shadow: 0 1px 2px rgba(26, 24, 19, .04), 0 12px 30px -24px rgba(26, 24, 19, .3);

  /* ── The document grid ─────────────────────────────────────────────────
        Every page is one grid: a narrow RAIL carrying the section number and
        label, and a wide COLUMN carrying the heading and the content. A
        hairline runs across BOTH at the top of every row, which is the thing
        that makes the page read as a document rather than as a stack of
        centred cards.

        --measure still caps running text inside the column; the column itself
        is wider so a table has somewhere to go. */
  --pad: clamp(16px, 3.4vw, 48px);      /* the page's own margin, fluid */
  --maxw: 1560px;                        /* only stops it on a very wide display */
  /* --rail and --gutter used to size the two-column section grid. That grid is
     gone (see "THE STICKY RAIL IS GONE" in site.css): every section is one
     full-width column with its number and label in a strap above the heading.
     Nothing reads these any more, and a token nothing reads is a trap for the
     next person who assumes it is wired up. */

  --measure: 66ch;                       /* running text, in characters not pixels */
  --doc: var(--maxw);
  --column: var(--maxw);
  --wide: var(--maxw);
  --radius: clamp(14px, 1.6vw, 22px);
  --section: clamp(48px, 6.4vw, 104px);

  /* ── The two faces ──────────────────────────────────────────────────────
     A TOKEN RATHER THAN A LITERAL, and Chinese is the reason. The display
     face is Fraunces, which has no CJK coverage at all — so on a Chinese page
     every heading fell past Fraunces, past Georgia, and landed on whatever
     the reader's system calls `serif`. That is a different face at a
     different optical size next to the Latin word "Gushi" in the same line.

     Per-glyph fallback is what fixes it: Fraunces still sets every Latin
     letter, and Noto Serif SC — already loaded for the syllabus tables, so it
     costs nothing new — picks up the hanzi. The stack is switched below, on
     `html[lang|="zh"]`, rather than being made global, because naming a CJK
     face on the English and German pages would change which font renders a
     stray 好 in a gloss. */
  --serif: 'Fraunces', Georgia, serif;
  --serif-hz: 'Noto Serif SC', 'Songti SC', serif;

  /* Type. One scale, every language.
     --fs-display is the door only. Everywhere else uses --fs-h1, because
     /teaching's German H1 already runs to three lines and the display size
     would make it four. */
  --fs-display: clamp(40px, 7.4vw, 104px);
  --fs-h1: clamp(32px, 4.4vw, 60px);
  --fs-h2: clamp(24px, 2.6vw, 38px);
  --fs-h3: clamp(18px, 1.4vw, 22px);
  --fs-lead: clamp(17px, 1.4vw, 22px);
  --fs-body: clamp(16px, 1.05vw, 18px);
  --fs-small: clamp(14.5px, .95vw, 16px);
  --fs-fine: clamp(13px, .85vw, 14.5px);

  color-scheme: light;
/* ── The growth ramp, for the platform's data. Paper tints of the jade above.
      `docs/brand.md` carries a growth ramp already, but its four steps climb
      out of INK (#20301C -> #8FCD72) and the platform sits on paper, where the
      dark end of that ramp is the loudest thing on the page rather than the
      quietest.

      These are the same colour, mixed toward --paper-sunken at 25/50/75/100 %.
      No new hue enters the palette, which is the whole rule: the ramp is a
      derivation of jade, not a fifth accent. It is SEQUENTIAL because the thing
      it encodes — how well a learner knows something — is one quantity on one
      axis. Encoding it categorically would need four unrelated hues, and the
      first question a teacher asks of a chart like that is which colour is
      better, which is exactly what a sequential ramp answers without a legend.

      --growth-0 is "nothing here", and it is the sunken paper rather than a
      pale green: an empty day must not read as a small amount of work. */
  --growth-0: var(--paper-sunken);
  --growth-1: #C9D9C2;
  --growth-2: #A6C8A4;
  --growth-3: #82B887;
  --growth-4: #5FA86A;                /* == --jade, the top of the ramp */

/* ── The same ramp on ink, for the Learning Platform. ──────────────────────
      Added 2026-09-07. The five above are the ONLY ramp this file had, and the
      comment over them says why: the platform sits on paper. The learning
      platform does not — it is the first web surface where ink is the design
      being worked on rather than a shadow copy (see theme.js), and the paper
      ramp inverted on it exactly as the ink ramp inverts on paper. #C9D9C2 is
      the quietest step on paper and the loudest thing on the page on ink, so a
      character somebody half-remembers would have shouted louder than one they
      know.

      These are not new colours. They are the app's own ramp, which
      `docs/brand.md` has carried since before this file existed and
      `GushiUITests/PaletteTests.swift` already asserts: growth0 -> growth3 plus
      the heatmap's own level 0. Reusing it is also what keeps a learner's
      Library on a laptop the same green as the Library in their pocket.

      --growth-ink-0 is #1B1A14 — barely there rather than absent, which is the
      opposite decision from the paper --growth-0 and deliberate in both places:
      on paper an empty day must not read as a small amount of work, and on ink
      it must not read as a hole in the page. Same rule, different ground.

      NOTHING RESOLVES TO THESE HERE. This file declares; learn.css maps them
      onto --growth-0…4 inside its two dark blocks, the same way it maps --ink-*
      onto --bg and --fg. The site and the Teaching Platform are paper and never
      see them. */
  --growth-ink-0: #1B1A14;
  --growth-ink-1: #20301C;
  --growth-ink-2: #2F6B2E;
  --growth-ink-3: #5FA86A;            /* == --jade, and == tone 3; see brand.md */
  --growth-ink-4: #8FCD72;
}

/* ── Chinese ────────────────────────────────────────────────────────────────
   The one thing a Chinese page changes about the type. Fraunces stays first,
   so every Latin word — "Gushi", "HSK 3.0", "Teaching Platform" — is set in
   the same face it is set in everywhere else on the site, and the hanzi fall
   through to Noto Serif SC one glyph at a time.

   `|=` matches `zh` and `zh-Hans` both. The pages serve `zh-Hans`; the
   attribute selector is written to survive someone shortening it. */
html[lang|="zh"] {
  --serif: 'Fraunces', 'Noto Serif SC', 'Songti SC', Georgia, serif;
}

