/* ==========================================================================
   tokens.css — the only file in this codebase that names a colour.

   ONE palette. The skin system is gone: no `data-skin`, no switcher, no
   alternates. If you are about to add a second palette, don't — the site
   committed to a single look deliberately.

   The look, in one line: MySpace/Bebo structure and clutter, drawn in the
   screen-era grammar of the reference board — hard pixel edges, flat cel
   fills, an airbrushed sky, an energy bloom, invented glyphs.

   Colours that carry text are authored as literal hex so that
   tools/check-contrast.mjs can measure them straight out of the stylesheet
   the browser reads. Tokens built with color-mix() are derived decoration —
   bevels, rules, stripes — and carry no text.

   Run `node tools/check-contrast.mjs` after touching anything here.
   ========================================================================== */

/* ==========================================================================
   Archivo Narrow, self-hosted.

   Nothing is fetched from Google. Loading this from fonts.googleapis.com
   sent every visitor's IP address to Google on every page load, which for a
   UK company site is the kind of thing a privacy notice then has to declare.
   Self-hosting removes the disclosure and the request together.

   One variable file (wght 400-700) serves both weights the site asks for.
   Subsetted to Latin + the punctuation actually used: 93KB -> 14KB.
   SIL OFL 1.1 — see /font/OFL.txt, which permits exactly this.
   ========================================================================== */

