/* ==========================================================================
   GREA — v2-atlas
   MACROSTRUCTURE: 19 · Map / Diagram
   The page is a single map sheet. A fixed plate on the right holds a WebGL
   globe carrying the real operating geography; the document column on the left
   is that globe's legend, its station records and its gazetteer. The camera
   flies to each site as the sheet scrolls, and the pins fly it directly.
   Delete the canvas and the page loses the geography: the coordinates, the
   raster landmass, the state boundaries, the two operating states and the
   reach field all live in the scene.

   ACCENT: teal oklch(0.68 0.11 200) — one accent, under 3% of any viewport
   (site markers, the coverage arcs, focus rings, two hairlines).
   FONTS:  Instrument Serif (display) / Switzer (body) / Space Mono (outlier)

   PRE-EMIT SELF-CRITIQUE
     Philosophy  5 — the shape came from the content: a holding company whose
                    facts are addresses, so the page is an address map.
     Hierarchy   4 — one h1, then stations in travel order, then the gazetteer,
                    then contact. Headings and rules carry the order.
     Execution   4 — named transitions only, tokenised colour, real tabular
                    figures on every numeric column, focus states on all controls.
     Specificity 5 — coordinates, cell counts, simplification tolerances and
                    grant programs are this company's and no one else's.
     Restraint   4 — no icons, no images, no cards, one accent, no blur, no
                    carousel; the only ornament is the graticule.
     Variety     5 — a scroll-driven flying camera over real geometry, not a
                    colour-swapped hero.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens */
:root {
  /* Neutrals are tinted toward the anchor hue (200), never flat grey. */
  --paper:   oklch(0.160 0.012 210);
  --paper-2: oklch(0.195 0.013 210);
  --paper-3: oklch(0.235 0.014 210);
  --ink:     oklch(0.940 0.008 205);
  --ink-2:   oklch(0.700 0.010 208);
  --ink-3:   oklch(0.665 0.010 208);
  --line:    oklch(0.300 0.011 210);
  --line-2:  oklch(0.400 0.011 210);
  --accent:      oklch(0.680 0.110 200);
  --accent-dim:  oklch(0.500 0.075 200);
  --accent-deep: oklch(0.330 0.045 200);

  --fs-xs: 0.75rem;
  --fs-s:  0.875rem;
  --fs-m:  1rem;
  --fs-l:  1.25rem;
  --fs-xl: 1.5625rem;
  --fs-2xl: 1.953rem;
  --fs-3xl: 2.441rem;
  --fs-d: clamp(2.35rem, 5.4vw, 4.5rem);

  --serif: "Instrument Serif", serif;
  --body: "Switzer", sans-serif;
  --mono: "Space Mono", monospace;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --d-micro: 120ms;
  --d-short: 220ms;
  --d-long: 420ms;

  --mast-h: 6.6rem;
  --sheet-w: 45vw;
  --map-w: 55vw;
  --gutter: clamp(1.25rem, 4vw, 4rem);
}

* { box-sizing: border-box; }

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

body {
  overflow-x: clip;
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--body);
  font-size: var(--fs-m);
  line-height: 1.62;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-style: normal; }

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

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

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  padding: 0.6rem 1rem;
  background: var(--paper-2);
  color: var(--ink);
  font-family: var(--mono);
  font-size: var(--fs-s);
  white-space: nowrap;
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

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

/* ---------------------------------------------------------------- masthead
   Not the logo-left / four-links-centre / pill-right default. This is a map
   sheet header: the plate number sits with the wordmark, and the section
   links are numbered stations along a rule. */
.mast {
  position: relative;
  z-index: 6;
  background: var(--paper);
  border-bottom: 1px solid var(--line-2);
  padding: 0.9rem var(--gutter) 0.7rem;
}
.mast__top {
  display: flex;
  align-items: baseline;
  gap: 1.1rem;
  flex-wrap: wrap;
}
.mast__word {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.75rem;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--ink);
}
.mast__sub {
  margin: 0;
  font-size: var(--fs-s);
  color: var(--ink-3);
}
.mast__plate {
  margin: 0 0 0 auto;
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}
.mast__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.4rem;
  margin-top: 0.55rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--line);
}
.mast__nav a {
  font-size: var(--fs-s);
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
  padding: 0.15rem 0;
  transition: color var(--d-micro) var(--ease-out), border-color var(--d-micro) var(--ease-out);
  border-bottom: 1px solid transparent;
}
.mast__nav a:hover { color: var(--ink); border-bottom-color: var(--line-2); }
.mast__nav a .mono { font-size: var(--fs-xs); color: var(--ink-3); margin-right: 0.35rem; }
/* the sheet says which station you are at */
.mast__nav a[aria-current="true"] { color: var(--ink); border-bottom-color: var(--accent-dim); }
.mast__nav a[aria-current="true"] .mono { color: var(--accent); }

