/* ════════════════════════════════════════════════════════════════════
   FULL-STAG DIGITAL — fsd-theme.css
   Slice 1: theme (CSS variables) + base styles + brutal physics.
   React/utility port of the shipped skin.

   Source of truth for every value: tokens/tokens.json v0.1.0.
   Each declaration cites its token path. Values with no token cite
   their governing rule instead:
     [fsd]  docs/fsd-context.md (constitution)
     [dl]   docs/design-language.md
     [skin] src/assets/main.css (shipped reference — semantics preserved)
   ════════════════════════════════════════════════════════════════════ */

/* ── Brand font — self-hosted (uploaded 2026-07-06) ── */
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/JetBrainsMono-VariableFont_wght.ttf") format("truetype-variations");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/JetBrainsMono-Italic-VariableFont_wght.ttf") format("truetype-variations");
  font-weight: 100 800;
  font-style: italic;
  font-display: swap;
}

:root {
  /* ── Typography — font.mono is the one family; sans/heading/ui alias it
       (font.sans/heading/ui = {font.mono}, operator decision 2026-07-05) ── */
  --font-mono: "JetBrains Mono", "Fira Code", ui-monospace, "SFMono-Regular", "Menlo", monospace; /* font.mono */
  --font-sans: var(--font-mono);    /* font.sans */
  --font-heading: var(--font-mono); /* font.heading */
  --font-ui: var(--font-mono);      /* font.ui */

  /* ── Surfaces — color.surface.* ── */
  --color-background: #000000; /* color.surface.background — page ground, dark-only v1 */
  --color-card: #0a0a0a;       /* color.surface.card */
  --color-elevated: #141414;   /* color.surface.elevated */
  --color-muted: #0a0a0a;      /* color.surface.muted */

  /* ── Ink — color.ink.* ── */
  --color-foreground: #ffffff;       /* color.ink.foreground — role: information */
  --color-muted-foreground: #a0a0a0; /* color.ink.muted — role: context */

  /* ── Edges — color.edge.* ── */
  --color-border: #ffffff; /* color.edge.border — 2px structural borders */
  --color-input: #ffffff;  /* color.edge.input */

  /* ── Accent — color.accent.* — ATOMIC GROUP ──
     Commitment only: promises, guarantees, primary actions, live evidence,
     focus; plus index numerals (Amendments A+B). Never decoration.
     hover/active are DERIVED from default, never set independently
     (operator decision 2026-07-05: derive, not emit — the tokens.json
     hover/active literals are documentation only). */
  --color-accent: #00ff41;            /* color.accent.default */
  --color-accent-foreground: #000000; /* color.accent.foreground */
  --color-accent-hover: color-mix(in srgb, var(--color-accent) 80%, #fff);  /* derived per color.accent.hover $description */
  --color-accent-active: color-mix(in srgb, var(--color-accent) 65%, #fff); /* derived per color.accent.active $description */
  --color-ring: var(--color-accent);  /* focus = commitment [fsd rule 2]; [skin] */

  /* ── Status — color.status.* — status only, never decoration ── */
  --color-success: #00ff41;                /* color.status.success */
  --color-success-foreground: #000000;     /* color.status.success-foreground */
  --color-warning: #fbbf24;                /* color.status.warning */
  --color-warning-foreground: #000000;     /* color.status.warning-foreground */
  --color-info: #60a5fa;                   /* color.status.info */
  --color-info-foreground: #000000;        /* color.status.info-foreground */
  --color-destructive: #ff3131;            /* color.status.destructive — role: violation */
  --color-destructive-foreground: #ffffff; /* color.status.destructive-foreground */

  /* ── Texture — color.texture.* ── */
  --grid-line: #ffffff0d;       /* color.texture.grid-line (white 5%) */
  --grid-line-major: #ffffff1c; /* color.texture.grid-line-major (white 11%) */

  /* ── Semantic role aliases — color.semantic.* ──
     Content-level code addresses roles, not raw colours. */
  --color-structure: var(--color-border);            /* color.semantic.structure */
  --color-information: var(--color-foreground);      /* color.semantic.information */
  --color-context: var(--color-muted-foreground);    /* color.semantic.context */
  --color-commitment: var(--color-accent);           /* color.semantic.commitment */
  --color-violation: var(--color-destructive);       /* color.semantic.violation */

  /* ── Type scale — typescale.* (provisional per token $description) ── */
  --text-metadata: 0.75rem;   /* typescale.metadata */
  --text-small: 0.875rem;     /* typescale.small */
  --text-body: 1rem;          /* typescale.body */
  --text-lead: 1.25rem;       /* typescale.lead */
  --text-h3: 1.5rem;          /* typescale.h3 */
  --text-h2: 2rem;            /* typescale.h2 */
  --text-h1: 3rem;            /* typescale.h1 */
  --text-display: 4.5rem;     /* typescale.display */
  --text-display-max: 6rem;   /* typescale.display-max */

  /* ── Radius — radius.default ──
     The token carries the value; the literal reset below is FSD's pin.
     Both are intentional; keep both (token $description, mutation test
     2026-07-05). */
  --radius: 0rem; /* radius.default */

  /* ── Motion — motion.duration.* + motion.easing.standard ── */
  --duration-fast: 90ms; /* @kind other */    /* motion.duration.fast */
  --duration-normal: 180ms; /* @kind other */ /* motion.duration.normal */
  --duration-slow: 320ms; /* @kind other */   /* motion.duration.slow */
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1); /* @kind other */ /* motion.easing.standard */

  /* ── Illustration zones — PASS 1 (operator-approved 2026-07-07) ──
     Reserved canvas for the future logo system + illustration library.
     Dimension standards every zone snaps to; slots expect inline SVG,
     transparent ground, currentColor ink (dark/light capable), never
     raster. PROVISIONAL: not yet in tokens.json — governing rule is the
     ratified PASS 1 instruction until token designation (standing flag). */
  --illus-hero-w: 20rem; /* @kind other */            /* hero identity-rail column (320px) */
  --illus-hero-ratio: 4 / 5; /* @kind other */        /* portrait rail composition */
  --illus-feature-max-w: 34rem; /* @kind other */     /* feature panels (services/about) */
  --illus-feature-ratio: 4 / 3; /* @kind other */     /* landscape schematic */
  --illus-process-size: 11rem; /* @kind other */      /* square, keyed to process-card scale */
  --illus-social-ratio: 1200 / 630; /* @kind other */ /* OG canvas standard */

  color-scheme: dark; /* dark-only v1 [skin] */
}

/* ════════════════════════════════════════════════════════════════════
   LIGHT THEME — [data-theme="light"] (operator direction 2026-07-07: the HUD
   theme cell toggles it). Default stays dark — the brand's dark-first ground;
   this is the functional alternative. Overrides the token layer plus the two
   hardcoded-dark decorative surfaces (.ground-atmosphere base + the luminous
   stag gradient). The accent flips from neon GREEN to neon ORANGE on light
   (operator direction 2026-07-07 — everything green in dark is orange in light;
   a single accent token serves fills AND text) — still the one commitment
   colour. color-scheme flips so form controls and the UA/themed scrollbar
   follow.
   ════════════════════════════════════════════════════════════════════ */
[data-theme="light"] {
  --color-background: #ffffff;
  --color-card: #f3f3f1;
  --color-elevated: #e7e7e3;
  --color-muted: #f3f3f1;
  --color-foreground: #0a0a0a;
  --color-muted-foreground: #565656;
  --color-border: #0a0a0a;
  --color-input: #0a0a0a;
  --color-accent: #ff5a00;
  --color-accent-foreground: #000000;
  --grid-line: #0000000d;       /* black 5% */
  --grid-line-major: #0000001c; /* black 11% */
  color-scheme: light;
}

/* atmosphere: the grid + accent-glow layers are var-driven (auto-adapt); only
   the hardcoded near-black base gradient is swapped for a near-white lift */
[data-theme="light"] .ground-atmosphere {
  background-image:
    linear-gradient(color-mix(in srgb, var(--grid-line) 60%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--grid-line) 60%, transparent) 1px, transparent 1px),
    linear-gradient(color-mix(in srgb, var(--grid-line-major) 45%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--grid-line-major) 45%, transparent) 1px, transparent 1px),
    radial-gradient(56% 44% at 50% 0%, color-mix(in srgb, var(--color-accent) 8%, transparent), transparent 72%),
    linear-gradient(180deg, color-mix(in srgb, var(--color-accent) 4%, #f4f4f4) 0%, #fafafa 48%, var(--color-background) 100%);
}

/* the page's one luminous element: retint the hardcoded white→green stops so
   the mark reads on a light ground (dark→orange, matching the light accent) */
[data-theme="light"] #stag-lum-grad stop:nth-child(1) { stop-color: #1a1a1a; }
[data-theme="light"] #stag-lum-grad stop:nth-child(2) { stop-color: #ff8a3a; }
[data-theme="light"] #stag-lum-grad stop:nth-child(3) { stop-color: #ff5a00; }

/* ════════════════════════════════════════════════════════════════════
   BASE
   ════════════════════════════════════════════════════════════════════ */

html {
  font-family: var(--font-mono);
  color: var(--color-foreground);
  background-color: var(--color-background);
  /* Numbers use tabular figures [fsd rule 3] */
  font-variant-numeric: tabular-nums;
}

body {
  margin: 0;
  min-height: 100dvh;
  /* Hard guarantee: no horizontal scroll, ever (operator: "absolutely
     forbidden"). `clip` (not `hidden`) does NOT create a scroll container, so
     the sticky nav's viewport positioning is preserved; anything that would
     bleed past the viewport edge is clipped instead of scrolling. Real element
     widths are still fixed at source (buttons wrap, grids stack) — this is the
     backstop, not the excuse. */
  overflow-x: clip;
}

/* Smooth scroll is motion — UA default under reduced motion [skin] */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Box-sizing reset mirrors Tailwind preflight (same rationale as the anchor
   reset below): without it every `w-full px-6` container computes 100% width
   PLUS padding (content-box) and pushes 48px of horizontal overflow.
   Verifier catch, 2026-07-07. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  border-color: var(--color-border);
}

