/* ===========================================================================
   WebDeviAnt — core
   Tokens, reset, typography, layout primitives.

   Concept: "Standard Deviation". The page is a measuring instrument with one
   anomaly in it. Everything sits on an exposed module; exactly one thing per
   viewport breaks the line, and the break is always neon.

   Governing law: THE INSTRUMENT IS THE FRAME, THE WORDS ARE A DOCUMENT.
   Every conceptual device — the grid, the sigma offsets, the readout rules —
   lives in the chrome. Inside prose, nothing is encoded as a symbol and
   nothing must be decoded.
   ========================================================================= */

/* ---------------------------------------------------------------- tokens -- */

:root {
  /* -- colour ------------------------------------------------------------
     Colour is semantic here, not decorative:
       live  = current, actionable. The only thing permitted to glow.
       past  = history and metadata. Never animates on interaction —
               the past does not respond to you.
       atmos = atmosphere only, never text (it measures ~2:1 on the bg).
     Contrast on --bg: fg 15.2:1, dim 6.2:1, faint 5.0:1,
     live 14.4:1, past-text 6.5:1. All pass WCAG AA for body text.        */
  --bg:          #0d1117;
  --bg-raised:   #11161d;
  --bg-sunken:   #090d12;

  --fg:          #e6edf3;
  --fg-dim:      #8b949e;
  --fg-faint:    #79858f;

  --live:        #70ff21;
  --live-ink:    #0d1117;   /* text placed on a --live fill */
  --past:        #a055ff;   /* rules, plots, graphics */
  --past-text:   #b47cff;   /* the same hue, raised to AA for text */
  --atmos:       #6610f2;

  --rule:        #21262d;
  --rule-strong: #303842;

  /* -- the deviation -----------------------------------------------------
     Every off-module offset on both sites derives from this one value, so
     the rule-breaking reads as systematic rather than sloppy.             */
  --sigma: clamp(0.75rem, 2.2vw, 1.75rem);

  /* -- module ------------------------------------------------------------
     A 40px rhythm. Every vertical space is a multiple; nothing is eyeballed. */
  --m:   2.5rem;          /* 40px */
  --m-1: calc(var(--m) * 0.25);
  --m-2: calc(var(--m) * 0.5);
  --m-3: calc(var(--m) * 0.75);
  --m-4: var(--m);
  --m-6: calc(var(--m) * 1.5);
  --m-8: calc(var(--m) * 2);
  --m-12: calc(var(--m) * 3);
  --m-16: calc(var(--m) * 4);

  /* -- type -------------------------------------------------------------- */
  --font: 'Ubuntu Sans Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo,
          Consolas, 'Liberation Mono', monospace;

  --t-display: clamp(3.25rem, 13vw, 10rem);
  --t-h1:      clamp(2rem, 5.5vw, 3.5rem);
  --t-h2:      clamp(1.5rem, 3.2vw, 2.25rem);
  --t-h3:      1.1875rem;
  --t-lead:    clamp(1.0625rem, 1.6vw, 1.375rem);
  --t-body:    1.0625rem;   /* 17px — the document scale */
  --t-small:   0.8125rem;
  --t-micro:   0.6875rem;   /* readout labels only */

  --measure: 66ch;          /* prose never exceeds this */

  /* -- motion ------------------------------------------------------------
     One easing family, three durations, and a rule of one. A mixed easing
     vocabulary is the most reliable tell of an amateur site.              */
  --ease-out:   cubic-bezier(.16, 1, .3, 1);
  --ease-inout: cubic-bezier(.65, 0, .35, 1);

  --dur: 1;                                    /* global multiplier */
  --t-micro-dur: calc(180ms * var(--dur));     /* hover, focus, colour */
  --t-reveal:    calc(420ms * var(--dur));     /* entrances, rule draws */
  --t-overture:  calc(900ms * var(--dur));     /* the hero, once */

  /* Neon as a variable condition of the page rather than a permanent
     outline on everything. The floor reads this. */
  --floor-intensity: 0.55;

  /* Seconds per 20px tile on the baseline plane — this is what sets how fast
     the grid appears to travel toward you. ~0.95s ≈ 21px/s, matching the
     original. Lower is faster. */
  --baseline-tile-dur: calc(0.95s * var(--dur));

  --shell:  min(100% - 2.5rem, 78rem);
  --z-nav: 40;
  --z-top: 90;
}

/* ----------------------------------------------------------------- reset -- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchored sections must clear the fixed header rail. */
  scroll-padding-top: calc(var(--m-8) + var(--m-2));
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: 1.7;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* `clip` rather than `hidden`: it contains decorative bleed without turning
   the element into a scroll container, which is what lets the sticky header
   rail keep working. */
