/* Grand Conservatory / Piano Tuner.
   Brutalist chrome over a gilded photographic world: hard edges, exposed rules,
   structural type, nothing rounded. The ornate identity stays inside the film,
   where it belongs. */

:root {
  --sc-canvas:     #0B0906;
  --sc-surface:    #14100A;
  --sc-ink:        #F4E9D6;
  --sc-ink-soft:   #A2906F;
  --sc-accent:     #C9A227;
  --sc-accent-ink: #0B0906;

  --sc-font-display: "Archivo", system-ui, sans-serif;
  --sc-font-text:    "Geist", system-ui, sans-serif;

  /* One radius scale for the page, and it is zero. */
  --sc-r-sm: 0; --sc-r-md: 0; --sc-r-lg: 0; --sc-r-pill: 0;

  --rule: 1px solid color-mix(in oklab, var(--sc-accent) 42%, transparent);
  --rule-soft: 1px solid color-mix(in oklab, var(--sc-ink) 16%, transparent);
  --chan: clamp(15rem, 20vw, 21rem);   /* the side channel the copy lives in */
}

body { background: var(--sc-canvas); }

/* ------------------------------------------------------------------ map --
   The nav of a continuous world is a map: where you are, what is ahead, and a
   way to get there. Left channel on desktop, a tick strip on a phone. */
.map {
  position: fixed; z-index: var(--sc-z-chrome);
  top: 0; left: 0; bottom: 0;
  width: var(--chan);
  padding: var(--sc-5) var(--sc-5) var(--sc-8);
  display: flex; flex-direction: column; gap: var(--sc-7);
  pointer-events: none;
}
.map > * { pointer-events: auto; }

.map__mark { text-decoration: none; color: var(--sc-ink); display: block; }
.map__name {
  display: block;
  font-family: var(--sc-font-display);
  font-weight: 900; font-size: var(--sc-t-xl);
  line-height: 0.9; letter-spacing: var(--sc-track-tight);
  text-transform: uppercase;
}
.map__sub {
  display: block; margin-top: var(--sc-2);
  font-size: var(--sc-t-xs); letter-spacing: var(--sc-track-wide);
  text-transform: uppercase; color: var(--sc-ink-soft);
}

