/* ==================================================================
   RAKSHIT HOODA — portfolio (night sage mix)
   Palette: near-black base, sage accent, warm off-white text.
   Type: Clash Display (display) + JetBrains Mono (labels/tags).
   ================================================================== */

:root {
  --bg: #0a0b0a;
  --surface: #131513;
  --line: rgba(234, 234, 226, 0.09);
  --text: #eaeae2;
  --muted: #7e827a;
  --accent: #a8b58a;
  --accent-dim: rgba(168, 181, 138, 0.14);
  --font-d: "Clash Display", "Arial Narrow", sans-serif;
  --font-m: "JetBrains Mono", ui-monospace, monospace;
  --pad: clamp(1.2rem, 5vw, 4rem);
  --dock: 64px;
  /* the fixed bar's own height — every section's top padding clears exactly
     this much, so an anchor can land a section flush with the viewport top */
  --nav-h: 5rem;
  /* breathing room inside that frame; shrinks first on short viewports */
  --sec-gap: clamp(1rem, 3.5vh, 2.4rem);
  /* the footer's own height, dock clearance included — the outro subtracts
     it so the two share one screen */
  --footer-h: 7.5rem;
}

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

html { scroll-behavior: smooth; scrollbar-width: thin; scrollbar-color: #262a26 transparent; }
html.lenis { scroll-behavior: auto !important; } /* Lenis drives the scroll itself */
.lenis.lenis-stopped { overflow: hidden; }
html, body { overflow-x: hidden; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-d);
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

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

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

.mono { font-family: var(--font-m); }

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

/* film grain — one tiled SVG, fixed, barely there */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.7'/%3E%3C/svg%3E");
}

.skip {
  position: fixed;
  top: -48px;
  left: var(--pad);
  z-index: 200;
  padding: 0.6rem 1rem;
  background: var(--accent);
  color: var(--bg);
  font-family: var(--font-m);
  font-size: 12px;
  transition: top 0.2s;
}
.skip:focus { top: 12px; }

/* ---------------- loader ---------------- */
#loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--bg);
  display: grid;
  place-items: center;
}
#loader .l-brand {
  position: absolute;
  top: 1.4rem;
  left: var(--pad);
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--muted);
}
.l-hello {
  font-family: var(--font-d);
  font-weight: 600;
  font-size: clamp(4rem, 11vw, 7.5rem);
  letter-spacing: -0.02em;
  color: var(--accent);
  text-align: center;
}
.l-quip {
  position: absolute;
  bottom: 2.2rem;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.06em;
}

/* ---------------- nav ----------------
   A floating glass bar. At rest it spans the page; once the reader is
   past the hero it eases into a wide pill — the way the macOS/Apple Music
   transport dock behaves. The contraction is deliberately partial and
   slow: the wordmark stays whole, only the track numbers and the sound
   readout step aside, and the ease is symmetric so the bar neither snaps
   at the start nor lands hard at the end.
   ------------------------------------------------------------------ */
#nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  padding: 0.85rem var(--pad);
  pointer-events: none; /* only the glass itself is interactive */
  transition: padding-top var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1));
}

.nav-shell {
  /* eased in *and* out — the old curve spent its speed in the first
     100ms, which is what made the collapse read as a snap */
  --nav-ease: cubic-bezier(0.62, 0.02, 0.24, 1);
  --nav-ease-t: 1.15s;
  pointer-events: auto;
  position: relative;
  width: 100%;
  max-width: 100%;
  display: grid;
  grid-template-columns: 1fr auto 1fr; /* links land in the true center */
  align-items: center;
  gap: 1rem;
  padding: 0.55rem 1.4rem;
  border-radius: 999px; /* capsule at every width — the ends never square off */
  border: 1px solid rgba(234, 234, 226, 0.11);
  background: rgba(19, 21, 19, 0.55);
  -webkit-backdrop-filter: blur(22px) saturate(165%);
  backdrop-filter: blur(22px) saturate(165%);
  /* top-edge sheen + a soft drop so the glass reads as a lifted pane */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(0, 0, 0, 0.22),
    0 10px 34px rgba(0, 0, 0, 0.34);
  transition:
    max-width var(--nav-ease-t) var(--nav-ease),
    padding var(--nav-ease-t) var(--nav-ease),
    gap var(--nav-ease-t) var(--nav-ease),
    background 0.45s ease,
    box-shadow 0.45s ease,
    border-color 0.45s ease;
}

/* specular highlight that curves with the corners */
.nav-shell::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(
    rgba(255, 255, 255, 0.055),
    rgba(255, 255, 255, 0) 42%,
    rgba(255, 255, 255, 0.018)
  );
}

/* ---- contracted state ----
   A wide pill, not a badge: it keeps a hand's width of air around the
   content (~645px) so the travel reads as a settle rather than a snap
   shut, and the vertical squeeze is half what it was. */