/* Razor-sharp rectangles + no soft/blurred shadows, globally [fsd rule 4].
   Literal 0, not var(--radius): the reset is FSD's pin, the token carries
   the variable (radius.default $description — keep both). Hard offset
   shadows are re-enabled inside @layer brutal-shadows below: for
   !important declarations the cascade reverses, so layered beats
   unlayered [skin]. */
*,
*::before,
*::after {
  border-radius: 0 !important;
  text-shadow: none !important;
  box-shadow: none !important;
}

/* Monospace every control [skin] */
button,
input,
select,
textarea {
  font-family: var(--font-mono);
}

/* Anchors inherit ink and carry no default underline [skin: Tailwind
   preflight `a { color: inherit; text-decoration: inherit }`]. Underlines
   are grammar, opted back in where the law spends them: the active nav
   link (aria-current, below) and the link-variant hover. */
a {
  color: inherit;
  text-decoration: inherit;
}

/* ALL-CAPS, bold, wide-tracked headings — hierarchy through weight, case,
   size, spacing [fsd rule 3]; 0.1em tracking [skin] */
h1,
h2,
h3 {
  font-family: var(--font-heading);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* Accessible brutalist focus — focus is a commitment, so it is accent
   [fsd rule 2]; replaces the removed ring shadow [skin] */
*:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Heavy 2px structural borders wherever a border utility is applied
   (color.edge.border $description; [fsd rule 4]) */
.border { border-width: 2px !important; border-style: solid; }
.border-t { border-top-width: 2px !important; border-top-style: solid; }
.border-b { border-bottom-width: 2px !important; border-bottom-style: solid; }
.border-l { border-left-width: 2px !important; border-left-style: solid; }
.border-r { border-right-width: 2px !important; border-right-style: solid; }
.border-x { border-left-width: 2px !important; border-right-width: 2px !important; border-left-style: solid; border-right-style: solid; }
.border-y { border-top-width: 2px !important; border-bottom-width: 2px !important; border-top-style: solid; border-bottom-style: solid; }

/* ════════════════════════════════════════════════════════════════════
   BRUTAL PHYSICS — hard offset shadows + mechanical press
   The only shadows are hard offsets [fsd rule 4]. Two elevation tiers
   [dl, Amendment D]: the standard 6px block shadow, and one deeper 8px
   tier reserved for the primary CTA — exactly one element per page sits
   highest. Press travel derives from the shadow offset: half depth on
   hover, flat on active [skin].
   ════════════════════════════════════════════════════════════════════ */

@layer brutal-shadows {
  .brutal-shadow {
    box-shadow: 6px 6px 0 0 var(--color-foreground) !important;
  }

  .brutal-shadow-accent {
    /* commitment blocks only [fsd rule 2] */
    box-shadow: 6px 6px 0 0 var(--color-accent) !important;
  }

  .brutal-shadow-lg {
    /* 8px tier — primary CTA only [dl, Amendment D] */
    box-shadow: 8px 8px 0 0 var(--color-foreground) !important;
  }

  /* Mechanical press: the element physically sinks into its shadow. */
  .brutal-press,
  .brutal-press-accent,
  .brutal-press-lg {
    transition:
      transform var(--duration-fast) var(--ease-standard),
      box-shadow var(--duration-fast) var(--ease-standard);
  }

  .brutal-press:hover {
    transform: translate(3px, 3px);
    box-shadow: 3px 3px 0 0 var(--color-foreground) !important;
  }

  .brutal-press:active {
    transform: translate(6px, 6px);
    box-shadow: 0 0 0 0 transparent !important;
  }

  .brutal-press-accent:hover {
    transform: translate(3px, 3px);
    box-shadow: 3px 3px 0 0 var(--color-accent) !important;
  }

  .brutal-press-accent:active {
    transform: translate(6px, 6px);
    box-shadow: 0 0 0 0 transparent !important;
  }

  /* Deep press — pairs with .brutal-shadow-lg; same travel grammar. */
  .brutal-press-lg:hover {
    transform: translate(4px, 4px);
    box-shadow: 4px 4px 0 0 var(--color-foreground) !important;
  }

  .brutal-press-lg:active {
    transform: translate(8px, 8px);
    box-shadow: 0 0 0 0 transparent !important;
  }
}

/* The press is motion — under reduced motion the state still lands,
   without the animated slide [skin]. */
@media (prefers-reduced-motion: reduce) {
  .brutal-press,
  .brutal-press-accent,
  .brutal-press-lg {
    transition: none;
  }
}

/* ════════════════════════════════════════════════════════════════════
   TEXTURE — vector-plotter atmosphere
   The engineering grid expresses real layout structure, like plotter
   paper. Hazard stripes mark genuine boundaries (dev-only zones,
   destructive areas), never decoration [dl]. Scanlines are on probation
   (dev-lab zones only) and are deliberately NOT ported in Slice 1.
   ════════════════════════════════════════════════════════════════════ */

/* Fine 40px squares + bolder 200px major squares [skin] */
.brutal-grid {
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px),
    linear-gradient(var(--grid-line-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line-major) 1px, transparent 1px);
  background-size:
    40px 40px,
    40px 40px,
    200px 200px,
    200px 200px;
}

