/* ══════════════════════════════════════════════════════════════
   Jishan Ali Thobani - Singer & Music Director
   "rooms of light" - the page moves between a night room and a
   day room; every component reads its colours from the room it is in.
   ══════════════════════════════════════════════════════════════ */

:root {
  --night:     #131010;
  --night-2:   #1d1917;
  --night-3:   #272120;

  --day:       #f7f2e8;
  --day-2:     #efe7d8;
  --paper:     #fffdf8;

  --ink:       #17130f;
  --ink-70:    #4b4239;
  --ink-45:    #6d6358;

  --cream:     #f4ece0;
  --cream-70:  rgba(244, 236, 224, 0.72);
  --cream-45:  rgba(244, 236, 224, 0.55);

  --flame:     #c2361c;   /* solid fills + accent text on day */
  --flame-lit: #f4693f;   /* accent text on night */
  --flame-hot: #ef5a33;   /* display type on night */
  --ember:     #e9a13c;   /* warm highlight, glow, equaliser */

  --ff-display: "Bricolage Grotesque", "Archivo", system-ui, sans-serif;
  --ff-body:    "Archivo", system-ui, -apple-system, sans-serif;
  --ff-deva:    "Rozha One", "Archivo", serif;

  --gut: clamp(1.25rem, 4vw, 4.5rem);
  --rail-w: clamp(0px, 11vw, 12rem);
  --ease: cubic-bezier(0.22, 0.61, 0.24, 1);
}

/* ── the two rooms ───────────────────────────────────────────── */

.room-day {
  --bg: var(--day);
  --bg-2: var(--day-2);
  --card: var(--paper);
  --fg: var(--ink);
  --fg-2: var(--ink-70);
  --fg-3: var(--ink-45);
  --line: rgba(23, 19, 15, 0.13);
  --line-2: rgba(23, 19, 15, 0.07);
  --accent: var(--flame);
  --accent-strong: var(--flame);
}

.room-night {
  --bg: var(--night);
  --bg-2: var(--night-2);
  --card: var(--night-2);
  --fg: var(--cream);
  --fg-2: var(--cream-70);
  --fg-3: var(--cream-45);
  --line: rgba(244, 236, 224, 0.17);
  --line-2: rgba(244, 236, 224, 0.09);
  --accent: var(--flame-lit);
  --accent-strong: var(--flame-hot);
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  background: var(--night);
}

body {
  background: var(--night);
  color: var(--cream);
  font-family: var(--ff-body);
  font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.05rem);
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

::selection { background: var(--ember); color: var(--night); }

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

/* film grain over the whole page - the single cheapest source of warmth */
.grain {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.5;
  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='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.14'/%3E%3C/svg%3E");
}

.skip-link {
  position: fixed;
  top: 0.6rem;
  left: 0.6rem;
  z-index: 200;
  background: var(--ember);
  color: var(--night);
  padding: 0.7rem 1.1rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  border-radius: 4px;
  transform: translateY(-160%);
  transition: transform 0.2s var(--ease);
}

.skip-link:focus-visible { transform: none; }

/* ── shared type ─────────────────────────────────────────────── */

.act-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: clamp(1rem, 2vw, 1.6rem);
}

.act-eyebrow em {
  font-style: normal;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.08em;
}

.act-eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
  max-width: 5rem;
}

.act-title {
  font-family: var(--ff-display);
  font-weight: 700;
  font-variation-settings: "wdth" 92, "opsz" 72;
  font-size: clamp(2.4rem, 6.2vw, 5.4rem);
  line-height: 0.92;
  letter-spacing: -0.028em;
  text-wrap: balance;
}

.act-lede {
  margin-top: clamp(1rem, 2vw, 1.5rem);
  max-width: 42ch;
  color: var(--fg-2);
  font-size: clamp(0.95rem, 0.9rem + 0.3vw, 1.12rem);
  line-height: 1.62;
}

/* ── loader ──────────────────────────────────────────────────── */

#loader {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: var(--night);
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1.4rem;
  transition: opacity 0.5s var(--ease), visibility 0.5s;
}

#loader.is-done { opacity: 0; visibility: hidden; }

.loader-mark {
  font-family: var(--ff-display);
  font-weight: 800;
  font-variation-settings: "wdth" 80;
  font-size: clamp(2.4rem, 8vw, 4rem);
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--cream);
}

.loader-bar {
  width: clamp(110px, 22vw, 190px);
  height: 2px;
  background: rgba(244, 236, 224, 0.2);
  overflow: hidden;
}

.loader-bar i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--ember);
  transition: width 0.75s var(--ease);
}

#loader.is-filling .loader-bar i { width: 100%; }

/* ── fixed chrome ────────────────────────────────────────────── */

.wordmark {
  position: fixed;
  top: clamp(1rem, 2.4vw, 2rem);
  left: clamp(1rem, 2.4vw, 2.2rem);
  z-index: 60;
  display: flex;
  text-decoration: none;
}

.wordmark-jat {
  font-family: var(--ff-display);
  font-weight: 800;
  font-variation-settings: "wdth" 78;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  line-height: 1;
  padding: 0.36rem 0.45rem 0.32rem;
  background: var(--flame);
  color: var(--cream);
  border-radius: 3px;
  transition: background 0.28s var(--ease);
}

.wordmark:hover .wordmark-jat { background: var(--ember); color: var(--night); }

/* the section rail is a sound wave, not a hairline */

.rail {
  position: fixed;
  top: 50%;
  left: clamp(1rem, 2.4vw, 2.2rem);
  transform: translateY(-50%);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: clamp(0.3rem, 0.8vh, 0.55rem);
  padding-left: 1.6rem;
  color: var(--cream-45);
  transition: color 0.4s var(--ease);
}

/* fixed chrome sits outside the rooms, so it is told which room it floats over */
body.on-day .rail { color: var(--ink-45); }
body.on-day .rw-track { stroke: rgba(23, 19, 15, 0.2); }
body.on-day .rail button:hover,
body.on-day .rail button.is-here { color: var(--ink); }

.rail-wave {
  position: absolute;
  left: 0;
  top: -0.6rem;
  bottom: -0.6rem;
  width: 12px;
  height: auto;
  overflow: visible;
}

