/* =============================================================================
   Design tokens — the single source of truth for colour, type and rhythm.

   Two rules that everything else follows from:

   1. Colours are declared with light-dark(). NOT with a prefers-color-scheme
      media query. A media query cannot be overridden by an explicit choice, and
      that is precisely how sites end up needing a render-blocking inline script
      to avoid flashing the wrong theme. light-dark() resolves against the
      color-scheme property, which the server writes onto <html> from a cookie —
      so the first byte of HTML is already correct. See Theme/ThemeMode.cs.

   2. Per-title accent colour is built from ONE number: --h, the dominant hue of
      that title's cover art. Anything that carries a hue also carries .tint,
      which rebuilds --accent locally. (--accent cannot live on :root: custom
      properties substitute at computed-value time, so a :root formula would
      bake in the root hue and every card would come out the same colour.)
   ============================================================================= */

@layer tokens {
  :root {
    color-scheme: light dark;

    /* --- surfaces ------------------------------------------------------------
       Dark mode is deliberately near-black. The first draft used a mid-grey
       (0.145) and every cover looked washed out against it — the art has to be
       the brightest thing on the page, so the page gets out of its way.
       Light mode is warm paper, never pure white. */
    --paper:      light-dark(oklch(0.975 0.006 70),  oklch(0.105 0.006 285));
    --paper-sunk: light-dark(oklch(0.940 0.008 70),  oklch(0.075 0.005 285));
    --paper-rise: light-dark(oklch(1.000 0.003 70),  oklch(0.165 0.008 285));

    /* --- ink ---------------------------------------------------------------- */
    --ink:    light-dark(oklch(0.175 0.014 50), oklch(0.975 0.004 80));
    --ink-2:  light-dark(oklch(0.425 0.012 50), oklch(0.775 0.008 80));
    --ink-3:  light-dark(oklch(0.585 0.010 50), oklch(0.590 0.010 80));

    --hairline: light-dark(oklch(0.175 0.014 50 / 0.13), oklch(0.975 0.004 80 / 0.13));

    /* --- fixed-meaning colours ---------------------------------------------
       Stars are gold in both modes (it is the currency, it must stay
       recognisable); lightness shifts so contrast holds on either surface. */
    --gold: light-dark(oklch(0.62 0.135 85),  oklch(0.855 0.145 88));
    --free: light-dark(oklch(0.52 0.120 155), oklch(0.815 0.130 158));

    /* Default hue, used before any title-specific tint applies. */
    --h: 250;

    /* --- type ---------------------------------------------------------------
       Self-hosted, see css/fonts.css. The first draft used the system stack and
       the result read as a Word document rather than a designed page — for a
       Thai site the typeface is the single biggest lever there is.
         Kanit              display: geometric, high contrast in weight, and its
                            Thai and Latin were designed together so mixed
                            Thai/English headlines keep an even rhythm.
         IBM Plex Sans Thai body: quiet and legible down to 12px. */
    --display: "Kanit", "Leelawadee UI", "Segoe UI", system-ui, sans-serif;
    --sans: "IBM Plex Sans Thai", "Leelawadee UI", "Segoe UI", system-ui, sans-serif;
    --mono: ui-monospace, "Cascadia Code", "Consolas", monospace;

    /* Fluid scale — continuous, so there is no jump at a breakpoint. */
    --step--2: clamp(0.70rem, 0.68rem + 0.08vw, 0.76rem);
    --step--1: clamp(0.80rem, 0.78rem + 0.10vw, 0.88rem);
    --step-0:  clamp(0.95rem, 0.92rem + 0.16vw, 1.06rem);
    --step-1:  clamp(1.10rem, 1.03rem + 0.32vw, 1.32rem);
    --step-2:  clamp(1.35rem, 1.18rem + 0.76vw, 1.85rem);
    --step-3:  clamp(1.70rem, 1.34rem + 1.60vw, 2.70rem);
    /* Headline max reduced from 4.6rem: at 4.6 a long Latin title such as
       "L.A.G (Unlimited Passive)" ran off a phone screen. */
    --step-4:  clamp(1.95rem, 1.35rem + 2.90vw, 3.85rem);

    /* --- rhythm -------------------------------------------------------------
       Page column width, as a share of the viewport on a 12-column mental model
       (owner's spec): 10/12 on desktop, 11/12 on phones — a phone cannot afford
       to give away two columns of margin.

       Everything that forms a page column reads this ONE token (.wrap, .rail),
       so the rail and the grids below it line up by construction rather than
       because two numbers happen to match today.

       There is deliberately no max-width: the spec is proportional, so on a very
       wide monitor the column keeps growing. Capping it would be one line here
       (`max-width`) if that turns out to be unwanted. */
    --page-width: 83.3333%;   /* 10 / 12 */
    --gutter: clamp(1.15rem, 0.6rem + 2.4vw, 2.75rem);
    --measure: 66ch;
    --radius: 4px;
    --radius-lg: 8px;

    /* Covers are 0.67-0.78 in the real catalogue, clustered near 0.70. */
    --cover-ratio: 7 / 10;
  }

  /* Phones get 11/12. This block MUST stay after the :root above — a media query
     adds no specificity, so if it sat first the base value would simply win.
     (That exact mistake is what made the header overflow on mobile earlier.) */
  @media (width < 48rem) {
    :root {
      --page-width: 91.6667%;   /* 11 / 12 */
    }
  }

  /* Rebuilds --accent from the local --h. Put this on anything that sets a hue.
     Chroma is held fairly low: the first draft pushed 0.145 and, on a title whose
     hue landed on orange, the button fought the artwork instead of supporting it.
     The accent's job is to agree with the cover, not to compete with it. */
  .tint {
    --accent:      light-dark(oklch(0.48 0.115 var(--h)), oklch(0.84 0.115 var(--h)));
    --accent-ink:  light-dark(oklch(0.40 0.105 var(--h)), oklch(0.88 0.080 var(--h)));
    --accent-wash: light-dark(oklch(0.48 0.115 var(--h) / 0.08),
                              oklch(0.84 0.115 var(--h) / 0.12));
  }
}
