/* ==========================================================================
   PRIME Lab — tokens.css
   The single source of truth for colour, type, space, motion and elevation.

   Rule: this is the ONLY file in the project allowed to contain a raw colour
   value. Everything downstream references var(--...). See brief/art-direction.md.

   Order:
     1. Fonts
     2. Design tokens (:root)
     3. Land theming ([data-land])
     4. Reset
     5. Base element styles
     6. Focus, selection, scrollbar
     7. Layout primitives
     8. Type utilities
     9. User-preference overrides (reduced motion / contrast / transparency /
        forced colors / print)
   ========================================================================== */


/* ==========================================================================
   1. FONTS — self-hosted. No CDN, no <link> to fonts.googleapis.com.
   Fetch into /prime-lab/fonts/ (see art-direction.md §3.2).
   ========================================================================== */

@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin-wdth-wght-normal.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/ibm-plex-sans-latin-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* Metric-matched fallbacks so the font swap does not reflow the page. */
@font-face {
  font-family: "Archivo Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Liberation Sans");
  size-adjust: 97%;
  ascent-override: 92%;
  descent-override: 24%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Plex Sans Fallback";
  src: local("Segoe UI"), local("Helvetica Neue"), local("Arial");
  size-adjust: 102%;
  ascent-override: 96%;
  descent-override: 26%;
  line-gap-override: 0%;
}


/* ==========================================================================
   2. DESIGN TOKENS
   ========================================================================== */