#nav.shrunk { padding-top: 0.7rem; }
#nav.shrunk .nav-shell {
  max-width: min(760px, 100%);
  padding: 0.44rem 0.85rem 0.44rem 1.3rem;
  gap: 0.95rem;
  background: rgba(19, 21, 19, 0.68);
  border-color: rgba(234, 234, 226, 0.14);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    inset 0 -1px 0 rgba(0, 0, 0, 0.28),
    0 12px 40px rgba(0, 0, 0, 0.45);
}

.nav-links { justify-self: center; }
.nav-right { justify-self: end; }

.nav-logo {
  font-family: var(--font-m);
  font-size: 11px;
  letter-spacing: 0.22em;
  font-weight: 500;
  white-space: nowrap;
  padding-left: 0.25rem;
}
.nav-logo em { font-style: normal; color: var(--accent); }
/* The wordmark folds by trading AKSHIT for a single K — RAKSHIT HOODA →
   RK HOODA — so the surname survives the contraction instead of the whole
   name dropping to initials. Under 768px the tail goes too and it lands
   on RK, where the pill genuinely runs out of room. */
.nav-logo .nl-first,
.nav-logo .nl-k,
.nav-logo .nl-tail {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  transition:
    max-width var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1)),
    opacity 0.5s ease;
}
.nav-logo .nl-first,
.nav-logo .nl-tail { max-width: 8em; }
.nav-logo .nl-k { max-width: 0; opacity: 0; } /* only exists in the pill */

#nav.shrunk .nav-logo .nl-first { max-width: 0; opacity: 0; }
#nav.shrunk .nav-logo .nl-k { max-width: 1.4em; opacity: 1; }

.nav-links {
  display: flex;
  align-items: center;
  /* the links carry their own padding now — that padding *is* the pill's
     body, so the gap only has to keep neighbouring pills from touching */
  gap: clamp(0.3rem, 1.1vw, 1rem);
  font-size: 11px;
  letter-spacing: 0.12em;
  transition: gap var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1));
}
/* ---- the sliding indicator ----
   One highlight travels between the links instead of five lighting up on
   their own. It follows the cursor and, when the cursor leaves, settles
   back on the section you're actually reading. JS owns x/width/height;
   this is only the material. */
.nav-links { position: relative; }
.nav-pill {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 999px;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(rgba(168, 181, 138, 0.19), rgba(168, 181, 138, 0.075));
  border: 1px solid rgba(168, 181, 138, 0.24);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.13),
    0 1px 8px rgba(0, 0, 0, 0.22);
  will-change: transform, width;
}

/* Plain text, no chrome — the glass capsule is the only surface here. */
.nav-links a,
#soundToggle {
  position: relative;
  white-space: nowrap;
  transition:
    color 0.25s,
    opacity 0.3s ease,
    padding var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1)),
    max-width var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1));
}
.nav-links a { padding: 0.46rem 0.85rem; }
.nav-links a:hover { color: var(--accent); }
.nav-links a:active { color: var(--accent); opacity: 0.65; transition-duration: 0.06s; }

/* the section you're reading — the indicator is parked here by default */
.nav-links a.is-active { color: var(--accent); }
.nav-links a.is-active span { color: rgba(168, 181, 138, 0.55); }
/* the track numbers are the first thing to go when space gets tight */
.nav-links a span {
  display: inline-block;
  max-width: 3em;
  overflow: hidden;
  color: var(--muted);
  margin-right: 0.4em;
  vertical-align: bottom;
  transition:
    max-width var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1)),
    margin-right var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1)),
    opacity 0.55s ease;
}
#nav.shrunk .nav-links { gap: 0.45rem; }
#nav.shrunk .nav-links a span { max-width: 0; margin-right: 0; opacity: 0; }

.nav-right {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  transition: gap var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1));
}
#nav.shrunk .nav-right { gap: 0.7rem; }
/* the sound readout is the widest passenger — it steps aside in the pill */
#soundToggle {
  display: inline-block;
  max-width: 10em;
  overflow: hidden;
}
#nav.shrunk #soundToggle {
  max-width: 0;
  opacity: 0;
  visibility: hidden; /* also drops it out of the tab order */
  transition:
    max-width var(--nav-ease-t, 1.15s) var(--nav-ease, cubic-bezier(0.62, 0.02, 0.24, 1)),
    opacity 0.5s ease,
    visibility 0s linear 0.6s;
}
#soundToggle {
  font-family: var(--font-m);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--muted);
  white-space: nowrap;
}
#soundToggle:hover { color: var(--text); }
#soundToggle.on { color: var(--accent); }

.btn-talk {
  position: relative;
  font-family: var(--font-m);
  font-size: 11px;
  letter-spacing: 0.12em;
  padding: 0.55rem 1.15rem;
  border: 1px solid rgba(168, 181, 138, 0.45);
  border-radius: 999px;
  white-space: nowrap;
  transition: background 0.25s, color 0.25s, border-color 0.25s;
}
.btn-talk:hover { background: var(--accent); color: var(--bg); border-color: var(--accent); }

/* shiny streak orbiting the button border: a conic glint clipped to a
   thin ring by masking out the button's interior */