/* ---------------------------------------------------------------- main */
main { display: block; }

/* ---------------------------------------------------------------- the plate */
.mapframe {
  position: fixed;
  top: 0; right: 0;
  width: var(--map-w);
  height: 100vh;
  z-index: 1;
  background: var(--paper);
  border-left: 1px solid var(--line);
  overflow: hidden;
}
#plate3d {
  display: block;
  width: 100%;
  height: 100%;
  cursor: crosshair;
}
.mapframe__hud {
  position: absolute;
  left: 1rem; bottom: 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  pointer-events: none;
}
.hud__site {
  margin: 0;
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.hud__read {
  margin: 0;
  font-size: var(--fs-s);
  color: var(--ink-2);
}
.mapframe__scale {
  position: absolute;
  right: 1rem; bottom: 0.9rem;
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--ink-3);
  pointer-events: none;
  white-space: nowrap;
}
.mapframe__pins { position: absolute; inset: 0; pointer-events: none; }

/* Pins are real buttons anchored to real 3D positions: app.js projects each
   marker to screen space every frame. Remove the canvas and they have no
   anchor, which is the point. */
.pin {
  position: absolute;
  left: 0; top: 0;
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.45rem 0.3rem 0.35rem;
  background: none;
  border: 0;
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--fs-xs);
  letter-spacing: 0.03em;
  white-space: nowrap;
  cursor: pointer;
  transform: translate3d(calc(var(--x, -40px) - 4px), calc(var(--y, -40px) - 50%), 0);
  transition: color var(--d-micro) var(--ease-out), opacity var(--d-short) var(--ease-out);
}
.pin__dot {
  width: 8px; height: 8px;
  flex: 0 0 auto;
  border: 1px solid var(--accent);
  background: transparent;
  transform: rotate(45deg);
  transition: background-color var(--d-micro) var(--ease-out);
}
.pin__txt {
  /* A cartographic label halo: without it the type sits on the dot field in
     the same value range as the dots. */
  background: var(--paper);
  padding: 0 0.25rem;
  /* --ox/--oy are the cartographic offset; --ny is added at runtime when a
     label would otherwise collide with one already placed. */
  transform: translate(var(--ox, 8px), var(--oy, 0px)) translateY(var(--ny, 0px));
}
.pin--co { --ox: 2px; --oy: -14px; }
.pin--az { --ox: 2px; --oy: 14px; }
.pin--us { --ox: 10px; --oy: 22px; }
.pin:hover { color: var(--ink); }
.pin:hover .pin__dot { background: var(--accent-dim); }
.pin[aria-current="location"] { color: var(--ink); }
.pin[aria-current="location"] .pin__dot { background: var(--accent); }
.pin[hidden] { display: none; }
.pin--pending .pin__dot { background: var(--accent); }

/* No-WebGL: the sheet still carries every fact the plate encodes. */
.fallback {
  position: absolute;
  inset: auto 1.5rem 1.5rem 1.5rem;
  margin: 0;
  max-width: 34ch;
  font-size: var(--fs-s);
  line-height: 1.55;
  color: var(--ink-3);
}
.mapframe.is-dead #plate3d,
.mapframe.is-dead .mapframe__scale,
.mapframe.is-dead .mapframe__pins { display: none; }
.mapframe.is-dead { display: grid; align-items: end; }

/* ---------------------------------------------------------------- the sheet */
.sheet {
  width: var(--sheet-w);
  padding: 0 var(--gutter) 0 var(--gutter);
}

h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: var(--fs-d);
  font-weight: 400;
  line-height: 1.0;
  letter-spacing: -0.02em;
  color: var(--ink);
  overflow-wrap: anywhere;
  min-width: 0;
  max-width: 14ch;
}
h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: var(--fs-2xl);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--ink);
  overflow-wrap: anywhere;
  min-width: 0;
}