:root {

  /* ---------- 2.1 Base world — "panel black". Never #000. ---------- */
  --c-void:        #04060C;  /* page background */
  --c-base-900:    #080B14;  /* alternating section band */
  --c-base-800:    #0D121C;  /* default surface */
  --c-base-700:    #141A27;  /* raised surface, inputs, hover on 800 */
  --c-base-600:    #1D2534;  /* highest surface, active state, table header */

  --c-line:        #232C3D;  /* 1.34:1 on 800 — decorative reinforcement ONLY */
  --c-line-strong: #34405A;  /* 1.81:1 — borders of interactive elements */
  --c-line-hover:  #3E4C69;  /* 2.18:1 — hover border */

  /* ---------- 2.2 Text. Ratios measured against --c-base-800. ---------- */
  --c-text-hi:  #EDF1F9;  /* 16.56:1 — AAA. Headlines, key figures.        */
  --c-text:     #C9D2E3;  /* 12.33:1 — AAA. Default body.                  */
  --c-text-mid: #9AA6BF;  /*  7.66:1 — AAA. Secondary body, captions.      */
  --c-text-low: #78849D;  /*  4.99:1 — AA on 800 and darker ONLY.          */
  /* --c-text-low is 4.09:1 on --c-base-600 and ~4.2:1 on land tints:
     large text (>=24px, or >=18.66px bold) or non-essential meta only.    */

  /* ---------- 2.3 BRAIN — violet -> cyan (the invisible spectrum) ------- */
  --c-brain:        #9B8CFF;  /* 6.77:1 on 800 — key */
  --c-brain-2:      #5CE3FF;  /* 12.39:1 — cyan second, data lines, active */
  --c-brain-signal: #FF6E86;  /* 6.99:1 — oxy-Hb "signal detected". Rare.  */
  --c-brain-deep:   #2A1F6B;  /* glow source / gradient stop. NEVER text.  */
  --c-brain-tint:   #1B1E33;  /* panel background */

  /* ---------- 2.4 BODY — magenta -> amber (thermal load) --------------- */
  --c-body:      #FF3E7F;  /* 5.58:1 on 800 — key */
  --c-body-2:    #FFB24D;  /* 10.47:1 — amber second, peak/effort */
  --c-body-soft: #FF6A9C;  /* 6.96:1 — lifted variant, use on --c-base-600 */
  --c-body-deep: #5C0E33;  /* glow source. NEVER text. */
  --c-body-tint: #251626;  /* panel background */

  /* ---------- 2.5 ENVIRONMENT — teal -> sky (atmosphere, distance) ----- */
  --c-env:      #3FE3B8;  /* 11.51:1 on 800 — key */
  --c-env-2:    #5FA8FF;  /*  7.61:1 — sky second, depth, far plane */
  --c-env-deep: #06382F;  /* glow source. NEVER text. */
  --c-env-tint: #12272C;  /* panel background */

  /* ---------- 2.6 Reserved ---------------------------------------------
     --c-knvb means "existing KNVB Campus". It is never a land colour,
     never a CTA, never decorative.                                       */
  --c-knvb: #FF8A2B;  /* 7.96:1 on 800 */

  /* ---------- 2.7 Status. Never colour-alone: shape + text always. ----- */
  --c-status-live:      #4ADE80;  /* 10.76:1 — in use today   (solid dot)  */
  --c-status-planned:   #FFC24B;  /* 11.67:1 — funded plan    (half dot)   */
  --c-status-exploring: #7FB2FF;  /*  8.67:1 — investigating  (dashed ring)*/

  /* Ledger plausibility — the client's own honest self-assessment. */
  --c-plaus-strong:    #4ADE80;  /* 10.76:1 */
  --c-plaus-depends:   #FFC24B;  /* 11.67:1 */
  --c-plaus-ambitious: #FF8A2B;  /*  7.96:1 */
  --c-plaus-growth:    #7FB2FF;  /*  8.67:1 */

  /* ---------- 2.8 Focus — two-tone. A single ring FAILS here.
     --c-focus vs env teal is 1.08:1, vs body 2.22:1, vs brain 1.83:1.
     The dark core carries bright fills (>=6.0:1); the cyan halo carries
     the dark world (>=10.1:1). One of the two always passes.            */
  --c-focus:      #5CE3FF;
  --c-focus-core: #04060C;

  /* ---------- 2.9 Land aliases.
     Components reference --c-land-*; [data-land] rebinds them. Default is
     land-neutral (no land colour leaks into un-themed sections).        */
  --c-land:      var(--c-text-hi);
  --c-land-2:    var(--c-text-mid);
  --c-land-deep: var(--c-base-700);
  --c-land-tint: var(--c-base-800);


  /* ---------- 2.10 Typography ---------- */
  --font-display: "Archivo", "Archivo Fallback", "Archivo Expanded",
                  "Helvetica Neue", "Segoe UI", system-ui, sans-serif;
  --font-body:    "IBM Plex Sans", "Plex Sans Fallback", "Segoe UI", system-ui,
                  -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, "Cascadia Mono",
                  "SFMono-Regular", Consolas, "Liberation Mono", monospace;

  /* Width axis carries the NL/EN length difference instead of the type scale. */
  --wdth-display: 112;

  /* Display scale — park signage. Fluid 360px -> 1600px. */
  --fs-d1: clamp(3.25rem,  1.58rem + 7.42vw, 9rem);      /*  52 -> 144px */
  --fs-d2: clamp(2.5rem,   1.48rem + 4.52vw, 6rem);      /*  40 ->  96px */
  --fs-d3: clamp(2rem,     1.42rem + 2.58vw, 4rem);      /*  32 ->  64px */
  --fs-d4: clamp(1.625rem, 1.30rem + 1.45vw, 2.75rem);   /*  26 ->  44px */

  /* Body scale — calm, nearly static. Substance must not move underfoot. */
  --fs-xl:  clamp(1.25rem,   1.18rem  + 0.32vw, 1.5rem);    /* 20 -> 24px */
  --fs-lg:  clamp(1.0625rem, 1.008rem + 0.24vw, 1.25rem);   /* 17 -> 20px */
  --fs-md:  clamp(1rem,      0.982rem + 0.08vw, 1.0625rem); /* 16 -> 17px */
  --fs-sm:  clamp(0.875rem,  0.857rem + 0.08vw, 0.9375rem); /* 14 -> 15px */
  --fs-xs:  0.8125rem;   /* 13px — mono labels, meta */
  --fs-2xs: 0.6875rem;   /* 11px — mono eyebrows ONLY, uppercase, +tracking */

  --fw-thin: 300; --fw-reg: 400; --fw-med: 500;
  --fw-semi: 600; --fw-bold: 700; --fw-black: 900;

  --track-gate:    -0.045em;
  --track-display: -0.03em;
  --track-d4:      -0.02em;
  --track-body:     0em;
  --track-sm:       0.005em;
  --track-eyebrow:  0.16em;
  --track-mono:     0.01em;

  --lh-gate:    0.86;
  --lh-display: 0.94;
  --lh-d4:      1.08;
  --lh-tight:   1.28;
  --lh-body:    1.62;
  --lh-relaxed: 1.72;
  --lh-mono:    1.45;


  /* ---------- 2.11 Space. 1-6 inside components, 7-11 between them. ---- */
  --s-1: 0.25rem;  --s-2: 0.5rem;  --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;    --s-7: 3rem;     --s-8: 4rem;
  --s-9: 6rem;     --s-10: 8rem;   --s-11: 12rem;

  --sect-y:    clamp(5rem, 3rem + 8vw,  11rem);
  --sect-y-lg: clamp(7rem, 4rem + 12vw, 16rem);
  --sect-y-sm: clamp(3rem, 2rem + 4vw,  5.5rem);


  /* ---------- 2.12 Layout ---------- */
  --grid-cols: 12;
  --gutter: clamp(1rem, 0.6rem + 1.2vw, 1.5rem);
  --pad-x:  clamp(1.25rem, 0.5rem + 2.4vw, 3rem);
  --rail-w: clamp(0px, -20rem + 30vw, 4.5rem);  /* 0 below ~667px, 72px @1200+ */

  --w-prose:   66ch;
  --w-narrow:  46rem;    /*  736px */
  --w-content: 82.5rem;  /* 1320px */
  --w-wide:    97.5rem;  /* 1560px */

  --nav-h: 4rem;
  --horizon-y: 62%;  /* shared by CSS and the BODY/ENV WebGL cameras */

  --bp-xs: 480px; --bp-sm: 720px; --bp-md: 960px;
  --bp-lg: 1200px; --bp-xl: 1440px;

  /* The accessibility floor for anything you can point at (§8.8). It is a
     token because every control has to answer to the same number. */
  --target-min: 2.75rem;   /* 44px */


  /* ---------- 2.13 Radii. Engineered, not soft. ---------- */
  --r-0: 0px;
  --r-1: 2px;   /* chips, status dots, table cells */
  --r-2: 4px;   /* buttons, inputs */
  --r-3: 8px;   /* panels, popovers */
  --r-full: 999px;  /* pills and avatars only */


  /* ---------- 2.14 Elevation is LIGHT, not shadow.
     On a dark world a drop shadow is invisible; an edge highlight and a
     coloured bloom are how depth actually reads.                        */
  --edge-hi:  inset 0 1px 0 0 rgb(237 241 249 / 0.07);  /* light catching a top edge */
  --edge-low: inset 0 -1px 0 0 rgb(4 6 12 / 0.6);

  --glow-sm: 0 0 12px -2px rgb(92 227 255 / 0.18);
  --glow-md: 0 0 32px -6px rgb(92 227 255 / 0.22);
  --glow-lg: 0 0 72px -12px rgb(92 227 255 / 0.28);
  --glow-land: 0 0 40px -8px var(--c-land-deep);

  /* Real shadows exist only for things that float above the world. */
  --shadow-pop:   0 8px 24px -8px rgb(0 0 0 / 0.7), 0 2px 6px -2px rgb(0 0 0 / 0.5);
  --shadow-modal: 0 32px 80px -16px rgb(0 0 0 / 0.85), 0 4px 12px -4px rgb(0 0 0 / 0.6);

  --bloom-opacity: 0.55;
  --bloom-size: 70vmin;


  /* ---------- 2.15 Motion. Machinery and light — no springs, no bounce. */
  --ease-gate:   cubic-bezier(0.62, 0.05, 0.15, 1);
  --ease-glide:  cubic-bezier(0.33, 0.06, 0.16, 1);
  --ease-settle: cubic-bezier(0.20, 0.80, 0.28, 1);
  --ease-snap:   cubic-bezier(0.40, 0.00, 0.10, 1);
  --ease-beam:   cubic-bezier(0.00, 0.70, 0.20, 1);
  --ease-drift:  cubic-bezier(0.40, 0.00, 0.60, 1);

  --t-1: 90ms;   --t-2: 140ms;  --t-3: 220ms;  --t-4: 320ms;
  --t-5: 520ms;  --t-6: 840ms;  --t-7: 1400ms;
  --t-amb: 12s;
  --stagger: 60ms;

  /* Set to 0 under prefers-reduced-motion; JS reads this to gate timelines. */
  --motion: 1;


  /* ---------- 2.16 z-index ladder. Nothing invents its own value. ------ */
  --z-below:    -1;
  --z-canvas:    1;
  --z-horizon:   5;
  --z-content:  10;
  --z-sticky:   20;
  --z-rail:     30;
  --z-nav:      60;
  --z-overlay:  80;
  --z-modal:    90;
  --z-toast:    95;
  --z-skip:    100;
}


