/* StrictTools — design tokens.

   Derived from the tinymoon token sheet (assets/css/tokens.css in tinymoon):
   the palette, the three-font system, the spacing scale and the motion bands
   are tinymoon's, kept under the same names so the vocabulary stays shared.
   The landing site adds display type sizes, the notch geometry, offset
   shadows, the dot grid, the CRT overlay and the arrow module's variables.

   A variation overrides tokens in its own tokens.css, loaded AFTER this file.
   Only override; never redeclare a component. */

:root {
  color-scheme: dark;

  /* ---------- palette (tinymoon dark) ---------- */
  --bg: #0a0a0a;
  --surface: #141414;
  --surface-2: #191919;
  --surface-3: #1f1f1f;
  --border: #1e1e1e;
  --border-2: #646464;
  --text: #e6e6e6;
  --text-dim: #9c9ca3;
  --text-faint: #8a8a94;
  --accent: #2d6cf4;
  --accent-hi: #5c9dff;
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
  --accent-glow: color-mix(in srgb, var(--accent) 35%, transparent);
  --accent-a12: color-mix(in srgb, var(--accent) 12%, transparent);
  --accent-a18: color-mix(in srgb, var(--accent) 18%, transparent);
  --accent-a35: color-mix(in srgb, var(--accent) 35%, transparent);
  --accent-a40: color-mix(in srgb, var(--accent) 40%, transparent);
  --on-accent: #ffffff;
  --green: #2fbf71;
  --red: #e5484d;
  --gold: #d9a91e;
  --input-bg: #0a0a0a;
  --hover-border: #3a3a3a;

  /* A second accent for variations that want a two-colour arcade palette.
     Defaults to the primary accent so single-accent variations need not care. */
  --accent-2: var(--accent);
  --accent-2-hi: var(--accent-hi);

  /* ---------- fonts (vendored, see base.css) ---------- */
  --font-ui: "Plex", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "Plex Mono", ui-monospace, "Cascadia Code", "Source Code Pro", monospace;
  --font-brand: "Grotesk", system-ui, sans-serif;
  /* The display face for hero and section titles; a variation may point it at
     the mono or at the brand grotesk. Pixel headings use the pixeltext module
     rather than a font. */
  --font-display: var(--font-brand);

  /* ---------- type scale (tinymoon) ---------- */
  --text-3xl: 1.375rem;
  --text-2xl: 1.25rem;
  --text-xl: 1.0625rem;
  --text-lg: 1rem;
  --text-base: 0.875rem;
  --text-sm: 0.84375rem;
  --text-xs: 0.8125rem;
  --text-2xs: 0.75rem;
  --text-3xs: 0.71875rem;
  --text-micro: 0.65625rem;
  --text-label: 0.625rem;

  /* ---------- display scale (landing) ---------- */
  --display-1: clamp(2.75rem, 7vw, 6.5rem);
  --display-2: clamp(2rem, 4.2vw, 3.6rem);
  --display-3: clamp(1.5rem, 2.6vw, 2.2rem);
  --lead: clamp(1.0625rem, 1.4vw, 1.3125rem);
  /* The line under the motto: smaller than the display sizes above, larger
     than the lead and the body text under it. */
  --support: clamp(1.25rem, 2.4vw, 2rem);
  --leading-display: 0.95;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --leading-tight: 1.35;
  --leading-normal: 1.5;
  --leading-relaxed: 1.6;

  /* ---------- spacing (tinymoon) ---------- */
  --space-1: 0.0625rem;
  --space-2: 0.125rem;
  --space-3: 0.1875rem;
  --space-4: 0.25rem;
  --space-5: 0.3125rem;
  --space-6: 0.375rem;
  --space-7: 0.4375rem;
  --space-8: 0.5rem;
  --space-9: 0.5625rem;
  --space-10: 0.625rem;
  --space-12: 0.75rem;
  --space-14: 0.875rem;
  --space-16: 1rem;
  --space-18: 1.125rem;
  --space-20: 1.25rem;
  --space-24: 1.5rem;
  --space-26: 1.625rem;
  --space-28: 1.75rem;
  --space-48: 3rem;
  /* Landing rhythm: the gap between sections and the page gutter. Generous
     by design — few elements per screen, long quiet stretches between them. */
  --section-gap: clamp(5.5rem, 14vw, 13rem);
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --content-max: 1180px;

  /* ---------- ordered dithering ---------- */
  /* The cell size of the Bayer dither the canvas painter draws, and the cell
     size of the CSS checker texture that carries the same look where the
     canvas is not painted (no script, or a page still loading). */
  --dither-pixel: 5;
  --dither-cell: 6px;
  --dither-tint: color-mix(in srgb, var(--accent) 60%, transparent);
  --dither-band-height: clamp(160px, 22vw, 320px);
  /* The three Bayer densities as ready-made images. A conic gradient centred
     on a square tile cuts it into quadrants, so 25%, 50% and 75% coverage are
     exact, square-celled, and need no image file. */
  --dither-checker: conic-gradient(var(--dither-tint) 25%, transparent 0 50%, var(--dither-tint) 0 75%, transparent 0);
  --dither-checker-25: conic-gradient(var(--dither-tint) 25%, transparent 0);
  --dither-checker-75: conic-gradient(transparent 25%, var(--dither-tint) 0);

  /* ---------- shape: the notch ---------- */
  /* The brand angle is 22.5 degrees from vertical (tinymoon's tab slant). A
     notch of rise R has a horizontal run of R x tan(22.5deg) = R x 0.41421.
     Every notched corner in the site is cut from these two numbers. */
  --notch: 24px;
  --notch-run-ratio: 0.41421;
  --notch-sm: 12px;
  --notch-lg: 44px;
  --line-w: 1px;
  --line: var(--border-2);
  --line-strong: var(--text);

  /* ---------- solid offset shadows ---------- */
  /* A shadow is black and semi-transparent, never an accent: an accent block
     behind a box reads as glow, not as weight. Against a near-black page the
     shadow reads because it swallows the dot grid and the dithering under it,
     while the hairline outline keeps the shape's edge. A variation may move
     the offset; it never recolours the shadow. */
  --shadow-x: 8px;
  --shadow-y: 8px;
  --shadow-black: rgb(0 0 0 / 0.72);
  --shadow-black-strong: rgb(0 0 0 / 0.85);
  --shadow-color: var(--shadow-black);
  --shadow-color-hover: var(--shadow-black-strong);
  --shadow-hover-x: 13px;
  --shadow-hover-y: 13px;

  /* ---------- dot grid ---------- */
  --dot-color: color-mix(in srgb, var(--text) 22%, transparent);
  --dot-size: 1px;
  --dot-gap: 24px;
  --dot-parallax: 0.25;

  /* ---------- CRT overlay ---------- */
  --crt-opacity: 0.16;
  --crt-line: 3px;
  --crt-vignette: 0.45;

  /* ---------- arrows ---------- */
  --arrow-color: var(--accent);
  --arrow-width: 5px;
  --arrow-dash: 18 12;
  --arrow-glow: var(--accent-glow);
  --arrow-head: 22px;

  /* ---------- effects ---------- */
  --reveal-shift: 26px;

  /* ---------- motion (tinymoon bands) ---------- */
  --dur-fast: 100ms;
  --dur-quick: 120ms;
  --dur-base: 150ms;
  --dur-mid: 160ms;
  --dur-slow: 180ms;
  --dur-essential-base: 150ms;
  --dur-reveal: 520ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-snap: cubic-bezier(0.6, 0, 0.1, 1);

  /* ---------- z-index ---------- */
  --z-bg: -1;
  --z-arrows: 1;
  --z-content: 2;
  --z-sticky: 20;
  --z-nav: 30;
  --z-crt: 400;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0ms;
    --dur-quick: 0ms;
    --dur-base: 0ms;
    --dur-mid: 0ms;
    --dur-slow: 0ms;
    --dur-essential-base: 100ms;
    --dur-reveal: 0ms;
  }
}

/* The review override (?motion=force, see site/assets/js/gates.js): the
   durations the query above zeroed are put back for that one page load, so a
   workstation that asks for reduced motion can still be shown the page a
   reader with motion allowed sees. Nothing on the site links to it. */
.st-motion-force {
  --dur-fast: 100ms;
  --dur-quick: 120ms;
  --dur-base: 150ms;
  --dur-mid: 160ms;
  --dur-slow: 180ms;
  --dur-essential-base: 150ms;
  --dur-reveal: 520ms;
}

@media (prefers-contrast: more) {
  :root {
    --text-dim: #d4d4da;
    --text-faint: #c8c8d0;
    --border: #4a4a4a;
    --border-2: #8a8a8a;
    --crt-opacity: 0;
    --dot-color: color-mix(in srgb, var(--text) 35%, transparent);
  }
}