html, body { overflow-x: clip; }

@supports not (overflow: clip) {
  html, body { overflow-x: hidden; }
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }

img, svg, video { display: block; max-width: 100%; height: auto; }

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

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }

:target { scroll-margin-top: calc(var(--m-8) + var(--m-2)); }

/* A single, unmistakable focus treatment. Never removed, only restyled. */
:focus-visible {
  outline: 2px solid var(--live);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--live); color: var(--live-ink); }

/* ------------------------------------------------------------ typography -- */

h1, h2, h3, h4 { font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; }

.display {
  font-size: var(--t-display);
  line-height: 0.86;
  letter-spacing: -0.055em;   /* hand-tuned: mono at display size runs wide */
  font-weight: 700;
}

.h1 { font-size: var(--t-h1); }
.h2 { font-size: var(--t-h2); letter-spacing: -0.03em; }
.h3 { font-size: var(--t-h3); letter-spacing: -0.01em; }

.lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  color: var(--fg);
  letter-spacing: -0.01em;
}

.prose { max-width: var(--measure); }
.prose p + p { margin-top: var(--m-2); }
.prose a { color: var(--live); text-decoration: underline; }
.prose a:hover { background: var(--live); color: var(--live-ink); text-decoration: none; }

.dim   { color: var(--fg-dim); }
.faint { color: var(--fg-faint); }

/* The one italic on the site — the dictionary definition. */
.definition {
  font-style: italic;
  color: var(--fg-dim);
  max-width: 48ch;
}
.definition b { color: var(--fg); font-style: normal; font-weight: 700; }
.definition .ipa { color: var(--fg-faint); font-style: normal; }

/* Readout labels — the instrument's voice. Never used for content. */
.readout {
  font-size: var(--t-micro);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* ---------------------------------------------------------------- layout -- */

.shell {
  width: var(--shell);
  margin-inline: auto;
}

.section { padding-block: var(--m-8); position: relative; }
.section--tight { padding-block: var(--m-6); }

/* Section headers set as instrument readouts: a full-bleed hairline with
   micro-labels sitting on it. This is the rhythm unit that makes the silence
   between blocks read as intentional rather than empty. */
.rule {
  display: flex;
  align-items: center;
  gap: var(--m-2);
  padding-bottom: var(--m-2);
  margin-bottom: var(--m-4);
  border-bottom: 1px solid var(--rule);
}
.rule__index { color: var(--live); }
.rule__label { margin-left: auto; text-align: right; }

/* A real <h2>, so both documents have a heading outline a screen reader can
   navigate — but styled to sit in the readout rule rather than shout. */
.rule__title {
  font: inherit;
  letter-spacing: inherit;
  margin: 0;
}

.stack > * + * { margin-top: var(--m-2); }
.stack-4 > * + * { margin-top: var(--m-4); }

.grid { display: grid; gap: var(--m-4); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }

/* The deviation, applied. Content sits on the module; anything marked
   deviant steps off it by exactly one sigma. */
.deviant { transform: translateX(var(--sigma)); }

/* ------------------------------------------------------------- utilities --
   A deliberately small set. These exist so the markup carries no `style`
   attributes at all, which is what lets the Content-Security-Policy ship as
   `style-src 'self'` with no 'unsafe-inline' — the directive that actually
   blunts an injected-markup attack.                                        */

.u-live      { color: var(--live); }
.u-plain     { text-decoration: none; }
.u-small     { font-size: var(--t-small); }
.u-flush     { margin: 0; }
.u-mt-1      { margin-top: var(--m-1); }
.u-mt-2      { margin-top: var(--m-2); }
.u-mt-3      { margin-top: var(--m-3); }
.u-mt-4      { margin-top: var(--m-4); }
.u-mb-2      { margin-bottom: var(--m-2); }
.u-tight     { max-width: 34ch; }
.u-tighter   { max-width: 32ch; }
.u-mid       { max-width: 46ch; }
.u-col       { max-width: 34rem; }
.u-pair      { gap: 0 var(--m-2); }
.u-framed    { border: 1px solid var(--rule); border-radius: 3px; }
.u-name      { font-size: clamp(2.75rem, 9vw, 6.5rem); }

/* A button that has to sit in a nav rail and look like the links beside it. */
.u-linkbtn {
  background: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Keyboard users get to the content without walking the whole header. */
.skip-link {
  position: absolute;
  top: -100%;
  left: var(--m-2);
  z-index: var(--z-top);
  background: var(--live);
  color: var(--live-ink);
  padding: var(--m-1) var(--m-2);
  font-weight: 700;
  text-decoration: none;
}
.skip-link:focus { top: var(--m-2); }