/* ==========================================================================
   3. LAND THEMING
   Set data-land on any section, page <body>, or component root.
   ========================================================================== */

[data-land="brain"] {
  --c-land:      var(--c-brain);
  --c-land-2:    var(--c-brain-2);
  --c-land-deep: var(--c-brain-deep);
  --c-land-tint: var(--c-brain-tint);
  --c-land-signal: var(--c-brain-signal);
}

[data-land="body"] {
  --c-land:      var(--c-body);
  --c-land-2:    var(--c-body-2);
  --c-land-deep: var(--c-body-deep);
  --c-land-tint: var(--c-body-tint);
  --c-land-signal: var(--c-body-soft);
}

[data-land="environment"] {
  --c-land:      var(--c-env);
  --c-land-2:    var(--c-env-2);
  --c-land-deep: var(--c-env-deep);
  --c-land-tint: var(--c-env-tint);
  --c-land-signal: var(--c-env-2);
}

/* Land-tinted panels drop --c-text-low below AA. Force the floor up. */
[data-land] .panel,
[data-land][data-tinted="true"] {
  background-color: var(--c-land-tint);
  --c-text-low: var(--c-text-mid);
}


/* ==========================================================================
   4. RESET
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + var(--s-4));
  color-scheme: dark;
  tab-size: 2;
}

body {
  min-height: 100svh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

img, video { height: auto; }

input, button, textarea, select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button { background: none; border: none; padding: 0; cursor: pointer; }

p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }

table { border-collapse: collapse; border-spacing: 0; }

hr { border: none; border-top: 1px solid var(--c-line); }

[hidden] { display: none !important; }

:target { scroll-margin-block-start: calc(var(--nav-h) + var(--s-6)); }


/* ==========================================================================
   5. BASE ELEMENT STYLES
   ========================================================================== */