.rail-wave path { fill: none; stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.rw-track { stroke: rgba(244, 236, 224, 0.22); transition: stroke 0.4s var(--ease); }
.rw-fill { stroke: var(--ember); transition: stroke-dashoffset 0.18s linear; }

.rail button {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  background: none;
  border: 0;
  padding: 0.42rem 0;
  cursor: pointer;
  font-family: var(--ff-body);
  text-align: left;
  color: inherit;
  transition: color 0.28s var(--ease);
}

.rail button em {
  font-style: normal;
  font-size: 0.62rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  opacity: 0.8;
}

.rail button span {
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  opacity: 0;
  transform: translateX(-5px);
  transition: opacity 0.28s var(--ease), transform 0.28s var(--ease);
}

.rail:hover button span,
.rail button:focus-visible span { opacity: 1; transform: none; }

.rail button:hover,
.rail button.is-here { color: var(--fg, var(--cream)); }
.rail button.is-here em { color: var(--ember); opacity: 1; }
.rail button.is-here span { opacity: 1; transform: none; font-weight: 600; }

.hire {
  position: fixed;
  right: clamp(1rem, 2.4vw, 2.2rem);
  bottom: clamp(1rem, 2.4vw, 2rem);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.78rem 1.15rem;
  background: var(--flame);
  color: var(--cream);
  text-decoration: none;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  border-radius: 999px;
  box-shadow: 0 10px 30px rgba(19, 16, 16, 0.35);
  transition: background 0.28s var(--ease), color 0.28s var(--ease),
              transform 0.35s var(--ease), opacity 0.35s var(--ease);
}

body.at-contact .hire {
  opacity: 0;
  transform: translateY(14px);
  pointer-events: none;
}

.hire i { font-style: normal; transition: transform 0.28s var(--ease); }
.hire:hover { background: var(--ember); color: var(--night); transform: translateY(-2px); }
.hire:hover i { transform: translateX(3px); }

/* ── the travelling record ───────────────────────────────────── */

/*
   z 1 - above section backgrounds, below every content card (z 2),
   so it can tuck behind a panel like a record into its sleeve.
*/
.disc-assembly {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1;
  will-change: transform;
  pointer-events: none;
}

.disc-slot { position: relative; pointer-events: none; }

.disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    repeating-radial-gradient(circle at 50% 50%,
      rgba(255, 236, 210, 0.055) 0 1px,
      rgba(255, 236, 210, 0) 1px 4px),
    radial-gradient(circle at 34% 26%, #2b2422 0%, #14100f 62%, #0a0808 100%);
  box-shadow:
    0 0 0 1px rgba(233, 161, 60, 0.22),
    0 1px 0 rgba(255, 224, 186, 0.16) inset,
    0 30px 70px -26px rgba(0, 0, 0, 0.85),
    0 0 70px -18px rgba(233, 161, 60, 0.18);
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: auto;
  overflow: hidden;
}

.disc:active { cursor: grabbing; }

/*
   Dragging the record scrubs the campaign reel - the single least
   discoverable thing on the page. `cursor: grab` hints it; this says it,
   but only in the act where dragging actually does something.
*/
.disc { transition: box-shadow 0.4s var(--ease); }

.disc-assembly.is-scrubbing .disc:hover {
  box-shadow:
    0 0 0 1px rgba(233, 161, 60, 0.52),
    0 1px 0 rgba(255, 224, 186, 0.2) inset,
    0 30px 70px -26px rgba(0, 0, 0, 0.85),
    0 0 90px -14px rgba(233, 161, 60, 0.34);
}

.disc-hint {
  position: absolute;
  top: calc(100% + 0.85rem);
  left: 50%;
  transform: translate(-50%, 6px);
  white-space: nowrap;
  font-family: var(--ff-body);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ember);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s var(--ease), transform 0.32s var(--ease);
}

.disc-assembly.is-scrubbing .disc:hover ~ .disc-hint {
  opacity: 1;
  transform: translate(-50%, 0);
}

.platter { position: absolute; inset: 0; border-radius: 50%; will-change: transform; }

.platter::before,
.platter::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(255, 236, 210, 0.06);
}

.platter::before { inset: 9%; }
.platter::after { inset: 22%; }

/* a warm rim light so the record reads as an object, not a hole */
.disc-sheen {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 200deg,
    rgba(255, 218, 170, 0) 0deg,
    rgba(255, 218, 170, 0.13) 26deg,
    rgba(255, 218, 170, 0) 68deg,
    rgba(255, 218, 170, 0) 186deg,
    rgba(255, 218, 170, 0.08) 212deg,
    rgba(255, 218, 170, 0) 252deg);
  pointer-events: none;
}

.disc-label {
  position: absolute;
  inset: 31%;
  border-radius: 50%;
  overflow: hidden;
  background: var(--night-3);
  box-shadow: 0 0 0 1px rgba(233, 161, 60, 0.45), 0 6px 20px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

.disc-label-art {
  position: absolute;
  inset: 0;
  background-image: url("assets/jishan.jpg?v=2");
  background-size: 190%;
  background-position: 47% 10%;
  transition: opacity 0.45s var(--ease);
}

.disc-label-art.is-art { background-size: cover; background-position: center 32%; }

.disc-spindle {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 3.6%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--cream);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55);
  pointer-events: none;
  z-index: 3;
}

.disc-progress {
  position: absolute;
  inset: -3.4%;
  transform: rotate(-90deg);
  overflow: visible;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--ease);
}

.disc-assembly.is-scrubbing .disc-progress { opacity: 1; }

.disc-progress circle { fill: none; stroke-width: 1.1; vector-effect: non-scaling-stroke; }
.dp-track { stroke: rgba(122, 108, 96, 0.35); }

.dp-fill {
  stroke: var(--ember);
  stroke-linecap: round;
  stroke-dasharray: 304.2;
  stroke-dashoffset: 304.2;
  transition: stroke-dashoffset 0.12s linear;
}

.disc-needle {
  position: absolute;
  top: -8%;
  left: 50%;
  width: 2px;
  height: 8.5%;
  transform: translateX(-50%);
  background: var(--ember);
  border-radius: 2px;
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}

.disc-assembly.is-scrubbing .disc-needle { opacity: 1; }

/* equaliser ring - erupts around the record while something plays */

.eq { position: absolute; inset: -7%; opacity: 0; transition: opacity 0.5s var(--ease); pointer-events: none; }

body.is-playing .eq { opacity: 1; }

.eq-bar { position: absolute; inset: 0; transform: rotate(var(--a)); }

.eq-bar span {
  position: absolute;
  top: -1%;
  left: 50%;
  width: 1.5%;
  height: 7%;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--ember), rgba(233, 161, 60, 0.25));
  transform-origin: center bottom;
  transform: translateX(-50%) scaleY(0.15);
  animation: eq-pulse var(--dur) ease-in-out var(--del) infinite alternate;
}

@keyframes eq-pulse {
  from { transform: translateX(-50%) scaleY(0.12); opacity: 0.5; }
  to   { transform: translateX(-50%) scaleY(1); opacity: 1; }
}

/* ── layout skeleton ─────────────────────────────────────────── */

main { position: relative; }

.act {
  position: relative;
  background: var(--bg);
  color: var(--fg);
  padding-left: var(--rail-w);
  padding-right: var(--gut);
}

/* ══ 00 · index - the night room ═════════════════════════════ */

.act-hero {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: clamp(5.5rem, 13vh, 8rem);
  padding-bottom: clamp(1.5rem, 4vh, 2.5rem);
  overflow: clip;
}

.hero-glow {
  position: absolute;
  top: -18%;
  right: -6%;
  width: min(78vw, 900px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(233, 161, 60, 0.19) 0%,
    rgba(194, 54, 28, 0.11) 38%,
    rgba(19, 16, 16, 0) 68%);
  pointer-events: none;
}

.hero-grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  flex: 1;
}

.hero-place {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cream-45);
  margin-bottom: clamp(0.9rem, 2vw, 1.4rem);
}

.hero-name {
  font-family: var(--ff-display);
  font-weight: 800;
  font-variation-settings: "wdth" 88, "opsz" 96;
  font-size: clamp(3rem, 9.4vw, 8.4rem);
  line-height: 0.845;
  letter-spacing: -0.042em;
}

/* the masked reveal clips the line box - pad it back out for descenders */
.hn-line {
  display: block;
  overflow: hidden;
  padding: 0.02em 0.08em 0.1em 0;
  margin: -0.02em -0.08em -0.1em 0;
}

.hn-in {
  display: inline-block;
  will-change: transform;
  transform: translateY(102%);
  animation: hn-rise 0.85s var(--ease) forwards;
  animation-delay: calc(0.28s + var(--i) * 0.09s);
}

@keyframes hn-rise { to { transform: none; } }

.hn-last { color: var(--flame-hot); }

