/* Palette, fonts and --gutter/--ease come from /theme.css.
   --hue is written per chapter by js/main.js as the artwork crossfades. */
:root { --hue: var(--red); }

* { box-sizing: border-box; margin: 0; padding: 0; }
html { background: var(--bg); }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
:where(button, label.btn, label.chip) { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--hue); color: var(--bg); }

.mono {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

#gl { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; z-index: 0; }
.grain {
  position: fixed; inset: -50%; z-index: 2; pointer-events: none; opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 0.9s steps(4) infinite;
}
:root[data-theme='dark'] .grain { opacity: 0.07; }
@keyframes grain {
  0% { transform: translate(0, 0); } 25% { transform: translate(-3%, 2%); }
  50% { transform: translate(2%, -3%); } 75% { transform: translate(-1%, -2%); }
}
.vignette {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 45%, transparent 55%, var(--vignette));
}
/* Brief wash of the chapter color on every kick */
.flash { position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: 0;
  background: radial-gradient(60% 60% at 50% 50%, var(--hue), transparent 70%); mix-blend-mode: multiply; }
:root[data-theme='dark'] .flash { mix-blend-mode: screen; }

/* ---------- Cursor ---------- */
.cursor { position: fixed; left: 0; top: 0; z-index: 70; pointer-events: none; opacity: 0; transition: opacity 0.3s; }
body.has-cursor .cursor { opacity: 1; }
.cursor i {
  position: absolute; left: -18px; top: -18px; width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--hue); transition: width 0.35s var(--ease), height 0.35s var(--ease), left 0.35s var(--ease), top 0.35s var(--ease), background 0.3s;
}
.cursor::after { content: ""; position: absolute; left: -2px; top: -2px; width: 4px; height: 4px; border-radius: 50%; background: var(--hue); }
.cursor.is-link i { left: -30px; top: -30px; width: 60px; height: 60px; background: color-mix(in srgb, var(--hue) 12%, transparent); }
.cursor span { position: absolute; left: 24px; top: 14px; white-space: nowrap; color: var(--hue); font-size: 9px; opacity: 0; transition: opacity 0.3s; }
.cursor.has-label span { opacity: 1; }
@media (hover: hover) and (pointer: fine) { body.has-cursor, body.has-cursor a, body.has-cursor button, body.has-cursor label, body.has-cursor summary { cursor: none; } }

/* The nav panel is ordinary UI and sits above the custom cursor, which would
   otherwise leave the pointer invisible inside it. Hand the real one back. */
html.nav-open .cursor { opacity: 0; }
@media (hover: hover) and (pointer: fine) {
  html.nav-open body.has-cursor, html.nav-open body.has-cursor a,
  html.nav-open body.has-cursor button, html.nav-open body.has-cursor label,
  html.nav-open body.has-cursor summary { cursor: revert; }
}

:focus-visible { outline: 1px solid var(--hue); outline-offset: 4px; }

/* The outro keeps this pairing of call-to-action buttons. */
.gate__row { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

/* ---------- Buttons ---------- */
.btn {
  position: relative; display: inline-flex; align-items: center; gap: 10px;
  padding: 16px 26px; border-radius: 999px; border: 1px solid var(--faint);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  background: var(--scrim);
  transition: border-color 0.3s, background 0.3s, color 0.3s;
  will-change: transform;
}
.btn:hover { border-color: var(--ink-3); }
.btn--primary { background: var(--hue); color: var(--bg); border-color: var(--hue); }
.btn__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 50% { transform: scale(0.5); opacity: 0.5; } }
:focus-visible { outline: 1px solid var(--hue); outline-offset: 4px; }