body {
  background-color: var(--c-void);
  color: var(--c-text);
  font-family: var(--font-body);
  font-size: var(--fs-md);
  font-weight: var(--fw-reg);
  line-height: var(--lh-body);
  letter-spacing: var(--track-body);
  font-synthesis-weight: none;
}

/* Dutch compounds are long; allow hyphenation only where it is correct. */
:lang(nl) { hyphens: auto; }
:lang(nl) { --wdth-display: 92; }
:lang(en) { --wdth-display: 112; }

/* Display type names things. Body type explains them. Never mix the jobs. */
h1, h2, h3 {
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" var(--fw-black);
  font-weight: var(--fw-black);
  color: var(--c-text-hi);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  text-wrap: balance;
}

/* Hyphenation is a reading aid for prose, not for signage. A gate word broken
   across two lines with a hyphen ("werk-woord") stops looking like a sign, so
   the width axis and text-wrap: balance carry the Dutch length instead. */
h1, h2, h3, .display { hyphens: manual; }

h1 { font-size: var(--fs-d2); }
h2 { font-size: var(--fs-d3); }
h3 {
  font-size: var(--fs-d4);
  font-variation-settings: "wdth" var(--wdth-display), "wght" var(--fw-bold);
  font-weight: var(--fw-bold);
  line-height: var(--lh-d4);
  letter-spacing: var(--track-d4);
}