/* his name in Devanagari, set as display type rather than a caption */
.hero-deva {
  font-family: var(--ff-deva);
  font-size: clamp(1.35rem, 3.4vw, 2.9rem);
  line-height: 1.25;
  color: var(--ember);
  opacity: 0.85;
  margin-top: clamp(0.5rem, 1.4vw, 0.9rem);
}

.hero-role {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem 0.7rem;
  margin-top: clamp(1.1rem, 2.4vw, 1.6rem);
  padding-top: clamp(1.1rem, 2.4vw, 1.4rem);
  border-top: 1px solid var(--line);
  font-size: clamp(0.72rem, 1.1vw, 0.86rem);
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.hero-role i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--ember);
  display: inline-block;
}

.hero-lede {
  margin-top: clamp(0.9rem, 2vw, 1.25rem);
  max-width: 46ch;
  color: var(--cream-70);
  line-height: 1.62;
}

/* the portrait - with the record peeking out from behind it */

.hero-shot { position: relative; }

/* the record sits behind the portrait; only the crescent above it shows */
.hero-shot .disc-slot {
  position: absolute;
  top: -13%;
  right: 4%;
  width: min(42vmin, 310px);
  aspect-ratio: 1;
  z-index: 0;
}

.hero-shot-frame {
  position: relative;
  z-index: 2;
  overflow: hidden;
  border-radius: 2px;
  background: var(--night-2);
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.95);
}

.hero-shot-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(19, 16, 16, 0) 52%, rgba(19, 16, 16, 0.55));
  pointer-events: none;
}

.hero-shot img {
  width: 100%;
  height: auto;   /* the width/height attrs would otherwise beat aspect-ratio */
  aspect-ratio: 4 / 5;
  max-height: 56svh;   /* keep the figures below it above the fold */
  object-fit: cover;
  object-position: 52% 12%;
  filter: saturate(0.88) contrast(1.04) brightness(0.94) sepia(0.14);
}

.hero-shot figcaption {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: 0.75rem;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cream-45);
}

.hero-shot figcaption i {
  width: 14px;
  height: 1px;
  background: var(--ember);
  display: inline-block;
}

.hero-figures {
  position: relative;
  z-index: 2;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.6rem, 2vw, 2rem);
  border-top: 1px solid var(--line);
  margin-top: clamp(1.6rem, 4vh, 2.6rem);
  padding-top: clamp(1rem, 2.2vw, 1.5rem);
}

.hero-figures b {
  display: block;
  font-family: var(--ff-display);
  font-weight: 700;
  font-variation-settings: "wdth" 86;
  font-size: clamp(1.5rem, 3.6vw, 2.9rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
}

.hero-figures span {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--cream-45);
}

/* ══ 03 · campaigns ══════════════════════════════════════════ */

.act-campaigns { padding-bottom: 0; }

/* the brand strip - a band of daylight between the hero and the first act.
   It sits outside any section, so .room-day on the element gives it colours */
.logo-rail {
  position: relative;
  padding: clamp(1rem, 2.4vh, 1.5rem) 0;
  border-block: 1px solid var(--line);
  overflow: hidden;
  background: var(--bg-2);
}

/* the logos fade out at the ends; the band itself runs edge to edge */
.logo-rail::before,
.logo-rail::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  width: 7%;
  pointer-events: none;
}

.logo-rail::before { left: 0; background: linear-gradient(90deg, var(--bg-2), transparent); }
.logo-rail::after { right: 0; background: linear-gradient(270deg, var(--bg-2), transparent); }

.logo-rail-track {
  display: flex;
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  width: max-content;
  animation: rail-run 48s linear infinite;
}

.logo-rail:hover .logo-rail-track { animation-play-state: paused; }

@keyframes rail-run { to { transform: translateX(-50%); } }

.logo-rail img {
  height: clamp(26px, 3.2vw, 38px);
  width: auto;
  max-width: 132px;
  object-fit: contain;
  mix-blend-mode: multiply;
  flex: none;
}

.logo-rail img.is-sq { height: clamp(34px, 4.2vw, 50px); }

/* sticky makes its own stacking context - z 2 keeps the whole pin above the
   record (z 1) so the card can cover it, while empty areas reveal it */
.camp-pin {
  position: sticky;
  z-index: 2;
  top: 0;
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding: clamp(3.5rem, 9vh, 6rem) 0 clamp(3rem, 7vh, 4.5rem);
}

.camp-disc { margin-top: clamp(1.6rem, 4vh, 2.8rem); }

.act-campaigns .camp-disc .disc-slot { width: min(30vmin, 260px); aspect-ratio: 1; }

.camp-right { display: flex; flex-direction: column; gap: clamp(1rem, 2vh, 1.5rem); min-width: 0; }

.camp-card {
  position: relative;
  z-index: 2;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: clamp(1.1rem, 2.4vw, 1.8rem);
  box-shadow: 0 24px 50px -34px rgba(23, 19, 15, 0.45);
  min-width: 0;
}

.camp-card.is-swapping { animation: camp-swap 0.34s var(--ease); }

@keyframes camp-swap {
  from { opacity: 0.35; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

.camp-head {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.4rem);
  padding-bottom: clamp(0.9rem, 2vw, 1.3rem);
  margin-bottom: clamp(0.9rem, 2vw, 1.3rem);
  border-bottom: 1px solid var(--line);
}

.camp-logo {
  height: clamp(30px, 4vw, 46px);
  width: auto;
  max-width: min(180px, 40%);
  object-fit: contain;
  object-position: left center;
  mix-blend-mode: multiply;
  flex: none;
}

.camp-headmeta { min-width: 0; }

/* the brand is the headline of each scene - set big enough that nine
   campaigns read as nine different screens, not one card reloading */
.camp-brand {
  font-family: var(--ff-display);
  font-weight: 700;
  font-variation-settings: "wdth" 88, "opsz" 72;
  font-size: clamp(1.5rem, 2.9vw, 2.7rem);
  line-height: 0.98;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.camp-tag {
  margin-top: 0.28rem;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent);
}

.camp-films { display: grid; gap: clamp(0.6rem, 1.4vw, 0.9rem); grid-template-columns: 1fr; }
.camp-films.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.camp-films.n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* video facade - no iframe until the visitor asks for one */

.film {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 7px;
  overflow: hidden;
  background: var(--night);
  cursor: pointer;
  font-family: var(--ff-body);
  text-align: left;
  transition: border-color 0.28s var(--ease), transform 0.28s var(--ease), box-shadow 0.28s var(--ease);
}

.film:hover {
  border-color: rgba(194, 54, 28, 0.55);
  transform: translateY(-3px);
  box-shadow: 0 18px 32px -22px rgba(23, 19, 15, 0.55);
}

.film-shot { display: block; position: relative; aspect-ratio: 16 / 9; background: var(--night-2); }
.film-shot img { width: 100%; height: 100%; object-fit: cover; }

.film-veil {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: linear-gradient(180deg, rgba(19, 16, 16, 0.05) 40%, rgba(19, 16, 16, 0.55));
}

.film-cue {
  width: clamp(34px, 4vw, 46px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(244, 236, 224, 0.94);
  color: var(--night);
  display: grid;
  place-items: center;
  font-size: 0.72rem;
  padding-left: 2px;
  transition: background 0.24s var(--ease), transform 0.24s var(--ease), color 0.24s var(--ease);
}

.film:hover .film-cue { background: var(--ember); color: var(--night); transform: scale(1.1); }

.film-name {
  display: block;
  padding: 0.62rem 0.75rem 0.68rem;
  background: var(--card);
  color: var(--ink);
  font-size: 0.76rem;
  font-weight: 500;
  line-height: 1.3;
}

.film.is-live { cursor: default; transform: none; }
.film.is-live .film-shot > img,
.film.is-live .film-veil { display: none; }

.film-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* transport */

.camp-transport { display: flex; align-items: center; gap: clamp(0.7rem, 1.6vw, 1.1rem); }

.tp-btn {
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--fg);
  cursor: pointer;
  font-size: 0.95rem;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: background 0.24s var(--ease), color 0.24s var(--ease), border-color 0.24s var(--ease);
}

/* hover only where there is a pointer - a phone keeps :hover stuck on the
   last button tapped, which left the arrow looking pressed */
@media (hover: hover) {
  .tp-btn:hover { background: var(--ink); color: var(--day); border-color: var(--ink); }
}
.tp-btn:active { background: var(--ink); color: var(--day); border-color: var(--ink); }
.tp-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.tp-btn:disabled:hover { background: transparent; color: var(--fg); border-color: var(--line); }

.tp-count {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: var(--fg-3);
}

.tp-count b { color: var(--fg); font-weight: 600; }
.tp-count i { font-style: normal; opacity: 0.5; }

.tp-reel { flex: 1; min-width: 0; position: relative; }

.tp-marks {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(9, minmax(0, 1fr));
  padding-bottom: 0.55rem;
}

.tp-marks button {
  display: grid;
  place-items: center;
  width: 100%;
  height: 2.6rem;
  padding: 0 0.3rem;
  background: none;
  border: 0;
  cursor: pointer;
  position: relative;
}

.tp-marks img {
  max-height: 1.5rem;
  max-width: 100%;
  width: auto;
  object-fit: contain;
  mix-blend-mode: multiply;
  filter: grayscale(1) contrast(1.1);
  opacity: 0.55;
  transition: opacity 0.3s var(--ease), filter 0.3s var(--ease), transform 0.3s var(--ease);
}

.tp-marks img.is-sq { max-height: 2.1rem; }
.tp-marks button:hover img { opacity: 0.9; }
.tp-marks button.is-on img { opacity: 1; filter: none; transform: scale(1.18); }

/* a tick on the track under each mark - the current one lit */
.tp-marks button::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -0.55rem;
  width: 1px;
  height: 0.4rem;
  background: var(--line);
  transition: background 0.3s var(--ease), height 0.3s var(--ease);
}