/* Single-density grid accent [skin] */
.halftone {
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 40px 40px;
}

/* Quiet page-ground grid — operator direction (2026-07-06): the full
   .brutal-grid reads too intense as a site ground (the 200px majors too
   white over content). Same geometry, line inks derived DOWN from the
   texture tokens (fine at 60%, major at 45% of their token alphas). Use
   for page grounds; .brutal-grid stays for bounded texture panels. */
.brutal-grid-quiet {
  background-image:
    linear-gradient(color-mix(in srgb, var(--grid-line) 60%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--grid-line) 60%, transparent) 1px, transparent 1px),
    linear-gradient(color-mix(in srgb, var(--grid-line-major) 45%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--grid-line-major) 45%, transparent) 1px, transparent 1px);
  background-size:
    40px 40px,
    40px 40px,
    200px 200px,
    200px 200px;
}

/* Dense diagonal hazard stripes — genuine boundaries only [dl] [skin] */
.hazard-stripes {
  background-image: repeating-linear-gradient(
    45deg,
    var(--color-accent) 0,
    var(--color-accent) 10px,
    transparent 10px,
    transparent 20px
  );
}

/* Touch texture — operator direction (2026-07-06, revised ×3): every
   interactive (touch) surface carries a faint PRINT-STYLE texture — ONE dot
   matrix reading as transparency: dots are the page ground
   [color.surface.background] at partial strength, so they read as
   perforations through the face on any variant, never as added ink. Green
   never decorates [fsd rule 2] — trivially held, the dots carry no hue.
   The matrix lives on a masked pseudo-element with a HARD-EDGED RECTANGULAR
   EXCLUSION ZONE around the centred label (operator, 2026-07-06, ×4: the
   gradient ellipse read as a translucent smear — the exclusion is a solid
   rectangle now): the mask keeps a 13px frame of dots — exactly two dot
   rows above/below the label and two columns each side (the grid is centred
   so both axes stay symmetric at any element size) — and cuts a clean
   rectangle over the label.
   z-index: the pseudo sits above the face, below the label (stacking
   context on the host, pseudo at -1). Outer box-shadows need no clipping:
   they are clipped inside the border box by spec, so a face going
   transparent on hover shows the page ground through the dots — never the
   shadow rectangle. */