/* h4-h6 are body type. Below --fs-d4 nothing uses the display face. */
h4, h5, h6 {
  font-family: var(--font-body);
  font-weight: var(--fw-semi);
  color: var(--c-text-hi);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-body);
  text-wrap: balance;
}
h4 { font-size: var(--fs-xl); }
h5 { font-size: var(--fs-lg); }
h6 { font-size: var(--fs-md); }

p {
  text-wrap: pretty;
  max-width: var(--w-prose);
}

a {
  color: var(--c-land, var(--c-text-hi));
  text-decoration: none;
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
  transition: color var(--t-2) var(--ease-snap),
              text-decoration-color var(--t-2) var(--ease-snap);
}

/* Inline links inside prose are always underlined — colour is never the
   only signal that something is a link. */
p a, li a, dd a, td a {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
}
p a:hover, li a:hover, dd a:hover, td a:hover {
  text-decoration-color: currentColor;
}

strong, b { font-weight: var(--fw-semi); color: var(--c-text-hi); }
em, i { font-style: italic; }
small { font-size: var(--fs-sm); }

code, kbd, samp, pre {
  font-family: var(--font-mono);
  font-size: 0.9em;
  letter-spacing: var(--track-mono);
}

/* Every measured thing on this site is mono, and every number is tabular. */
:is(code, kbd, samp, pre, .mono, [data-measure], td, th) {
  font-variant-numeric: tabular-nums;
}

table { width: 100%; font-size: var(--fs-sm); }

th {
  text-align: start;
  font-family: var(--font-mono);
  font-weight: var(--fw-med);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-text-mid);
  background-color: var(--c-base-600);
  padding: var(--s-3) var(--s-4);
  border-block-end: 1px solid var(--c-line-strong);
}

td {
  padding: var(--s-3) var(--s-4);
  border-block-end: 1px solid var(--c-line);
  vertical-align: top;
}

caption {
  text-align: start;
  padding-block-end: var(--s-3);
  color: var(--c-text-mid);
  font-size: var(--fs-sm);
}

figcaption {
  font-size: var(--fs-sm);
  color: var(--c-text-mid);
  margin-block-start: var(--s-3);
  max-width: var(--w-prose);
}

blockquote {
  font-size: var(--fs-d4);
  font-family: var(--font-display);
  font-variation-settings: "wdth" var(--wdth-display), "wght" var(--fw-med);
  line-height: var(--lh-d4);
  letter-spacing: var(--track-d4);
  color: var(--c-text-hi);
  border-inline-start: 2px solid var(--c-land);
  padding-inline-start: var(--s-5);
  max-width: 24ch;
}

/* Canvases never carry meaning. */
canvas {
  z-index: var(--z-canvas);
  pointer-events: none;
}


/* ==========================================================================
   6. FOCUS, SELECTION, SCROLLBAR
   ========================================================================== */

/* Two-tone ring. Never remove it. See art-direction.md §2.7. */
:focus-visible {
  outline: 2px solid var(--c-focus-core);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--c-focus);
  border-radius: var(--r-2);
}

/* Inside SVG (the campus map) box-shadow does not paint — use a stroke ring. */
svg :focus-visible {
  outline: none;
  box-shadow: none;
  stroke: var(--c-focus);
  stroke-width: 3;
  paint-order: stroke fill;
}