.tp-marks button.is-on::after { background: var(--flame); height: 0.65rem; }

.tp-scrub { display: block; height: 1px; background: var(--line); position: relative; }
.tp-scrub i { position: absolute; inset: 0 auto 0 0; width: 0%; background: var(--flame); transition: width 0.14s linear; }

/* ══ 02 · brands - the day room ═════════════════════════════ */

.act-brands {
  padding-top: clamp(5rem, 14vh, 9rem);
  padding-bottom: clamp(4rem, 10vh, 7rem);
}

.wall-head { margin-bottom: clamp(2rem, 5vh, 3.4rem); max-width: 62rem; }

.wall {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(110px, 15vw, 172px), 1fr));
  gap: 1px;
  background: var(--line-2);
  border: 1px solid var(--line-2);
}

.wall li {
  position: relative;
  background: var(--bg);
  aspect-ratio: 5 / 3;
  display: grid;
  place-items: center;
  padding: clamp(0.75rem, 1.8vw, 1.3rem);
  transition: background 0.3s var(--ease);
}

.wall li::after {
  content: attr(data-n);
  position: absolute;
  top: 0.4rem;
  left: 0.5rem;
  font-size: 0.56rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--fg-3);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}

.wall li:hover { background: var(--card); }
.wall li:hover::after { opacity: 0.85; }

.wall img {
  max-height: clamp(26px, 3.4vw, 42px);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
  filter: grayscale(1) contrast(1.06);
  opacity: 0.64;
  transition: opacity 0.32s var(--ease), filter 0.32s var(--ease);
}

.wall img.is-sq { max-height: clamp(38px, 5vw, 62px); }
.wall li:hover img { opacity: 1; filter: grayscale(0) contrast(1); mix-blend-mode: normal; }

.wall-type {
  font-family: var(--ff-display);
  font-weight: 600;
  font-variation-settings: "wdth" 84;
  font-size: clamp(0.9rem, 1.6vw, 1.2rem);
  letter-spacing: -0.01em;
  color: var(--fg-3);
  transition: color 0.32s var(--ease);
}

.wall li:hover .wall-type { color: var(--fg); }

.wall li.wall-more { background: var(--night); color: var(--cream); }

.wall-more span {
  font-family: var(--ff-display);
  font-weight: 700;
  font-variation-settings: "wdth" 86;
  font-size: clamp(0.85rem, 1.5vw, 1.1rem);
  line-height: 1.15;
  text-align: center;
  letter-spacing: -0.01em;
}

.wall-more small {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--ff-body);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ember);
}

/* ══ 01 · on screen - the Pop Kaun? credit ══════════════════ */

.act-screen {
  padding-top: clamp(5rem, 14vh, 9rem);
  padding-bottom: clamp(5rem, 13vh, 8rem);
  overflow: clip;
}

.screen-glow {
  position: absolute;
  top: 4%;
  left: 42%;
  width: min(80vw, 940px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(233, 161, 60, 0.16) 0%,
    rgba(194, 54, 28, 0.09) 40%,
    rgba(19, 16, 16, 0) 70%);
  pointer-events: none;
}

.screen-head { position: relative; z-index: 2; max-width: 62rem; margin-bottom: clamp(1.8rem, 4vh, 2.8rem); }

.screen-title {
  font-family: var(--ff-display);
  font-weight: 800;
  font-variation-settings: "wdth" 90, "opsz" 96;
  font-size: clamp(3rem, 9vw, 7.5rem);
  line-height: 0.9;
  letter-spacing: -0.04em;
}

.screen-title span { color: var(--ember); }

.screen-lede { max-width: 46ch; }

/* the key art doubles as the trailer poster */
.screen-media {
  position: relative;
  z-index: 2;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  overflow: hidden;
  background: var(--night-2);
  box-shadow:
    0 0 0 1px rgba(233, 161, 60, 0.22),
    0 44px 90px -46px rgba(0, 0, 0, 0.95);
}

.screen-art { width: 100%; height: 100%; object-fit: cover; }

.screen-play {
  position: absolute;
  inset: 0;
  border: 0;
  background:
    radial-gradient(circle at 50% 48%, rgba(19, 16, 16, 0.26) 0%, rgba(19, 16, 16, 0) 46%),
    linear-gradient(180deg, rgba(19, 16, 16, 0) 55%, rgba(19, 16, 16, 0.72));
  cursor: pointer;
  display: grid;
  place-items: center;
  align-content: center;
  font-family: var(--ff-body);
}

.screen-play-ring {
  width: clamp(54px, 6.5vw, 84px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(244, 236, 224, 0.95);
  color: var(--night);
  display: grid;
  place-items: center;
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  padding-left: 4px;
  transition: background 0.24s var(--ease), color 0.24s var(--ease), transform 0.24s var(--ease);
}

.screen-play:hover .screen-play-ring { background: var(--ember); color: var(--night); transform: scale(1.08); }

.screen-play-label {
  position: absolute;
  left: clamp(1rem, 2.4vw, 1.8rem);
  bottom: clamp(0.9rem, 2vw, 1.4rem);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244, 236, 224, 0.92);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.8);
}

.screen-mount { position: absolute; inset: 0; display: none; }
.screen-mount iframe { width: 100%; height: 100%; border: 0; display: block; }