p { margin: 0 0 1rem; max-width: 46ch; }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: var(--fs-l);
  line-height: 1.45;
  color: var(--ink);
  max-width: 40ch;
  margin-top: 1.4rem;
}
.body { color: var(--ink-2); max-width: 44ch; }
.body + .body { margin-top: 1rem; }
.body--caveat { color: var(--ink-3); font-size: var(--fs-s); }

.plate { padding-top: 4.2rem; padding-bottom: 5.5rem; }
.plate .body { margin-top: 1.6rem; }

/* keys and legends — a rule down the left, no card, no border box */
.key { margin-top: 2.4rem; border-left: 1px solid var(--line-2); padding-left: 1rem; }
.key__title {
  margin: 0 0 0.7rem;
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.key__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.65rem; }
.key__list li {
  position: relative;
  padding-left: 1.35rem;
  font-size: var(--fs-s);
  line-height: 1.55;
  color: var(--ink-3);
  max-width: 42ch;
}
.key__list b { color: var(--ink-2); font-weight: 500; font-variant-numeric: tabular-nums; }
.swatch {
  position: absolute;
  left: 0; top: 0.42em;
  width: 9px; height: 9px;
}
.swatch--site { border: 1px solid var(--accent); transform: rotate(45deg); }
.swatch--land { background: var(--ink-2); border-radius: 50%; width: 7px; height: 7px; left: 1px; }
.swatch--line { height: 1px; background: var(--line-2); top: 0.75em; }
.swatch--reach { border-top: 1px solid var(--accent-dim); border-radius: 50% 50% 0 0 / 100% 100% 0 0; top: 0.5em; height: 5px; }

.stats {
  margin: 2.6rem 0 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line-2);
}
.stats > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--line);
}
.stats dt { font-size: var(--fs-s); color: var(--ink-3); }
.stats dd {
  margin: 0;
  font-size: var(--fs-l);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- stations */
.site { padding: 3.4rem 0 3.2rem; border-top: 1px solid var(--line-2); }
.site__no {
  margin: 0 0 1rem;
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  color: var(--accent);
}
.site__lead {
  margin: 0.85rem 0 1.35rem;
  font-size: var(--fs-l);
  line-height: 1.4;
  color: var(--ink);
  max-width: 32ch;
}
.record {
  margin: 2.2rem 0 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  border-top: 1px solid var(--line);
}
.record > div {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: 0.4rem 1.2rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--line);
}
.record dt { font-family: var(--mono); font-size: var(--fs-xs); color: var(--ink-3); letter-spacing: 0.02em; }
.record dd { margin: 0; font-size: var(--fs-s); color: var(--ink-2); }
.record dd.mono { font-variant-numeric: tabular-nums; color: var(--ink); }

.reach { padding: 5rem 0 4.4rem; border-top: 1px solid var(--line-2); }
.reach .site__lead { margin-top: 0.9rem; }

/* ---------------------------------------------------------------- gazetteer */
.index { padding: 6rem 0 4rem; border-top: 1px solid var(--line-2); }
.index .body { margin-bottom: 2.2rem; }
.tablewrap { overflow-x: auto; margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter); }
.gaz {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-variant-numeric: tabular-nums;
  text-align: left;
}
.gaz caption { text-align: left; }
.gaz th, .gaz td {
  padding: 0.62rem 0.9rem 0.62rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: baseline;
  font-weight: 400;
}
.gaz thead th {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom-color: var(--line-2);
}
.gaz tbody th { color: var(--ink); font-size: var(--fs-s); white-space: nowrap; }
.gaz td { font-size: var(--fs-s); color: var(--ink-2); }
.gaz .num { color: var(--ink-3); font-size: var(--fs-xs); width: 2.4rem; }
.gaz td.none { color: var(--ink-3); }
.gaz a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: var(--fs-xs);
  transition: border-color var(--d-micro) var(--ease-out);
}
.gaz a:hover { border-bottom-color: var(--accent); }
.footnote {
  margin: 2rem 0 0;
  font-size: var(--fs-s);
  color: var(--ink-3);
  max-width: 46ch;
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}

