/* ============================================================
   /.metanomicon — tokens.css
   The root token layer. Every namespace inherits from this.

   Layer order:
     1. :root            the canon. Never overridden in place.
     2. [data-ns="..."]  namespace overrides. Additive only.
     3. [data-mode]      substrate mode (void | paper).

   Rule: a namespace may override --ns-* tokens and nothing else.
   ============================================================ */

@font-face {
  font-family: "Departure";
  src: url("./fonts/DepartureMono-Regular.woff2") format("woff2"),
       url("./fonts/DepartureMono-Regular.woff") format("woff");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("./fonts/Geist-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("./fonts/Geist-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

:root {
  /* ── Substrate ───────────────────────────────────────────
     Two grounds. void is the dark index; paper is the page.
     The system is legible on both — that is the requirement. */
  --void:        #050505;   /* the dark index */
  --void-2:      #0a0a0b;   /* raised surface on void */
  --void-3:      #111113;   /* raised twice */
  --ink:         #0b0b0c;   /* 1-bit black — marks on paper */
  --paper:       #f2f0e9;   /* 1-bit white — the grimoire page */
  --paper-2:     #e8e5dc;   /* recessed paper */

  /* ── Signal ─────────────────────────────────────────────── */
  --fg:          #e6e6e6;   /* on void */
  --fg-ink:      #14141a;   /* on paper */
  /* The same two inks as channel triplets, which is how the ladder is
     written on every surface that has one: rgba(var(--signal), var(--o-n))
     (DESIGN.md §14, artifact/design-system.src.html). Added 2026-10-04 (R8,
     language-2): the artifact and src/index.css carried --signal and
     --witness and this file did not, so the mirror could not be generated
     from it. --witness is the dot/halftone testimony of DESIGN.md §1. */
  --signal:      230,230,230;
  --witness:     226,228,230;

  /* ── The dot ─────────────────────────────────────────────
     Inherited from HORCRX unchanged. At the meta layer the dot
     HIDES (dotfile, index, occult). At the vessel layer it LIVES
     (essence). One glyph, two functions. Never a fill. */
  --essence:     #00f0ff;
  --essence-ink: #056a75;   /* the dot, on paper */

  /* ── The sigil ───────────────────────────────────────────
     NEW at the meta layer. The instrumentation colour: coordinate
     frames, annotation rules, measurement marks. Lines and labels
     only — never a fill, never body text. */
  --sigil:       #c2333d;
  --sigil-dim:   rgba(194, 51, 61, 0.42);
  --sigil-ghost: rgba(194, 51, 61, 0.16);

  /* --sigil is a LINE colour. On void it measures 3.72:1 — fine for a
     rule or a tick, below the 4.5:1 bar for text. Where sigil sets
     text, use --sigil-text: sigil lifted 18% toward white, which is
     the minimum that clears the bar with margin (5.00:1). The lift is
     derived, not chosen, and it is void-only — on paper it would fall
     to 3.58:1, and there plain sigil already passes at 4.80:1, so the
     paper block below resolves it back. See DESIGN.md section 15. */
  --sigil-text:  #cd5860;

  /* ── Chromatic split ─────────────────────────────────────
     One signal scattered across channels. Ghost layers only:
     these never carry meaning alone. */
  --split-r:     rgb(255, 55, 55);
  --split-c:     rgb(60, 220, 230);
  --split-w:     rgb(225, 225, 230);

  --abb-min:     0.6px;   /* body — barely perceptible */
  --abb-base:    1.2px;   /* hover */
  --abb-large:   2.4px;   /* display / brand chrome */
  --abb-event:   4.0px;   /* click, sweep, fragmentation */

  /* ── Opacity ladder ──────────────────────────────────────
     Hierarchy comes from opacity, not weight. Single-weight faces.

     o-4 IS THE FLOOR FOR TEXT. Measured against --void:
       o-1 16.33  o-2 11.69  o-3 8.08  o-4 5.23   <- AA and above
       o-5  3.19  o-6  1.88  o-7 1.36  o-8 1.14   <- not text
     o-5 is legal for UI borders and large type; o-6 for disabled
     states; o-7/o-8 for hairlines. A 10px label at o-5 is not dim,
     it is unreadable. See DESIGN.md section 15. */
  --o-1: 1.00;  --o-2: 0.85;  --o-3: 0.70;  --o-4: 0.55;
  --o-5: 0.40;  --o-6: 0.25;  --o-7: 0.15;  --o-8: 0.08;

  /* ── Typography ──────────────────────────────────────────
     Two faces, and the split is doctrinal:

       Geist (grotesque)  — the META layer. The container of all
                            brands must not itself look branded.
                            Wordmark, section titles, prose.
       Departure (mono)   — the SYSTEM layer. Data, chrome, code,
                            terminal, vessel-level identity.

     A namespace may not add a third face. */
  --font-meta:   "Geist", ui-sans-serif, system-ui, sans-serif;
  --font-system: "Departure", "SF Mono", "Courier New", monospace;

  /* ── The scale ───────────────────────────────────────────
     One scale, written from what the surfaces measure (R8, 2026-10-04,
     artifact/strata4/type-scale/evidence.md: one row per token, with the
     surface and selector it was read from). The previous scale here
     (9 10 12 14 16 18 24 36 48 64 96, three leadings, seven trackings)
     had no consumer in the artifact, the document shell or src/, and the
     artifact's inline mirror had drifted to 21 sizes; DESIGN.md §14
     predicted that a restated token layer disagrees with the code within
     a month. Now the artifact's mirror is generated from this block by
     scripts/tokens-mirror.mjs and never typed.

     Mono: two sizes, on Departure's pixel grid. Departure is an 11 px
     bitmap: unitsPerEm 550, every metric a multiple of 50, so one drawn
     pixel is 50 units. At 11 px one drawn pixel is one device pixel at
     1x; at 22 px it is two. At any other size the drawn pixels straddle
     device pixels and the rasteriser writes grey (R4,
     artifact/strata4/mono-grid/). Two sizes, no others. */
  --text-mono:    11px;   /* label, data, code, chrome */
  --text-mono-2x: 22px;   /* display mono: glyph plate, specimen, the mobile index glyph */

  /* Text: four sizes, Geist. */
  --text-sm:  13px;   /* captions, tables, secondary paragraphs */
  --text-md:  15px;   /* body */
  --text-lg:  17px;   /* subhead, a document's lede */
  --text-xl:  19px;   /* the canon's standfirst, printed values */

  /* Display: the rows each surface computes, named by the surface that
     computes them (W14, artifact/strata4/hero-rows/). A display size
     enters this list only when a live surface computes it. */
  --display-wordmark:       clamp(2.5rem, 12.5vw, 317px);   /* `/`, [data-probe=wordmark]; src/App.tsx sets the same clamp */
  --display-hero:           clamp(2.6rem, 8.4vw, 7.4rem);   /* /canon/ .hero h1 */
  --display-phantom:        clamp(180px, 30vw, 440px);      /* /canon/ .ch-phantom */
  --display-phantom-narrow: clamp(140px, 44vw, 260px);      /* /canon/ .ch-phantom at <= 700 px */
  --display-doc:            clamp(34px, 5.6vw, 68px);       /* header.doc h1 on every document page */
  --display-specimen:       clamp(1.7rem, 4.4vw, 2.9rem);   /* /canon/ .spec-geist */
  --display-title:          clamp(1.5rem, 4vw, 2.3rem);     /* /canon/ .ns-title; article h1 on document pages */
  --display-section:        clamp(1.4rem, 3.1vw, 2.05rem);  /* /canon/ .sec-head h2; article h2 on document pages */

  /* The mark ramp of the §13 mark block (W12): design values from the
     brandkit, status asserted, kept here so the artifact has no typed size:
     the ramp's markup and the paper raise in JS (12 -> 18 for a Departure
     mark on paper) both assign var(--mark-*). The one px string left in the
     artifact's JS is the beat-plot canvas font, whose number is read from
     --text-mono at run time, because the canvas API takes a number. */
  --mark-96: min(96px, 14vw);
  --mark-30: 30px;
  --mark-18: 18px;
  --mark-12: 12px;

  /* Tracking: four values. Display is negative, prose is zero, a label is
     tracked and uppercase, the brand line is tracked wider. */
  --tracking-display: -0.022em;
  --tracking-prose:    0em;
  --tracking-label:    0.14em;
  --tracking-brand:    0.32em;

  /* Retired names, 2026-10-04. public/preview/*.html and
     public/applications/index.html (22 uses, not this change's files)
     still name --text-3xs, --text-2xs, --tracking-wide and
     --tracking-wider; each resolves to a token of the scale above. Remove
     when those pages are rewritten. --text-xs…5xl, --tracking-tight,
     -normal, -widest and the three --leading-* had no consumer and are gone. */
  --text-3xs:       var(--text-mono);
  --text-2xs:       var(--text-mono);
  --tracking-wide:  var(--tracking-label);
  --tracking-wider: var(--tracking-label);

  /* ── Space ───────────────────────────────────────────────
     4px base. The lattice is hexagonal; the layout grid is not. */
  --space-1: 0.25rem;  --space-2: 0.5rem;   --space-3: 0.75rem;
  --space-4: 1rem;     --space-5: 1.25rem;  --space-6: 1.5rem;
  --space-8: 2rem;     --space-10: 2.5rem;  --space-12: 3rem;
  --space-16: 4rem;    --space-20: 5rem;    --space-24: 6rem;

  /* ── Edges ───────────────────────────────────────────────
     Sharp by default. Radius is an exception that must be argued. */
  --radius-none: 0;
  --radius-sm:   2px;
  --radius-md:   4px;

  --rule:        1px solid rgba(230, 230, 230, 0.08);
  --rule-strong: 1px solid rgba(230, 230, 230, 0.16);
  --rule-ink:    1px solid rgba(11, 11, 12, 0.14);

  /* ── Dither ──────────────────────────────────────────────
     1-bit is the native depth. Grey is a lie told by dots. */
  --dither-cell:  2px;   /* device px per dither cell at 1x */
  --bayer-order:  8;     /* 2 | 4 | 8 | 16 */
  --halftone-min: 0.6px;
  --halftone-max: 6.5px;

  /* ── Motion ──────────────────────────────────────────────
     Heartbeats and sweeps. Nothing bounces. Nothing eases out
     with personality. The system breathes; it does not perform. */
  --beat:        1.6s;    /* primary breath */
  --beat-fast:   0.62s;
  --sweep:       10s;     /* scan beam re-fire */
  /* The lunation: the synodic month, IAU mean value. The canon's third
     period after the beat and the sweep, and the only one measured in
     days. The field's warm/cold balance is bound to it (DESIGN.md §09) —
     new moon cold-led, full moon warm-led, the asymmetry breathing with
     the quarter. A period that long cannot be perceived as motion; it is
     perceived as a calendar, which is the point. */
  --lunation:    29.530588861d;
  /* --cycle (6.5s, "phrase / memory swap") was deleted 2026-10-03: a grep over
     first-party source printed 0 consumers (artifact/strata4/one-beat/grep.mjs).
     --beat-fast stays: .mn-anim-blink below consumes it. */
  --ease:        cubic-bezier(0, 0, 0.2, 1);
  --ease-linear: linear;

  /* ── Depth ───────────────────────────────────────────────
     Flat system. z is for overlay chrome only. */
  --z-field:    0;
  --z-content: 10;
  --z-frame:   40;   /* coordinate/annotation overlay */
  --z-grain:   50;   /* scanlines, dither overlay */
  --z-modal:   90;

  /* ── Namespace defaults ──────────────────────────────────
     A registered namespace overrides ONLY these. See REGISTRY.md. */
  --ns-name:    "metanomicon";
  --ns-accent:  var(--essence);
  --ns-sigil:   var(--sigil);
  --ns-mark:    "/.";
  --ns-face:    var(--font-meta);
}

/* ── Substrate modes ───────────────────────────────────────
   [data-mode="void"]  dark index (default)
   [data-mode="paper"] 1-bit grimoire page                    */

:root,
[data-mode="void"] {
  --bg:       var(--void);
  --bg-2:     var(--void-2);
  --bg-3:     var(--void-3);
  --text:     var(--fg);
  --dot:      var(--essence);
  --line:     var(--rule);
  --mark-ink: #ffffff;
}

[data-mode="paper"] {
  --bg:       var(--paper);
  --bg-2:     var(--paper-2);
  --bg-3:     var(--paper);
  --text:     var(--fg-ink);
  --signal:   20,20,26;     /* --fg-ink as channels */
  --dot:      var(--essence-ink);
  --line:     var(--rule-ink);
  --mark-ink: var(--ink);
  /* The lift exists to raise sigil off a dark ground. On paper it is
     the wrong direction — lifting toward white drops it to 3.58:1 —
     so sigil text resolves back to the unlifted value (4.80:1). */
  --sigil-text: var(--sigil);
}

/* ── Registered namespaces ─────────────────────────────────
   Additive only. Adding an org = adding a block here + a row in
   REGISTRY.md. Nothing else in this file changes, ever. */

[data-ns="metanomicon"] {
  --ns-name:   "metanomicon";
  --ns-accent: var(--essence);
  --ns-mark:   "/.";
  --ns-face:   var(--font-meta);
}

[data-ns="horcrx"] {
  --ns-name:   "horcrx";
  --ns-accent: var(--essence);
  --ns-mark:   "[[. ]]";
  --ns-face:   var(--font-system);
}

[data-ns="atlas"] {
  --ns-name:   "atlas";
  --ns-accent: #7fd4c1;
  --ns-mark:   "[[. ]]";
  --ns-face:   var(--font-system);
}

/* ══════════════════════════════════════════════════════════
   Utilities
   ══════════════════════════════════════════════════════════ */

.mn-meta {
  font-family: var(--font-meta);
  color: var(--text);
  letter-spacing: var(--tracking-prose);
}
.mn-system {
  font-family: var(--font-system);
  color: var(--text);
  letter-spacing: var(--tracking-prose);
}
.mn-label {
  font-family: var(--font-system);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: rgb(from var(--text) r g b / var(--o-4));
}
.mn-dot { color: var(--dot); }

/* Chromatic split — ghost channels behind a solid core */
.mn-split {
  text-shadow:
    calc(-1 * var(--abb-base)) 0 rgb(from var(--split-r) r g b / 0.35),
    var(--abb-base) 0 rgb(from var(--split-c) r g b / 0.35);
}
.mn-split-lg {
  text-shadow:
    calc(-1 * var(--abb-large)) 0 rgb(from var(--split-r) r g b / 0.40),
    var(--abb-large) 0 rgb(from var(--split-c) r g b / 0.40);
}
.mn-split-hover { transition: text-shadow 0.25s var(--ease); }
.mn-split-hover:hover {
  text-shadow:
    calc(-1 * var(--abb-large)) 0 rgb(from var(--split-r) r g b / 0.45),
    var(--abb-large) 0 rgb(from var(--split-c) r g b / 0.45);
}

/* Grain — CRT scanlines. Multiply so it darkens without tinting. */
.mn-scanlines {
  position: absolute; inset: 0;
  pointer-events: none; z-index: var(--z-grain);
  background: repeating-linear-gradient(
    0deg, transparent 0, transparent 2px,
    rgba(0, 0, 0, 0.20) 2px, rgba(0, 0, 0, 0.20) 3px);
  mix-blend-mode: multiply;
  opacity: 0.45;
}
[data-mode="paper"] .mn-scanlines { opacity: 0.14; }

.mn-vignette {
  position: absolute; inset: 0;
  pointer-events: none; z-index: var(--z-grain);
  background: radial-gradient(ellipse at center,
    transparent 42%, rgb(from var(--bg) r g b / 0.72) 100%);
}

/* Sigil frame — the instrumentation overlay */
.mn-frame {
  position: absolute;
  border: 1px solid var(--sigil-dim);
  pointer-events: none;
  z-index: var(--z-frame);
}
.mn-frame::before {
  content: attr(data-label);
  position: absolute; top: -1.15em; left: -1px;
  font-family: var(--font-system);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-label);
  color: var(--sigil);
  white-space: nowrap;
}

/* ── Motion ─────────────────────────────────────────────── */
@keyframes mn-beat   { 0%,100% { opacity: 1; }    50% { opacity: 0.72; } }
@keyframes mn-blink  { 0%,100% { opacity: 1; }    50% { opacity: 0; } }
@keyframes mn-fade   { from { opacity: 0; }       to  { opacity: 1; } }

.mn-anim-beat  { animation: mn-beat var(--beat) ease-in-out infinite; }
.mn-anim-blink { animation: mn-blink var(--beat-fast) step-end infinite; }
.mn-anim-fade  { animation: mn-fade 0.6s var(--ease) forwards; }

@media (prefers-reduced-motion: reduce) {
  .mn-anim-beat, .mn-anim-blink, .mn-anim-fade { animation: none; }
  * { transition-duration: 0.01ms !important; }
}