.screen-media.is-live .screen-mount { display: block; }
.screen-media.is-live .screen-art,
.screen-media.is-live .screen-play { display: none; }

/* billing block, set like end credits */
.screen-credits {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 0.85fr 1.15fr 0.9fr 1.7fr 1.1fr;
  gap: clamp(1rem, 2.4vw, 2rem);
  margin-top: clamp(1.6rem, 3.5vh, 2.4rem);
  padding-top: clamp(1.2rem, 2.6vh, 1.8rem);
  border-top: 1px solid var(--line);
}

.screen-credits dt {
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ember);
  margin-bottom: 0.45rem;
}

.screen-credits dd {
  font-size: clamp(0.86rem, 1.1vw, 0.98rem);
  line-height: 1.45;
  color: var(--cream);
}

.screen-note {
  position: relative;
  z-index: 2;
  max-width: 64ch;
  margin-top: clamp(2rem, 5vh, 3.2rem);
  padding-left: clamp(1.6rem, 3vw, 2.6rem);
  color: var(--cream-70);
  font-size: clamp(0.98rem, 1.2vw, 1.14rem);
  line-height: 1.65;
}

.sn-mark {
  position: absolute;
  left: 0;
  top: 0.15em;
  bottom: 0.15em;
  width: 2px;
  background: linear-gradient(180deg, var(--ember), rgba(233, 161, 60, 0));
}

/* ══ 04 · records - back into the night ══════════════════════ */

.act-records {
  padding-top: clamp(4.5rem, 12vh, 7.5rem);
  padding-bottom: clamp(4rem, 10vh, 7rem);
  overflow: clip;
}

.rec-glow {
  position: absolute;
  top: 6%;
  left: 30%;
  width: min(70vw, 820px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(233, 161, 60, 0.14) 0%,
    rgba(194, 54, 28, 0.08) 42%,
    rgba(19, 16, 16, 0) 70%);
  pointer-events: none;
}

.rec-head { position: relative; z-index: 2; margin-bottom: clamp(2rem, 5vh, 3.2rem); max-width: 62rem; }

.rec-pin {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(1.5rem, 4vw, 3.4rem);
  align-items: start;
}

.rec-stage { position: sticky; z-index: 2; top: clamp(4.5rem, 12vh, 7rem); }

.rec-stage .disc-slot {
  position: absolute;
  top: clamp(-5.5rem, -8vw, -3.5rem);
  right: clamp(-2.5rem, -3.5vw, -1rem);
  width: min(26vmin, 210px);
  aspect-ratio: 1;
  z-index: 0;
  pointer-events: none;
}

.rec-feature {
  position: relative;
  z-index: 2;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 34px 70px -44px rgba(0, 0, 0, 0.9);
}

.rec-media { position: relative; aspect-ratio: 16 / 9; background: var(--night); }
.rec-thumb { width: 100%; height: 100%; object-fit: cover; }

.rec-play {
  position: absolute;
  inset: 0;
  border: 0;
  background:
    radial-gradient(circle at 50% 46%, rgba(19, 16, 16, 0.3) 0%, rgba(19, 16, 16, 0) 42%),
    linear-gradient(180deg, rgba(19, 16, 16, 0.05) 46%, rgba(19, 16, 16, 0.72));
  cursor: pointer;
  display: grid;
  place-items: center;
  align-content: center;
  font-family: var(--ff-body);
}

.rec-play-ring {
  width: clamp(46px, 5.4vw, 62px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(244, 236, 224, 0.95);
  color: var(--night);
  display: grid;
  place-items: center;
  font-size: 0.92rem;
  padding-left: 3px;
  transition: background 0.24s var(--ease), color 0.24s var(--ease), transform 0.24s var(--ease);
}

.rec-play:hover .rec-play-ring { background: var(--ember); color: var(--night); transform: scale(1.08); }

.rec-play-label {
  position: absolute;
  left: clamp(0.85rem, 2vw, 1.3rem);
  right: clamp(0.85rem, 2vw, 1.3rem);
  bottom: clamp(0.7rem, 1.6vw, 1rem);
  text-align: left;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244, 236, 224, 0.92);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.75);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rec-play-label b { font-weight: 600; }

.rec-mount { position: absolute; inset: 0; display: none; }
.rec-mount iframe { width: 100%; height: 100%; border: 0; display: block; }

.rec-media.is-live .rec-mount { display: block; }
.rec-media.is-live .rec-thumb,
.rec-media.is-live .rec-play { display: none; }

.rec-meta { padding: clamp(1rem, 2.2vw, 1.5rem); }

.rec-title {
  font-family: var(--ff-display);
  font-weight: 700;
  font-variation-settings: "wdth" 90;
  font-size: clamp(1.25rem, 2.6vw, 1.95rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
}

.rec-note { margin-top: 0.5rem; color: var(--fg-2); font-size: 0.92rem; max-width: 46ch; }

.rec-index {
  position: relative;
  z-index: 2;
  list-style: none;
  border-top: 1px solid var(--line);
}

.rec-row { border-bottom: 1px solid var(--line); }

.rec-row button {
  width: 100%;
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: clamp(0.5rem, 1.4vw, 1rem);
  padding: clamp(0.85rem, 2vw, 1.25rem) 0.2rem;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--ff-body);
  color: var(--fg);
  transition: padding-left 0.3s var(--ease), color 0.3s var(--ease);
}

.rec-row button:hover { padding-left: 0.7rem; }

.rec-n { font-size: 0.68rem; font-variant-numeric: tabular-nums; letter-spacing: 0.1em; color: var(--fg-3); transition: color 0.3s var(--ease); }

.rec-name {
  font-family: var(--ff-display);
  font-weight: 600;
  font-variation-settings: "wdth" 92;
  font-size: clamp(1rem, 2vw, 1.35rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  min-width: 0;
}

.rec-sub {
  display: block;
  margin-top: 0.22rem;
  font-family: var(--ff-body);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.06em;
  color: var(--fg-3);
  text-transform: uppercase;
}

.rec-year { font-size: 0.74rem; font-variant-numeric: tabular-nums; color: var(--fg-3); white-space: nowrap; }

.rec-row.is-on { background: rgba(244, 236, 224, 0.05); }
.rec-row.is-on button { padding-left: 0.7rem; }
.rec-row.is-on .rec-n { color: var(--ember); font-weight: 600; }
.rec-row.is-on .rec-name { color: var(--ember); }

/* ══ 05 · contact ════════════════════════════════════════════ */

.act-contact {
  padding-top: clamp(6rem, 20vh, 12rem);
  padding-bottom: clamp(2rem, 5vh, 3rem);
  overflow: clip;
}

.contact-pin { position: relative; display: flex; flex-direction: column; gap: clamp(1.4rem, 3vh, 2.2rem); }

/* "mehfil" - a gathering for music - set huge and low behind the card */
.contact-deva {
  position: absolute;
  top: clamp(-4.5rem, -7vw, -2.5rem);
  left: -0.04em;
  font-family: var(--ff-deva);
  font-size: clamp(4rem, 14vw, 12rem);
  line-height: 1.1;
  color: var(--ember);
  opacity: 0.11;
  pointer-events: none;
  white-space: nowrap;
}

.contact-card {
  position: relative;
  z-index: 2;
  background: var(--night-2);
  color: var(--cream);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: clamp(1.8rem, 5vw, 4rem);
}

/* the record slides in behind the card, like going back into its sleeve */
.contact-card .disc-slot {
  position: absolute;
  top: clamp(-9rem, -14vw, -5rem);
  right: calc(var(--gut) * -0.55);
  width: min(34vmin, 300px);
  aspect-ratio: 1;
}

.contact-body {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  column-gap: clamp(2rem, 5vw, 4.5rem);
  row-gap: clamp(1.6rem, 3vw, 2.4rem);
  align-items: start;
}

.contact-eyebrow { grid-column: 1 / -1; }

.contact-title {
  font-family: var(--ff-display);
  font-weight: 700;
  font-variation-settings: "wdth" 90, "opsz" 72;
  font-size: clamp(2rem, 5.2vw, 4rem);
  line-height: 0.95;
  letter-spacing: -0.03em;
}

.contact-lines { list-style: none; border-top: 1px solid var(--line); }

.contact-lines li {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: 0.8rem;
  align-items: baseline;
  padding: clamp(0.7rem, 1.6vw, 0.95rem) 0;
  border-bottom: 1px solid var(--line);
}

.cl-label { font-size: 0.66rem; letter-spacing: 0.15em; text-transform: uppercase; color: var(--cream-45); }

.cl-value {
  font-size: clamp(0.95rem, 1.8vw, 1.2rem);
  color: var(--cream);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.26s var(--ease), border-color 0.26s var(--ease);
  word-break: break-word;
}

a.cl-value:hover { color: var(--ember); border-bottom-color: var(--ember); }
.cl-plain { color: var(--cream-70); }

.contact-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.8rem; }