@property --orbit {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.btn-talk::before {
  content: "";
  position: absolute;
  inset: -2px;
  padding: 2px;
  border-radius: 999px;
  background: conic-gradient(from var(--orbit),
    transparent 0deg 290deg,
    rgba(168, 181, 138, 0.7) 325deg,
    #f2f5e8 344deg,
    rgba(168, 181, 138, 0.7) 352deg,
    transparent 360deg);
  -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, linear-gradient(#000 0 0);
  mask-composite: exclude;
  filter: drop-shadow(0 0 5px rgba(168, 181, 138, 0.55));
  animation: orbit 3.4s linear infinite;
  pointer-events: none;
}
@keyframes orbit {
  to { --orbit: 360deg; }
}

/* ---------------- layout primitives ----------------
   Every track is a full screen of its own: one viewport tall, headed at the
   top, and framed by exactly the nav above and the player dock below. Jumping
   to a section therefore lands its kicker under the bar with nothing cut off
   and no dead band above it. */
section {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  padding: calc(var(--nav-h) + var(--sec-gap)) var(--pad) calc(var(--dock) + var(--sec-gap));
}
/* a column flex box would otherwise squeeze its children under their own
   content and let the text spill over the dock — only the two blocks meant
   to breathe are allowed to resize */
section > * { flex-shrink: 0; }
.about-grid { flex-shrink: 1; }

.sec-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 0.4rem 2rem;
  margin-bottom: clamp(1.5rem, 4.5vh, 3.4rem);
  border-bottom: 1px solid var(--line);
  padding-bottom: 1.4rem;
}
.kicker {
  grid-column: 1 / -1;
  font-family: var(--font-m);
  font-size: 10.5px;
  letter-spacing: 0.24em;
  color: var(--accent);
}
.sec-head h2 {
  font-weight: 600;
  font-size: clamp(2.4rem, 6vw, 4.2rem);
  letter-spacing: -0.02em;
  line-height: 1;
}
.sec-meta { font-family: var(--font-m); font-size: 10.5px; letter-spacing: 0.18em; color: var(--muted); }

/* ---------------- hero ---------------- */
.hero {
  justify-content: center; /* the intro is the one track that sits centred */
  background:
    radial-gradient(ellipse 60% 45% at 18% 30%, rgba(168, 181, 138, 0.07), transparent 70%),
    radial-gradient(ellipse 50% 40% at 85% 75%, rgba(168, 181, 138, 0.04), transparent 70%);
}
.hero-kicker {
  font-size: 13px;
  letter-spacing: 0.22em;
  color: var(--muted);
  margin-bottom: clamp(1.4rem, 3vh, 2.4rem);
}
.hero-kicker b { color: var(--accent); font-weight: 400; }
.hero-name {
  font-weight: 600;
  font-size: clamp(3rem, 9.5vw, 7.75rem);
  line-height: 0.97;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.hero-name .line { display: block; overflow: hidden; padding-bottom: 0.04em; margin-bottom: -0.04em; }
.hero-name .ch, .hero-name .w { display: inline-block; }
.contact-title .ch, .contact-title .w { display: inline-block; }
.hero-tag {
  margin-top: clamp(1.6rem, 3.5vh, 2.6rem);
  font-size: clamp(1.15rem, 2vw, 1.55rem);
  font-weight: 400;
  max-width: 38ch;
  color: rgba(234, 234, 226, 0.92);
}
.hero-roles {
  margin-top: 1.2rem;
  font-size: 12.5px;
  letter-spacing: 0.16em;
  color: var(--accent);
}
.hero-cue {
  position: absolute;
  left: var(--pad);
  bottom: calc(var(--dock) + 1.8rem);
  font-size: 10px;
  letter-spacing: 0.24em;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.hero-cue span { color: var(--accent); animation: bob 1.8s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(4px); } }

/* the animated field behind everything — under the text and the diorama.
   The mask dissolves it toward the hero's edges so the map never ends on
   a hard line; the scrubbed fade into the work section lives in JS. */
.hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.6s ease;
  -webkit-mask-image: linear-gradient(to bottom, #000 58%, rgba(0, 0, 0, 0.55) 80%, transparent 99%);
  mask-image: linear-gradient(to bottom, #000 58%, rgba(0, 0, 0, 0.55) 80%, transparent 99%);
}
.hero-bg.in { opacity: 1; }

/* the 3d desk diorama lives in the hero's empty right half; text stacks above it */
.hero-scene {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(50vw, 940px);
  z-index: 0;
}
.hero-scene canvas { display: block; width: 100%; height: 100%; opacity: 0; }
.hero-kicker, .hero-name, .hero-tag, .hero-roles { position: relative; z-index: 1; }
.hero-cue { z-index: 1; }

/* ---------------- work gallery: draggable infinite grid ---------------- */
.work-body { position: relative; }

.stage {
  position: relative;
  height: min(86vh, 800px);
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y; /* vertical swipe still scrolls the page on touch */
  user-select: none;
  -webkit-user-select: none;
  /* the grid is pressed into a dish — see WARP in main.js */
  perspective: 1200px;
  perspective-origin: 50% 50%;
}
.stage.grabbing { cursor: grabbing; }
/* top and bottom rows dip into the page — the bottom runs longer and softer
   so the last row melts out instead of stopping on a hard line */
.stage::before,
.stage::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  z-index: 4;
  pointer-events: none;
}
.stage::before { top: 0; height: 62px; background: linear-gradient(var(--bg), transparent 88%); }
.stage::after {
  bottom: 0;
  height: 122px;
  background: linear-gradient(transparent, rgba(10, 11, 10, 0.6) 48%, var(--bg) 90%);
}
/* the outer ring loses a little light, nothing more — the stretched corner
   cards are the point of the dish, so they stay legible */
.stage-fade {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background:
    radial-gradient(135% 125% at 50% 50%, transparent 74%, rgba(10, 11, 10, 0.3) 93%, rgba(10, 11, 10, 0.72) 100%),
    linear-gradient(90deg, var(--bg), transparent 5%, transparent 95%, var(--bg));
}

.plane {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  /* the warp pushes cards to negative z — behind the plane's own box — so the
     plane must not hit-test, or it swallows every hover and click */
  pointer-events: none;
}

.gcell {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: auto;
  transform-style: preserve-3d;
  backface-visibility: hidden;
}
/* The grid is 54 cells, so promoting them unconditionally pins 54 compositor
   layers for the whole session. `.live` is set by an observer with a wide
   margin, so promotion is always in place before the gallery is on screen —
   it is only released once you are well past it. */
.stage.live .gcell { will-change: transform; }
.gcard {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  /* the side padding is the gap between neighbours — it has to absorb the
     growth the rim cards pick up without them touching */
  padding: 0.7rem 1.35rem;
  text-align: left;
  cursor: inherit;
  transition: background 0.35s;
}
.gcard:hover, .gcard:focus-visible { background: rgba(234, 234, 226, 0.03); }
.g-top {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 9px;
  letter-spacing: 0.14em;
}
.g-top span:first-child { color: var(--muted); }
.g-top span:last-child {
  color: var(--text);
  transition: color 0.3s;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gcard:hover .g-top span:last-child,
.gcard:focus-visible .g-top span:last-child { color: var(--accent); }
.g-mid {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 0;
  padding: 0.35rem 0;
}
.g-mid .cover { width: 100%; height: 100%; }
.g-mid .cover .ghost { font-size: clamp(2rem, 3.2vw, 3rem); }
.g-mid .v-label { width: 34%; font-size: 7px; letter-spacing: 0.02em; white-space: nowrap; }
.g-bot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--muted);
}
.g-chips { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.g-chips i {
  font-style: normal;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.22rem 0.5rem;
  background: rgba(19, 21, 19, 0.6);
  transition: color 0.3s, border-color 0.3s;
}
.gcard:hover .g-chips i,
.gcard:focus-visible .g-chips i { color: var(--accent); border-color: rgba(168, 181, 138, 0.35); }

.drag-hint {
  position: absolute;
  right: 1.4rem;
  bottom: 1.2rem;
  z-index: 5;
  font-size: 9px;
  letter-spacing: 0.24em;
  color: var(--muted);
  pointer-events: none;
  transition: opacity 0.6s;
}
.stage.grabbing .drag-hint, .stage.dragged .drag-hint { opacity: 0; }

/* grid <-> list floating toggle */
.view-toggle {
  position: absolute;
  left: 1.2rem;
  bottom: 1.2rem;
  z-index: 6;
  display: flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(19, 21, 19, 0.85);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.vt-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--muted);
  transition: background 0.25s, color 0.25s;
}
.vt-btn svg { width: 13px; height: 13px; fill: currentColor; }
.vt-btn:hover { color: var(--text); }
.vt-btn[aria-pressed="true"] { background: var(--text); color: var(--bg); }

.work-rows { margin-top: 0.5rem; padding-bottom: 5rem; /* clears the floating toggle */ }

.cover {
  display: block;
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: 6px;
  border: 1px solid var(--line);
  background:
    radial-gradient(ellipse 80% 70% at 78% 8%, color-mix(in srgb, var(--tint) 28%, transparent), transparent 68%),
    linear-gradient(145deg, color-mix(in srgb, var(--tint) 20%, #0f110f), #0b0d0b 72%);
  transition: filter 0.45s;
}
/* hover is deliberately quiet: the tint washes across the cover, nothing moves */
.cover::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(150deg, color-mix(in srgb, var(--tint) 26%, transparent), transparent 62%);
  transition: opacity 0.45s;
}
.gcard:hover .cover, .gcard:focus-visible .cover { filter: brightness(1.12); }
.gcard:hover .cover::after, .gcard:focus-visible .cover::after { opacity: 1; }
.cover .shot { width: 100%; height: 100%; object-fit: cover; display: block; -webkit-user-drag: none; user-select: none; }

.ghost {
  position: absolute;
  left: 5%;
  top: -4%;
  font-family: var(--font-d);
  font-weight: 600;
  font-size: clamp(6rem, 11vw, 9.5rem);
  line-height: 1;
  color: var(--tint);
  opacity: 0.22;
  transition: opacity 0.5s;
}
.gcard:hover .ghost, .gcard:focus-visible .ghost { opacity: 0.3; }

.vinyl {
  position: absolute;
  right: -9%;
  bottom: -20%;
  width: 56%;
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    repeating-radial-gradient(circle at 50%, rgba(234, 234, 226, 0.05) 0 1px, transparent 1px 5px),
    radial-gradient(circle at 38% 34%, rgba(234, 234, 226, 0.06), transparent 45%),
    #0e100e;
  border: 1px solid rgba(234, 234, 226, 0.07);
  display: grid;
  place-items: center;
}
.v-label {
  width: 27%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--tint);
  color: var(--bg);
  font-size: clamp(8px, 0.8vw, 10px);
  font-weight: 700;
  letter-spacing: 0.06em;
  display: grid;
  place-items: center;
}
.cov-wip {
  position: absolute;
  top: 0.8rem;
  right: 0.9rem;
  font-size: 9px;
  letter-spacing: 0.16em;
  color: var(--tint);
  border: 1px solid color-mix(in srgb, var(--tint) 55%, transparent);
  padding: 0.28rem 0.55rem;
  border-radius: 999px;
}

/* ---------------- B-sides tracklist ---------------- */
.bsides { list-style: none; border-top: 1px solid var(--line); }
.bside {
  display: grid;
  grid-template-columns: 2.6rem 1.3fr 1.8fr 0.8fr 3.4rem 1.4rem;
  align-items: center;
  gap: 1.2rem;
  width: 100%;
  text-align: left;
  padding: clamp(0.7rem, 1.9vh, 1.15rem) 0.6rem;
  border-bottom: 1px solid var(--line);
  transition: background 0.3s, padding-left 0.3s;
}
.bside:hover { background: var(--surface); padding-left: 1.1rem; }
.b-idx { font-size: 10.5px; color: var(--muted); letter-spacing: 0.1em; }
.b-name { font-weight: 500; font-size: 1.05rem; transition: color 0.3s; }
.bside:hover .b-name { color: var(--accent); }
.b-name em {
  font-style: normal;
  font-size: 8.5px;
  letter-spacing: 0.14em;
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  padding: 0.18rem 0.45rem;
  border-radius: 999px;
  margin-left: 0.5rem;
  vertical-align: middle;
}
.b-desc { font-size: 0.88rem; color: var(--muted); }
.b-tags { font-size: 9.5px; letter-spacing: 0.16em; color: var(--muted); }
.b-dur { font-size: 10.5px; color: var(--muted); text-align: right; }
.b-arrow { color: var(--muted); transition: color 0.3s, transform 0.3s; }
.bside:hover .b-arrow { color: var(--accent); transform: translate(2px, -2px); }

/* ---------------- about / liner notes ---------------- */
/* the liner notes are the densest track — its spacing is keyed to viewport
   height so the whole spread still lands inside one screen */
.about-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
  flex: 1;
  align-content: start;
}
.a-bio { font-size: clamp(1.1rem, 1.9vw, 1.4rem); line-height: 1.5; max-width: 42ch; }
.a-bio.sub { margin-top: clamp(0.7rem, 1.8vh, 1.2rem); font-size: clamp(0.95rem, 1.4vw, 1.05rem); color: var(--muted); }