.skip-link {
  position: absolute;
  inset-block-start: var(--s-2);
  inset-inline-start: var(--s-2);
  z-index: var(--z-skip);
  padding: var(--s-3) var(--s-5);
  background-color: var(--c-base-600);
  color: var(--c-text-hi);
  border-radius: var(--r-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
  transform: translateY(-200%);
  transition: transform var(--t-2) var(--ease-snap);
}
.skip-link:focus-visible { transform: translateY(0); }

::selection {
  background-color: var(--c-land, var(--c-brain-2));
  color: var(--c-void);
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background-color: var(--c-void); }
::-webkit-scrollbar-thumb {
  background-color: var(--c-base-600);
  border: 3px solid var(--c-void);
  border-radius: var(--r-full);
}
::-webkit-scrollbar-thumb:hover { background-color: var(--c-line-hover); }
html { scrollbar-color: var(--c-base-600) var(--c-void); scrollbar-width: thin; }


/* ==========================================================================
   7. LAYOUT PRIMITIVES
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--w-content);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}
.container--wide   { max-width: var(--w-wide); }
.container--narrow { max-width: var(--w-narrow); }
.container--prose  { max-width: var(--w-prose); }

.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-6);
}

@media (max-width: 959px) { :root { --grid-cols: 8; } }
@media (max-width: 719px) { :root { --grid-cols: 4; } }

/* The wayfinding rail is part of the grid, never an overlay. */
.page {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
}
.rail { grid-column: 1; z-index: var(--z-rail); }
.page > :not(.rail) { grid-column: 2; }

.section {
  padding-block: var(--sect-y);
  position: relative;
}
.section--lg { padding-block: var(--sect-y-lg); }
.section--sm { padding-block: var(--sect-y-sm); }
.section--band { background-color: var(--c-base-900); }
.section--land { background-color: var(--c-land-tint); }

/* The horizon: one hairline of light, the connective device of the whole park. */
.horizon {
  position: relative;
  block-size: 1px;
  inline-size: 100%;
  z-index: var(--z-horizon);
  background: linear-gradient(
    to right,
    transparent 0%,
    var(--c-line-strong) 12%,
    var(--c-land, var(--c-line-strong)) 50%,
    var(--c-line-strong) 88%,
    transparent 100%
  );
}
.horizon::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  block-size: 12vh;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--c-land-deep) 55%, transparent), transparent);
  pointer-events: none;
}

/* The bloom: a land lit up in the distance. Max one per viewport. */
.bloom {
  position: absolute;
  inline-size: var(--bloom-size);
  block-size: var(--bloom-size);
  border-radius: var(--r-full);
  background: radial-gradient(circle,
    var(--c-land-deep) 0%,
    color-mix(in srgb, var(--c-land-deep) 40%, transparent) 45%,
    transparent 70%);
  opacity: var(--bloom-opacity);
  filter: blur(24px);
  pointer-events: none;
  z-index: var(--z-below);
}


/* ==========================================================================
   8. TYPE UTILITIES
   ========================================================================== */

.display-1, .display-2, .display-3, .display-4 {
  font-family: var(--font-display);
  color: var(--c-text-hi);
  text-wrap: balance;
}
.display-1 {
  font-size: var(--fs-d1);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  line-height: var(--lh-gate);
  letter-spacing: var(--track-gate);
}
.display-2 {
  font-size: var(--fs-d2);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 900;
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
}
.display-3 {
  font-size: var(--fs-d3);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 800;
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
}
.display-4 {
  font-size: var(--fs-d4);
  font-variation-settings: "wdth" var(--wdth-display), "wght" 700;
  line-height: var(--lh-d4);
  letter-spacing: var(--track-d4);
}

.lead {
  font-size: var(--fs-xl);
  line-height: var(--lh-tight);
  color: var(--c-text);
  max-width: 52ch;
}

.prose { max-width: var(--w-prose); line-height: var(--lh-relaxed); }

/* Eyebrow: mono, uppercase, 11px. Only ever labels something stated in full
   nearby — it never carries unique information. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--c-land, var(--c-text-mid));
  line-height: var(--lh-mono);
}

/* If it is mono, it came off an instrument or a spreadsheet. */
.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  line-height: var(--lh-mono);
  color: var(--c-text-mid);
}

