/* Site-wide theme — three pure neon inks on white, maximum brightness.
   The whole site is drawn in exactly three colours — the brightest possible
   neon red ink and lines, neon cobalt for the disc circles (and the text
   inside them), and neon green for the background grid — all sitting on a
   single bright white field. No gradients, no ripples: just a flat field.

   This file owns the shared canvas: the colours, the one typeface, the
   reset and the single base type size and weight. Every page inherits that
   one font, size and weight so type reads in a single voice across the whole
   site; pages add only layout on top, never their own font, size or weight. */

:root {
  /* neon red ink for all type and lines — the brightest possible red */
  --ink: #ff0000;
  /* neon cobalt for the disc circles and the text inside them — the brightest possible blue */
  --circle: #0000ff;
  /* one typeface for the whole site */
  --font: 'Inter', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  /* the single type size for the whole site. Every word on every page is set at
     exactly this size — there is no larger or smaller tier anywhere — and it is
     kept deliberately small for a quiet, minimal read on a phone and on a wide
     desktop alike. Eased down a step so the type sits lighter on the page and the
     surrounding white field reads more open. */
  --type: clamp(0.85rem, 1.5vw, 1rem);
  /* the single type weight for the whole site. Every word on every page is set
     at exactly this weight — there is no bold or light tier anywhere. It is the
     weight the disc text reads at, carried a touch above the default so the
     deliberately small type stays legible on a phone and on a wide desktop.
     Versioned up a step (500 -> 560) to give the small type a touch more
     presence while staying a single, uniform weight across every surface. */
  --weight: 560;
  /* the single softening for every quiet voice on the site. Secondary lines —
     intro copy, legends, the in-disc hints and the stepper captions — are all
     dimmed by exactly this one amount rather than each page picking its own, so
     the contrast between primary and quiet type is identical everywhere. */
  --quiet: 0.8;

  /* One fluid spacing scale for the whole site. Every buffer — page gutters,
     the vertical rhythm between blocks, and the headroom that clears the fixed
     corner logo — is drawn from these tokens, so the whitespace stays in the
     same proportion to the type and to the viewport from a narrow phone all the
     way out to a wide desktop. No page invents its own fixed paddings. The
     rungs run small -> grid -> block, each a step of the same fluid family, so
     every gap on every page is one of these three sizes and nothing else. */

  /* side padding on every page */
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  /* the smallest rung: gaps inside a single component (a disc and its name,
     a stepper's caption and arrows) */
  --gap-sm: clamp(0.6rem, 2vw, 0.9rem);
  /* the middle rung: the gap between discs in every three-by-three grid */
  --gap: clamp(0.9rem, 3vw, 1.6rem);
  /* the largest rung: vertical rhythm between stacked blocks */
  --space: clamp(1.6rem, 4.5vw, 2.6rem);
  /* top headroom: always tall enough to clear the fixed corner logo
     (which itself scales up to ~94px) and the centred back arrow, and to
     keep a clear, even buffer (~1.25–1.7rem at every width) between the bottom
     of the logo and the first element below it, so content never crowds the
     mark. */
  --top-gap: clamp(7.5rem, 18vw, 10.5rem);
  /* matching breathing room at the foot of the page, mirroring the headroom that
     clears the corner logo and back arrow up top, so page content eases into the
     bottom edge fade rather than crowding it. */
  --bottom-gap: clamp(5rem, 11vw, 7.5rem);
}

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

html,
body {
  width: 100%;
  min-height: 100%;
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--type);
  font-weight: var(--weight);
  line-height: 1.4;
  /* keep mobile browsers from inflating our deliberately small type */
  -webkit-text-size-adjust: 100%;
}

/* The white field lives on the root element so the body can stay transparent,
   letting the faint tracer canvas (tracers.js) show through behind the type. */
html {
  background: #ffffff;
}

a {
  color: var(--ink);
}

/* A line asked to stay on one line. The fit-text helper (fit-text.js) measures
   each of these and, only when it would otherwise wrap, eases the type down and
   compresses it horizontally until it fits. The nowrap here states that intent
   declaratively so the line never flashes wrapped before the script runs. */
.fit-line {
  white-space: nowrap;
}

/* The shared "back" chevron, centred at the top of every interior page. As a
   navigation control it sits on the same line as the fixed corner logo
   (home-logo.js, ~64–94px tall), so it is sized up from the body type to a
   fluid scale that reads in proportion to that mark rather than as a stray body
   character. Its offset is fluid and tuned to keep it aligned with the logo.
   Trimmed back a step alongside the logo so the top controls sit lighter and
   leave more open field around them. */
.back-arrow {
  position: fixed;
  top: clamp(1rem, 3vw, 1.8rem);
  /* on a notched phone the status-bar / rounded corner eats into the top of the
     viewport, so add the safe-area inset to the offset. the plain clamp above is
     the fallback for browsers that don't understand env(); they simply ignore
     this second declaration. */
  top: calc(clamp(1rem, 3vw, 1.8rem) + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  color: var(--ink);
  text-decoration: none;
  font-size: clamp(2.2rem, 5vw, 3.2rem);
  line-height: 1;
  padding: 0.4em 0.6em;
  z-index: 10; /* stay above the edge fades, like the fixed corner controls */
}
.back-arrow:hover {
  opacity: 0.7;
}

/* Site-wide edge fade: two fixed white veils, one at the top of the viewport and
   one at the bottom, each a gradient from solid white at the screen edge to fully
   transparent inward. Page content scrolls beneath them, so it dissolves softly
   into the white field as it nears either scrolling edge instead of hitting a
   hard cut — the buffer can never run out, the content just fades away at the
   bottom (and eases in at the top). The veils never take pointer events, and sit
   above the page content but below the fixed corner controls and back arrow
   (z-index 10), so those stay crisp. Their height stays within the page's top and
   bottom buffers so centred pages are untouched. */
body::before,
body::after {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  z-index: 5;
  pointer-events: none;
}
body::before {
  top: 0;
  height: clamp(3rem, 7vh, 5rem);
  background: linear-gradient(to bottom, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
}
body::after {
  bottom: 0;
  height: clamp(3.5rem, 9vh, 6rem);
  background: linear-gradient(to top, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
}
