/* ═══════════════════════════════════════════════════════════════════════
   THE PALETTE. THE ONLY FILE IN THIS REPOSITORY THAT CONTAINS A COLOUR.
   ═══════════════════════════════════════════════════════════════════════

   Five identity candidates are sitting in `candidates/` and none of them has
   won yet. This file exists so that when one does, dropping it in is an edit
   to ONE file rather than a sweep across a stylesheet, four pages and a head
   block — and so that "we swapped the palette" is a diff a reviewer can read
   in thirty seconds instead of a hunt for the hex that got missed.

   THE RULE, AND IT IS ENFORCED. `css/studio.css` and every .html in the tree
   contain no colour literal at all: no hex, no rgb(), no hsl(), no named
   colour, no oklch(). Everything paints through a token declared below.
   `tools/checks/source.mjs` asserts both halves — no literals outside this
   file, and no `var(--…)` anywhere that this file does not declare — so a
   colour smuggled into a rule fails the suite rather than quietly surviving
   the swap.

   WHAT IS IN HERE THAT IS NOT STRICTLY A COLOUR. The type family stacks, and
   deliberately: a candidate identity is a palette AND a letterform, and
   splitting them across two files means half a swap is a thing that can
   happen. The @font-face rules stay in studio.css because they are asset
   paths, not choices.

   ── THE VALUES BELOW ARE A PLACEHOLDER AND ARE MEANT TO LOOK LIKE ONE ────

   Achromatic ground, one muted cool accent, one warm attention hue. It is
   deliberately unremarkable, because a shell that arrives with an opinion
   about the palette pre-empts a decision that is not this file's to make. Do
   not refine these. Replace them.

   Every pair below clears 4.5:1 composited against the surface it actually
   sits on, and `tools/check-contrast.mjs` measures that against the pixels
   rather than against this comment — in two motion states and two viewports,
   because the large-text floor is size-dependent. A replacement palette is
   not finished until that check is green on the same four routes.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Ground ────────────────────────────────────────────────────────────
     `--ground` is cross-checked by the contrast sweep against what the
     document actually paints: it reads the real painted stack off <html> and
     <body>, and a token that disagrees with the paint is reported as a defect
     of its own. So this is not documentation — it is an assertion. If you
     change what `html` is painted with in studio.css, change this with it. */
  --ground: #0b0b0d;
  /* One step up, for anything that has to read as a surface rather than as a
     hole. Used opaque under prefers-reduced-transparency, where the
     translucent panel token below is not available to us. */
  --ground-lift: #16161a;

  /* ── Ink ───────────────────────────────────────────────────────────────
     Two levels, and there is deliberately no third. The main site deleted its
     tertiary text colour rather than ship type below the floor, and expresses
     quiet through size, tracking and case instead. Do not add `--text-faint`.
     15.9:1 and 8.1:1 on the ground; both survive the panel composite. */
  --text: #ece9e4;
  --text-dim: #a8a49d;

  /* ── The dominant ──────────────────────────────────────────────────────
     One hue that is the composition. Everything structural that is not ink
     is this or a step of it. */
  --accent: #9fb4c4;
  --accent-dim: #6c8494;
  /* Behind ink, never carrying it: fills, rules, glow cores. Anything that
     renders text uses --accent or lighter. */
  --accent-deep: #33424c;

  /* ── The rationed one ──────────────────────────────────────────────────
     The only hue on the page that is not part of the composition, which is
     exactly why it is what must-be-noticed things use. It works because it is
     rationed: if a second thing starts using it, the first thing stops being
     noticed. Today it is spent on one item — the empty state's status line. */
  --attention: #e8c47a;

  /* ── Surfaces ──────────────────────────────────────────────────────────
     Translucent over the live ground. Both are overridden to opaque under
     prefers-reduced-transparency below, which is the whole reason a panel's
     fill is a token and not an inline rgba(). */
  --panel: rgba(236, 233, 228, 0.045);
  --panel-edge: rgba(236, 233, 228, 0.14);
  --panel-edge-strong: rgba(236, 233, 228, 0.26);

  /* ── Focus ────────────────────────────────────────────────────────────
     One ring, one colour, applied by ONE global :focus-visible rule in
     studio.css. Two tokens because a single ring colour is invisible on
     whichever of ground or ink it happens to resemble; the outline is drawn
     in --focus and offset over --focus-behind so it reads on both. */
  --focus: #f4d795;
  --focus-behind: #0b0b0d;

  /* ── The ambient layer ────────────────────────────────────────────────
     Two soft blobs behind the masthead, on coprime clocks. Kept at this
     strength on purpose: the contrast sweep composites a fixed decorative
     layer as the page ground it sits over, so anything bright enough to
     change the surface under real type would pass the sweep and fail a
     reader. Scoped to the masthead, where there is no small type, for the
     same reason. */
  --ambient-a: rgba(159, 180, 196, 0.16);
  --ambient-b: rgba(232, 196, 122, 0.09);

  /* ── THE FIELD ────────────────────────────────────────────────────────
     The three hues the canvas background paints with, and the only tokens in
     this file that are read by JAVASCRIPT rather than by a stylesheet:
     js/field.js pulls them through getComputedStyle at construction, with
     these exact values hard-coded as its fallback. Change one here and change
     the fallback with it, or a page that fails to load this file paints a
     different background from one that does.

     Wraith's palette. That project is retired and its site is offline, so the
     hue is free — and it is already in the family's vocabulary: the main site
     paints its drifting specters rgb(124,108,240), inherited from here. Ice
     cyan is phasmotic.com's, amber is /work's, green is Verdant's. This is
     the lane nobody is standing in. */
  --field-a: #7c6cf0;   /* Secure Violet  */
  --field-b: #2dd4bf;   /* Spectral Teal  */
  --field-c: #ef4444;   /* Angry Crimson  */

  /* ── The landing page ─────────────────────────────────────────────────
     `/` is a canvas with a wordmark on it and nothing else, and it needs a
     vocabulary the document pages do not: a vignette, a glow under the
     wordmark, and the artifacts the ASCII wall paints when it takes over.

     THEY LIVE HERE RATHER THAN INLINE FOR THE ORDINARY REASON. The page they
     serve carried its own :root while it was a candidate, which is why it was
     able to ask for --attention and --f-mono and silently get neither: those
     names existed in THIS file and not in that one, so the fault caption
     rendered in body-weight sans instead of amber monospace and nothing
     reported it. One palette, one file, one place to be wrong. */

  /* The vignette: clear at the centre, ground at the edge. Three stops rather
     than two because a linear fall from nothing to opaque reads as a ring. */
  --veil-clear: rgba(11, 11, 13, 0);
  --veil-faint: rgba(11, 11, 13, 0.06);
  --veil-soft:  rgba(11, 11, 13, 0.22);
  --veil-half:  rgba(11, 11, 13, 0.44);
  --veil-most:  rgba(11, 11, 13, 0.66);
  --veil-mid:   rgba(11, 11, 13, 0.80);
  --veil-deep:  rgba(11, 11, 13, 0.97);

  /* The wordmark's glow, four stops from a tight bright core to a wide dim
     halo. The core is lighter than --field-a on purpose: a glow the same hue
     as its own text reads as a blur rather than as light. */
  --glow-core: rgba(196, 190, 255, 0.40);
  --glow-near: rgba(124, 108, 240, 0.34);
  --glow-far:  rgba(124, 108, 240, 0.20);
  --glow-haze: rgba( 96,  84, 220, 0.12);

  /* ── The wall's artifacts ─────────────────────────────────────────────
     What the ASCII video panels paint when one is struck. All of them sit
     over live video rather than over the ground, so the alphas are low and
     the "clear" ends are the SAME hue at zero alpha rather than `transparent`
     — a gradient that fades to transparent in one browser and to black in
     another is a bug nobody can reproduce. */

  /* The sync bar: one soft band of lifted picture rolling up a tile. */
  --sync-clear: rgba(190, 215, 255, 0);
  --sync-low:   rgba(190, 215, 255, 0.05);
  --sync-mid:   rgba(190, 215, 255, 0.09);
  --sync-peak:  rgba(190, 215, 255, 0.16);

  /* The torn scanlines, and the gap between them. */
  --tear-line:  rgba(210, 225, 255, 0.15);
  --tear-clear: rgba(210, 225, 255, 0);

  /* The fault caption: a tight backing, a halo that keeps the glyphs behind
     it from eating the letterforms, and the two directions colour separates
     in on a tube — which are this site's own crimson and violet rather than a
     generic red and blue. */
  --osd-ground: rgba(11, 11, 13, 0.55);
  --osd-halo:   rgba(11, 11, 13, 0.96);
  --osd-edge:   rgba( 45, 212, 191, 0.50);
  --fringe-warm: rgba(239,  68,  68, 0.34);
  --fringe-cool: rgba(124, 108, 240, 0.32);

  /* ── Type ─────────────────────────────────────────────────────────────
     Inter and JetBrains Mono are the ledger's INHERIT row and are on disk.
     THE DISPLAY FACE IS NOT CHOSEN, and `--f-display` falling back to the
     body stack is that fact rendered rather than hidden — a placeholder
     display face would be a decision made by default.

     Whatever wins has to be OFL. Self-hosting is what makes the zero
     third-party rule possible and the licence is what makes self-hosting
     legal, so a commercial display face is not a slower option here, it is
     not an option. It also needs a row in assets/fonts/LICENSES.md with
     family, copyright and upstream, and an @font-face in studio.css, in the
     same commit as the value below. */
  --f-display: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;
}