.touch-texture {
  position: relative;
  z-index: 0;
}

.touch-texture::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* crisp SQUARE pixels on an exact 6px grid: a solid ground-coloured fill
     masked by a tiled SVG of one 2px square per cell — every pixel is whole
     and grid-aligned, no radial fuzz and no exclusion-zone band to bisect a
     square (operator direction 2026-07-07, supersedes ruling 4's masked bands).
     The fill is the page ground (theme-adaptive), so the pixels read as punched
     holes on any face; the link variant stays exempt. */
  background-color: color-mix(in srgb, var(--color-background) 42%, transparent);
  /* two mask layers, INTERSECTED: the square-pixel tile AND a feathered radial
     that fades out the centre — so the pixels clear the label region with a soft
     edge (no hard-cut / bisected squares) and it scales to any button size
     (operator direction 2026-07-07: keep squares off the label, gracefully). */
  -webkit-mask-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Crect width='2' height='2' fill='%23fff'/%3E%3C/svg%3E"),
    radial-gradient(ellipse 102% 108% at 50% 50%, transparent 0 46%, #000 82%);
  mask-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Crect width='2' height='2' fill='%23fff'/%3E%3C/svg%3E"),
    radial-gradient(ellipse 102% 108% at 50% 50%, transparent 0 46%, #000 82%);
  -webkit-mask-size: 6px 6px, 100% 100%;
  mask-size: 6px 6px, 100% 100%;
  -webkit-mask-position: 0 0, center;
  mask-position: 0 0, center;
  -webkit-mask-repeat: repeat, no-repeat;
  mask-repeat: repeat, no-repeat;
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* Focal frame — corner brackets marking the page's SINGLE primary CTA
   (operator direction 2026-07-06, revised ×4): four quiet corners at rest
   (context ink, 2px); on hover/focus of the CTA ALL FOUR corners swap to
   pure-white 3px brackets standing 8px further out (motion on state change,
   duration.fast; the ×3 bottom-right-only lead corner was widened to all
   four — operator correction). Emphasis via
   borders (transformation rule), so the brackets are ink, never green — the
   commitment colour lives on the button itself. 24px inset clears the 8px
   press travel + 8px shadow. One per page, paired with .brutal-shadow-lg. */
.focal-frame {
  position: relative;
  display: inline-block;
  padding: 24px;
}

/* rest: four equal quiet corners — context ink [color.ink.muted], 2px arms */
.focal-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: opacity var(--duration-fast) var(--ease-standard);
  background:
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) left top / 16px 2px,
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) left top / 2px 16px,
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) right top / 16px 2px,
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) right top / 2px 16px,
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) left bottom / 16px 2px,
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) left bottom / 2px 16px,
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) right bottom / 16px 2px,
    linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground)) right bottom / 2px 16px;
  background-repeat: no-repeat;
}