.btn-primary, .btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.95rem 1.5rem;
  border-radius: 999px;
  text-decoration: none;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  transition: background 0.26s var(--ease), color 0.26s var(--ease), border-color 0.26s var(--ease), transform 0.26s var(--ease);
}

.btn-primary i, .btn-ghost i { font-style: normal; transition: transform 0.26s var(--ease); }

.btn-primary { background: var(--flame); color: var(--cream); }
.btn-primary:hover { background: var(--ember); color: var(--night); transform: translateY(-2px); }
.btn-primary:hover i { transform: translateX(3px); }

.btn-ghost { border: 1px solid rgba(244, 236, 224, 0.3); color: var(--cream); }
.btn-ghost:hover { border-color: var(--ember); color: var(--ember); transform: translateY(-2px); }

.contact-socials { list-style: none; display: flex; flex-direction: column; gap: 0.15rem; padding-top: clamp(0.6rem, 1.5vw, 1rem); }

.contact-socials a {
  display: inline-block;
  padding: 0.28rem 0;
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--cream-70);
  text-decoration: none;
  transition: color 0.26s var(--ease);
}

.contact-socials a:hover { color: var(--ember); }

.site-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.8rem 1.5rem;
  padding: 0 0.4rem clamp(4.5rem, 9vh, 5.5rem);
}

.foot-urdu {
  font-family: "Noto Nastaliq Urdu", "Geeza Pro", "Scheherazade New", serif;
  direction: rtl;
  font-size: 1.05rem;
  line-height: 1.9;
  color: var(--ember);
  opacity: 0.9;
}

.foot-legal { font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cream-45); }

/* ══════════════════════════════════════════════════════════════
   the motion layer

   `.motion-on` is set by motion.js only once GSAP is up and the
   visitor has not asked for reduced motion. Anything under it either
   hands a property over to GSAP or adds an effect that would look
   half-finished without a script to drive it.
   ══════════════════════════════════════════════════════════════ */

/* GSAP owns these transforms now - a CSS transition on the same
   property would fight quickTo for the inline style every frame */
.motion-on .logo-rail-track { animation: none; }
.motion-on .camp-card.is-swapping { animation: none; }
.motion-on .film:hover { transform: none; }

.motion-on .film-cue,
.motion-on .rec-play-ring,
.motion-on .screen-play-ring {
  transition: background 0.24s var(--ease), color 0.24s var(--ease);
}

.motion-on .hire {
  transition: background 0.28s var(--ease), color 0.28s var(--ease), opacity 0.35s var(--ease);
}

.motion-on .btn-primary,
.motion-on .btn-ghost {
  transition: background 0.26s var(--ease), color 0.26s var(--ease), border-color 0.26s var(--ease);
}

/* the wipe below supplies the colour change, so the fill stays put */
.motion-on .hire:hover,
.motion-on .btn-primary:hover { background: var(--flame); }

/* magnetics own the transform; without this the v4 lift snaps in for the
   one frame between pointerenter and the first pointermove */
.motion-on .hire:hover,
.motion-on .btn-primary:hover,
.motion-on .btn-ghost:hover { transform: none; }

/* the retire gives up transform too, so magnetics can keep it */
.motion-on body.at-contact .hire { transform: none; }

.logo-rail-track { will-change: transform; }

/* ── the hero answers you ────────────────────────────────────── */

/* a warm light you push around his face - the "rooms of light" idea
   made something you can actually touch */
.hero-glint {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
  background: radial-gradient(34% 34% at var(--gx, 50%) var(--gy, 40%),
    rgba(255, 226, 178, 0.42) 0%,
    rgba(255, 186, 112, 0.16) 42%,
    rgba(255, 170, 90, 0) 72%);
  transition: opacity 0.55s var(--ease);
}

.hero-shot-frame:hover .hero-glint { opacity: 1; }

/* on touch there is no hover to hold it open - the scroll moves it instead */
.hero-shot-frame.glint-lit .hero-glint { opacity: 1; }

/* his name is set in a variable face; the cursor widens the letters
   nearest it and lifts them a little off the baseline */
.hn-ch {
  --hl: 0;
  display: inline-block;
  will-change: font-variation-settings, transform;
  transform: translateY(calc(var(--hl) * -14px));
  /* the letters nearest the cursor warm toward the ember and light up -
     the room's stage light, run across his own name */
  color: color-mix(in oklab, var(--ember) calc(var(--hl) * 68%), var(--hn-base, var(--cream)));
  text-shadow: 0 0 calc(var(--hl) * 30px) rgba(233, 161, 60, calc(var(--hl) * 0.5));
}

.hero-name { --hn-base: var(--cream); }
.hn-last { --hn-base: var(--flame-hot); }

/* the entrance masks each line - once it has played the clip has to go,
   or a letter can never lift out of its own line box */
.hero-name.is-live .hn-line { overflow: visible; }

/* ── type that arrives a line at a time ──────────────────────── */

.sp-line { display: block; will-change: transform; }

/* SplitText's line masks clip on the baseline - pad the descenders back.
   Only the mask gets it: padding the line inside as well would grow the
   mask by the same amount again and loosen the leading. */
.split-title > div { padding-bottom: 0.1em; margin-bottom: -0.1em; }

/* ── the film still, lit as you pass over it ─────────────────── */

.film-shot img { transition: transform 0.7s var(--ease), filter 0.5s var(--ease); }
.film:hover .film-shot img { transform: scale(1.055); filter: brightness(1.06); }

/* a bar of light sweeps the still, the way a screen catches one */
.film-shot::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(105deg,
    rgba(255, 255, 255, 0) 38%,
    rgba(255, 245, 225, 0.16) 48%,
    rgba(255, 255, 255, 0) 58%);
  transform: translateX(-115%);
  transition: transform 0s 0.7s;
}

.film:hover .film-shot::after { transform: translateX(115%); transition: transform 0.7s var(--ease); }
.film.is-live .film-shot::after { display: none; }

/* nothing to hover on a phone, so the light passes once as the tile lands */
.film.is-swept .film-shot::after {
  transform: translateX(115%);
  transition: transform 0.9s var(--ease);
}

.film-cue { will-change: transform; }

/* ── the brand wall under a moving stage light ───────────────── */