/* ---------- HUD ---------- */
.hud {
  position: fixed; left: 0; right: 0; z-index: 20;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  padding: var(--gutter); pointer-events: none;
  opacity: 0; transition: opacity 1s var(--ease) 0.4s;
}
body.is-in .hud { opacity: 1; }
.hud > * { pointer-events: auto; }
.hud .mark-link { justify-self: center; margin-top: calc(-1 * var(--gutter)); }
.hud .mark { width: 72px; height: auto; display: block; overflow: visible; }
.hud--top { top: 0; z-index: 60; }
/* The HUD floats over scrolling copy; a short fade off the ground keeps both
   the chrome and the text under it readable in either theme. */
.hud--top::before, .hud--bottom::before {
  content: ""; position: absolute; left: 0; right: 0; height: calc(100% + 26px);
  pointer-events: none; z-index: -1;
}
.hud--top::before { top: 0; background: linear-gradient(to bottom, var(--paper) 18%, transparent); }
.hud--bottom::before { bottom: 0; background: linear-gradient(to top, var(--paper) 18%, transparent); }
.hud--bottom { bottom: 0; align-items: end; }
.hud__left { color: var(--dim); transition: opacity 0.4s; }
.hud__left.is-swap { opacity: 0; }
.hud__right { justify-self: end; display: flex; align-items: center; gap: 22px; }
.hud__right .link { white-space: nowrap; }
.hud__right-text { justify-self: end; color: var(--dim); font-variant-numeric: tabular-nums; }
.link { position: relative; padding: 4px 0; }
.link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: right; transition: transform 0.5s var(--ease);
}
.link:hover::after { transform: scaleX(1); transform-origin: left; }
#audioState { display: inline-block; min-width: 3ch; text-align: left; }
#audioToggle[aria-pressed="true"] #audioState { color: var(--hue); }


.menu-btn { display: flex; gap: 3px; padding: 8px 0; }
.menu-btn i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; transition: transform 0.4s var(--ease); }
.menu-btn:hover i:nth-child(1) { transform: translateY(-3px); }
.menu-btn:hover i:nth-child(3) { transform: translateY(3px); }
.menu-btn::after { display: none; }

.spectrum { display: flex; align-items: flex-end; gap: 5px; height: 44px; }
.spectrum i { width: 1px; height: 100%; background: var(--fg); opacity: 0.4; transform-origin: bottom; transform: scaleY(0.08); }
.spectrum i.hot { background: var(--hue); }

.progress { position: fixed; right: 6px; top: 50%; transform: translateY(-50%); height: 30vh; width: 1px; background: var(--faint); z-index: 20; }
.progress span { position: absolute; left: 0; top: 0; width: 1px; height: 100%; background: var(--hue); transform-origin: top; transform: scaleY(0); }

/* ---------- Sound dock ---------- */
.audio-dock {
  position: fixed; right: var(--gutter); bottom: calc(var(--gutter) + 42px); z-index: 45;
  display: flex; align-items: center; gap: 9px;
  padding: 9px 15px 9px 12px; border-radius: 999px;
  border: 1px solid var(--faint); background: var(--scrim-2);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  color: var(--dim); box-shadow: var(--shadow);
  opacity: 0; transform: translateY(6px);
  transition: opacity .6s var(--ease) .3s, transform .6s var(--ease) .3s,
              border-color .3s, color .3s;
}
body.is-in .audio-dock { opacity: 1; transform: none; }
.audio-dock:hover { border-color: var(--hue); color: var(--fg); }
.audio-dock__label { white-space: nowrap; }
#audioState { display: inline-block; min-width: 3ch; text-align: left; }