/* hover/focus: the quiet corners yield entirely… */
.focal-frame:hover::before,
.focal-frame:focus-within::before {
  opacity: 0;
}

/* …to four white brackets — pure white [color.ink.foreground], 3px arms,
   8px further out */
.focal-frame::after {
  content: "";
  position: absolute;
  inset: -8px;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-standard);
  background:
    linear-gradient(var(--color-foreground), var(--color-foreground)) left top / 28px 3px,
    linear-gradient(var(--color-foreground), var(--color-foreground)) left top / 3px 28px,
    linear-gradient(var(--color-foreground), var(--color-foreground)) right top / 28px 3px,
    linear-gradient(var(--color-foreground), var(--color-foreground)) right top / 3px 28px,
    linear-gradient(var(--color-foreground), var(--color-foreground)) left bottom / 28px 3px,
    linear-gradient(var(--color-foreground), var(--color-foreground)) left bottom / 3px 28px,
    linear-gradient(var(--color-foreground), var(--color-foreground)) right bottom / 28px 3px,
    linear-gradient(var(--color-foreground), var(--color-foreground)) right bottom / 3px 28px;
  background-repeat: no-repeat;
}

.focal-frame:hover::after,
.focal-frame:focus-within::after {
  opacity: 1;
}

/* state still lands under reduced motion, without the fade */
@media (prefers-reduced-motion: reduce) {
  .focal-frame::before,
  .focal-frame::after {
    transition: none;
  }
}

/* ════════════════════════════════════════════════════════════════════
   MOTION — the three sanctioned signatures [fsd rule 5]
   Blinking cursor, one ticker marquee, and the stag-mark glow trace
   (Amendment C). They signal liveness, never decorate. Nothing else
   animates on a loop. All removed under prefers-reduced-motion.
   ════════════════════════════════════════════════════════════════════ */

/* 1 — terminal cursor blink [skin: 1.1s steps(1)] */
@keyframes brutal-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.brutal-blink {
  animation: brutal-blink 1.1s steps(1) infinite;
}

/* 2 — industrial ticker marquee [skin: 28s linear]
   Content must be a real readout; duplicate it once inside the track for
   the seamless -50% loop. */
@keyframes brutal-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

.brutal-marquee {
  animation: brutal-marquee 28s linear infinite;
}

/* 3 — stag-mark glow trace — Amendment C (operator, 2026-07-05).
   A scoped exception to the no-glow / no-extra-loops rules, granted for
   exactly this treatment on exactly this element. Two accent stroke
   layers trace the mark's vector lines on one shared 16s linear loop,
   half-cycle offset. Base fill stays white; the mark never turns solid
   green. Generalises to nothing else. */