.wall li {
  --lit: 0;
  z-index: 0;
  transform: scale(calc(1 + var(--lit) * 0.05));
  transition: background 0.3s var(--ease);
}

.wall li:hover { z-index: 2; }

/* the pool of warmth itself, painted under the mark */
.wall li::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--lit);
  background:
    radial-gradient(circle at 50% 44%, rgba(255, 253, 248, 0.95) 0%, rgba(255, 250, 240, 0.5) 62%, rgba(255, 250, 240, 0) 100%),
    radial-gradient(circle at 50% 44%, rgba(233, 161, 60, 0.16) 0%, rgba(233, 161, 60, 0) 70%);
}

.wall li > * { position: relative; z-index: 1; }

/* the one dark tile takes the light as an ember bloom, not a white wash */
.wall li.wall-more::before {
  background: radial-gradient(circle at 50% 44%, rgba(233, 161, 60, 0.22) 0%, rgba(233, 161, 60, 0) 72%);
}

.wall img {
  opacity: calc(0.64 + var(--lit) * 0.36);
  filter: grayscale(calc(1 - var(--lit))) contrast(calc(1.06 - var(--lit) * 0.06));
}

/* only the mark actually under the cursor drops out of multiply */
.wall li:hover img { mix-blend-mode: normal; }
.wall li::after { opacity: calc(var(--lit) * 0.9); }
.wall-type { color: color-mix(in oklab, var(--fg) calc(var(--lit) * 100%), var(--fg-3)); }

/* the pool is already eased in JS - a transition on top would only lag it.
   Without the motion layer these keep their original hover transitions. */
.motion-on .wall img,
.motion-on .wall li::after,
.motion-on .wall-type { transition: none; }

/* ── the record index as a running order ─────────────────────── */

.rec-row button { grid-template-columns: 2.4rem minmax(0, 1fr) auto auto; }

.rec-row { position: relative; }

/* an ember rule wipes in under the row you are pointing at */
.rec-row::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--ember);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.45s var(--ease);
}

.rec-row:hover::after,
.rec-row.is-on::after { transform: scaleX(1); }

/* three bars that only move for the record currently cued up */
.rec-eq {
  display: flex;
  align-items: flex-end;
  align-self: center;
  gap: 2px;
  height: 0.85rem;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}

.rec-eq i {
  width: 2px;
  height: 30%;
  background: var(--ember);
  transform-origin: 50% 100%;
}

.rec-row.is-on .rec-eq { opacity: 1; }
.rec-row.is-on .rec-eq i { animation: rec-eq 0.9s ease-in-out infinite alternate; }
.rec-row.is-on .rec-eq i:nth-child(2) { animation-duration: 0.62s; }
.rec-row.is-on .rec-eq i:nth-child(3) { animation-duration: 1.15s; }

@keyframes rec-eq { to { height: 100%; } }

/* ── links that draw their own underline ─────────────────────── */

.contact-socials a { position: relative; text-decoration: none; }

.contact-socials a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: var(--ember);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform 0.4s var(--ease);
}

.contact-socials a:hover::after {
  transform: scaleX(1);
  transform-origin: 0 50%;
}

/* the primary button fills from the floor rather than just swapping colour */
.btn-primary { position: relative; }
.btn-primary, .hire { overflow: hidden; isolation: isolate; }

.btn-primary::before, .hire::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--ember);
  transform: translateY(101%);
  transition: transform 0.45s var(--ease);
}

.btn-primary:hover::before, .hire:hover::before { transform: none; }

/* ── notes off the pointer ───────────────────────────────────
   Drawn as SVG, not the ♪ character: system symbol fonts render
   those at wildly different weights and some platforms swap in a
   colour emoji. Sits under the grain (z 90) so the notes take the
   same film as everything else, and inert to the pointer so it
   never intercepts a hover it is drawn on top of. */

.note-fx-layer {
  position: fixed;
  inset: 0;
  z-index: 80;
  overflow: hidden;
  pointer-events: none;
}

.note-fx {
  position: absolute;
  top: 0;
  left: 0;
  width: 18px;
  height: 18px;
  opacity: 0;
  color: var(--flame-lit);
  will-change: transform, opacity;
}

.note-fx svg { display: block; width: 100%; height: 100%; fill: currentColor; }

/* the note belongs to whichever room it is falling through */
body.on-day .note-fx { color: var(--flame); }
body.on-night .note-fx { filter: drop-shadow(0 0 7px rgba(233, 161, 60, 0.4)); }

@media (hover: none) {
  .note-fx { width: 16px; height: 16px; }
}


/* ── notes off the portrait ──────────────────────────────────
   Phone only. Down there the photograph bleeds to both screen
   edges and dissolves into the night; these drift up out of the
   dissolve, so the soft edge reads as the picture turning into
   music rather than as a blurred crop.

   Deliberately CSS keyframes and not a tween. Nothing here reacts
   to anything - no pointer, no scroll - so it has no business on
   a ticker. motion.js only builds the elements, which also means
   they never exist for a visitor who asked for reduced motion.

   Sits over the frame rather than inside it: the frame both clips
   and masks its children, and a note emerging from the fade has
   to be outside both. Its box is pinned to the frame's through the
   shared --shot-h token. */

.hero-notes {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  pointer-events: none;
}

.hn-note {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--w);
  height: var(--w);
  margin: calc(var(--w) / -2);
  color: var(--ember);
  opacity: 0;
  filter: drop-shadow(0 0 6px rgba(233, 161, 60, 0.35));
  animation: hero-note-out var(--t) var(--d) infinite linear;
  will-change: transform, opacity;
}

.hn-note svg { display: block; width: 100%; height: 100%; fill: currentColor; }

/* the rise is a fraction of the frame's own height, not a fixed distance:
   --shot-h collapses to a letterbox on a phone held sideways, and a note
   travelling 100px would leave the photograph entirely */
@keyframes hero-note-out {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) scale(0.7) rotate(0deg); }
  16%  { opacity: var(--o); }
  60%  { opacity: var(--o); }
  100% {
    opacity: 0;
    transform: translate3d(var(--dx), calc(var(--shot-h, 300px) * var(--dyf)), 0) scale(1) rotate(var(--rot));
  }
}


/* ── reveal ──────────────────────────────────────────────────── */

.rv {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--d, 0s);
}

.rv.in { opacity: 1; transform: none; }

/* ══ responsive ══════════════════════════════════════════════ */