.stats {
  display: grid;
  /* one strip rather than a 2x2 block: it costs a row of height the section
     doesn't have once the whole spread has to sit inside one screen */
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-top: clamp(1.2rem, 3.4vh, 2.6rem);
}
.stat { background: var(--bg); padding: clamp(0.8rem, 2.2vh, 1.3rem) 1.4rem; }
.stat b {
  display: block;
  font-family: var(--font-d);
  font-weight: 600;
  font-size: clamp(1.7rem, 3vw, 2.3rem);
  letter-spacing: -0.01em;
}
.stat span {
  font-family: var(--font-m);
  font-size: 9.5px;
  letter-spacing: 0.2em;
  color: var(--muted);
}

.a-tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: clamp(1rem, 2.6vh, 2.2rem); }
.a-tags i {
  font-style: normal;
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--muted);
  border: 1px solid var(--line);
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
  transition: color 0.3s, border-color 0.3s;
}
.a-tags i:hover { color: var(--accent); border-color: rgba(168, 181, 138, 0.4); }

/* the Now Playing card */
.np-card, .studio-card {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.5rem 1.6rem;
  background: linear-gradient(160deg, rgba(168, 181, 138, 0.05), transparent 55%), var(--surface);
}
.np-card { box-shadow: 0 0 60px rgba(168, 181, 138, 0.06); }
.np-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 10px;
  letter-spacing: 0.24em;
  color: var(--accent);
  margin-bottom: 1.3rem;
}
.np-eq { display: flex; gap: 2px; align-items: flex-end; height: 12px; }
.np-eq i {
  width: 3px;
  background: var(--accent);
  height: 100%;
  transform: scaleY(0.25);
  transform-origin: bottom;
}
body.sound-on .np-eq i { animation: eqp 0.9s ease-in-out infinite; }
body.sound-on .np-eq i:nth-child(2) { animation-delay: 0.18s; }
body.sound-on .np-eq i:nth-child(3) { animation-delay: 0.36s; }
@keyframes eqp { 0%, 100% { transform: scaleY(0.25); } 50% { transform: scaleY(1); } }

