/**
 * Colour and type, as custom properties.
 *
 * The same rule as the app: no page picks a colour. Everything below the first
 * block is derived from four values a reader can change, so a tint applies to
 * the whole site the moment it is set — including this stylesheet's own
 * borders, cards and secondary text.
 *
 * Mirrors `apps/mobile/src/reading.tsx`. A test asserts the two agree.
 */

:root {
  /* Parchment. The bare default, so the page is right before any script runs. */
  --ground: #efe4d3;
  --ink: #3a332b;
  --accent: #8a5a3b;

  /* What the reading panel changes. Every one has a unit-free or unit-carrying
     value that can be dropped straight onto the element by the bootstrap. */
  --scale: 1;
  --leading: 1;
  --tracking: 0;
  --soften: 0%;
  --measure: 66;

  --font:
    'Open Sans', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

/**
 * Somebody who has told their operating system they want a dark screen has
 * already answered this question once. `:not([data-tint])` so an explicit choice
 * always wins — the bootstrap sets that attribute before first paint.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-tint]) {
    --ground: #2e2a26;
    --ink: #b5a895;
    --accent: #c89b72;
  }
}

/**
 * The presets, transcribed from the app.
 *
 * The two Rilver grounds lead because they are the defaults. The cooler options
 * are kept even though the brand is warm throughout: these are the reading
 * surface, chosen by the reader, and a rule about chrome has no business
 * overriding what somebody's eyes need.
 *
 * None is pure black on pure white. Maximum contrast is what tends to hurt most.
 */
[data-tint='parchment'] {
  --ground: #efe4d3;
  --ink: #3a332b;
  --accent: #8a5a3b;
}
[data-tint='butter'] {
  --ground: #f5eed4;
  --ink: #3a372a;
  --accent: #675a29;
}
[data-tint='peach'] {
  --ground: #ffe9da;
  --ink: #40342c;
  --accent: #795032;
}
[data-tint='rose'] {
  --ground: #f6e9ea;
  --ink: #3e3234;
  --accent: #774e52;
}
[data-tint='lavender'] {
  --ground: #f0eafe;
  --ink: #383440;
  --accent: #61527d;
}
[data-tint='mint'] {
  --ground: #e6f1e9;
  --ink: #2e3a32;
  --accent: #3d654b;
}
[data-tint='aqua'] {
  --ground: #dbf4f3;
  --ink: #2a3a3a;
  --accent: #1e6766;
}
[data-tint='slate'] {
  --ground: #dde2e6;
  --ink: #33393e;
  --accent: #475e70;
}
[data-tint='charcoal'] {
  --ground: #2e2a26;
  --ink: #b5a895;
  --accent: #c89b72;
}
[data-tint='olive'] {
  --ground: #161505;
  --ink: #c4c3b3;
  --accent: #bdbb86;
}
[data-tint='warmDark'] {
  --ground: #181310;
  --ink: #d6c7b8;
  --accent: #cdb1a0;
}
[data-tint='mulberry'] {
  --ground: #200e10;
  --ink: #cfbdbe;
  --accent: #e0a5aa;
}
[data-tint='plum'] {
  --ground: #18101f;
  --ink: #c6becc;
  --accent: #c4acda;
}
[data-tint='pine'] {
  --ground: #08180e;
  --ink: #b8c6bc;
  --accent: #94c5a4;
}
[data-tint='ocean'] {
  --ground: #021818;
  --ink: #b3c6c6;
  --accent: #80c6c5;
}
[data-tint='midnight'] {
  --ground: #0c1017;
  --ink: #b5bfcb;
  --accent: #a1b8e1;
}

/**
 * Everything else, derived.
 *
 * `color-mix(in oklab, …)` reproduces what `buildTheme()` does in the app —
 * pulling two colours together in a space where the steps are perceptually even
 * — with no ported arithmetic and no JavaScript.
 *
 * Depth comes from mixing the ground *towards the ink*, which lifts a surface
 * away from its background in whichever direction that background sits: darker
 * on a light ground, lighter on a dark one. Hardcoding "lighter" would invert
 * the cue on half of the palettes above.
 */
:root {
  /**
   * Two text tiers, not three.
   *
   * There was a third — `--ink-faint`, at 40% — and it failed WCAG on all nine
   * tints, between 2.77:1 and 3.99:1 where 4.5 is required. It was carrying the
   * price, the licences, the captions and the panel's own hints: not decoration,
   * just content that had been styled quiet.
   *
   * A visibly fainter third grey needs about 25% of headroom. Charcoal has 13%,
   * because its pair is only 6.10:1 to begin with — so on this palette the third
   * tier cannot exist and be readable. The app never hits this: `buildTheme`
   * runs `ensureContrast()` and walks each derived colour back until it passes.
   * A `color-mix` chain cannot measure itself, so the percentages below are
   * chosen to clear 4.5:1 on the tightest tint and asserted in `site.test.ts`.
   *
   * Muted is checked against `--raised` rather than `--ground`: that is the
   * tighter of the two, so anything readable on a card is readable on the page
   * behind it. The app makes the same call for the same reason.
   */
  --ink-soft: color-mix(in oklab, var(--ink), var(--ground) var(--soften));
  --ink-muted: color-mix(in oklab, var(--ink-soft), var(--ground) 12%);

  /**
   * Ornament, and never text — the app's `decorative` token. Free to be as
   * quiet as it likes precisely because nothing it paints carries meaning.
   */
  --decorative: color-mix(in oklab, var(--ink-soft), var(--ground) 45%);

  --raised: color-mix(in oklab, var(--ground), var(--ink) 5%);
  --sunken: color-mix(in oklab, var(--ground), var(--ink) 9%);
  --border: color-mix(in oklab, var(--ground), var(--ink) 20%);

  /**
   * The accent as it arrives is a brand colour, not a text colour. On cream it
   * is 4.26:1 and on mint 4.31:1 — so links set in it, and buttons filled with
   * it, both failed. Pulling it toward the ink lifts the worst case to 4.87:1
   * as text and 5.34:1 as a fill, while leaving it recognisably the same hue.
   *
   * Raw `--accent` stays for ornament: rules, borders, the source glyphs. Those
   * only need 3:1, which every tint clears comfortably.
   */
  --accent-ink: color-mix(in oklab, var(--accent), var(--ink) 25%);
  --accent-soft: color-mix(in oklab, var(--accent), var(--ground) 85%);

  /* 4pt scale, as the app. */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-base: 16px;
  --space-lg: 20px;
  --space-xl: 32px;
  --space-xxl: 48px;
  /* Between whole sections only. Section gaps sharing a step with in-section
     gaps is what made the page read as crowded. */
  --space-section: 80px;

  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  /* An accessibility floor, and this audience skews older than the average. */
  --touch: 44px;
}

/**
 * The typefaces the app offers, and the same six.
 *
 * Declaring every `@font-face` costs nothing until one is used — a browser
 * fetches only the file a rule actually applies — so the picker is free for
 * everybody who never opens it.
 */
[data-font='system'] {
  --font: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
[data-font='openSans'] {
  --font: 'Open Sans', system-ui, sans-serif;
}
[data-font='atkinson'] {
  --font: 'Atkinson Hyperlegible', system-ui, sans-serif;
}
[data-font='lexend'] {
  --font: 'Lexend', system-ui, sans-serif;
}
[data-font='mono'] {
  --font: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;
}
[data-font='openDyslexic'] {
  --font: 'OpenDyslexic', system-ui, sans-serif;
}

/**
 * `font-display: swap` on purpose. A blank page while a font loads is worse for
 * this audience than a moment of the fallback: the fallback is readable, and
 * nothing here is laid out so tightly that a reflow loses somebody's place.
 *
 * See `fonts/README.md` for where these files come from. Until they are added
 * every rule below simply falls through to the stack's next entry, which is why
 * the picker works before the fonts land.
 */
@font-face {
  font-family: 'Open Sans';
  src: url('../fonts/open-sans-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Open Sans';
  src: url('../fonts/open-sans-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Open Sans';
  src: url('../fonts/open-sans-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  src: url('../fonts/atkinson-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  src: url('../fonts/atkinson-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Lexend';
  src: url('../fonts/lexend-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Lexend';
  src: url('../fonts/lexend-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Lexend';
  src: url('../fonts/lexend-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'OpenDyslexic';
  src: url('../fonts/opendyslexic-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'OpenDyslexic';
  src: url('../fonts/opendyslexic-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