.stag-trace {
  pointer-events: none;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.stag-trace-a {
  filter: drop-shadow(0 0 3px var(--color-accent));
  stroke: var(--color-accent);
  stroke-dasharray: 90 3600;
  stroke-width: 2.5;
  animation: stag-trace 16s linear infinite;
}

.stag-trace-b {
  filter: drop-shadow(0 0 2px var(--color-accent-hover));
  stroke: var(--color-accent-hover);
  stroke-dasharray: 60 3630;
  stroke-width: 1.5;
  animation: stag-trace 16s linear infinite;
  animation-delay: -8s;
}

@keyframes stag-trace {
  from { stroke-dashoffset: 0; }
  to { stroke-dashoffset: -3690; }
}

/* Kill switches: all three signatures die entirely under reduced motion
   [fsd rule 5]. */
@media (prefers-reduced-motion: reduce) {
  .brutal-blink,
  .brutal-marquee {
    animation: none;
  }

  .stag-trace {
    display: none;
  }
}

/* ════════════════════════════════════════════════════════════════════
   ACTIVE NAVIGATION — grammar addition (emergent trial) [skin]
   The current page's nav link carries aria-current="page" and a minimal
   underline. No other treatment; the label is navigation, so it is
   never green.
   ════════════════════════════════════════════════════════════════════ */
[data-nav-link][aria-current="page"] {
  color: var(--color-foreground);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}

/* ════════════════════════════════════════════════════════════════════
   SCROLLBAR — operator direction (2026-07-06, corrected ×2): the page
   scrollbar is a touch surface: accent thumb at rest; hovered or dragged,
   the face goes transparent with a slight white infill (the visible "held"
   state) while the border stays illuminated accent. Track stays
   ground behind a structural border. Radius 0 set explicitly — the global
   reset does not reach scrollbar pseudo-elements. Firefox gets the
   two-colour fallback (no per-state styling exists there).
   ════════════════════════════════════════════════════════════════════ */
html {
  scrollbar-color: var(--color-accent) var(--color-background);
}

::-webkit-scrollbar {
  width: 14px;
  height: 14px;
  background: var(--color-background);
}

::-webkit-scrollbar-track {
  background: var(--color-background);
  border-left: 2px solid var(--color-border);
  border-radius: 0;
}

::-webkit-scrollbar-thumb {
  background: var(--color-accent);
  border: 2px solid var(--color-accent);
  border-radius: 0;
}

/* hover/drag (operator correction 2026-07-06 ×2): transparent face + slight
   white infill, border stays accent; the drag infill is one step stronger. */
::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--color-foreground) 12%, transparent);
  border-color: var(--color-accent);
}

::-webkit-scrollbar-thumb:active {
  background: color-mix(in srgb, var(--color-foreground) 22%, transparent);
  border-color: var(--color-accent);
}

::-webkit-scrollbar-corner {
  background: var(--color-background);
}

/* ════════════════════════════════════════════════════════════════════
   ATMOSPHERE — evolution, operator-ratified 2026-07-07.
   A scoped bend to "flat black ground" (the ruling ratifies exactly this
   evolution): the page ground gets life from two levers — a faint accent
   glow behind the content, and a near-black gradient base instead of pure
   #000. The surface ladder above it stays tokenised: ground → card
   [color.surface.card #0a0a0a] → elevated [color.surface.elevated #141414].
   Discipline: the glow is atmospheric and BEHIND content only — no glass,
   no rounded surfaces; every foreground plane stays hard terminal. The
   quiet grid rides on top of the atmosphere (same geometry/inks as
   .brutal-grid-quiet). Glow + base are viewport-fixed so the atmosphere
   holds while content scrolls past.
   ════════════════════════════════════════════════════════════════════ */