.map__legs { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
.map__now { display: none; }
.map__leg {
  width: 100%; display: grid; grid-template-columns: 44px 1fr;
  align-items: center; gap: var(--sc-3);
  background: none; border: 0; border-top: var(--rule-soft);
  padding: var(--sc-2) 0;
  font-size: var(--sc-t-xs); letter-spacing: var(--sc-track-wide);
  text-transform: uppercase; color: var(--sc-ink-soft);
  text-align: left; cursor: pointer;
  transition: color var(--sc-d-fast) var(--sc-ease-out);
}
.map__legs li:last-child .map__leg { border-bottom: var(--rule-soft); }
.map__bar { display: block; height: 3px; background: color-mix(in oklab, var(--sc-ink) 18%, transparent); position: relative; }
.map__bar::after {
  content: ""; position: absolute; inset: 0 auto 0 0;
  width: 100%; background: var(--sc-accent);
  transform: scaleX(0); transform-origin: 0 50%;
}
.map__leg[aria-current="true"] { color: var(--sc-ink); }
.map__leg[data-done="true"] .map__bar::after { transform: scaleX(1); }
.map__leg[aria-current="true"] .map__bar::after { transform: scaleX(var(--segp, 0)); }
@media (hover: hover) and (pointer: fine) { .map__leg:hover { color: var(--sc-ink); } }
.map__leg:active { transform: translateY(1px); }

/* The motion opt-in. Only exists for readers whose system asked for reduced
   motion, because for anyone else the film is already playing. */
.map__motion {
  display: none;
  background: none; color: var(--sc-ink-soft);
  border: 0; border-top: var(--rule);
  padding: var(--sc-3) 0 0;
  font-size: var(--sc-t-xs); letter-spacing: var(--sc-track-wide);
  text-transform: uppercase; text-align: left; cursor: pointer;
  text-decoration: underline; text-underline-offset: 4px;
  transition: color var(--sc-d-fast) var(--sc-ease-out);
}
:root[data-os-reduce] .map__motion { display: block; }
@media (hover: hover) and (pointer: fine) { .map__motion:hover { color: var(--sc-accent); } }

/* ----------------------------------------------------------------- copy --
   The film is a portrait plate on a blurred field. The copy takes the right
   channel, which is why the plate was framed to leave one. */
.scrim {
  background:
    linear-gradient(to left,
      color-mix(in oklab, var(--sc-canvas) 94%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 86%, transparent) 26%,
      color-mix(in oklab, var(--sc-canvas) 40%, transparent) 62%,
      transparent 82%),
    linear-gradient(to right,
      color-mix(in oklab, var(--sc-canvas) 92%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 30%, transparent) 30%,
      transparent 50%);
}

.copy {
  position: absolute;
  right: var(--sc-5);
  /* Bounded above the beat bar rather than centred on the viewport. The engine
     owns transform on a copy block for its drift, so a translateY(-50%) here is
     overwritten every frame and the block runs down under the bar. */
  top: var(--sc-6); bottom: 104px;
  width: min(var(--chan), 92vw);
  display: flex; flex-direction: column; justify-content: center;
}
.copy h1, .copy h2 {
  font-family: var(--sc-font-display);
  font-weight: 900; text-transform: uppercase;
  letter-spacing: var(--sc-track-tight);
  line-height: var(--sc-leading-none);
  margin: 0 0 var(--sc-4);
  text-wrap: balance;
  /* the copy channel is narrow by design; a long word must break, not clip */
  overflow-wrap: break-word;
}
.copy h1 { font-size: clamp(2rem, 2.4vw + 1rem, 3.1rem); }
.copy h2 { font-size: clamp(1.5rem, 1.5vw + 0.85rem, 2.1rem); }
.copy p { margin: 0 0 var(--sc-4); max-width: 34ch; text-wrap: pretty; color: var(--sc-ink); }
.copy .lede { font-size: var(--sc-t-lg); line-height: 1.45; color: var(--sc-ink); }
.copy p:last-child { margin-bottom: 0; }

.kicker {
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-xs); font-weight: 500;
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  color: var(--sc-accent);
  margin: 0 0 var(--sc-3) !important;
  padding-bottom: var(--sc-2); border-bottom: var(--rule);
}
.note { font-size: var(--sc-t-sm); color: var(--sc-ink-soft); }

/* the three real readings, set as a register rather than as cards */
.facts { list-style: none; margin: 0 0 var(--sc-4); padding: 0; display: grid; gap: 1px; }
.facts li {
  display: grid; grid-template-columns: 2.2rem 1fr; align-items: baseline;
  border-top: var(--rule-soft); padding: var(--sc-2) 0;
}
.facts li:last-child { border-bottom: var(--rule-soft); }
.facts b {
  font-family: var(--sc-font-display); font-weight: 800;
  color: var(--sc-accent); font-size: var(--sc-t-sm);
}
.facts span {
  display: flex; justify-content: space-between; gap: var(--sc-3);
  font-variant-numeric: tabular-nums; font-size: var(--sc-t-sm);
}
.facts i { font-style: normal; color: var(--sc-ink-soft); }

/* ---------------------------------------------------------------- close --
   Arrival: the CTA is an object in the place, not a button island floating
   over a fade-out. */