.np-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--line);
  font-size: 11px;
  letter-spacing: 0.08em;
}
.np-row span { color: var(--muted); letter-spacing: 0.18em; font-size: 10px; padding-top: 2px; }
.np-row b { font-weight: 500; color: var(--text); text-align: right; }
.np-row b.hl { color: var(--accent); }
.blink::after { content: "▍"; color: var(--accent); animation: blink 1.1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.studio-card { margin-top: 1.4rem; }
.studio-card ul { list-style: none; }
.studio-card li {
  font-family: var(--font-m);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--text);
  padding: 0.5rem 0;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 0.7rem;
}
.studio-card li::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.7;
  animation: blink 2.2s steps(1) infinite;
}

/* ---------------- contact / outro ---------------- */
/* the footer is part of this last screen, so the outro reserves room for it
   rather than running a full viewport and leaving a dead band above it */
#contact {
  text-align: left;
  min-height: calc(100svh - var(--footer-h));
  padding-bottom: var(--sec-gap);
}
.contact-title {
  font-weight: 600;
  font-size: clamp(3.2rem, 12vw, 9.5rem);
  line-height: 0.95;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  overflow: hidden;
  padding-bottom: 0.06em;
}
.contact-sub {
  margin-top: 1.6rem;
  color: var(--muted);
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  max-width: 44ch;
}
.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 2.2rem 2.8rem;
  align-items: flex-start;
  margin-top: 3rem;
}
.cta { display: flex; flex-direction: column; gap: 0.55rem; }
.btn-email {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--font-m);
  font-size: 12.5px;
  letter-spacing: 0.12em;
  padding: 1.05rem 2rem;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent);
  transition: background 0.3s, color 0.3s, box-shadow 0.3s;
}
.btn-email:hover {
  background: var(--accent);
  color: var(--bg);
  box-shadow: 0 0 42px rgba(168, 181, 138, 0.25);
}
.link-plain {
  font-family: var(--font-m);
  font-size: 12px;
  letter-spacing: 0.14em;
  padding: 1.05rem 0;
  border-bottom: 1px solid var(--line);
  transition: color 0.3s, border-color 0.3s;
}
.link-plain:hover { color: var(--accent); border-color: var(--accent); }
.micro {
  font-family: var(--font-m);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--muted);
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity 0.3s, transform 0.3s;
}
.cta:hover .micro, .cta:focus-within .micro { opacity: 1; transform: none; }