.ground-atmosphere {
  background-color: var(--color-background); /* color.surface.background — the floor */
  background-image:
    /* quiet grid (geometry + derived inks identical to .brutal-grid-quiet) */
    linear-gradient(color-mix(in srgb, var(--grid-line) 60%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--grid-line) 60%, transparent) 1px, transparent 1px),
    linear-gradient(color-mix(in srgb, var(--grid-line-major) 45%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--grid-line-major) 45%, transparent) 1px, transparent 1px),
    /* faint accent glow — sanctioned by this ruling; derived from
       color.accent.default, never an independent green */
    radial-gradient(56% 44% at 50% 0%, color-mix(in srgb, var(--color-accent) 6%, transparent), transparent 72%),
    /* near-black base — a breath of lift at the top, settling to the
       token floor; the faint green warmth is accent-derived */
    linear-gradient(180deg, color-mix(in srgb, var(--color-accent) 3%, #0d0d0d) 0%, #050505 48%, var(--color-background) 100%);
  background-size:
    40px 40px,
    40px 40px,
    200px 200px,
    200px 200px,
    100% 100%,
    100% 100%;
  background-attachment: scroll, scroll, scroll, scroll, fixed, fixed;
}

/* ════════════════════════════════════════════════════════════════════
   HUD — terminal amplification (operator final pass, 2026-07-07).
   Governing rule: a HUD element that shows a value must trace to a real
   source and renders absent otherwise; a HUD element with no value is
   free ornament.

   .hud-status — the persistent status strip (hud.jsx): fixed to the
   viewport bottom on every route, one surface step up the ladder
   [color.surface.card], structural 2px top rule, hard cells. Real
   readouts only — the component enforces absent-when-unreal.
   .hud-offset — body companion class: clears the strip's height so the
   footer's colophon is never occluded.
   ════════════════════════════════════════════════════════════════════ */
.hud-status {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40; /* under the sticky nav (z-50) */
  display: flex;
  align-items: stretch;
  overflow: hidden;
  border-top: 2px solid var(--color-foreground);
  background: var(--color-card); /* surface ladder: one step above ground */
}

.hud-status :where(.hud-cell) {
  /* :where() zeroes specificity so the shim's .hidden / sm:flex / lg:flex
     variants win by source order, as designed (verifier-caught) */
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.75rem;
  border-right: 2px solid var(--color-foreground);
  white-space: nowrap;
}

.hud-status :where(.hud-cell--end) {
  margin-left: auto;
  border-right: 0;
  border-left: 2px solid var(--color-foreground);
}

/* interactive cells — locale switch + theme toggle (operator direction
   2026-07-07). A real <button> that reads like a cell: it reports live state
   (honest readout) AND acts. Reset the UA button chrome, keep the cell's
   right rule, add an affordance on hover/focus. */
.hud-status :where(.hud-cell--btn) {
  cursor: pointer;
  background: transparent;
  border: 0 solid var(--color-foreground);
  border-right-width: 2px;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  transition: background var(--duration-fast) var(--ease-standard);
}

.hud-status :where(.hud-cell--btn:hover) {
  background: color-mix(in srgb, var(--color-foreground) 12%, transparent);
}

.hud-status :where(.hud-cell--btn:focus-visible) {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

/* ── HUD controls: locale drop-up, fullscreen, small-screen expander
   (operator direction 2026-07-07) ─────────────────────────────────── */

/* a cell that hosts a drop-up menu (locale, extras) — relative so the panel
   can open UPWARD from the bottom-anchored bar */
.hud-status :where(.hud-cell--menu) {
  position: relative;
}

/* labels collapse on phones so the primary cells stay compact; values remain.
   (Drop-up rows carry their own label markup, not .hud-label, so they stay.) */
.hud-status .hud-label {
  display: none;
}
@media (min-width: 640px) {
  .hud-status .hud-label {
    display: inline;
  }
}

/* drop-up panel — opens above the bar; hard terminal card */
.hud-dropup {
  position: fixed;
  z-index: 60;
  display: flex;
  flex-direction: column;
  border: 2px solid var(--color-foreground);
  background: var(--color-card);
}

.hud-menu-item {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  cursor: pointer;
  white-space: nowrap;
  border: 0 solid var(--color-foreground);
  border-bottom-width: 2px;
  background: transparent;
  color: var(--color-foreground);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  padding: 0.5rem 0.75rem;
}
.hud-menu-item:last-child { border-bottom-width: 0; }
.hud-menu-item:hover,
.hud-menu-item:focus-visible {
  background: color-mix(in srgb, var(--color-foreground) 12%, transparent);
  outline: none;
}
.hud-menu-code { color: var(--color-accent); }
.hud-menu-name { color: var(--color-muted-foreground); }

/* fullscreen exit X — red (destructive ink), the always-reachable escape from
   auto-fullscreen; stays visible even when the bar is shrunk on phones */
.hud-fs-x { color: var(--color-destructive); }

/* the small-screen expander chevron (navbar-style disclosure) */
.hud-nudge svg { transition: transform var(--duration-fast) var(--ease-standard); }
.hud-nudge[aria-expanded="true"] svg { transform: rotate(180deg); }

.hud-offset {
  padding-bottom: 2.25rem;
}

/* ════════════════════════════════════════════════════════════════════
   CORNER TICKS — registration-mark ornament (final pass, 2026-07-07).
   Crop-mark L ticks in the four corners of a composition. Shows no
   value → free ornament under the HUD rule. Quiet ink (foreground 40%),
   hard edges, 12×2px arms; host must be position:relative. Never on an
   already-bordered panel — it frames open compositions, not boxes.
   ════════════════════════════════════════════════════════════════════ */
.corner-ticks::after {
  content: "";
  position: absolute;
  /* inset half a 40px grid unit — registration marks carry clear space on
     both sides: never flush to the page edge or a section boundary
     (operator fix pass, 2026-07-07) */
  inset: 20px;
  pointer-events: none;
  /* tick ink: foreground 40% — derived, not a token (local ornament only) */
  background-image:
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent));
  background-repeat: no-repeat;
  background-size: 12px 2px, 2px 12px, 12px 2px, 2px 12px, 12px 2px, 2px 12px, 12px 2px, 2px 12px;
  background-position: 0 0, 0 0, 100% 0, 100% 0, 0 100%, 0 100%, 100% 100%, 100% 100%;
}