.copy--finale h2 { font-size: clamp(2rem, 2.4vw + 1rem, 3.1rem); }
.cta {
  display: inline-block; margin: var(--sc-2) 0 var(--sc-5);
  background: var(--sc-accent); color: var(--sc-accent-ink);
  font-family: var(--sc-font-display); font-weight: 800;
  text-transform: uppercase; letter-spacing: var(--sc-track-wide);
  font-size: var(--sc-t-sm);
  padding: var(--sc-3) var(--sc-5);
  text-decoration: none; white-space: nowrap;
  border: 2px solid var(--sc-accent);
  transition: background var(--sc-d-fast) var(--sc-ease-out),
              color var(--sc-d-fast) var(--sc-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .cta:hover { background: transparent; color: var(--sc-accent); }
}
.cta:active { transform: translateY(1px); }
.fine { font-size: var(--sc-t-sm); color: var(--sc-ink-soft); }
.fine a { color: var(--sc-ink); text-underline-offset: 3px; }

/* ------------------------------------------------------------ beat bar --
   The signature move. Three strings of one unison, beating at the frequency
   their cent offsets actually imply. */
.beat {
  position: fixed; z-index: calc(var(--sc-z-chrome) + 1);
  left: 0; right: 0; bottom: 0;
  height: 88px;
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: var(--sc-5);
  padding: 0 var(--sc-5);
  background: linear-gradient(to top,
    color-mix(in oklab, var(--sc-canvas) 96%, transparent),
    color-mix(in oklab, var(--sc-canvas) 72%, transparent) 70%,
    transparent);
  border-top: var(--rule);
}
.beat__wave { width: 100%; height: 64px; touch-action: pan-y; cursor: ew-resize; }
.beat__read {
  display: flex; align-items: baseline; gap: var(--sc-3);
  font-size: var(--sc-t-xs); letter-spacing: var(--sc-track-wide);
  text-transform: uppercase;
}
.beat__label { color: var(--sc-ink-soft); }
.beat__hz {
  font-family: var(--sc-font-display); font-weight: 800;
  font-size: var(--sc-t-lg); letter-spacing: var(--sc-track-snug);
  color: var(--sc-accent); font-variant-numeric: tabular-nums;
  min-width: 6.5ch; text-align: right; text-transform: none;
}
.beat__hint { color: var(--sc-ink-soft); }
@media (hover: none), (pointer: coarse) { .beat__hint { display: none; } }

/* ------------------------------------------------------------- narrower --
   Below 1200px the plate takes the whole frame, so the copy stops being a
   channel and becomes a band, and the map collapses to a tick strip. */
@media (max-width: 1200px) {
  :root { --chan: 100%; }
  .map {
    inset: 0 0 auto 0; width: auto; bottom: auto;
    flex-direction: row; align-items: center; gap: var(--sc-4);
    padding: var(--sc-3) var(--sc-4);
    background: linear-gradient(to bottom,
      color-mix(in oklab, var(--sc-canvas) 92%, transparent),
      transparent);
  }
  .map__name { font-size: var(--sc-t-base); }
  .map__sub { display: none; }
  .map__legs { flex: 1; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--sc-1); }
  .map__leg { grid-template-columns: 1fr; border: 0; padding: var(--sc-2) 0; gap: 0; }
  /* Seven labels do not fit across a phone, and seven truncated ones are worse
     than none. The bars carry position; one live label carries the name. */
  .map__leg span { display: none; }
  .map__motion { padding: 0; border: 0; order: 4; white-space: nowrap; }
  .map__now {
    display: block; margin: 0; order: 3;
    font-size: var(--sc-t-xs); letter-spacing: var(--sc-track-wide);
    text-transform: uppercase; color: var(--sc-ink);
    white-space: nowrap;
  }
  .scrim {
    background: linear-gradient(to top,
      color-mix(in oklab, var(--sc-canvas) 96%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 88%, transparent) 34%,
      color-mix(in oklab, var(--sc-canvas) 34%, transparent) 62%,
      transparent 78%);
  }
  .copy {
    right: var(--sc-4); left: var(--sc-4); width: auto;
    display: block; top: auto; bottom: 96px;
  }
  .copy p { max-width: 46ch; }
  .beat { height: 76px; grid-template-columns: 1fr auto; }
  .beat__wave { height: 46px; }
}

@media (max-width: 700px) {
  .copy h1 { font-size: clamp(1.7rem, 6vw, 2.2rem); }
  .copy h2 { font-size: clamp(1.45rem, 5.2vw, 1.9rem); }
  .copy .lede { font-size: var(--sc-t-base); }
  .facts span { font-size: var(--sc-t-xs); }
  .beat__hz { font-size: var(--sc-t-base); }
}

/* ------------------------------------------------------- reduced motion --
   Fewer and gentler, not zero: the posters still cross-dissolve through the
   same seams and every copy window still opens. The beat bar holds one locked
   frame instead of animating. */
@media (prefers-reduced-motion: reduce) {
  .map__leg:active, .cta:active { transform: none; }
}