/* ── prefers-reduced-transparency ──────────────────────────────────────────
   A design whose whole surface is translucent panels over a live background
   is exactly the design this preference is about, and the main repo answers
   it nowhere. The answer is a token swap and nothing else: the panels become
   opaque, the ambient layer stops contributing, and no rule in studio.css
   knows the difference.

   Not folded into prefers-contrast. They are different questions — one is
   about layering, one is about separation — and a visitor can ask for either
   without the other. */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --panel: #16161a;
    --panel-edge: #33424c;
    --panel-edge-strong: #6c8494;
    --ambient-a: transparent;
    --ambient-b: transparent;
  }
}

/* ── prefers-contrast: more ────────────────────────────────────────────────
   Ink to the ceiling, dim ink up to where it is no longer dim, edges from a
   hint to a line. The floors in the base palette are already above WCAG AA;
   this is for the reader for whom AA is not enough, which is a different
   person from the one the base palette is tuned for. */
@media (prefers-contrast: more) {
  :root {
    --text: #ffffff;
    --text-dim: #dedad3;
    --accent: #cddce6;
    --accent-dim: #9fb4c4;
    --panel: #16161a;
    --panel-edge: #6c8494;
    --panel-edge-strong: #9fb4c4;
    --ambient-a: transparent;
    --ambient-b: transparent;
  }
}

/* ── forced-colors ─────────────────────────────────────────────────────────
   Windows High Contrast and its relatives. The UA overrides most colour
   properties itself; what it cannot do is know which of our surfaces was
   carrying meaning through a colour the UA just discarded. So the tokens are
   re-pointed at the system-supplied keywords — the only "colours" in this
   file that are not values, because they are the reader's values and not
   ours — and studio.css handles the STRUCTURAL half (borders that were
   invisible becoming visible, decorative fills going away) with no colour in
   it at all.

   `forced-color-adjust` is deliberately never set to `none` anywhere in this
   repository. Opting a surface out of forced colours is opting the reader's
   own choice out, and nothing here is important enough for that. */
@media (forced-colors: active) {
  :root {
    --ground: Canvas;
    --ground-lift: Canvas;
    --text: CanvasText;
    --text-dim: CanvasText;
    --accent: LinkText;
    --accent-dim: CanvasText;
    --accent-deep: Canvas;
    --attention: CanvasText;
    --panel: Canvas;
    --panel-edge: CanvasText;
    --panel-edge-strong: CanvasText;
    --focus: Highlight;
    --focus-behind: Canvas;
    --ambient-a: transparent;
    --ambient-b: transparent;
  }
}