@font-face {
  font-family: 'Archivo Narrow';
  src: url('/font/archivo-narrow-subset.woff2') format('woff2-variations'),
       url('/font/archivo-narrow-subset.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* ==========================================================================
   DSEG14 Classic, self-hosted — the moving sign, and nothing else.

   SIL OFL 1.1, Copyright (c) 2017 keshikan, with Reserved Font Name "DSEG".
   See /font/DSEG-OFL.txt. Shipped UNMODIFIED because of that reserved name:
   subsetting is modification and a Modified Version may not keep the name.
   Upstream is 5.8KB, so there was nothing to buy by touching it.

   It is a FOURTEEN-segment display, not a seven. DSEG7 was tried first and
   is the truer clock face, but seven segments cannot form a w or an m and
   the sentence came out close to unreadable — and the sign has to stay
   legible with the scroll stopped. The full reasoning is in /font/README.txt.

   The face is caseless: every lowercase outline is identical to its
   uppercase one, measured rather than assumed. Do not "fix" that with
   text-transform — the markup's lower case is what a screen reader says.
   ========================================================================== */

@font-face {
  font-family: 'DSEG14 Classic';
  src: url('/font/DSEG14Classic-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {

  /* ========================================================================
     THE PALETTE

     Taken from the reference board: sky blue and white bloom, gold aura,
     cyan halo, a purple and a red-orange. Loud and saturated, which is what
     survives from the MySpace/Bebo direction — but every value here belongs
     to this palette. Nothing was carried over from leopard, nu-metal or
     acid because it happened to already exist.
     ==================================================================== */

  /* --- Surfaces --------------------------------------------------------- */

  /* The sky, top to horizon. Four stops rather than one --pool, because the
     field is a gradient now; they live here because tokens.css is still the
     only file allowed to name a colour. */
  --sky-top:     #0A2E4E;
  --pool:        #2E86C8;   /* the sky's mid band, and the fallback fill   */
  --sky-low:     #9FD6F2;
  --sky-horizon: #EAF7FF;
  --plate:       #0A1B2E;   /* deep night blue: name bar, footer, plates  */
  --plate-ink:   #F2FBFF;   /* text on the plate                          */
  --plate-soft:  #93CDEA;   /* secondary text on the plate                */
  --chrome:      #0E5E86;   /* the 940px canvas surface                   */
  --chrome-ink:  #F2FBFF;   /* text on the canvas                         */
  --paper:       #F4FBFF;   /* panel surface — the flat cel fill          */

  /* --- Text ------------------------------------------------------------- */

  --ink:         #0A1A26;   /* body text                                  */
  --ink-soft:    #2C5468;   /* 10px data and captions                     */
  --link:        #0A5C80;   /* links on paper                             */
  --link-hover:  #7A2BB8;   /* links on paper, hover and focus — board purple */

  /* --- Section header bars ---------------------------------------------- */

  /* --bar is as dark as it is for a measured reason: at the brighter sky
     blue it started from, PURE WHITE only reached 4.39:1 on it, and white
     is the lightest a label can be. There was no text colour left to move,
     so the bar itself had to come down. That is the one place in this
     palette where the surface moved rather than the text, and it is
     recorded here so nobody lightens it back. */
  --bar:         #156391;
  --bar-lo:      #0A3A55;
  --bar-ink:     #FFFFFF;

  /* --- Energy ----------------------------------------------------------- */

  --accent:      #FFC21E;   /* gold aura — the board's strongest note      */
  --accent-2:    #5FD8FF;   /* cyan halo, and the glyph script             */
  /* Deepened from #FF5A1F, which was 2.98:1 on --paper — two hundredths
     short of the 3:1 a meaningful non-text marker needs. The marker moved,
     the paper did not. */
  --accent-3:    #EC4A0A;   /* red-orange, used rarely: live dot, markers  */

  --focus:       #FFE81A;
  --focus-back:  #0A1A26;

  /* --- Chrome bevel on display type ------------------------------------- */

  --shine-hi:    #FFFFFF;
  --shine-mid:   #DCF3FF;
  --shine-lo:    #0B4A66;

  /* --- Photography -------------------------------------------------------
     DELIBERATELY UNCHANGED. The cel treatment — posterisation, flattened
     mid-tones, a heavier sky cast — is the one place the two directions
     fight hardest, because these are real photographs of real people.
     Kearnan wants to see the rest of the look before that is touched.
     Do not change these values without his word. */

  --ph-sat: 1.45;
  --ph-con: 1.55;
  --ph-hue: -4deg;
  --wash:      #00A8D6;
  --wash-op:   .16;
  --vignette:  42%;

  /* ========================================================================
     Derived. Mixes of the above; none of these carry text, which is why
     none are measured.
     ==================================================================== */

  --rule:      color-mix(in srgb, var(--paper) 52%, var(--ink));
  --rule-soft: color-mix(in srgb, var(--paper) 74%, var(--ink));
  --bevel:     color-mix(in srgb, var(--paper) 55%, white);
  --bevel-lo:  color-mix(in srgb, var(--paper) 68%, var(--ink));
  --stripe:    color-mix(in srgb, var(--paper) 92%, var(--ink));
  --scrim:     color-mix(in srgb, var(--plate) 88%, var(--pool));

  --photo:       saturate(var(--ph-sat)) contrast(var(--ph-con)) hue-rotate(var(--ph-hue));
  --photo-hover: saturate(calc(var(--ph-sat) * 1.22)) contrast(calc(var(--ph-con) * 1.08)) hue-rotate(var(--ph-hue));

  /* ========================================================================
     Type, space, structure, motion
     ==================================================================== */

  --font-display: 'Archivo Narrow', 'Arial Narrow', Arial, sans-serif;
  --font-ui:      Verdana, Geneva, 'DejaVu Sans', sans-serif;
  /* The moving sign only. The fallback is a monospace so that a failed font
     load degrades to something evenly spaced rather than to Verdana, which
     would reflow the sign's width mid-loop. */
  --font-sign:    'DSEG14 Classic', 'Courier New', monospace;

  --fs-body:  11px;   /* the default. Do not scale this up "for readability". */
  --fs-data:  10px;   /* data rows, captions, counts */
  --fs-name:  30px;   /* profile name — chrome bevel */
  --fs-head:  12px;   /* section header bars */
  --fs-album: 17px;   /* album titles */

  --lh-body: 1.45;
  --lh-tight: 1.3;

  --track-data:    .02em;
  --track-display: .07em;

  --w-page: 940px;   /* fixed canvas, centred on the sky */
  --w-rail: 300px;   /* left column */
  --w-main: 620px;   /* right column */
  --gap:    20px;
  --radius: 0;       /* nothing is rounded. Hard pixel edges, per the board. */

  /* Density is deliberate. Old web pages were dense and the density is most
     of what reads as period. Loosening these undoes the look. */
  --pad:        8px;
  --pad-tight:  5px;
  --pad-loose: 12px;
  --stack:     12px;
  --bar-h:     17px;

  /* The pixel step. Corners and bevels move in whole units of this, so
     edges read as sprite art rather than as a rounded box. */
  --px: 3px;

  --fade: 140ms;
}

/* Text-size control (js/desktop.js). The default stays 11. */
:root[data-textsize='large'] {
  --fs-body: 13px;
  --fs-data: 12px;
}

@media (prefers-reduced-motion: reduce) {
  :root { --fade: 0ms; }
}