footer {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 2rem;
  justify-content: space-between;
  padding: 1.6rem var(--pad) calc(var(--dock) + 1.6rem);
  border-top: 1px solid var(--line);
  font-family: var(--font-m);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  color: var(--muted);
}

/* ---------------- mini-player dock ---------------- */
#player {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  height: var(--dock);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 clamp(1rem, 3vw, 2rem);
  background: rgba(10, 11, 10, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--line);
}

/* the seek bar straddles the dock's top edge; it IS the scroll bar */
#pSeek {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  top: -8px;
  left: 0;
  width: 100%;
  height: 16px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
#pSeek::-webkit-slider-runnable-track {
  height: 2px;
  background: linear-gradient(to right, var(--accent) var(--p, 0%), rgba(234, 234, 226, 0.14) var(--p, 0%));
}
#pSeek::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  margin-top: -4px;
  opacity: 0;
  transition: opacity 0.25s;
  box-shadow: 0 0 12px rgba(168, 181, 138, 0.8);
}
#pSeek:hover::-webkit-slider-thumb, #pSeek:focus-visible::-webkit-slider-thumb { opacity: 1; }
#pSeek::-moz-range-track {
  height: 2px;
  background: linear-gradient(to right, var(--accent) var(--p, 0%), rgba(234, 234, 226, 0.14) var(--p, 0%));
}
#pSeek::-moz-range-thumb {
  width: 10px;
  height: 10px;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0;
  transition: opacity 0.25s;
}
#pSeek:hover::-moz-range-thumb, #pSeek:focus-visible::-moz-range-thumb { opacity: 1; }
#pSeek:focus-visible { outline: none; }

.p-left { display: flex; align-items: center; gap: 1rem; min-width: 0; }
#eq { display: flex; gap: 2.5px; align-items: flex-end; height: 16px; flex: none; }
#eq i {
  width: 3px;
  background: var(--accent);
  height: 100%;
  transform-origin: bottom;
  transform: scaleY(0.18);
  transition: transform 0.1s linear;
}
#eq i:nth-child(2) { transform: scaleY(0.34); }
#eq i:nth-child(3) { transform: scaleY(0.5); }
#eq i:nth-child(4) { transform: scaleY(0.3); }
#eq i:nth-child(5) { transform: scaleY(0.22); }

