@font-face {
  font-family: 'Source Code Pro';
  src: url('/fonts/source-code-pro-latin-var.woff2') format('woff2');
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #1a1a1a;
  --panel: #2a2a2a;
  --face: #3d3d3d;      /* QUEUED */
  --line: #444444;
  --black: #000000; /* DISPLAY SURFACES ONLY */

  --text: #e0e0e0;
  --text2: #aaaaaa;
  --dim: #888888;

  --mint: #7ccbc3;      /* NOW */
  --mint-past: #3e6360; /* PLAYED */
  --coral: #ff828a;     /* live state + primary action + hover. Nothing else is warm. */

  --band-h: clamp(130px, 26vh, 240px);
  --transport-h: 48px;
  --radius: 2px;
  --t: 120ms;
}

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

html {
  background: var(--bg);
  scroll-behavior: smooth;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: 'Source Code Pro', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

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

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  padding: 12px 20px;
  background: var(--panel);
  color: var(--text);
}
.skip:focus {
  left: 0;
}

/* Tabular numerals — a timecode that jitters column-width reads as a toy. */
.tc {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  color: var(--mint);
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

.hero__ground {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  gap: clamp(1.5rem, 3vh, 2.5rem);
  padding: clamp(1.5rem, 5vw, 5rem);
  padding-bottom: clamp(1.5rem, 4vh, 3rem);
}

.hero__title {
  font-weight: 400;
}

/* aspect-ratio from the SVG's viewBox. Without it the hero reflows when the SVG
   lands, and main.js measures section offsets against the document — a late
   reflow would move the cues. */
.hero__logo {
  display: block;
  width: clamp(240px, 40vw, 470px);
  height: auto;
  aspect-ratio: 775.14 / 194.61;
}

.hero__copy {
  max-width: 62ch;
  color: var(--text2);
  font-size: clamp(14px, 1.05vw, 17px);
  line-height: 1.75;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* The readout strip that turns the band below it into an instrument.
   It carries the band's top rule: the border cannot live on the canvas itself
   (see .band). The strip sits directly above the band, so it lands identically. */
.hero__meta {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 clamp(1.5rem, 5vw, 5rem) 8px;
  border-bottom: 1px solid var(--line);
  color: var(--dim);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.hero__readout {
  display: flex;
  gap: 1.25rem;
}

/* ---------- Instrument band ---------- */

/* The canvas IS the band — no wrapper.
   NO BORDER HERE, EVER. A canvas is a replaced element: its bitmap paints into
   the CONTENT box, but every measurement API worth using (getBoundingClientRect,
   offsetWidth) reports the BORDER box. Under box-sizing: border-box a 1px border
   makes those disagree by 1px, so main.js would size a backing store the browser
   then resamples at a fractional scale — a permanently soft waveform, at every
   dpr. The top rule lives on .hero__meta instead. Same reason .scrub__canvas is
   clean: its border sits on the parent .scrub. */
.band {
  display: block;
  flex-shrink: 0;
  width: 100%;
  height: var(--band-h);
  background: var(--black);
}

/* The hero and the three sections live inside <main>. It must stay a bare box:
   no positioning, no transform, no padding — the playhead is absolutely positioned
   against .hero, and main.js measures section offsets against the document. */
main {
  display: block;
}

/* Runs the full height of the hero, through both zones. This is what stops the
   hero reading as two stacked boxes. */
.playhead {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 1px;
  background: var(--mint);
  box-shadow: 0 0 12px color-mix(in srgb, var(--mint) 55%, transparent);
  pointer-events: none;
  will-change: transform;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-decoration: none;
  text-transform: uppercase;
  transition: color var(--t) linear, border-color var(--t) linear, background var(--t) linear;
}
.btn:hover {
  color: var(--coral);
  border-color: var(--coral);
}

.btn--primary {
  background: var(--coral);
  border-color: var(--coral);
  color: var(--bg);
  font-weight: 600;
}
.btn--primary:hover {
  color: var(--bg);
  filter: brightness(1.12);
}

/* ---------- Sections ---------- */

.section {
  max-width: 1100px;
  padding: clamp(4rem, 12vh, 9rem) clamp(1.5rem, 5vw, 5rem);
  scroll-margin-top: calc(var(--transport-h) + 16px);
}

.section__head {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding-bottom: 1rem;
  margin-bottom: 2rem;
  border-bottom: 1px solid var(--line);
}

/* The index is a state readout, not a label. It rides the same
   queued -> played -> now progression as the waveform. main.js sets the classes. */
.section__idx {
  color: var(--face);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  transition: color var(--t) linear;
}
.section.is-played .section__idx {
  color: var(--mint-past);
}
.section.is-now .section__idx {
  color: var(--mint);
}

.section__title {
  font-size: clamp(28px, 4vw, 52px);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.section__body {
  max-width: 68ch;
  color: var(--text2);
  font-size: clamp(14px, 1.05vw, 17px);
  line-height: 1.8;
}

/* ---------- Team ---------- */

.team {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(4, 1fr);
  margin-bottom: 2.5rem;
  list-style: none;
}

/* Fixed box: these images are hot-linked from a third party and can 404 without
   notice. When they do, the slot stays a panel rectangle instead of collapsing. */
.team__member {
  aspect-ratio: 3 / 4;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

/* Permanently desaturated. There is deliberately no colour-on-hover reveal: the
   <li><img alt=""> is not interactive, so it would be a false affordance, it is
   the only hover on the page that is not coral, and it is dead on touch. */
.team__member img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
}

/* ---------- Contact ---------- */

/* The record has to have somewhere to end. Without a tail below #contact the last section
   gets ~0 scroll span — it begins inside the final viewport-height of the document, which is
   made of scroll positions that do not exist — so its region of the track collapses to zero
   width and the taper to silence, the whole point of the ending, never plays. This space IS
   the taper: the waveform fades to nothing across it, and then END OF TIMELINE.

   The tail is a fixed budget that the hero and contact SHARE: contact's region of the track
   is (tail - vh * (1 - NOW_LINE)) / scrollMax, and the hero's is vh * (1 - NOW_LINE) /
   scrollMax, so the two always sum to tail / scrollMax. Shrinking this padding shrinks that
   budget for both — it cannot be traded away for free, and NOW_LINE in main.js is tuned
   against it. Measured: at 30vh the smallest contact region across 390/912/1024/1440/2560 is
   0.166 of the track, which is enough for the taper to read. Below ~26vh it stops being. */
#contact {
  padding-bottom: 30vh;
}

/* The rule is an underline, not a border, so the box can be padded to a 44px
   target without the rule drifting away from the text. */
.email {
  display: inline-block;
  min-height: 44px;
  padding: 8px 0;
  margin-bottom: 2.5rem;
  color: var(--text);
  font-size: clamp(18px, 2.6vw, 30px);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
  transition: color var(--t) linear, text-decoration-color var(--t) linear;
}
.email:hover {
  color: var(--coral);
  text-decoration-color: var(--coral);
}

.social {
  display: flex;
  gap: 12px;
  list-style: none;
}

.social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 44px;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text2);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-decoration: none;
  transition: color var(--t) linear, border-color var(--t) linear;
}
.social a:hover {
  color: var(--coral);
  border-color: var(--coral);
}
.social svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
}