/* ---------------------------------------------------------------- contact */
.contact { padding: 3.6rem 0 7rem; border-top: 1px solid var(--line-2); }
.contact .body { margin-top: 1.1rem; }
.mail { margin: 2rem 0 1.6rem; }
.mail a {
  font-size: var(--fs-l);
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--accent-dim);
  padding-bottom: 0.15rem;
  white-space: nowrap;
  transition: border-color var(--d-micro) var(--ease-out), color var(--d-micro) var(--ease-out);
}
.mail a:hover { border-bottom-color: var(--accent); }

/* ---------------------------------------------------------------- footer
   One rule, one line of links, one colophon. Not four columns and icons. */
.foot {
  position: relative;
  z-index: 6;
  background: var(--paper);
  border-top: 1px solid var(--line);
  padding: 1.5rem var(--gutter) 2.5rem;
  width: var(--sheet-w);
}
.foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.foot__links a {
  font-family: var(--mono);
  font-size: var(--fs-s);
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
  transition: color var(--d-micro) var(--ease-out), border-color var(--d-micro) var(--ease-out);
}
.foot__links a:hover { color: var(--ink); border-bottom-color: var(--accent-dim); }
.foot__note, .foot__colophon {
  margin: 1.1rem 0 0;
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: var(--ink-3);
  max-width: 46ch;
}

/* ---------------------------------------------------------------- load moment
   One orchestrated entrance on the sheet, staggered by --i, total under 500ms.
   Nothing animates on scroll except the camera. */
.plate > * {
  opacity: 0;
  transform: translate3d(0, 10px, 0);
  transition: opacity var(--d-long) var(--ease-out), transform var(--d-long) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.plate.is-in > * { opacity: 1; transform: translate3d(0, 0, 0); }
.plate.is-in > *:nth-child(1) { --i: 0; }
.plate.is-in > *:nth-child(2) { --i: 1; }
.plate.is-in > *:nth-child(3) { --i: 2; }
.plate.is-in > *:nth-child(4) { --i: 3; }

/* ---------------------------------------------------------------- narrow */
@media (max-width: 1000px) {
  :root { --gutter: 1.5rem; }
  .sheet, .foot { width: 100%; }
  .mapframe {
    position: sticky;
    top: 0;
    left: 0;
    width: 100%;
    height: 42vh;
    border-left: 0;
    border-bottom: 1px solid var(--line-2);
    order: -1;
    z-index: 4;
  }
  main { display: flex; flex-direction: column; }
  .mast { position: sticky; top: 0; }
  .mast__plate { display: none; }
  .mapframe__scale { display: none; }
  .site, .reach, .index, .contact, .plate { scroll-margin-top: 44vh; }
  .tablewrap { margin: 0; padding: 0; }
}

@media (max-width: 640px) {
  :root { --fs-l: 1.1875rem; }
  .mast__nav { gap: 0.15rem 1.1rem; }
  .mast__nav a { font-size: var(--fs-xs); }
  .plate { padding-top: 2.6rem; padding-bottom: 3.6rem; }
  .site { padding: 2.6rem 0 2.4rem; }
  .reach { padding: 3.2rem 0 3rem; }
  .index { padding: 3.4rem 0 2.6rem; }
  .contact { padding: 2.6rem 0 4rem; }
  .record > div { grid-template-columns: minmax(0, 1fr); gap: 0.1rem; }
  h1 { max-width: 12ch; }
  .mapframe { height: 36vh; }
  .site, .reach, .index, .contact, .plate { scroll-margin-top: 38vh; }
  /* On a 375 px plate the two real sites land about 25 px apart, so the three
     labels get explicit slots instead of one shared offset. Each label carries
     a paper halo because it sits on top of the dot field. */
  .pin { font-size: 0.6875rem; }
  .pin--co { --ox: -64px; --oy: -21px; }
  .pin--az { --ox: -64px; --oy: 6px; }
  .pin--us { --ox: 8px; --oy: 12px; }
}

/* ---------------------------------------------------------------- reduced motion
   Every spatial motion collapses to an opacity crossfade, and the camera
   snaps instead of flying. */
@media (prefers-reduced-motion: reduce) {
  .plate > * {
    transform: none;
    transition: opacity var(--d-micro) linear;
    transition-delay: 0ms;
  }
  .plate.is-in > * { transform: none; }
  .pin, .pin__dot, .mast__nav a, .gaz a, .mail a, .foot__links a {
    transition-property: color, background-color, border-color, opacity;
  }
}