/* while the page scrolls, the dock reads as "playing": bars dance
   (only faked when sound is off — the analyser owns them when it's on)
   and the button shows the pause glyph, both off the same .scrolling state */
@keyframes eqdance {
  0%, 100% { transform: scaleY(0.18); }
  50% { transform: scaleY(0.95); }
}
body:not(.sound-on) #player.scrolling #eq i,
body.sound-on #eq.fake i { animation: eqdance 0.6s ease-in-out infinite; }
body:not(.sound-on) #player.scrolling #eq i:nth-child(2),
body.sound-on #eq.fake i:nth-child(2) { animation-duration: 0.45s; animation-delay: 0.1s; }
body:not(.sound-on) #player.scrolling #eq i:nth-child(3),
body.sound-on #eq.fake i:nth-child(3) { animation-duration: 0.7s; animation-delay: 0.05s; }
body:not(.sound-on) #player.scrolling #eq i:nth-child(4),
body.sound-on #eq.fake i:nth-child(4) { animation-duration: 0.5s; animation-delay: 0.15s; }
body:not(.sound-on) #player.scrolling #eq i:nth-child(5),
body.sound-on #eq.fake i:nth-child(5) { animation-duration: 0.65s; animation-delay: 0.2s; }
#player.scrolling #playBtn .i-play { display: none; }
#player.scrolling #playBtn .i-pause { display: block; }
/* slow ease-down when the dance ends (default 0.1s stays for the analyser) */
#eq.settling i { transition: transform 0.65s cubic-bezier(0.22, 1, 0.36, 1); }

.p-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.p-label { font-size: 8.5px; letter-spacing: 0.26em; color: var(--muted); }
#pTrack {
  font-family: var(--font-m);
  font-size: 12px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#pTrack.swap { animation: swap 0.4s ease; }
@keyframes swap {
  from { transform: translateY(9px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

.p-right { display: flex; align-items: center; gap: 1rem; flex: none; }
.p-right time { font-family: var(--font-m); font-size: 10.5px; color: var(--muted); letter-spacing: 0.08em; }
#pTime { color: var(--accent); }

#playBtn {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(168, 181, 138, 0.4);
  display: grid;
  place-items: center;
  transition: background 0.3s, border-color 0.3s, transform 0.3s;
}
#playBtn:hover { background: var(--accent-dim); border-color: var(--accent); }
#playBtn svg { width: 11px; height: 12px; fill: var(--accent); display: block; }
#playBtn .i-pause { display: none; }
#playBtn.playing .i-play { display: none; }
#playBtn.playing .i-pause { display: block; }

/* ---------------- custom cursor ---------------- */
body.custom-cursor, body.custom-cursor * { cursor: none !important; }
#cDot, #cRing {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 130;
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
}
body.cursor-seen #cDot, body.cursor-seen #cRing { opacity: 1; }
#cDot {
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  background: var(--accent);
  box-shadow: 0 0 12px rgba(168, 181, 138, 0.65);
  transition: width 0.25s, height 0.25s, margin 0.25s;
}
#cRing {
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid rgba(168, 181, 138, 0.4);
  transition: width 0.3s ease, height 0.3s ease, margin 0.3s ease,
    border-color 0.3s, background 0.3s;
}
/* over anything clickable: ring blooms, dot tightens */
body.cursor-hover #cRing {
  width: 54px;
  height: 54px;
  margin: -27px 0 0 -27px;
  border-color: rgba(168, 181, 138, 0.85);
  background: rgba(168, 181, 138, 0.07);
}
body.cursor-hover #cDot { width: 4px; height: 4px; margin: -2px 0 0 -2px; }
/* pressed: ring snaps in */
body.cursor-down #cRing { width: 24px; height: 24px; margin: -12px 0 0 -12px; }

