/* ==========================================================================
   BASE — reset, type scale, layout, texture, focus, link treatment

   Spacing is one-sided everywhere: vertical space is applied as
   `margin-block-start` on the following element, never as a bottom margin.
   A `margin-bottom` in this codebase is a defect — gaps could then stack.
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
  /* Fully matte, sharp corners. The only circles in the system are status
     lamps, which opt back in explicitly. */
  border-radius: 0;
}

:where(body, h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd) {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  background-color: var(--ground);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lead-body);
  /* No horizontal scroll at any width; layouts reflow instead. */
  overflow-x: hidden;
}

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

/* --------------------------------------------------------------------------
   Texture — two generated layers, behind all content, information-free.
   Grain: coarse fractal noise biased faint by an alpha gamma curve, so it
   reads as material tooth rather than static — feature size (~5px), not
   intensity, is what makes it perceptible. Peak per-pixel alpha is capped by
   --grain-alpha (8% dark / 4% light) because the layer's opacity multiplies
   the source.
   -------------------------------------------------------------------------- */

.texture {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.texture__grain {
  position: absolute;
  inset: 0;
  opacity: var(--grain-alpha);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='280' height='280'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.18' numOctaves='5' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='gamma' exponent='2.6' amplitude='1' offset='0'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='280' height='280' filter='url(%23g)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 392px 392px; /* 280px tile at ~1.4x */
}

.texture__vignette {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    120% 55% at 50% 0%,
    rgb(0 0 0 / var(--vignette-alpha)) 0%,
    rgb(0 0 0 / 0) 72%
  );
}

/* --------------------------------------------------------------------------
   Type scale
   -------------------------------------------------------------------------- */

.t-display {
  font-family: var(--font-mono);
  font-size: var(--text-display);
  line-height: var(--lead-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--track-display);
  color: var(--ink);
}

.t-kicker {
  font-family: var(--font-sans);
  font-size: var(--text-kicker);
  line-height: var(--lead-kicker);
  color: var(--ink);
}

.t-lead {
  font-family: var(--font-sans);
  font-size: var(--text-lead);
  line-height: var(--lead-lead);
  color: var(--ink);
}

.t-body {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lead-body);
  color: var(--ink);
}

/* --muted is for labels and captions only. A muted paragraph is a defect. */
.t-label {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  line-height: var(--lead-label);
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--muted);
  font-weight: 400;
}

.t-micro {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--lead-micro);
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--muted);
}

.t-terminal {
  font-family: var(--font-mono);
  font-size: var(--text-terminal);
  line-height: var(--lead-terminal);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.t-readout {
  font-family: var(--font-mono);
  font-size: var(--text-readout);
  line-height: var(--lead-readout);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

code {
  font-family: var(--font-mono);
  font-size: 0.9375em;
  color: var(--ink);
}

/* Every metric, timestamp and count-up target holds its column. */
[data-countup],
.metric,
time {
  font-variant-numeric: tabular-nums;
}

/* Read but not seen. The count-up's stand-in — the exact final value, held in
   the accessibility tree for the 1.2 seconds the visible digits spend being
   wrong (scripts/count-up.js). No page content uses this: an element only
   ever carries it while a number is rolling, and only the engine creates it.
   Absolutely positioned and one pixel, so it costs no layout and cannot move
   the cell it stands in for. */
.a11y-value {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  white-space: nowrap;
  clip-path: inset(50%);
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.container {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.read {
  max-width: var(--read-max);
}

.flow > * + * {
  margin-block-start: var(--gap-flow);
}

/* Sections own no external margins. The section rule sits flush at the top
   edge; the section's own air is applied below it and after its content. */
.section {
  padding-block: 0 var(--gap-section);
}

.section--hero {
  padding-block-start: var(--gap-section);
}

.section__body {
  margin-block-start: var(--gap-section);
}

/* --------------------------------------------------------------------------
   Scroll landing — where ANY scroll-into-view comes to rest (page-shell.md §7.1)

   The page does not snap: the reader's scroll rests exactly where the reader
   leaves it, and nothing here declares scroll-snap-type on the document
   scroller. The one snap container on the page is §4's sheet track, on its own
   x axis, inside one section (sections.css).

   This padding was never part of that feature and does not leave with it:
   anchors, the skip link and the browser's own find-in-page all land under the
   sticky bar without it. It is the bar plus one --rhythm rather than the bar's
   own height, so a section's opening hairline never parks a few pixels beneath
   the bar's and reads as an accidental double rule. It stays under reduced
   motion — a reader who asked for less motion still needs to clear the bar.
   -------------------------------------------------------------------------- */

:root {
  scroll-padding-block-start: var(--scroll-pad);
}

/* --------------------------------------------------------------------------
   Links and focus
   -------------------------------------------------------------------------- */

/* Rust at reading size measures below AA, so the underline carries linkness
   and the text stays full ink. */
a {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   Coarse pointers — the hit area grows, the visual does not.
   -------------------------------------------------------------------------- */

@media (pointer: coarse) {
  .chip,
  .control,
  .link-block,
  .pagefoot__receipts a {
    min-block-size: 44px;
    min-inline-size: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* --------------------------------------------------------------------------
   Forced colors — texture drops out, every border becomes a system colour,
   nothing depends on a background alone.
   -------------------------------------------------------------------------- */

@media (forced-colors: active) {
  .texture {
    display: none;
  }

  :focus-visible {
    outline-color: Highlight;
  }
}