/* ---------- Footer ---------- */

.footer {
  display: flex;
  justify-content: space-between;
  padding: 1.5rem clamp(1.5rem, 5vw, 5rem);
  border-top: 1px solid var(--line);
  color: var(--dim);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* End of the record, not the playhead — so it must not wear NOW's colour. */
.footer .tc {
  color: var(--dim);
}

/* ---------- Transport ---------- */

.transport {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 20px;
  height: var(--transport-h);
  padding: 0 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  transform: translateY(-100%);
  transition: transform var(--t) linear;
}
.transport.is-visible {
  transform: translateY(0);
}

.transport__mark {
  height: 16px;
  width: auto;
  flex: none;
}

/* --text2, not --dim: --dim on --panel is 4.05:1 and fails AA. (--dim is fine on
   --bg, so .hero__meta and .footer keep it.) */
.transport__status {
  flex: none;
  color: var(--text2);
  font-size: 10px;
  letter-spacing: 0.16em;
}

.transport .tc {
  flex: none;
  font-size: 12px;
}

/* The scrub bar is a real transport control, not a progress indicator.
   NOTE: no overflow: hidden here — it would clip ::after, the hit area. The cue
   labels are clipped by .cues instead. */
.scrub {
  position: relative;
  flex: 1;
  height: 26px;
  min-width: 0;
  background: var(--black);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: ew-resize;
  touch-action: none; /* drag scrubs; it must not also pan the page */
}

/* The bar reads as 26px but must be draggable at 44px — it is the primary
   transport control. Invisible, and outside .cues so nothing clips it. */
.scrub::after {
  content: '';
  position: absolute;
  inset: -9px 0;
}

.scrub__canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* Clips the cue labels to the bar. pointer-events: none already, so unlike
   .scrub this can safely carry overflow. */
.cues {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.cue {
  position: absolute;
  top: 0;
  bottom: 0;
}

.cue__tick {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line);
}

/* The label sits on top of the drawn waveform, so it needs its own ground:
   --dim on bare --face bars is 3.06:1. The chip restores it to a readable
   contrast and keeps the cue reading as a hard marker. */
.cue__label {
  position: absolute;
  top: 50%;
  left: 5px;
  transform: translateY(-50%);
  padding: 2px 3px;
  background: var(--black);
  color: var(--dim);
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.12em;
  white-space: nowrap;
  transition: color var(--t) linear;
}

/* CONTACT US is by construction the cue nearest the right edge; left-anchored it
   escapes the bar and paints over the status text below ~1185px. Flip it. */
.cue:last-child .cue__label {
  left: auto;
  right: 5px;
}

.cue.is-active .cue__tick {
  background: var(--mint);
}
.cue.is-active .cue__label {
  color: var(--mint);
}

/* ---------- Responsive ---------- */

@media (max-width: 720px) {
  .team {
    grid-template-columns: repeat(2, 1fr);
  }
  .transport__status,
  .transport__mark {
    display: none;
  }
  .cue__label {
    display: none;
  }
  /* Direct child only. A descendant selector here would also match #status-hero,
     which is the first child of .hero__readout — hiding TRANSPORT ROLLING and
     leaving the timecode alone on the strip. */
  .hero__meta > span:first-child {
    display: none;
  }
  .hero__readout {
    flex: 1;
    justify-content: space-between;
  }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  * {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
  }
}