/* ---------------- Lab peek card (rides the cursor) ---------------- */
#labPeek {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 120; /* under the cursor dot, over everything else */
  width: 290px;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
}
.peek-in {
  overflow: hidden;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--tint) 18%, var(--line));
  /* the project's own tint washes down the panel so each card reads different */
  background:
    linear-gradient(165deg, color-mix(in srgb, var(--tint) 10%, transparent), transparent 58%),
    color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow:
    0 26px 60px -20px rgba(0, 0, 0, 0.85),
    0 0 0 1px color-mix(in srgb, var(--tint) 14%, transparent);
  transform-origin: 18% 14%; /* grows out of the cursor, not the corner */
}
.peek-art {
  display: block;
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(ellipse 80% 70% at 78% 8%, color-mix(in srgb, var(--tint) 30%, transparent), transparent 68%),
    linear-gradient(145deg, color-mix(in srgb, var(--tint) 20%, #0f110f), #0b0d0b 72%);
}
/* the shared album-art parts are sized for a full card — shrink them to fit */
.peek-art .ghost { font-size: 5.4rem; left: 6%; top: -7%; opacity: 0.26; }
.peek-art .vinyl { width: 46%; right: -6%; bottom: -17%; }
.peek-art .shot { width: 100%; height: 100%; object-fit: cover; display: block; }
.peek-badge {
  position: absolute;
  top: 0.6rem;
  left: 0.7rem;
  font-size: 8.5px;
  letter-spacing: 0.16em;
  color: var(--tint);
  background: rgba(10, 11, 10, 0.5);
  border: 1px solid color-mix(in srgb, var(--tint) 45%, transparent);
  padding: 0.24rem 0.5rem;
  border-radius: 999px;
}
.peek-body { display: block; padding: 0.85rem 0.95rem 0.8rem; }
.peek-meta {
  display: flex;
  justify-content: space-between;
  gap: 0.7rem;
  font-size: 9px;
  letter-spacing: 0.16em;
  color: var(--muted);
}
.peek-title {
  display: block;
  font-family: var(--font-d);
  font-weight: 500;
  font-size: 1.18rem;
  line-height: 1.15;
  margin: 0.42rem 0 0.36rem;
}
.peek-desc { display: block; font-size: 0.82rem; line-height: 1.45; color: var(--muted); }
.peek-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem;
  margin-top: 0.75rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--line);
  font-size: 8.5px;
  letter-spacing: 0.14em;
}
.peek-stack { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.peek-stack i {
  font-style: normal;
  color: var(--muted);
  border: 1px solid var(--line);
  padding: 0.22rem 0.4rem;
  border-radius: 3px;
}
.peek-cta { color: var(--tint); white-space: nowrap; }

/* ---------------- track-change overlay ---------------- */
.track-overlay {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(10, 11, 10, 0.93);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  display: grid;
  place-items: center;
  visibility: hidden;
  opacity: 0;
}
.track-overlay.open { visibility: visible; }
.t-inner { text-align: center; padding: 0 var(--pad); }
.t-label { font-size: 10.5px; letter-spacing: 0.3em; color: var(--accent); }
.t-name {
  font-weight: 600;
  font-size: clamp(2.2rem, 7vw, 4.8rem);
  letter-spacing: -0.02em;
  margin: 1.1rem 0 0.7rem;
}
.t-dur { font-size: 12px; letter-spacing: 0.18em; color: var(--muted); }
.t-line {
  width: min(320px, 60vw);
  height: 1px;
  background: var(--line);
  margin: 1.8rem auto 0;
  overflow: hidden;
}
.t-line span {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
}

/* ---------------- 404 ---------------- */
.err {
  min-height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--pad);
}
.err .kicker { display: block; margin-bottom: 1.4rem; }
.err h1 {
  font-weight: 600;
  font-size: clamp(6rem, 22vw, 16rem);
  line-height: 0.9;
  letter-spacing: -0.03em;
}
.err p { margin: 1.6rem 0 2.6rem; color: var(--muted); font-size: 1.05rem; }

/* ---------------- responsive ---------------- */
/* short screens: the two wordiest tracks trade type size for the promise
   that a whole section still lands inside one viewport */
@media (min-width: 901px) and (max-height: 820px) {
  .a-bio { font-size: 1.05rem; }
  .a-bio.sub { font-size: 0.92rem; }
  .stat b { font-size: 1.5rem; }
  .np-card, .studio-card { padding: 1.05rem 1.2rem; }
  .np-head { margin-bottom: 0.8rem; }
  .np-row { padding: 0.34rem 0; }
  .studio-card { margin-top: 0.9rem; }
  .studio-card li { padding: 0.32rem 0; }
  .contact-title { font-size: clamp(2.6rem, 8vw, 6rem); }
  .contact-sub { margin-top: 1rem; }
  .cta-row { margin-top: 1.8rem; }
}

@media (max-width: 1023px) {
  .hero-scene { display: none; } /* small screens keep the clean hero */
}

@media (max-width: 900px) {
  .b-desc { display: none; }
  .bside { grid-template-columns: 2.4rem 1.6fr 1fr 3.2rem 1.2rem; }
  .about-grid { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  .nav-links { display: none; }
  /* with the centre column gone, two columns keep the right group on the
     right edge instead of auto-placing it into the middle */
  .nav-shell { grid-template-columns: 1fr auto; }
  /* no centre links to trade away here, so the sound readout stays put —
     otherwise the contracted pill would be empty but for the mark */
  #nav.shrunk #soundToggle {
    max-width: 9em;
    opacity: 1;
    visibility: visible;
    transition: opacity 0.3s ease;
  }
  /* the one width the phone can't spare: the surname goes too, → RK */
  #nav.shrunk .nav-logo .nl-tail { max-width: 0; opacity: 0; }
  #nav.shrunk .nav-shell { padding: 0.5rem 0.5rem 0.5rem 0.9rem; }
  .stage { height: min(64vh, 560px); }
  .p-label { display: none; }
  .hero-cue { display: none; }
}

@media (max-width: 540px) {
  .bside { grid-template-columns: 2rem 1fr 3rem 1.1rem; gap: 0.8rem; }
  .b-tags { display: none; }
  #pTotal { display: none; }
  .btn-talk { display: none; }
  .stats { grid-template-columns: 1fr 1fr; }
  .np-row b { max-width: 60%; }
}

/* ---------------- reduced motion: calm everything ---------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