@media (max-width: 1080px) {
  .camp-pin { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
  .screen-credits { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rec-pin { grid-template-columns: 1fr; }
  .rec-stage { position: static; }
  .rec-stage .disc-slot { display: none; }
  .contact-lines li { grid-template-columns: 5.5rem minmax(0, 1fr); }
  .contact-body { grid-template-columns: 1fr; row-gap: clamp(1.5rem, 4vw, 2.4rem); }
  .contact-socials { flex-direction: row; flex-wrap: wrap; gap: 0.2rem 1.4rem; }
}

@media (max-width: 860px) {
  :root { --rail-w: 0px; }

  .act { padding-left: var(--gut); }

  .wordmark { top: 0.85rem; left: 0.9rem; }

  .rail {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    transform: none;
    flex-direction: row;
    justify-content: space-between;
    gap: 0;
    padding: 0.55rem clamp(0.6rem, 3vw, 1.2rem) calc(0.55rem + env(safe-area-inset-bottom));
    background: rgba(19, 16, 16, 0.92);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-top: 1px solid rgba(244, 236, 224, 0.14);
    color: var(--cream-45);
  }

  .rail-wave { display: none; }

  /* the waveform carried scroll progress; down here that job goes to a
     hairline along the top edge of the bar. app.js writes --prog in the
     same frame it fills the wave, so this costs one transform. */
  .rail::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background: linear-gradient(90deg, var(--flame), var(--ember));
    transform: scaleX(var(--prog, 0));
    transform-origin: 0 50%;
  }

  /* the bar is always dark, whichever room is behind it - the on-day
     rules above are for the floating desktop rail and must not reach here */
  body.on-day .rail { color: var(--cream-45); }

  /* six numbered tabs at 8px read as noise on a phone: the label alone,
     large enough to read, and an ember pip for where you are */
  .rail button { flex-direction: column; align-items: center; gap: 0.3rem; padding: 0.35rem 0.35rem 0.2rem; min-height: 2.75rem; justify-content: center; }
  .rail button em { display: none; }
  .rail button span { opacity: 1; transform: none; font-size: 0.7rem; letter-spacing: 0.02em; }
  .rail button::before {
    content: "";
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--ember);
    opacity: 0;
    transform: scale(0.4);
    transition: opacity 0.28s var(--ease), transform 0.28s var(--ease);
  }
  .rail button.is-here::before { opacity: 1; transform: none; }
  .rail button:hover,
  .rail button.is-here,
  body.on-day .rail button:hover,
  body.on-day .rail button.is-here { color: var(--cream); }

  .hire { display: none; }

  /* the portrait carries the top of this screen, so the room opens on it
     rather than on 7rem of nothing. What is left above is filled by the
     photograph's own top edge dissolving - see .hero-shot-frame below. */
  .act-hero {
    min-height: auto;
    padding-top: clamp(3.1rem, 7.5vh, 4rem);
    /* 5:4 of the full screen width, capped so the name still clears the
       fold on a short phone. Held as a token because three things have to
       agree on it: the photograph, the note layer over it, and the record
       docked into it - and .hero-shot is taller than all of them, so
       percentages against it do not work. */
    --shot-h: min(80vw, 44svh);
  }

  .hero-grid { grid-template-columns: 1fr; gap: clamp(1.6rem, 5vh, 2.4rem); }

  /* full bleed: a soft edge that stops short of the screen edge reads as
     a mistake, so the photograph runs the whole width and dissolves into
     the night on both sides. The caption takes the gutter back so it
     still lines up with the name underneath it. */
  .hero-shot { order: -1; margin-inline: calc(var(--gut) * -1); }
  .hero-shot figcaption { margin-inline: var(--gut); }
  .hero-shot .disc-slot {
    --disc-w: min(30vmin, 150px);
    top: calc(var(--shot-h) - var(--disc-w) - 1.1rem);
    bottom: auto;
    right: 4%;
    width: var(--disc-w);
  }
  .hero-shot img { height: var(--shot-h); aspect-ratio: auto; max-height: none; object-position: 52% 10%; }

  /* the dissolve.

     Two mask layers intersected - one across, one down - rather than a
     night-coloured gradient painted on top: .hero-glow sits BEHIND the
     portrait, and an opaque overlay would stamp the ember out. Masked,
     the photograph fades into the stage light instead of over it.

     It goes on the frame and not on the <img> because motion.js scales
     and scroll-drifts the image; a mask on a transformed element travels
     with it, and the soft edges would visibly slide as you scroll.

     Browsers without mask-composite fall back to the default `add`,
     i.e. no fade - which is exactly what this looked like before. */
  .hero-shot-frame {
    --fade-x: 13%;
    --fade-y: 15%;
    background: none;
    box-shadow: none;
    -webkit-mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--fade-x), #000 calc(100% - var(--fade-x)), transparent 100%),
      linear-gradient(180deg, transparent 0, #000 var(--fade-y), #000 82%, transparent 100%);
    mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--fade-x), #000 calc(100% - var(--fade-x)), transparent 100%),
      linear-gradient(180deg, transparent 0, #000 var(--fade-y), #000 82%, transparent 100%);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
  }

  /* the bottom of the frame already dissolves; the scrim that used to do
     that job would only mud it */
  .hero-shot-frame::after { display: none; }

  .hero-notes { display: block; height: var(--shot-h); }

  .hero-name { font-size: clamp(2.6rem, 15vw, 4.6rem); line-height: 0.88; }
  .hero-deva { font-size: clamp(1.2rem, 7vw, 2rem); }
  .hero-lede { font-size: 0.95rem; }

  .hero-figures { grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: 1rem; }


  .camp-pin {
    position: static;
    min-height: 0;
    grid-template-columns: 1fr;
    padding: clamp(3rem, 9vh, 5rem) 0 clamp(2rem, 6vh, 3.5rem);
    gap: clamp(1.6rem, 4vh, 2.4rem);
  }

  .camp-disc { display: none; }

  /* the reel takes a row of its own; the arrows and count sit under it.
     The whole transport goes ABOVE the card here: campaigns have one to
     three films, so the card changes height on every tap, and controls
     below it would jump out from under the thumb pressing them. */
  .camp-transport { flex-wrap: wrap; row-gap: 1rem; order: -1; }
  /* nine marks will not fit across a phone at a readable size - the reel
     becomes a strip you swipe, and app.js keeps the current mark centred */
  .tp-reel {
    flex-basis: 100%;
    order: -1;
    display: grid;
    overflow-x: auto;
    scrollbar-width: none;
    margin-inline: calc(var(--gut) * -1);
    padding-inline: var(--gut);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 1.4rem, #000 calc(100% - 1.4rem), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 1.4rem, #000 calc(100% - 1.4rem), transparent);
  }
  .tp-reel::-webkit-scrollbar { display: none; }
  .tp-marks { grid-template-columns: repeat(9, 5.2rem); width: max-content; }
  .tp-marks button { height: 3rem; padding: 0 0.5rem; }

  .act-brands { padding-bottom: 3rem; }

  .camp-films.n3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .camp-films.n3 > :first-child { grid-column: 1 / -1; }

  .screen-credits { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .rec-row button { grid-template-columns: 1.9rem minmax(0, 1fr) auto auto; }

  .contact-card .disc-slot { display: none; }
  /* on a phone the word stands clear above the card: half-buried behind
     its top edge it read as a rendering fault, not as depth */
  .act-contact { padding-top: clamp(5.5rem, 16vh, 7.5rem); }
  .contact-deva { font-size: clamp(3rem, 18vw, 6rem); top: -0.98em; opacity: 0.16; }

  .site-foot { padding-bottom: clamp(4.5rem, 12vh, 6rem); justify-content: center; text-align: center; }
}

@media (max-width: 520px) {
  .camp-films.n2, .camp-films.n3 { grid-template-columns: 1fr; }
  .camp-films.n3 > :first-child { grid-column: auto; }
  .camp-head { flex-direction: column; align-items: flex-start; gap: 0.7rem; }
  .camp-logo { max-width: 60%; }
  .contact-lines li { grid-template-columns: 1fr; gap: 0.15rem; }
  .rail { justify-content: space-around; padding-left: 0.3rem; padding-right: 0.3rem; }
  .rail button { padding-inline: 0.15rem; }
  .rail button span { font-size: 0.66rem; letter-spacing: 0; }
}

/* ══ reduced motion ══════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .logo-rail-track { animation: none; }
  /* motion.js never builds these - belt and braces if that ever moves */
  .hero-notes { display: none; }
  .rv { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body.rm .camp-pin { position: static; min-height: 0; }
body.rm .rec-stage { position: static; }
body.rm .rec-stage .disc-slot,
body.rm .contact-card .disc-slot { display: none; }
body.rm .disc { cursor: default; }
body.rm .eq { display: none; }
