/* Aurascope Labs - one canvas: an eleven-station flythrough and the company page. Monochrome on purpose. */

:root {
  --bg: #000;
  --ink: #f2f2ef;
  --muted: #8d8d8a;
  --dim: #55555a;
  --rule: rgba(255, 255, 255, 0.14);
  --sans: "Instrument Sans", "Inter", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --gutter: clamp(16px, 5vw, 72px);
  --measure: 34rem;
}

* { box-sizing: border-box; }
html { background: var(--bg); color: var(--ink); scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
::selection { background: var(--ink); color: var(--bg); }

/* ---------------------------------------------------------------- canvas */
#scene {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  pointer-events: none;
}
.no-webgl #scene { display: none; }

/* ---------------------------------------------------------------- top bar */
.bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px var(--gutter);
  mix-blend-mode: difference;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: var(--mono);
  font-size: 15px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.brand svg { width: 38px; height: 38px; }
.bar nav { display: flex; gap: 22px; font-family: var(--mono); font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; }
.bar nav a { color: var(--muted); }
.bar nav a:hover { color: var(--ink); text-decoration: none; }

/* ---------------------------------------------------------------- stations */
main { position: relative; z-index: 2; }

.station {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: 18vh var(--gutter);
}
.station[data-text="right"] { justify-content: flex-end; }
.station .card {
  max-width: var(--measure);
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s cubic-bezier(0.2, 0.7, 0.2, 1), transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.station.is-visible .card { opacity: 1; transform: none; }

.eyebrow {
  margin: 0 0 18px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}
.eyebrow::before {
  content: "";
  display: inline-block;
  width: 28px;
  height: 1px;
  background: var(--ink);
  vertical-align: middle;
  margin-right: 12px;
  opacity: 0.6;
}
h1, h2 {
  margin: 0 0 20px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.02;
  text-wrap: balance;
}
h1 { font-size: clamp(42px, 7.2vw, 96px); }
h2 { font-size: clamp(32px, 4.6vw, 60px); }
.body { margin: 0; color: #c9c9c5; font-size: clamp(16px, 1.25vw, 19px); max-width: 30rem; }
.status {
  margin: 26px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.cue {
  margin: 44px 0 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 14px;
}
.cue::after {
  content: "";
  width: 1px;
  height: 36px;
  background: linear-gradient(var(--ink), transparent);
  animation: drop 2.2s ease-in-out infinite;
}
@keyframes drop { 0% { transform: scaleY(0); transform-origin: top; } 50% { transform: scaleY(1); } 100% { transform: scaleY(0); transform-origin: bottom; } }

.lines { list-style: none; margin: 0; padding: 0; }
.lines li {
  padding: 18px 0;
  border-top: 1px solid var(--rule);
  font-size: clamp(20px, 2.2vw, 30px);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.lines li:last-child { border-bottom: 1px solid var(--rule); }

.roadmap { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 28px; margin: 30px 0 0; }
.roadmap-label {
  margin: 0 0 14px;
  padding-top: 12px;
  border-top: 1px solid var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.roadmap-col:nth-child(2) .roadmap-label { border-top-color: var(--muted); }
.roadmap-col:nth-child(3) .roadmap-label { border-top: 1px dashed var(--muted); }
.roadmap-col:nth-child(4) .roadmap-label { border-top: 1px dashed var(--dim); color: var(--muted); }
.roadmap ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.roadmap li { display: grid; gap: 2px; }
.roadmap-name { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink); }
.roadmap-text { font-size: 14px; line-height: 1.35; color: #c9c9c5; }
.roadmap-col:nth-child(4) .roadmap-text { color: var(--muted); }

/* What we do: one row per capability, its name and the projects that show it on one line,
   one sentence under them. The station runs on less vertical padding so all six rows fit
   one screen, which keeps the camera in step with the scroll. */
.station.has-caps { padding-top: 9vh; padding-bottom: 9vh; }
.caps { list-style: none; margin: 24px 0 0; padding: 0; }
.caps li {
  padding: 10px 0 11px;
  border-top: 1px solid var(--rule);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.7s cubic-bezier(0.2, 0.7, 0.2, 1), transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
  transition-delay: calc(0.3s + var(--i, 0) * 0.08s);
}
.caps li:last-child { border-bottom: 1px solid var(--rule); }
.station.is-visible .caps li { opacity: 1; transform: none; }
.cap-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.cap-name {
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
}
.cap-shown { margin: 0; font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.cap-shown .reveal-link { color: var(--ink); }
.cap-text { margin: 5px 0 0; font-size: 15px; line-height: 1.42; color: #c9c9c5; }

/* The company page: its heading is three short sentences, one per line, smaller than the
   flythrough's hero; each station lists the work that shows it under its body, a mono
   name column (like the contact rows) with a few plain words beside each name. */
body[data-page="company"] h1 { font-size: clamp(38px, 5.4vw, 76px); }
.bar nav a[aria-current="page"] { color: var(--ink); }
.shown { margin: 24px 0 0; padding-top: 12px; border-top: 1px solid var(--rule); }
.shown-label {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.shown-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.shown-list li { display: flex; align-items: baseline; gap: 12px; }
.shown-name {
  flex: none;
  min-width: 7.5em;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.shown-name .reveal-link { color: var(--ink); }
.shown-text { font-size: 15px; line-height: 1.42; color: #c9c9c5; }

.links { list-style: none; margin: 28px 0 0; padding: 0; display: grid; gap: 10px; }
.links li { font-family: var(--mono); font-size: 14px; letter-spacing: 0.04em; }
.links span { color: var(--muted); display: inline-block; min-width: 7.5em; }
.foot {
  margin-top: 56px;
  padding-top: 16px;
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--dim);
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------- rail */
/* Built by js/nav.js: one link per station, grouped by pillar, a hairline that fills with
   progress, and the active station's short label beside it. Each link is a 24px target
   with the dot drawn in ::after and a black halo in ::before that parts the hairline
   (black is a no-op under the difference blend, so the halo never shows on glow). */
.rail {
  position: fixed;
  right: max(6px, calc(var(--gutter) / 2 - 10px));
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  display: grid;
  mix-blend-mode: difference;
}
.rail a { position: relative; display: block; width: 24px; height: 22px; }
.rail a::before, .rail a::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.rail a::before { width: 11px; height: 11px; background: #000; }
.rail a::after {
  width: 5px; height: 5px;
  background: var(--ink);
  opacity: 0.34;
  transition: opacity 0.4s, transform 0.4s;
}
.rail a:hover { text-decoration: none; }
.rail a:hover::after { opacity: 0.8; }
.rail a.is-active::after { opacity: 1; transform: translate(-50%, -50%) scale(1.6); }
.rail a.rail-group-start { margin-top: 12px; }

/* ---------------------------------------------------------------- diagrams */
.diagram-toggle {
  display: block;
  margin: 22px 0 0;
  min-height: 44px;
  padding: 0 16px;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 0.3s, background 0.3s;
}
.diagram-toggle:hover { border-color: var(--ink); }
.diagram-toggle:focus-visible, .diagram-close:focus-visible, .bar a:focus-visible, .rail a:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 4px;
}

html:has(.diagram-dialog[open]) { overflow: hidden; }
.diagram-dialog {
  width: min(1240px, calc(100vw - 2 * var(--gutter)));
  max-width: none;
  max-height: min(88vh, 900px);
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--rule);
  overflow: auto;
}
.diagram-dialog::backdrop { background: rgba(0, 0, 0, 0.78); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.diagram-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 24px;
  background: var(--bg);
  border-bottom: 1px solid var(--rule);
}
.diagram-head .eyebrow { margin: 0; }
.diagram-close {
  min-height: 44px;
  padding: 0 4px;
  background: transparent;
  color: var(--muted);
  border: 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}
.diagram-close:hover { color: var(--ink); }
.diagram-body { padding: 8px 24px 28px; }
.diagram { margin: 24px 0 0; }
.diagram figcaption {
  margin: 0 0 16px;
  font-size: clamp(17px, 1.6vw, 22px);
  font-weight: 500;
  letter-spacing: -0.01em;
}
.diagram-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 6px; }
.diagram-scroll svg { display: block; width: 100%; height: auto; }
.diagram-hint {
  margin: 10px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--muted);
}

/* ---------------------------------------------------------------- fallback */
.no-webgl .hero-mark { display: block; width: min(42vw, 360px); margin: 0 0 32px; color: var(--ink); }
.hero-mark { display: none; }

/* ---------------------------------------------------------------- small screens */
@media (max-width: 720px) {
  body { font-size: 15px; }
  h1 { font-size: clamp(40px, 11vw, 56px); }
  h2 { font-size: clamp(27px, 7.4vw, 36px); }
  .body { font-size: 15px; }
  .bar nav { gap: 14px; font-size: 11px; letter-spacing: 0.12em; }
  .bar nav a { padding: 12px 0; }
  .brand span { display: none; }
  .brand svg { width: 32px; height: 32px; }
  .rail { display: none; }
  .station { padding: 14vh var(--gutter); align-items: flex-end; }
  .station[data-text="right"] { justify-content: flex-start; }
  .station .card { max-width: 100%; }
  .body { max-width: 100%; }
  .lines li { font-size: 19px; }
  .roadmap { grid-template-columns: 1fr; gap: 20px; }
  .station.has-caps { padding-top: 7vh; padding-bottom: 5vh; }
  .caps { margin-top: 14px; }
  .caps li { padding: 7px 0 8px; }
  .cap-head { gap: 10px; }
  .cap-name { font-size: 11px; letter-spacing: 0.1em; }
  .cap-shown { letter-spacing: 0.08em; }
  .cap-text { margin-top: 3px; font-size: 14px; line-height: 1.34; }
  .diagram-head { padding: 10px 16px; }
  .diagram-body { padding: 4px 16px 22px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .station .card { transition: none; opacity: 1; transform: none; }
  .caps li { transition: none; opacity: 1; transform: none; }
  .cue::after { animation: none; }
}

/* ================================================================ modules
   One section per module in js/; each carries its own phone and reduced-motion rules. */

/* ---------------------------------------------------------------- nav.js */
/* nav.js drives every in-page flight itself (eased, cancellable, instant under reduced
   motion), so the native smooth scroll would only fight it. */
html { scroll-behavior: auto; }
/* Flights move focus to the station for keyboard and screen-reader users; the section is
   the whole viewport, so it needs no ring. */
.station:focus { outline: none; }

/* The ring goes round the dot, not the 24px target. */
.rail a:focus-visible { outline: none; }
.rail a:focus-visible::after { opacity: 1; outline: 1px solid var(--ink); outline-offset: 4px; }
.rail-track {
  position: absolute;
  right: 11.5px;
  width: 1px;
  background: rgba(255, 255, 255, 0.16);
  pointer-events: none;
}
.rail-fill {
  position: absolute;
  inset: 0;
  background: var(--ink);
  opacity: 0.62;
  transform: scaleY(0);
  transform-origin: top;
}
/* The label runs down beside the rail, read top to bottom, so it stays in the margin even
   when a station's text column is on the right. Below 1100px that margin is too narrow to
   keep it off the text, so it is left out; the dots keep their labels for assistive tech. */
.rail-label {
  position: absolute;
  right: 100%;
  margin-right: 2px;
  writing-mode: vertical-rl;
  font-family: var(--mono);
  font-size: 10px;
  line-height: 1;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
  opacity: 0.6;
  pointer-events: none;
  transition: opacity 0.3s;
}
.rail-label.is-pointed { opacity: 1; }
@media (max-width: 1099px) { .rail-label { display: none; } }

/* Desktop: on the scroll cue's line, so the hero card does not grow (a taller hero would
   shift every station off the camera's stops). Phones: its own line; the bottom-aligned
   hero card has room there. */
.autopilot-play {
  display: inline-flex;
  vertical-align: baseline;
  align-items: center;
  gap: 12px;
  margin: 0 0 0 36px;
  min-height: 36px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.3s;
}
.autopilot-play::before {
  content: "";
  width: 0; height: 0;
  border-left: 7px solid currentColor;
  border-top: 4.5px solid rgba(0, 0, 0, 0);
  border-bottom: 4.5px solid rgba(0, 0, 0, 0);
}
.autopilot-play:hover, .autopilot-play:focus-visible { color: var(--ink); }
.autopilot-play:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }
.autopilot-play[hidden], .no-webgl .autopilot-play { display: none; }
.intro-hold .autopilot-play, .autopilot-play.is-waiting { visibility: hidden; }

.autopilot-chip {
  position: fixed;
  left: 50%;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: calc(100vw - 2 * var(--gutter));
  min-height: 44px;
  padding: 0 0 0 16px;
  background: rgba(0, 0, 0, 0.72);
  border: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  animation: autopilot-in 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.autopilot-chip[hidden] { display: none; }
.autopilot-chip-text { display: flex; gap: 12px; min-width: 0; overflow: hidden; }
.autopilot-chip-mode { color: var(--ink); }
.autopilot-chip-what { overflow: hidden; text-overflow: ellipsis; }
.autopilot-chip-stop {
  align-self: stretch;
  min-height: 44px;
  padding: 0 16px;
  background: none;
  color: var(--ink);
  border: 0;
  border-left: 1px solid var(--rule);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.autopilot-chip-stop:hover { background: rgba(255, 255, 255, 0.06); }
.autopilot-chip-stop:focus-visible { outline: 1px solid var(--ink); outline-offset: -4px; }
@keyframes autopilot-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }

@media (max-width: 720px) {
  .autopilot-play { display: flex; width: max-content; min-height: 44px; margin: 6px 0 0; }
  .autopilot-chip { font-size: 10px; gap: 10px; padding-left: 12px; }
  .autopilot-chip-mode { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .autopilot-play { display: none; }
  .autopilot-chip { animation: none; }
  .rail a::after, .rail-label { transition: none; }
}
/* end nav.js */

/* ---------------------------------------------------------------- type.js */
/* The real text stays in place (and in the accessibility tree) but transparent while an
   aria-hidden copy plays over it; type.js removes the copy when the effect ends. */
.tx-host { position: relative; }
.tx-host > .tx-real { opacity: 0; }
.tx-fx {
  position: absolute;
  inset: 0;
  pointer-events: none;
  user-select: none;
}
/* The eyebrow's leading rule is a pseudo-element on the host; the copy reserves its room. */
.eyebrow > .tx-fx::before {
  content: "";
  display: inline-block;
  width: 28px;
  height: 1px;
  margin-right: 12px;
  vertical-align: middle;
}
/* Title lines: each rises behind a soft-edged mask that sweeps open from the top. */
.tx-line {
  display: block;
  white-space: nowrap;
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
  -webkit-mask-image: linear-gradient(#000 0 34%, transparent 66% 100%);
  mask-image: linear-gradient(#000 0 34%, transparent 66% 100%);
  -webkit-mask-size: 100% 300%;
  mask-size: 100% 300%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
.tx-line-in { display: inline-block; will-change: transform; }
/* Status: the border is redrawn by .tx-rule while the text types on. */
.status.tx-host { border-top-color: transparent; }
.tx-rule {
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--rule);
  transform-origin: left center;
  pointer-events: none;
}
.tx-off { visibility: hidden; }
@media (prefers-reduced-motion: reduce) {
  .tx-fx, .tx-rule { display: none; }
  .tx-host > .tx-real { opacity: 1; }
  .status.tx-host { border-top-color: var(--rule); }
}
/* end type.js */

/* ---------------------------------------------------------------- reveal.js */
/* Project names in the fit station: no colour, a fine underline that firms up on hover and focus. */
.reveal-link {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(255, 255, 255, 0.3);
  text-underline-offset: 0.24em;
  transition: text-decoration-color 0.25s;
}
.reveal-link:hover, .reveal-link:focus-visible { text-decoration: underline; text-decoration-color: var(--ink); }
.reveal-link:focus-visible { outline: 1px solid var(--ink); outline-offset: 3px; }

/* Target lock: corner brackets and a mono label, under the text, never interactive. */
.reveal-lock { position: fixed; inset: 0; z-index: 1; pointer-events: none; display: none; }
.reveal-lock-c {
  position: absolute;
  left: 0; top: 0;
  width: 14px; height: 14px;
  border: 0 solid rgba(242, 242, 239, 0.8);
  will-change: transform;
}
.reveal-lock-tl { border-left-width: 1px; border-top-width: 1px; }
.reveal-lock-tr { border-right-width: 1px; border-top-width: 1px; }
.reveal-lock-bl { border-left-width: 1px; border-bottom-width: 1px; }
.reveal-lock-br { border-right-width: 1px; border-bottom-width: 1px; }
.reveal-lock-label {
  position: absolute;
  left: 0; top: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgba(242, 242, 239, 0.66);
  will-change: transform;
}
@media (max-width: 720px), (hover: none), (pointer: coarse) { .reveal-lock { display: none !important; } }
@media (prefers-reduced-motion: reduce) {
  .reveal-link { transition: none; }
  .reveal-lock { display: none !important; }
}
/* end reveal.js */

/* ---------------------------------------------------------------- sound.js */
/* The sound toggle sits at the end of the bar nav: a four-bar equaliser glyph and, above
   720 px, the word. The bar blends with difference, so it stays monochrome on any frame. */
.sound-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.sound-toggle:hover, .sound-toggle[aria-pressed="true"] { color: var(--ink); }
.sound-toggle:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }
.sound-eq { width: 14px; height: 11px; fill: currentColor; overflow: visible; }
.sound-eq rect { transform-box: fill-box; transform-origin: 50% 100%; transform: scaleY(0.3); transition: transform 0.6s ease; }
.sound-toggle[aria-pressed="true"] .sound-eq rect { animation: sound-eq 1.6s ease-in-out infinite alternate; }
.sound-toggle[aria-pressed="true"] .sound-eq rect:nth-child(2) { animation-duration: 1.1s; animation-delay: -0.4s; }
.sound-toggle[aria-pressed="true"] .sound-eq rect:nth-child(3) { animation-duration: 1.9s; animation-delay: -0.9s; }
.sound-toggle[aria-pressed="true"] .sound-eq rect:nth-child(4) { animation-duration: 1.3s; animation-delay: -0.2s; }
@keyframes sound-eq { from { transform: scaleY(0.25); } to { transform: scaleY(0.9); } }
@media (max-width: 720px) {
  .sound-label { display: none; }
  .sound-toggle { padding: 12px 4px; margin: 0 -4px; }
}
/* Reduced motion: the bars stand still, raised when on. */
@media (prefers-reduced-motion: reduce) {
  .sound-eq rect { transition: none; }
  .sound-toggle[aria-pressed="true"] .sound-eq rect { animation: none; transform: scaleY(0.7); }
  .sound-toggle[aria-pressed="true"] .sound-eq rect:nth-child(odd) { transform: scaleY(0.45); }
}
/* end sound.js */

/* ---------------------------------------------------------------- intro.js */
/* The cold open. While html.intro-hold is set the hero's words, the bar and the rail wait;
   the phase classes bring them in. The headline is uncovered one line at a time by a soft
   mask whose edge, --intro-k, counts lines (line-height 1.02). Removing intro-hold leaves
   every element exactly as the page draws it without the cold open. */
@property --intro-k { syntax: "<number>"; inherits: false; initial-value: 0; }
html.intro-hold #hero .card { opacity: 1; transform: none; transition: none; }
html.intro-hold #hero .card > * {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.9s cubic-bezier(0.2, 0.7, 0.2, 1), transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
html.intro-hold #hero h1 {
  transform: none;
  --intro-k: 0;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(var(--intro-k) * 1.02em - 0.45em), transparent calc(var(--intro-k) * 1.02em));
  mask-image: linear-gradient(to bottom, #000 calc(var(--intro-k) * 1.02em - 0.45em), transparent calc(var(--intro-k) * 1.02em));
  transition: --intro-k 0.6s cubic-bezier(0.3, 0.6, 0.2, 1), opacity 0.3s linear;
}
html.intro-hold.intro-title #hero h1 { opacity: 1; }
html.intro-hold.intro-body #hero .body,
html.intro-hold.intro-cue #hero .cue { opacity: 1; transform: none; }
html.intro-hold .bar,
html.intro-hold .rail { opacity: 0; transition: opacity 0.8s ease; }
html.intro-hold.intro-chrome .bar,
html.intro-hold.intro-chrome .rail { opacity: 1; }
html.intro-hold.intro-skip #hero .card > *,
html.intro-hold.intro-skip .bar,
html.intro-hold.intro-skip .rail { transition-duration: 0.25s; transition-delay: 0s; }
@media (prefers-reduced-motion: reduce) {
  html.intro-hold #hero .card > *, html.intro-hold .bar, html.intro-hold .rail { opacity: 1; transform: none; -webkit-mask-image: none; mask-image: none; }
}
/* end intro.js */

/* ---------------------------------------------------------------- flight.js */
/* end flight.js */

/* ---------------------------------------------------------------- diagrams.js */
/* Open: a short fade with a slight scale; the backdrop's dark and blur ease in.
   Close (.is-closing, set by diagrams.js before it calls close()): the same, reversed. */
.diagram-dialog[open] { animation: dg-in 0.38s cubic-bezier(0.2, 0.7, 0.2, 1); }
.diagram-dialog[open]::backdrop { animation: dg-backdrop-in 0.55s cubic-bezier(0.2, 0.7, 0.2, 1); }
.diagram-dialog.is-closing { animation: dg-out 0.24s cubic-bezier(0.4, 0, 1, 1) forwards; }
.diagram-dialog.is-closing::backdrop { animation: dg-backdrop-out 0.28s cubic-bezier(0.4, 0, 1, 1) forwards; }
@keyframes dg-in { from { opacity: 0; transform: translateY(8px) scale(0.975); } }
@keyframes dg-out { to { opacity: 0; transform: translateY(4px) scale(0.985); } }
@keyframes dg-backdrop-in {
  from { background-color: rgba(0, 0, 0, 0); backdrop-filter: blur(0); -webkit-backdrop-filter: blur(0); }
}
@keyframes dg-backdrop-out {
  to { background-color: rgba(0, 0, 0, 0); backdrop-filter: blur(0); -webkit-backdrop-filter: blur(0); }
}
.diagram-scroll .dg-light { pointer-events: none; }

/* "See how it works": a thin light runs once along the border on hover and focus. */
.diagram-toggle { position: relative; }
.diagram-toggle::after {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 0 38%, rgba(255, 255, 255, 0.85) 50%, transparent 62% 100%) no-repeat;
  background-size: 260% 100%;
  background-position: 120% 0;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0;
}
.diagram-toggle:hover::after, .diagram-toggle:focus-visible::after { animation: dg-sweep 0.9s cubic-bezier(0.4, 0, 0.2, 1) both; }
@keyframes dg-sweep {
  0% { background-position: 120% 0; opacity: 0; }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { background-position: -20% 0; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .diagram-dialog[open], .diagram-dialog[open]::backdrop,
  .diagram-dialog.is-closing, .diagram-dialog.is-closing::backdrop { animation: none; }
  .diagram-toggle::after { display: none; }
}
/* end diagrams.js */