.audio-dock__bars { display: flex; align-items: flex-end; gap: 2px; height: 12px; }
.audio-dock__bars i {
  width: 2px; height: 100%; background: currentColor; transform-origin: bottom;
  transform: scaleY(.28); border-radius: 1px;
}
.audio-dock[aria-pressed="true"] { color: var(--hue); border-color: var(--hue); }
.audio-dock[aria-pressed="true"] .audio-dock__bars i { animation: dockbars 1s ease-in-out infinite; }
.audio-dock[aria-pressed="true"] .audio-dock__bars i:nth-child(2) { animation-delay: .18s; }
.audio-dock[aria-pressed="true"] .audio-dock__bars i:nth-child(3) { animation-delay: .36s; }
@keyframes dockbars { 0%, 100% { transform: scaleY(.28); } 50% { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) {
  .audio-dock[aria-pressed="true"] .audio-dock__bars i { animation: none; transform: scaleY(.8); }
}
@media (max-width: 640px) {
  .audio-dock { padding: 8px 13px 8px 10px; bottom: calc(var(--gutter) + 38px); }
}

/* ---------- Chapters ---------- */
main { position: relative; z-index: 10; }
.chapter { min-height: 170vh; position: relative; display: flex; align-items: flex-start; justify-content: center; padding: 0 var(--gutter); }
.chapter > * { position: sticky; top: 0; height: 100vh; width: 100%; display: flex; flex-direction: column; justify-content: center; }
.chapter--hero { min-height: 150vh; }
.chapter--flow { min-height: auto; padding-top: 30vh; padding-bottom: 30vh; }
.chapter--flow > * { position: relative; height: auto; }

.hero-wrap { position: sticky; }
.hero {
  height: 100%; display: flex; flex-direction: column; justify-content: space-between;
  font-weight: 300; font-size: clamp(64px, min(13.5vw, 26vh), 230px); line-height: 0.86; letter-spacing: -0.045em;
  padding: calc(var(--gutter) * 2.6) 0 calc(var(--gutter) * 3.4); color: var(--ink);
}
.hero__line--b { align-self: flex-end; text-align: right; }
.lede {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  max-width: 470px; text-align: center; line-height: 1.8; color: var(--fg);
  text-shadow: var(--halo);
}

.entry { align-items: center; text-align: center; gap: 26px; }
.title {
  font-weight: 400; font-size: clamp(44px, min(8vw, 15vh), 128px); line-height: 0.95; letter-spacing: -0.035em;
  text-shadow: var(--halo);
}
.title sup { font-size: 13px; vertical-align: top; margin-left: 6px; position: relative; top: 0.6em; color: var(--hue); letter-spacing: 0; }
.desc { max-width: 440px; line-height: 1.8; color: var(--fg); text-shadow: var(--halo); }
.tags { list-style: none; display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.tags li { padding: 7px 12px; border: 1px solid var(--faint); border-radius: 999px; color: var(--dim); font-size: 10px; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
@media (min-width: 900px) {
  .entry--left { align-items: flex-start; text-align: left; padding-left: 4vw; }
  .entry--left .tags { justify-content: flex-start; }
  .entry--right { align-items: flex-end; text-align: right; padding-right: 4vw; }
  .entry--right .tags { justify-content: flex-end; }
}
.kicker { color: var(--hue); }

/* ---------- Work ----------
   The index of what the studio has built. It sits directly under the hero so
   the page reads as a portfolio before it reads as a visualiser. */
.work { max-width: 1140px; margin: 0 auto; gap: 26px; }
.work__lede { max-width: 620px; font-size: clamp(16px, 1.4vw, 19px); line-height: 1.7; color: var(--fg); text-shadow: var(--halo); }
.work__grid {
  list-style: none; margin-top: 18px;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 1px;
  background: var(--faint); border: 1px solid var(--faint);
}
.work__card {
  display: grid; gap: 7px; height: 100%; padding: 26px 24px 24px;
  background: var(--scrim); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  text-decoration: none; color: var(--fg);
  transition: background .25s var(--ease), color .25s var(--ease);
}
.work__card:hover { background: var(--scrim-2); color: var(--ink); }
.work__kind { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--hue); }
.work__card h3 { font-size: clamp(19px, 1.8vw, 24px); font-weight: 500; letter-spacing: -.02em; color: var(--ink); }
.work__card p { font-size: 14px; line-height: 1.65; color: var(--dim); }
.work__go { align-self: end; padding-top: 10px; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.work__foot { margin-top: 4px; }

/* ---------- Engine ---------- */
.engine { max-width: 1140px; margin: 0 auto; gap: 72px; }
.engine__head { max-width: 760px; display: flex; flex-direction: column; gap: 24px; }
.engine__lede { font-size: clamp(17px, 1.5vw, 20px); line-height: 1.6; font-weight: 300; text-shadow: var(--halo); }
.steps { list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--faint); border: 1px solid var(--faint); }
.steps li {
  background: var(--scrim); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  padding: 28px 24px 32px; display: flex; flex-direction: column; gap: 12px; min-height: 250px;
  transition: background 0.4s;
}
.steps li:hover { background: var(--scrim-2); }
.steps__n { color: var(--hue); }
.steps h3 { font-weight: 400; font-size: 28px; letter-spacing: -0.02em; }
.steps p { font-size: 14px; line-height: 1.65; color: var(--ink-2); }
.stats__grid { list-style: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(16px, 4vw, 64px); }
.stats__grid li { display: flex; flex-direction: column; gap: 12px; border-top: 1px solid var(--faint); padding-top: 18px; }
.stats__grid b { font-weight: 300; font-size: clamp(56px, 9vw, 140px); line-height: 0.9; letter-spacing: -0.04em; font-variant-numeric: tabular-nums; }
.stats__grid span { color: var(--dim); }
.faq { max-width: 780px; display: flex; flex-direction: column; gap: 0; }
.faq h2 { margin-bottom: 18px; }
.faq details { border-top: 1px solid var(--faint); background: var(--scrim); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.faq details:last-child { border-bottom: 1px solid var(--faint); }
.faq summary { cursor: pointer; list-style: none; padding: 20px 44px 20px 14px; font-size: 19px; position: relative; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; position: absolute; right: 14px; top: 50%; transform: translateY(-50%); font-family: var(--mono); color: var(--hue); transition: transform 0.4s var(--ease); }
.faq details[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq details p { padding: 0 44px 22px 14px; line-height: 1.7; color: var(--ink-2); font-size: 15px; }

/* ---------- Outro ---------- */
.outro { align-items: center; text-align: center; gap: 24px; justify-content: flex-end; padding-bottom: 16vh; }
.outro .title { font-size: clamp(56px, min(11vw, 18vh), 180px); }
.follow { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-top: 10px; color: var(--dim); }
.follow b { font-weight: 400; font-size: clamp(26px, 3vw, 40px); color: var(--fg); letter-spacing: -0.02em; transition: color 0.3s; }
.follow:hover b { color: var(--hue); }
.credit { position: absolute; bottom: calc(var(--gutter) * 3.6); color: var(--dim); font-size: 9px; text-transform: none; letter-spacing: 0.04em; }

/* ---------- Text reveal ---------- */
.split .ch { display: inline-block; opacity: 0; transform: translateY(0.35em); filter: blur(8px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease), filter 0.9s var(--ease); }
.split .w { display: inline-block; white-space: nowrap; }
.split.is-visible .ch { opacity: 1; transform: none; filter: none; }
.reveal { opacity: 0; transform: translateY(14px); transition: opacity 1s var(--ease) 0.25s, transform 1s var(--ease) 0.25s; }
.reveal.is-visible { opacity: 1; transform: none; }
.lede.reveal { transform: translate(-50%, calc(-50% + 14px)); }
.lede.reveal.is-visible { transform: translate(-50%, -50%); }

/* ---------- Index overlay ---------- */
.index {
  position: fixed; inset: 0; z-index: 30; display: flex; padding: 88px var(--gutter);
  background: var(--scrim-2); backdrop-filter: blur(22px); -webkit-backdrop-filter: blur(22px);
  opacity: 0; visibility: hidden; transition: opacity 0.6s var(--ease), visibility 0.6s; overflow-y: auto;
}
.index.is-open { opacity: 1; visibility: visible; }
.index__inner { margin: auto; width: min(900px, 100%); display: flex; flex-direction: column; gap: 32px; }
.index__label { color: var(--dim); margin-bottom: 10px; }
.index ol { list-style: none; }
.index li { border-top: 1px solid var(--faint); overflow: hidden; }
.index li:last-child { border-bottom: 1px solid var(--faint); }
.index li button {
  width: 100%; display: flex; align-items: baseline; gap: 20px; padding: 10px 0; text-align: left;
  font-size: clamp(22px, min(4.4vw, 5vh), 54px); font-weight: 300; letter-spacing: -0.03em;
  transform: translateY(100%); transition: transform 0.8s var(--ease), color 0.3s, padding 0.4s var(--ease);
}
.index.is-open li button { transform: none; }
.index li button:hover { color: var(--hue); padding-left: 14px; }
.index li button .mono { color: var(--dim); min-width: 3ch; }
.index li.is-current button { color: var(--hue); }
.index__foot { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; flex-wrap: wrap; }
.source-row { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { padding: 10px 16px; border-radius: 999px; border: 1px solid var(--faint); font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; transition: border-color 0.3s, color 0.3s; }
.chip:hover { border-color: var(--dim); }
.chip.is-active { border-color: var(--hue); color: var(--hue); }

/* ---------- Drop + toast ---------- */
.drop {
  position: fixed; inset: 12px; z-index: 60; border: 1px dashed var(--hue); border-radius: 18px;
  display: grid; place-items: center; background: var(--scrim);
  opacity: 0; pointer-events: none; transition: opacity 0.3s;
  font-size: clamp(40px, 7vw, 90px); font-weight: 300; letter-spacing: -0.03em;
}
.drop.is-on { opacity: 1; }
.toast {
  position: fixed; left: 50%; bottom: 90px; z-index: 60; transform: translate(-50%, 20px);
  padding: 10px 16px; border-radius: 999px; background: var(--fg); color: var(--bg);
  opacity: 0; pointer-events: none; transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.noscript { position: relative; z-index: 10; padding: 40px var(--gutter); max-width: 640px; }

@media (max-width: 899px) {
  .steps { grid-template-columns: 1fr 1fr; }
  .stats__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 1100px) { .hud__right { gap: 16px; } }
@media (max-width: 880px)  { .hud__right { gap: 12px; } .hud__left { font-size: 9px; } }
@media (max-width: 900px)  { .hide-sm { display: none; } }
@media (max-width: 640px) {
  .hud__left { font-size: 9px; }
  .hud__right { gap: 14px; }
  .spectrum { gap: 3px; height: 28px; }
  .hero { padding-bottom: calc(var(--gutter) * 5); }
  .entry { justify-content: flex-end; padding-bottom: 16vh; gap: 18px; }
  .title { font-size: 44px; }
  .steps { grid-template-columns: 1fr; }
  .steps li { min-height: 0; }
  .outro { padding-bottom: 20vh; }
}
@media (max-height: 640px) { .tags { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .grain { animation: none; }
  .split .ch, .reveal { transition-duration: 0.01s; filter: none; }
  .flash { display: none; }
}

.index__link { font-size: 15px; margin-bottom: 4px; }
.index__link a { color: var(--hue); }

/* the bottom HUD owns the bottom edge on a phone */
@media (max-width: 899px) { :root { --mark-bottom: 62px; } }

/* The hero on a phone: clear the chrome at both ends. The top bar is 68px and
   the bottom one carries the mark dock, so the two title lines are pushed
   inside them rather than under them. svh, because Safari's 100vh includes the
   browser chrome and would drop the second line out of sight. */
/* Below this the hint and the menu button meet in the middle of the bar. The
   hint is decorative; the scroll indicator already says the same thing. */
@media (max-width: 660px) { .hud__left { display: none; } }

@media (max-width: 899px) {
  .hero { padding: 92px 0 128px; }
  @supports (height: 100svh) {
    .chapter > * { height: 100svh; }
  }
}