.text-hi  { color: var(--c-text-hi); }
.text-mid { color: var(--c-text-mid); }
.text-low { color: var(--c-text-low); }
.text-land { color: var(--c-land); }

.visually-hidden:not(:focus):not(:active) {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ==========================================================================
   9. USER-PREFERENCE OVERRIDES
   ========================================================================== */

/* ---- 9.1 Reduced motion.
   Per-move fallbacks live in the components (art-direction.md §5.5); this
   block is the safety net. JS must read --motion BEFORE building any GSAP
   timeline or Lenis instance — do not build then disable. -------------- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion: 0;
    --t-1: 1ms; --t-2: 1ms; --t-3: 1ms; --t-4: 1ms;
    --t-5: 120ms; --t-6: 120ms; --t-7: 120ms;
    --t-amb: 0s;
    --stagger: 0ms;
  }
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  /* Opacity-only reveals survive; transforms do not. */
  .bloom { filter: none; }
}

/* ---- 9.2 Reduced transparency ---- */
@media (prefers-reduced-transparency: reduce) {
  :root { --bloom-opacity: 0.25; }
  .nav, .popover, .modal {
    backdrop-filter: none !important;
    background-color: var(--c-void) !important;
  }
}

/* ---- 9.3 More contrast — text steps up, hairlines become real strokes,
   decorative tints drop out. This is the site's answer to "light mode". */
@media (prefers-contrast: more) {
  :root {
    --c-text:     #EDF1F9;
    --c-text-mid: #C9D2E3;
    --c-text-low: #9AA6BF;
    --c-line:        #4A5876;
    --c-line-strong: #6B7A9B;
    --c-line-hover:  #8C99B6;
    --bloom-opacity: 0.2;
    --c-brain-tint: var(--c-base-800);
    --c-body-tint:  var(--c-base-800);
    --c-env-tint:   var(--c-base-800);
  }
  .horizon::after { display: none; }
  :focus-visible { outline-width: 3px; box-shadow: 0 0 0 6px var(--c-focus); }
}

/* ---- 9.4 Forced colors (Windows High Contrast).
   All glow and tint is removed; the system owns colour. Canvases go away —
   they were never load-bearing. ---- */
@media (forced-colors: active) {
  :root {
    --c-land: CanvasText;
    --c-land-2: CanvasText;
    --bloom-opacity: 0;
  }
  canvas, .bloom { display: none !important; }
  .horizon { background: CanvasText; block-size: 1px; }
  .horizon::after { display: none; }
  a { color: LinkText; }
  th, td { border-color: CanvasText; }
  :focus-visible { outline: 3px solid Highlight; box-shadow: none; }
  .panel, .section--land { border: 1px solid CanvasText; }
}

/* ---- 9.5 Print — the sanctioned exception to dark-only. The jury will
   PDF this. Ink on paper, no spectacle, all substance. ---- */
@media print {
  :root {
    --c-void: #FFFFFF; --c-base-900: #FFFFFF; --c-base-800: #FFFFFF;
    --c-base-700: #F2F2F2; --c-base-600: #E8E8E8;
    --c-text-hi: #000000; --c-text: #1A1A1A; --c-text-mid: #3A3A3A;
    --c-text-low: #5A5A5A;
    --c-line: #BBBBBB; --c-line-strong: #888888;
    --c-land: #000000; --c-land-tint: #FFFFFF; --c-land-deep: transparent;
    --bloom-opacity: 0;
    --sect-y: 2rem; --sect-y-lg: 2.5rem; --sect-y-sm: 1.5rem;
  }
  body { background: #FFFFFF; color: #1A1A1A; }
  canvas, .bloom, .rail, .nav, .skip-link { display: none !important; }
  .page { grid-template-columns: 1fr; }
  .page > :not(.rail) { grid-column: 1; }
  .horizon { background: #888888; }
  .horizon::after { display: none; }
  a { color: #000000; text-decoration: underline; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
  .section, table, figure { break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }
}