/* ════════════════════════════════════════════════════════════════════
   STAG LUMINANCE — Amendment C zone, extended by the 2026-07-07
   evolution ruling: the mark is the ONE luminous element on the page.
   A static two-radius accent glow under the mark (this class) pairs with
   the gradient fill inside StagMark (luminous prop). Static luminance is
   not motion, so it survives prefers-reduced-motion (the animated trace
   still dies there). Generalises to nothing else — no other element may
   glow.
   ════════════════════════════════════════════════════════════════════ */
.stag-luminous {
  filter:
    drop-shadow(0 0 18px color-mix(in srgb, var(--color-accent) 30%, transparent))
    drop-shadow(0 0 64px color-mix(in srgb, var(--color-accent) 16%, transparent));
}

/* ════════════════════════════════════════════════════════════════════
   PROCESS TIMELINE — evolution ruling 2026-07-07: /how-i-work renders as
   a vertical timeline — numbered nodes on a spine. Hard-edged terminal
   grammar throughout: square nodes (no circles), 2px structural spine
   segments running node-to-node (they end AT the last node — this is a
   spine with terminals, not a truncated separator; ruling 11 governs
   separators, not spines). Node numerals are accent (Amendment B index
   numerals); the ratified ruling extends accent to the node border.
   Spine geometry: nodes are 3.5rem squares → centre at 1.75rem; the ol
   carries gap-10 (2.5rem) → each segment reaches -2.5rem into the gap.
   ════════════════════════════════════════════════════════════════════ */
.process-spine > li {
  position: relative;
}

.process-spine > li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: calc(1.75rem - 1px);
  top: 3.5rem;
  bottom: -2.5rem;
  width: 2px;
  background: var(--color-border);
}

/* NOTE (2026-07-07 course correction): the 2026-07-06 "truncated structural
   rules" experiment (border-image gradients stubbing every white line short
   of its ends, open-corner SVG frames on white boxes) was REVERTED here —
   the separators are load-bearing structure, not ornament, and truncation
   made them read as floating dashes. Full-bleed 2px rules are canonical. */

/* ════════════════════════════════════════════════════════════════
   ILLUSTRATION ZONES — PASS 1 (operator-approved 2026-07-07).
   .illus-frame marks a reserved illustration slot: registration-mark
   corner ticks AT the slot bounds (inset 0 — unlike .corner-ticks the
   slot IS the registration target; the 20px clear-space rule applies to
   page compositions, callers give slots their own clear space via
   placement gaps). Tick ink: foreground 40%, 12×2px arms — same derived
   ornament grammar as .corner-ticks. Shows no value → free ornament under
   the HUD rule; the slot's honest-absence LABEL lives in the component
   (illustration.jsx), not here. Never on an already-bordered panel; the
   frame stays when real art arrives, so the art reads as part of the
   instrument. NOT luminous — the stag stays the page's single luminous
   element (operator constraint, PASS 1 approval).
   ════════════════════════════════════════════════════════════════ */
.illus-frame {
  position: relative;
}

/* ════════════════════════════════════════════════════════════════════
   SERVICES SCROLL GLOW — scroll-driven card illumination (operator
   direction 2026-07-07). ScrollGlow (services-spine.jsx) sets data-lit on
   whichever card the scroll playhead (viewport mid-line) is over; that
   card's border goes accent and a slow accent glow breathes. The breathing
   is a loop, so it dies under reduced motion (fsd rule 5), leaving the
   static accent border. Operator-directed green spend + a glow beyond the
   stag (flagged). The single central line threading the cards (m0104) is
   drawn by the wrapper, not here.
   ════════════════════════════════════════════════════════════════════ */
.scroll-glow :is(ul, ol) > li {
  transition: border-color 0.35s ease;
}

.scroll-glow :is(ul, ol) > li[data-lit="true"] {
  border-color: var(--color-accent);
}

@keyframes fsd-card-glow {
  0%, 100% { filter: drop-shadow(0 0 2px color-mix(in srgb, var(--color-accent) 12%, transparent)); }
  50% { filter: drop-shadow(0 0 14px color-mix(in srgb, var(--color-accent) 34%, transparent)); }
}

@media (prefers-reduced-motion: no-preference) {
  .scroll-glow :is(ul, ol) > li[data-lit="true"] {
    animation: fsd-card-glow 3.6s ease-in-out infinite;
  }
}

.illus-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent)),
    linear-gradient(color-mix(in srgb, var(--color-foreground) 40%, transparent), color-mix(in srgb, var(--color-foreground) 40%, transparent));
  background-repeat: no-repeat;
  background-size: 12px 2px, 2px 12px, 12px 2px, 2px 12px, 12px 2px, 2px 12px, 12px 2px, 2px 12px;
  background-position: 0 0, 0 0, 100% 0, 100% 0, 0 100%, 0 100%, 100% 100%, 100% 100%;
}
