@property --focus { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --progress { syntax: "<number>"; inherits: false; initial-value: 0; }
/* ==========================================================================
   Swapnil Dagliya — Fable 5 Motion Concept
   "The site is a performance." Scroll is the choreography.
   Vanilla CSS. Scroll progress arrives as --p (0..1) on each [data-scene].
   ========================================================================== */

:root {
  --ink: oklch(0.19 0.02 50);
  --ink-deep: oklch(0.15 0.018 45);
  --cream: oklch(0.955 0.02 85);
  --cream-dim: oklch(0.9 0.028 82);
  --blush: oklch(0.93 0.035 25);
  --rani: oklch(0.56 0.21 5);
  --rani-deep: oklch(0.44 0.185 5);
  --marigold: oklch(0.84 0.155 82);
  --saffron: oklch(0.68 0.19 45);
  --indigo: oklch(0.27 0.085 290);
  --indigo-deep: oklch(0.2 0.06 295);
  --peacock: oklch(0.6 0.11 195);

  /* CONTRAST RULE (measured 2026-09-07, WCAG AA 4.5:1):
     cool/dark grounds carry cream — cobalt 5.6:1, deep indigo 15:1
     warm/light grounds carry ink-deep — orange 4.9:1, marigold 12.3:1, pink 4.9:1
     Cream on orange was 3.6:1 and on pink 3.9:1; nothing light passes on either.
     Do not put cream on a warm ground. */
  /* BOLD SATURATED palette — vivid flat colour blocks (Codex energy). Reused across the show.
     Cobalt/orange/pink carry cream text; marigold is light so it carries ink text (used for
     the dense sections). --deep-indigo stays for Act I (the spotlight stage needs the dark). */
  --deep-indigo:  oklch(0.24 0.075 292);
  --bold-cobalt:  oklch(0.50 0.21 264);
  --bold-orange:  oklch(0.62 0.22 33);
  --bold-marigold:oklch(0.85 0.16 84);
  --bold-pink:    oklch(0.62 0.19 350);  /* +0.02 L so ink-deep clears 4.5:1 (was 4.48) */
  --bold-cream:   oklch(0.96 0.03 84);
  --ink-text:     oklch(0.2 0.03 50);    /* text on the light bold grounds (marigold) */
  --glow: oklch(0.91 0.16 92);           /* bright accent that pops on cobalt/orange/pink */
  --glow-rose: oklch(0.82 0.15 8);
  --panel: oklch(1 0 0 / 0.1);           /* translucent light surface on a bold ground */
  --panel-2: oklch(1 0 0 / 0.16);
  --hair: oklch(1 0 0 / 0.24);           /* faint light border */

  --font-display: "Archivo", "Avenir Next Condensed", "Arial Narrow", sans-serif;
  --font-body: "Instrument Sans", "Avenir Next", sans-serif;
  --font-hand: "Shantell Sans", "Comic Sans MS", cursive;

  --page: clamp(1.25rem, 4.5vw, 5rem);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-io: cubic-bezier(0.77, 0, 0.175, 1);
  --p: 0;
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  background: var(--ink-deep);
  overflow-x: clip; /* contain horizontal overflow at the root (x-only clip keeps sticky working) */
}

body {
  margin: 0;
  min-width: 320px;
  overflow-x: clip;
  background: var(--ink-deep);
  color: var(--cream);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  transition: background-color 640ms var(--ease-io), color 640ms var(--ease-io);
}

/* The house changes colour as the show moves through its acts.
   --house feeds both the page background and the top bar's glass scrim. */
body { --house: var(--ink-deep); background: var(--house); }
body[data-act="overture"]  { --house: var(--ink-deep); color: var(--cream); }
body[data-act="programme"] { --house: oklch(0.19 0.045 300); color: var(--cream); }
body[data-act="body"]      { --house: var(--indigo-deep); color: var(--cream); }
body[data-act="notes"]     { --house: oklch(0.17 0.045 300); color: var(--cream); }
body[data-act="classes"]   { --house: var(--cream); color: var(--ink); }
body[data-act="workshops"] { --house: var(--marigold); color: var(--ink); }
body[data-act="stage"]     { --house: oklch(0.14 0.015 45); color: var(--cream); }
body[data-act="live"]      { --house: var(--cream); color: var(--ink); }
body[data-act="table"]     { --house: var(--blush); color: var(--ink); }
body[data-act="hello"]     { --house: var(--rani-deep); color: var(--cream); }

body.menu-open { overflow: hidden; }

img { display: block; max-width: 100%; height: auto; }
button, a { font: inherit; }
button { color: inherit; }
a { color: inherit; text-decoration: none; }
p, h1, h2, h3, figure, fieldset, legend { margin: 0; padding: 0; }
fieldset { border: 0; min-width: 0; }
ol, ul { margin: 0; padding: 0; list-style: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 810;
  font-stretch: 112%;
  line-height: 0.88;
  letter-spacing: -0.03em;
  text-wrap: balance;
  text-transform: uppercase;
}

h2 { font-size: clamp(2.6rem, 7.2vw, 6.2rem); }
h2 em, h1 em {
  font-style: normal;
  font-weight: 320;
  font-stretch: 76%;
  letter-spacing: -0.01em;
}

.eyebrow {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.82;
  margin-bottom: 1.1rem;
}
.eyebrow__wink { opacity: 0.55; text-transform: none; letter-spacing: 0.04em; }

.scribble {
  font-family: var(--font-hand);
  font-weight: 500;
  font-size: clamp(1rem, 1.6vw, 1.3rem);
  line-height: 1.25;
  color: var(--marigold);
  rotate: -5deg;
}

.skip-link {
  position: fixed; z-index: 1000; top: 1rem; left: 1rem;
  padding: 0.8rem 1.1rem; background: var(--marigold); color: var(--ink);
  font-weight: 600; border-radius: 0.6rem;
  transform: translateY(-180%);
  transition: transform 200ms var(--ease-out);
}
.skip-link:focus-visible { transform: translateY(0); }

:focus-visible { outline: 3px solid var(--marigold); outline-offset: 3px; border-radius: 2px; }
body[data-act="workshops"] :focus-visible,
body[data-act="classes"] :focus-visible,
body[data-act="live"] :focus-visible,
body[data-act="table"] :focus-visible { outline-color: var(--ink); }

.grain {
  position: fixed; z-index: 90; inset: 0; pointer-events: none; opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.7'/%3E%3C/svg%3E");
}

/* Follow-spot that trails the cursor through the dark acts */
.followspot {
  position: fixed; z-index: 5; top: 0; left: 0;
  width: 64vmin; height: 64vmin; margin: -32vmin 0 0 -32vmin;
  border-radius: 50%;
  background: radial-gradient(circle, oklch(0.85 0.12 75 / 0.13), transparent 62%);
  mix-blend-mode: screen;
  pointer-events: none;
  opacity: 0;
  transition: opacity 500ms ease;
}
body.spot-on .followspot { opacity: 1; }

.progress {
  position: fixed; z-index: 130; inset: 0 0 auto; height: 3px;
  background: transparent; pointer-events: none;
}
.progress span {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--rani), var(--saffron), var(--marigold));
  transform: scaleX(0); transform-origin: left center;
}

/* ============================== Top bar ============================== */

.topbar {
  position: fixed; z-index: 140; inset: 0 0 auto;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 1rem;
  padding: 0.9rem var(--page) 1.1rem;
  color: var(--cream);
  background: color-mix(in oklch, var(--house), transparent 22%);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  -webkit-mask-image: linear-gradient(to bottom, black 72%, transparent);
  mask-image: linear-gradient(to bottom, black 72%, transparent);
  transition: color 500ms ease, background-color 640ms var(--ease-io);
}
body.menu-open .topbar {
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.topbar.is-ink { color: var(--ink); }

.brand { display: inline-flex; align-items: center; gap: 0.7rem; justify-self: start; }
.brand__mark {
  display: grid; place-items: center;
  width: 2.3rem; height: 2.3rem;
  background: var(--marigold); color: var(--ink);
  font-family: var(--font-display); font-weight: 850; font-size: 1.25rem;
  border-radius: 0.55rem; rotate: -5deg;
  transition: rotate 250ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .brand:hover .brand__mark { rotate: 4deg; } }
.brand__name {
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; line-height: 1.25;
}

.topbar__context {
  justify-self: center; display: inline-flex; align-items: baseline; gap: 0.6rem;
  font-size: 0.8rem; white-space: nowrap; max-width: 60vw; overflow: hidden;
}
.topbar__context span {
  font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--marigold);
}
.topbar.is-ink .topbar__context span { color: var(--rani); }
.topbar__context em { font-style: italic; opacity: 0.85; overflow: hidden; text-overflow: ellipsis; }

.menu-button {
  justify-self: end; display: inline-flex; align-items: center; justify-content: flex-end; gap: 0.6rem;
  background: none; border: 0; cursor: pointer; padding: 0.6rem 0.2rem;
  min-height: 44px; min-width: 44px;
  font-weight: 600; font-size: 0.85rem; letter-spacing: 0.1em; text-transform: uppercase;
  transition: transform 160ms var(--ease-out);
}
/* No JS: the menu button can't open the overlay — hide it; the playbill + footer sitemap navigate. */
html.no-js .menu-button { display: none; }
.menu-button:active { transform: scale(0.96); }
.menu-button i {
  position: relative; width: 1.5rem; height: 0.85rem; display: inline-block;
}
.menu-button i::before, .menu-button i::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px;
  background: currentColor; border-radius: 2px;
  transition: transform 200ms var(--ease-out);
}
.menu-button i::before { top: 0; }
.menu-button i::after { bottom: 0; }
.menu-button[aria-expanded="true"] { color: var(--cream); }
.menu-button[aria-expanded="true"] i::before { transform: translateY(calc(0.425rem - 1px)) rotate(45deg); }
.menu-button[aria-expanded="true"] i::after { transform: translateY(calc(-0.425rem + 1px)) rotate(-45deg); }

/* ============================== Menu ============================== */

.menu {
  position: fixed; z-index: 135; inset: 0;
  display: grid; align-content: center; justify-items: start;
  gap: 0.15rem;
  padding: 5.5rem var(--page) 3rem;
  background: color-mix(in oklch, var(--ink-deep), black 12%);
  color: var(--cream);
  visibility: hidden; opacity: 0;
  transition: opacity 340ms var(--ease-out), visibility 0s linear 340ms;
  overflow-y: auto;
}
.menu.is-open { visibility: visible; opacity: 1; transition: opacity 340ms var(--ease-out); }

.menu ol { display: grid; gap: 0.1rem; }
.menu li a {
  display: grid; grid-template-columns: 6.2rem auto; column-gap: 1rem; align-items: baseline;
  padding: 0.16em 0;
  font-family: var(--font-display);
  font-weight: 780; font-stretch: 100%;
  font-size: clamp(1.7rem, 4.6vh, 3rem);
  line-height: 1;
  text-transform: uppercase; letter-spacing: -0.02em;
  opacity: 0;
  transform: translateY(18px);
  transition: color 200ms ease, opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.menu.is-open li a { opacity: 1; transform: translateY(0); }
.menu.is-open li:nth-child(1) a { transition-delay: 40ms; }
.menu.is-open li:nth-child(2) a { transition-delay: 75ms; }
.menu.is-open li:nth-child(3) a { transition-delay: 110ms; }
.menu.is-open li:nth-child(4) a { transition-delay: 145ms; }
.menu.is-open li:nth-child(5) a { transition-delay: 180ms; }
.menu.is-open li:nth-child(6) a { transition-delay: 215ms; }
.menu.is-open li:nth-child(7) a { transition-delay: 250ms; }
.menu.is-open li:nth-child(8) a { transition-delay: 285ms; }
.menu.is-open li:nth-child(9) a { transition-delay: 320ms; }
.menu.is-open li:nth-child(10) a { transition-delay: 355ms; }
.menu li a small {
  grid-column: 1; grid-row: 1;
  font-family: var(--font-body); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.16em; color: var(--marigold);
}
.menu li a span { grid-column: 2; grid-row: 1; }
.menu li a i {
  grid-column: 2; grid-row: 2;
  font-family: var(--font-body); font-style: normal;
  font-size: 0.82rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: none; opacity: 0.5; margin-top: 0.2rem;
}
@media (hover: hover) and (pointer: fine) {
  .menu li a:hover { color: var(--marigold); }
}
.menu__aside {
  font-family: var(--font-hand); color: var(--marigold);
  font-size: 1.15rem; margin-bottom: 1.6rem; rotate: -2deg;
}
.menu__footer { margin-top: 2rem; font-size: 0.82rem; opacity: 0.65; letter-spacing: 0.08em; }

/* ============================== Scenes (pinned) ============================== */

main { position: relative; }

.scene { position: relative; height: calc(var(--len, 220) * 1vh); }
.scene__pin {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: clip;
}

html.no-js .scene { height: auto; }
html.no-js .scene__pin { position: static; height: auto; min-height: 100svh; }
/* Act I fallback — reduced-motion OR no-JS: static company row + all beats shown */
html.no-js .bdy-troupe,
.scene--body[data-static] .bdy-troupe { position: static; display: flex; justify-content: center; align-items: flex-end; gap: 3vw; margin: 2rem 0 1.5rem; overflow-x: auto; }
html.no-js .bdy-figure { position: static; height: min(38svh, 20rem); filter: none; opacity: 1; transform: none; flex: 0 0 auto; }
html.no-js .bdy-figure img { height: 100%; }
html.no-js .bdy-figure figcaption { position: static; transform: none; opacity: 0.9; text-align: center; margin-top: 0.4rem; }
html.no-js .bdy-ghost, html.no-js .bdy-spot, html.no-js .bdy-floor, html.no-js .bdy-meter { display: none; }
html.no-js .bdy-eyebrow, html.no-js .bdy-beats, html.no-js .bdy-caption, html.no-js .bdy-scribble { position: static; }
html.no-js .bdy-beats { display: block; max-width: none; margin-top: 1.5rem; }
html.no-js .bdy-beat { opacity: 1; transform: none; margin-bottom: 1.4rem; }
html.no-js .watch__iris { clip-path: none; }
html.no-js .watch__iris::after { opacity: 1; }

.scene--hero  { --len: 200; }
.scene--body  { --len: 700; } /* Six styles, one viewport of scroll each. */
.scene--invite{ --len: 280; }
.scene--watch { --len: 220; }

/* Each pinned act brings its own stage colour, so scenes never depend on the
   body's act transition timing (which lags at scene handovers). */
.scene--hero .scene__pin  { background: var(--ink-deep); color: var(--cream); }
.scene--body .scene__pin  { color: var(--cream); } /* .bdy-stage paints its own radial */
.scene--invite .scene__pin{ background: var(--bold-pink); color: var(--ink-deep); }
.scene--watch .scene__pin { background: oklch(0.14 0.015 45); color: var(--cream); }

/* ============================== Loading sequence (house lights) ============================== */

.preload {
  position: fixed; z-index: 1000; inset: 0;
  display: grid; place-items: center;
  background: var(--ink-deep);
  transition: opacity 620ms var(--ease-io), visibility 0s linear 620ms, transform 620ms var(--ease-io);
}
.preload__spot {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(42vmin 42vmin at 50% 46%, oklch(0.82 0.14 75 / 0.22), transparent 68%);
  opacity: 0; animation: spot-up 900ms var(--ease-out) forwards;
}
@keyframes spot-up { from { opacity: 0; transform: scale(0.6); } to { opacity: 1; transform: scale(1); } }
.preload__count {
  position: relative; margin: 0; display: flex; gap: clamp(0.7rem, 2.5vw, 1.6rem);
  font-family: var(--font-display); font-weight: 850; font-stretch: 112%;
  font-size: clamp(2.6rem, 11vw, 7rem); line-height: 1; letter-spacing: -0.02em;
}
.preload__count span {
  opacity: 0.1; transform: translateY(0.22em) scale(0.86);
  transition: opacity 200ms ease, transform 240ms var(--ease-out), color 200ms ease;
}
.preload__count span.lit { opacity: 1; transform: none; }
.preload__count span.lit:last-child { color: var(--marigold); }
.preload__hint {
  position: absolute; bottom: 22%; left: 0; right: 0; text-align: center;
  font-family: var(--font-hand); color: var(--marigold); opacity: 0;
  font-size: clamp(0.95rem, 2vw, 1.2rem); rotate: -2deg;
  animation: hint-in 700ms ease 500ms forwards;
}
@keyframes hint-in { to { opacity: 0.85; } }
.preload__skip {
  position: absolute; bottom: 1.4rem; right: 1.4rem;
  background: none; border: 1.5px solid color-mix(in oklch, var(--cream), transparent 60%);
  color: var(--cream); font: inherit;
  border-radius: 99px; padding: 0.5rem 1.1rem; cursor: pointer;
  font-size: 0.8rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  opacity: 0; animation: hint-in 400ms ease 900ms forwards; transition: background-color 180ms ease;
}
.preload__skip:hover { background: color-mix(in oklch, var(--cream), transparent 88%); }
.preload.is-flash { animation: house-flash 260ms ease forwards; }
.preload.is-done { opacity: 0; visibility: hidden; transform: scale(1.06); pointer-events: none; }
@keyframes house-flash { 0% { background: var(--ink-deep); } 100% { background: oklch(0.88 0.11 84); } }
html.no-js .preload { display: none; }

/* ============================== Overture / hero (cinematic) ==============================
   The hero is a preserve-3d space: what paints in front is decided by translateZ, NOT
   z-index. Depth order (back → front): beams −320 · title 10/40 · "is" 80 · dancer 120 ·
   note 140. Never reorder these with z-index — it will be ignored. */

.hero {
  --q:  max(0, calc((var(--progress) - 0.05) / 0.95));
  --q2: max(0, calc((var(--progress) - 0.72) / 0.28)); /* camera pull-back over the last 28% */
  --mx: 0; --my: 0;
  display: grid; place-items: center; text-align: center;
  perspective: 1500px;
}
/* the 3D stage — dollies back and fades as you scroll off: the hand-off to the Programme */
.hero__depth {
  position: relative; width: 100%; height: 100%;
  display: grid; grid-template-rows: 1fr auto 1fr; justify-items: center; align-content: center;
  padding: 5rem var(--page) 2rem;
  transform-style: preserve-3d; perspective: 1400px;
  /* This subtree is a 3D context that transforms and fades on every scroll
     frame, so without promotion the browser re-composites the whole hero each
     time — 31 dropped frames of 117 at 4x throttling. Naming the two
     properties that actually animate takes that to 0 with no visual change.
     Measured alternatives that did NOT work: dropping either perspective made
     it worse (29 and 37), and flattening .hero__title helped only by removing
     the title's translateZ recession, which changes the type size. */
  will-change: transform, opacity;
  transform:
    translateZ(calc(max(0, calc((var(--progress) - 0.72) / 0.28)) * -260px))
    scale(calc(1 - max(0, calc((var(--progress) - 0.72) / 0.28)) * 0.08))
    rotateY(calc(var(--mx) * 4deg)) rotateX(calc(var(--my) * -2.5deg));
  opacity: calc(1 - max(0, calc((var(--progress) - 0.72) / 0.28)) * 0.92);
  transition: transform 450ms var(--ease-out), opacity 450ms ease;
}

.hero__lights { position: absolute; inset: 0; pointer-events: none;  transform: translateZ(-320px) scale(1.35); }
.hero__beam {
  position: absolute; top: -12vh; width: 46vw; height: 125vh; opacity: 0.5;
  background: linear-gradient(190deg, oklch(0.8 0.14 60 / 0.34), transparent 68%);
}
.hero__beam--l { left: -6vw; transform-origin: top left; rotate: -16deg; animation: beam-sway-l 11s var(--ease-io) infinite alternate; }
.hero__beam--r { right: -6vw; transform-origin: top right; rotate: 16deg;
  background: linear-gradient(170deg, oklch(0.62 0.19 5 / 0.3), transparent 68%);
  animation: beam-sway-r 13s var(--ease-io) infinite alternate; }
@keyframes beam-sway-l { from { rotate: -19deg; } to { rotate: -9deg; } }
@keyframes beam-sway-r { from { rotate: 19deg; } to { rotate: 9deg; } }

.hero__eyebrow {
  align-self: end; margin: 0 0 1.2rem; max-width: 90vw;
  font-size: 0.8rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  opacity: calc(0.85 - max(0, calc((var(--progress) - 0.05) / 0.95)) * 2);
  transform: translateZ(20px);
}

.hero__title {
  position: relative; z-index: 2;
  display: grid; justify-items: center; gap: 0; margin: 0;
  font-size: clamp(2.6rem, min(10.8vw, 20svh), 12rem);
  transform-style: preserve-3d;
}
.hero__line { display: block; will-change: transform; }
.hero__line--1 { transform: translateZ(40px) translate3d(calc(max(0, calc((var(--progress) - 0.05) / 0.95)) * -66vw), calc(max(0, calc((var(--progress) - 0.05) / 0.95)) * -6vh), 0); }
.hero__line--3 { transform: translateZ(10px) translate3d(calc(max(0, calc((var(--progress) - 0.05) / 0.95)) * 66vw), calc(max(0, calc((var(--progress) - 0.05) / 0.95)) * 6vh), 0); }
.hero__line--2 {
  position: absolute; z-index: 4; top: 50%; left: 16.5%;
  font-size: 0.38em;
  padding: 0.12em 0.24em; /* room for the italic overhang — compositing clips at the box */
  rotate: -8deg;
  transform: translate(-50%, -50%) translateZ(80px) scale(calc(1 + max(0, calc((var(--progress) - 0.05) / 0.95)) * 2.2));
  opacity: calc(1 - max(0, calc((var(--progress) - 0.05) / 0.95)) * 1.35);
}
.hero__line--2 em { font-style: italic; font-weight: 350; font-stretch: 80%; color: var(--marigold); }

.hero__dancer {
  position: absolute; z-index: 3; bottom: 8vh; left: 50%; margin: 0; width: auto;
  /* NOTE: promoting .hero__depth to its own compositor layer changes how this
     element's translateZ(120px) projects, so the dancer renders about 9%
     smaller than it did unpromoted. Compensating the scale back to 1.05
     was tried and reverted: it restores the size but scaling from
     transform-origin: bottom center lifts the figure ~22px, and the flag
     then cuts through the eyebrow line. Smaller and clear beats correct
     and colliding. */
  transform: translateX(-50%) translateZ(120px) scale(calc(0.96 + var(--progress) * 0.34)) translateY(calc(max(0, calc((var(--progress) - 0.05) / 0.95)) * 8vh));
  transform-origin: bottom center;
  will-change: transform;
  /* The drop-shadow lives on the IMG, not here. This figure scales on every
     scroll frame, and a filter on a scaling element is re-rasterised each
     time — measured at 47 dropped frames out of 117 through the hero. On the
     child it rasterises once and the parent's transform is composited: 26
     dropped, identical to deleting the shadow, but the shadow is kept.
     Do NOT add will-change: filter here — measured worse (45 dropped). */
}
.hero__dancer img {
  height: min(58svh, 36rem); width: auto;
  filter: drop-shadow(0 22px 34px oklch(0 0 0 / 0.55));
}
.hero__shadow {
  position: absolute; left: 50%; bottom: -2.5vh;
  width: 130%; height: 5vh; transform: translateX(-50%);
  background: radial-gradient(ellipse closest-side, oklch(0 0 0 / 0.55), transparent);
}

/* sits at z 140 so it reads IN FRONT of the dancer (z 120) */
.hero__note {
  position: relative; align-self: start; z-index: 4; margin-top: 1.4rem;
  transform: translateZ(140px);
  font-size: clamp(0.95rem, 1.5vw, 1.1rem); line-height: 1.6;
  text-shadow: 0 2px 18px oklch(0 0 0 / 0.85), 0 1px 6px oklch(0 0 0 / 0.7);
  opacity: calc(1 - max(0, calc((var(--progress) - 0.05) / 0.95)) * 2.4);
}
.hero__note strong { color: var(--marigold); font-weight: 600; }
/* The only way to act from screen one. Everything else in the hero is an
   in-page anchor, so a visitor who arrives ready to book had to scroll five
   acts to find the form. Deliberately quiet — it must not outrank the title. */
.hero__ask {
  display: inline-block; margin-top: 0.75rem;
  font-weight: 600; color: var(--cream);
  border-bottom: 1.5px solid var(--marigold);
  transition: border-color 200ms ease;
}
.hero__ask span { display: inline-block; transition: transform 200ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .hero__ask:hover { border-color: var(--marigold); }
  .hero__ask:hover span { transform: translateY(3px); }
}

.hero__scribble { position: absolute; top: 14vh; left: clamp(1rem, 9vw, 12rem); z-index: 4; transform: translateZ(60px); }

.hero__cue {
  position: absolute; bottom: 3.2vh; left: 50%; z-index: 5;
  transform: translateX(-50%) translateZ(40px);
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-size: 0.85rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.65rem 1.2rem; border: 1.5px solid color-mix(in oklch, var(--cream), transparent 55%);
  border-radius: 99px;
  opacity: calc(1 - var(--progress) * 3);
  transition: border-color 200ms ease, background-color 200ms ease;
}
.hero__cue b { animation: cue-bob 1.9s var(--ease-io) infinite; }
@keyframes cue-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(4px); } }
@media (hover: hover) and (pointer: fine) {
  .hero__cue:hover { border-color: var(--marigold); background: oklch(0.84 0.155 82 / 0.12); }
}

.hero__place {
  position: absolute; right: clamp(0.6rem, 2.2vw, 2.4rem); bottom: 10vh; z-index: 4;
  transform: translateZ(30px);
  writing-mode: vertical-rl;
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.3em; text-transform: uppercase;
  opacity: calc(0.6 - var(--progress) * 1.4);
}

/* ---- entrance choreography ----
   Each element has exactly ONE transform rule: its base (scroll/depth) transform. The
   entrance FROM-state is scoped to body:not(.is-loaded), so it out-specifies BEFORE load
   and then drops away — letting the base transform take over. No specificity war. */
/* Was 820ms on cubic-bezier(0.34, 1.56, 0.64, 1) — a bounce: the element
   overshoots and springs back, which is the wobble at the end of every
   entrance. Now a settling ease-out, and short enough that the opening is
   over before the reader starts scrolling. */
html.js [data-in] { transition: transform 460ms var(--ease-out), opacity 380ms var(--ease-out); }
html.js body:not(.is-loaded) [data-in] { opacity: 0; }
html.js body:not(.is-loaded) .hero__eyebrow { transform: translateY(16px); }
html.js body:not(.is-loaded) .hero__line--1 { transform: translateY(-120vh); }
html.js body:not(.is-loaded) .hero__line--3 { transform: translateY(120vh); }
html.js body:not(.is-loaded) .hero__line--2 { transform: translate(-50%, -50%) scale(2.4); }
html.js body:not(.is-loaded) .hero__dancer { transform: translateX(-50%) translateY(18vh) scale(0.9); }
html.js body:not(.is-loaded) .hero__note,
html.js body:not(.is-loaded) .hero__scribble,
html.js body:not(.is-loaded) .hero__cue { transform: translateY(20px); }
body.is-loaded [data-in="1"] { transition-delay: 40ms; }
body.is-loaded [data-in="2"] { transition-delay: 110ms; }
body.is-loaded [data-in="3"] { transition-delay: 180ms; }
body.is-loaded [data-in="4"] { transition-delay: 320ms; }
body.is-loaded [data-in="5"] { transition-delay: 250ms; }
body.is-loaded [data-in="6"] { transition-delay: 390ms; }
body.is-loaded [data-in="7"] { transition-delay: 460ms; }
body.is-settled [data-in] { transition: none; } /* free the scroll transforms once seated */

/* No JS: the pin goes static, so .hero__depth's height:100% would collapse to nothing and
   stack the title lines on top of each other. Give it real height and flatten the 3D — with
   transform-style:flat, z-index works normally again and the note sits above the dancer. */
html.no-js .hero { perspective: none; }
html.no-js .hero__depth {
  height: auto; min-height: 100svh;
  transform: none; transform-style: flat; opacity: 1;
}
html.no-js .hero__lights { transform: none; }
html.no-js .hero__line--1,
html.no-js .hero__line--3,
html.no-js .hero__note,
html.no-js .hero__scribble,
html.no-js .hero__eyebrow,
html.no-js .hero__place { transform: none; }
html.no-js .hero__line--2 { transform: translate(-50%, -50%); }
html.no-js .hero__dancer,
html.no-js .hero__cue { transform: translateX(-50%); }

/* ============================== Programme — scene-selection reel ==============================
   Namespaced srl__ so it never collides with Act IV's video .reel. */

.scenereel { --len: 420; position: relative; background: var(--ink-deep); }
.srl__stage { display: grid; grid-template-rows: auto 1fr auto; background: #000; color: var(--cream); }

.srl__bar {
  height: clamp(2.2rem, 5vh, 3rem); background: #000;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0 clamp(1rem, 4vw, 3rem);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: color-mix(in oklch, var(--cream), transparent 30%);
}
.srl__bar span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.srl__rec { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--marigold); flex: none; }
.srl__rec i { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--marigold); animation: srl-blink 1.6s steps(1) infinite; }
@keyframes srl-blink { 50% { opacity: 0.25; } }

.srl__wrap { position: relative; display: grid; grid-template-rows: 1fr auto; gap: clamp(0.5rem, 1.4vh, 1rem); padding: clamp(0.5rem, 1.4vh, 1rem) clamp(1rem, 4vw, 3rem) 0; min-height: 0; }
.srl__frame { position: relative; border-radius: 0.4rem; overflow: hidden; min-height: 0; isolation: isolate; background: #0a0a0a; }
.srl__bg { position: absolute; inset: 0; background-size: cover; opacity: 0; transform: scale(1.06); transition: opacity 0.7s var(--ease-out), transform 7s linear; }
.srl__bg.is-on { opacity: 1; transform: scale(1.13); }
/* a scene that plays film — the footage supplies the motion, so no Ken Burns drift */
.srl__bg--video, .srl__bg--video.is-on { transform: none; }
.srl__bg video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* letterbox matte */
.srl__frame::before, .srl__frame::after { content: ""; position: absolute; left: 0; right: 0; height: 7%; z-index: 5; pointer-events: none; }
.srl__frame::before { top: 0; background: linear-gradient(#000, transparent); }
.srl__frame::after { bottom: 0; background: linear-gradient(transparent, #000); }
.srl__veil { position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(78deg, rgba(0,0,0,0.9), rgba(0,0,0,0.35) 44%, transparent 64%), radial-gradient(130% 130% at 72% 32%, transparent 40%, rgba(0,0,0,0.62)); }
.srl__grain { position: absolute; inset: 0; z-index: 4; pointer-events: none; opacity: 0.07; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 160 160' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.srl__tick { position: absolute; width: 22px; height: 22px; border: 2px solid color-mix(in oklch, var(--cream), transparent 50%); z-index: 3; }
.srl__tick.tl { top: 14px; left: 14px; border-right: 0; border-bottom: 0; }
.srl__tick.tr { top: 14px; right: 14px; border-left: 0; border-bottom: 0; }
.srl__tick.bl { bottom: 14px; left: 14px; border-right: 0; border-top: 0; }
.srl__tick.br { bottom: 14px; right: 14px; border-left: 0; border-top: 0; }

.srl__chapter { position: absolute; top: clamp(1.4rem, 3.4vh, 2.2rem); left: clamp(1.4rem, 4vw, 3rem); z-index: 6; margin: 0;
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.78rem; letter-spacing: 0.16em; color: var(--marigold); }
.srl__caption { position: absolute; left: clamp(1.4rem, 4vw, 3rem); bottom: clamp(2rem, 5vh, 3.2rem); z-index: 6; max-width: min(46rem, 82%); }
.srl__caption > * { transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out); }
.srl__caption.is-swapping > * { opacity: 0; transform: translateY(14px); }
.srl__kicker { margin: 0 0 0.5rem; font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase; color: color-mix(in oklch, var(--cream), transparent 30%); }
.srl__title { margin: 0; font-family: var(--font-display); font-weight: 840; font-stretch: 114%;
  font-size: clamp(2.2rem, 6vw, 5rem); line-height: 0.9; text-transform: uppercase; letter-spacing: -0.03em; }
.srl__syn { margin: 0.6rem 0 0; font-size: clamp(0.95rem, 1.4vw, 1.15rem); opacity: 0.85; max-width: 30rem; }
.srl__select { margin-top: 1.2rem; display: inline-flex; align-items: center; gap: 0.7rem;
  background: var(--cream); color: var(--ink-deep); border: 0; border-radius: 99px;
  padding: 0.7rem 1.3rem; font-weight: 600; font-size: 0.9rem; text-decoration: none;
  transition: transform 0.16s var(--ease-out), background-color 0.2s; }
@media (hover: hover) and (pointer: fine) { .srl__select:hover { background: var(--marigold); transform: scale(1.03); } }
.srl__scrub { position: absolute; right: clamp(1.4rem, 4vw, 3rem); bottom: clamp(2rem, 5vh, 3.2rem); z-index: 6; display: flex; gap: 0.4rem; align-items: center; }
.srl__scrub i { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: color-mix(in oklch, var(--cream), transparent 72%); transition: background-color 0.3s, transform 0.3s; }
.srl__scrub i.is-on { background: var(--marigold); transform: scale(1.5); }

.srl__rail { overflow: hidden; padding: 0.55rem 0; background: #0a0a0a; border-radius: 0.4rem;
  background-image: radial-gradient(circle, rgba(245,238,225,0.16) 1.2px, transparent 1.3px), radial-gradient(circle, rgba(245,238,225,0.16) 1.2px, transparent 1.3px);
  background-size: 14px 5px; background-position: top 0.18rem left 0, bottom 0.18rem left 0; background-repeat: repeat-x; }
.srl__strip { display: flex; gap: 0.5rem; padding: 0 0.6rem; transition: transform 0.55s var(--ease-out); will-change: transform; }
.srl__cell { flex: 0 0 auto; width: clamp(6rem, 12vw, 9.5rem); aspect-ratio: 16 / 10; position: relative;
  border-radius: 0.25rem; overflow: hidden; border: 2px solid transparent; cursor: pointer; background: #222;
  transition: border-color 0.25s, transform 0.3s var(--ease-out); margin: 0.35rem 0; padding: 0; }
.srl__cell img { width: 100%; height: 100%; object-fit: cover; opacity: 0.5; transition: opacity 0.3s; }
.srl__cell i { position: absolute; top: 0.25rem; left: 0.4rem; font-style: normal;
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.7rem; color: var(--cream); text-shadow: 0 1px 3px #000; z-index: 2; }
.srl__cell:hover img { opacity: 0.8; }
.srl__cell.is-on { border-color: var(--marigold); }
.srl__cell.is-on img { opacity: 1; }
.srl__cell:focus-visible { outline: 3px solid var(--marigold); outline-offset: 2px; }

/* no-JS / reduced-motion contact sheet */
.srl__sheet { display: none; gap: 1px; background: #000; }
.srl__card { position: relative; min-height: 62vh; display: grid; align-content: end;
  padding: 2rem var(--page); background-size: cover; color: var(--cream); text-decoration: none; }
.srl__card::after { content: ""; position: absolute; inset: 0; background: linear-gradient(transparent, rgba(0,0,0,0.85)); }
.srl__card > * { position: relative; z-index: 1; }
.srl__card strong { font-family: var(--font-display); font-weight: 820; font-stretch: 110%;
  font-size: clamp(1.8rem, 5vw, 3.4rem); text-transform: uppercase; line-height: 0.95; }
.srl__card span { opacity: 0.82; margin-top: 0.4rem; }
html.no-js .scenereel .scene__pin { display: none; }
html.no-js .srl__sheet { display: grid; }
/* ============================== Notes — The Credits (paper credit-roll) ==============================
   Programme notes as film end-credits: fixed title card + a credit roll that scrolls past a
   reader line as you scroll (driven by the engine's --p). Warm gold-cast paper. Colours are
   section-scoped (--nts-*) so they never touch the global tokens other acts rely on. */
.notes-credits {
  --len: 300;
  --nts-paper: var(--bold-orange); --nts-ink: var(--ink-deep);
  --nts-gold: var(--cream); --nts-rani: var(--cream);  /* --glow on orange was 2.4:1 */
  --nts-mono: ui-monospace, "SF Mono", Menlo, monospace;
}
.notes-credits .scene__pin {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.5rem, 5vw, 5rem); align-items: center; padding: 0 var(--page);
  background: radial-gradient(90vmax 70vmax at 12% 30%, oklch(0.68 0.21 40), var(--nts-paper) 72%);
  color: var(--nts-ink);
}
.nts-year { position: absolute; inset: 0; display: grid; place-items: center; z-index: 0; pointer-events: none; }
.nts-year span { font-family: var(--font-display); font-weight: 880; font-stretch: 120%; font-size: min(34vw, 40vh);
  line-height: 0.8; letter-spacing: -0.04em; color: oklch(1 0 0 / 0.05); font-variant-numeric: tabular-nums; }

.nts-card { position: relative; z-index: 2; max-width: 34rem; }
.notes-credits .eyebrow { color: color-mix(in oklch, var(--ink-deep), transparent 20%); opacity: 1; }
.notes-credits h2 { font-family: var(--font-display); font-weight: 840; font-stretch: 114%; font-size: clamp(2.4rem, 6vw, 4.6rem);
  line-height: 0.9; letter-spacing: -0.03em; text-transform: uppercase; margin: 0 0 1.2rem; color: var(--nts-ink); }
.notes-credits h2 em { font-style: normal; font-weight: 320; font-stretch: 76%; color: var(--nts-gold); }
.nts-bio { font-size: clamp(0.95rem, 1.3vw, 1.1rem); line-height: 1.65; opacity: 0.82; max-width: 30rem; }
.nts-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.4rem; }
.nts-chips span { font-size: 0.78rem; letter-spacing: 0.02em; padding: 0.4rem 0.8rem; border-radius: 99px;
  border: 1px solid color-mix(in oklch, var(--nts-ink), transparent 78%); opacity: 0.85; }

.nts-rollwrap { position: relative; z-index: 2; }
.nts-roll { position: relative; height: min(54vh, 30rem); overflow: hidden;
  -webkit-mask-image: linear-gradient(transparent, #000 16%, #000 84%, transparent);
  mask-image: linear-gradient(transparent, #000 16%, #000 84%, transparent); }
.nts-track { display: grid; gap: clamp(1.8rem, 4.2vh, 3rem); margin: 0; padding: 0; list-style: none; will-change: transform;
  transform: translateY(calc(var(--progress) * (var(--nts-travel, 0px) * -1))); }
/* Was opacity 0.3, which left exactly one of eight credits legible at a time —
   you had to scroll the whole pinned scene to read a CV. The roll should say
   "this one is current", not "the others do not exist". Inactive rows are now
   readable; the active row is marked by full opacity, the shift and the
   marker line, which is plenty of signal. */
.nts-credit { display: grid; grid-template-columns: 5.5rem 1fr; gap: 1.1rem; align-items: baseline;
  opacity: 0.66; transition: opacity 450ms var(--ease-out), transform 450ms var(--ease-out); transform: translateX(0); }
.nts-credit.is-lit { opacity: 1; transform: translateX(6px); }
.nts-credit time { font-family: var(--nts-mono); font-size: 0.78rem; letter-spacing: 0.08em; color: var(--nts-rani);
  font-variant-numeric: tabular-nums; padding-top: 0.25em; }
.nts-credit strong { display: block; font-family: var(--font-display); font-weight: 790; font-stretch: 106%;
  font-size: clamp(1.05rem, 2vw, 1.5rem); line-height: 1.15; letter-spacing: -0.015em; }
.nts-credit span { display: block; margin-top: 0.2rem; font-size: 0.9rem; opacity: 0.72; }
.nts-markline { position: absolute; left: 0; right: 0; top: 50%; z-index: 3; height: 1px; pointer-events: none;
  background: linear-gradient(90deg, var(--nts-rani), transparent 70%); opacity: 0.5; }
.nts-rolllabel { position: absolute; right: 0; top: -2.2rem; z-index: 3; font-family: var(--nts-mono);
  font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--nts-rani); opacity: 0.8; }

@media (max-width: 820px) {
  .notes-credits .scene__pin { grid-template-columns: 1fr; align-content: center; gap: 2rem; }
  .nts-bio, .nts-chips { display: none; }
  .nts-roll { height: min(52vh, 26rem); }
  .nts-credit { grid-template-columns: 4.4rem 1fr; gap: 0.8rem; }
}
/* reduced-motion / no-JS: static printed list */
html.no-js .notes-credits .scene__pin { grid-template-columns: 1fr; align-content: start; padding-top: 6rem; padding-bottom: 3rem; }
html.no-js .nts-year, html.no-js .nts-markline, html.no-js .nts-rolllabel { display: none; }
html.no-js .nts-roll { height: auto; overflow: visible; -webkit-mask-image: none; mask-image: none; }
html.no-js .nts-track { transform: none; padding: 0; gap: 1.6rem; }
html.no-js .nts-credit { opacity: 1; transform: none; }
/* ============================== Act I — The Body (tableau) ==============================
   The light IS the choreography: the whole company stands on a dark stage; the follow-spot
   sweeps all six dancers left→right (data-phase 0–5, set by the engine via data-phases=6),
   and the three story-beats change every two cues. Namespaced bdy- to stay clear of the
   rest of the site. */
/* NB: .bdy-stage IS the .scene__pin — do NOT set position here or it kills the sticky pin.
   Sticky is already a positioned value, so the absolute children anchor to it fine. */
.bdy-stage {
  background: radial-gradient(120vmax 90vmax at 50% 120%, oklch(0.2 0.03 300), var(--ink-deep) 70%);
}

/* the ghost word morphs Body → Rhythm → Joy */
.bdy-ghost { position: absolute; inset: 0; display: grid; place-items: center; z-index: 0; pointer-events: none; }
.bdy-ghost span {
  grid-area: 1 / 1; font-family: var(--font-display); font-weight: 880; font-stretch: 120%;
  font-size: min(42vw, 52vh); line-height: 0.8; letter-spacing: -0.04em; text-transform: uppercase;
  color: oklch(0.84 0.155 82 / 0.07); opacity: 0;
  transition: opacity 420ms var(--ease-out), transform 480ms var(--ease-out); transform: scale(0.94);
}
.scene--body[data-phase="0"] .bdy-ghost--0, .scene--body[data-phase="1"] .bdy-ghost--0,
.scene--body[data-phase="2"] .bdy-ghost--1, .scene--body[data-phase="3"] .bdy-ghost--1,
.scene--body[data-phase="4"] .bdy-ghost--2, .scene--body[data-phase="5"] .bdy-ghost--2 { opacity: 1; transform: scale(1); }

/* the company */
.bdy-troupe { position: absolute; inset: 0; z-index: 1; }
.bdy-figure {
  position: absolute; bottom: 0; height: var(--h); width: auto; transform-origin: bottom center;
  transform: translateX(calc((1 - var(--focus)) * var(--progress) * var(--drift) + var(--focus) * clamp(var(--cue-min, -100vw), calc(var(--progress) * var(--drift)), var(--cue-max, 100vw)))) translateY(calc((1 - var(--focus)) * 2vh)) scale(calc(.98 + var(--focus) * .08));
  filter: none; opacity: calc(.32 + var(--focus) * .68);
  transition: none;
  will-change: transform, opacity;
}
/* max-width:none defeats the global img{max-width:100%}, which otherwise clamps the widest
   cutout (Garba, at left:85%) to the right-edge sliver and squishes it. */
.bdy-figure img { height: 100%; width: auto; max-width: none; display: block; filter: drop-shadow(0 24px 30px oklch(0 0 0 / 0.55)); }
.bdy-figure figcaption {
  position: absolute; left: 50%; top: -1.9rem; transform: translateX(-50%);
  font-family: var(--font-body); font-size: 0.62rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--marigold); opacity: 0.3; transition: opacity 500ms ease; white-space: nowrap;
  text-shadow: 0 1px 8px oklch(0 0 0 / 0.9);
}
.f-folk { left: 24%; --h: 74vh; --drift: -15vw; }
.f-kalbel { left: 4%; --h: 64vh; --drift: -9vw; }
.f-bhangra { left: 39%; --h: 78vh; --drift: -17vw; }
.f-bolly { left: 55%; --h: 70vh; --drift: -12vw; }
.f-anarkali { left: 73%; --h: 60vh; --drift: -6vw; }
.f-garba { left: 85%; --h: 80vh; --drift: -15vw; }
/* the lit dancer per cue — brightens, lifts, and steps in front (z-index) */
.scene--body[data-phase="0"] .f-kalbel, .scene--body[data-phase="1"] .f-folk,
.scene--body[data-phase="2"] .f-bhangra, .scene--body[data-phase="3"] .f-bolly,
.scene--body[data-phase="4"] .f-anarkali, .scene--body[data-phase="5"] .f-garba {
  z-index: 3;
}
.scene--body[data-phase="0"] .f-kalbel figcaption, .scene--body[data-phase="1"] .f-folk figcaption,
.scene--body[data-phase="2"] .f-bhangra figcaption, .scene--body[data-phase="3"] .f-bolly figcaption,
.scene--body[data-phase="4"] .f-anarkali figcaption, .scene--body[data-phase="5"] .f-garba figcaption { opacity: 1; }

/* the follow-spot glow — position set per cue in CSS (no extra JS needed) */
.bdy-spot {
  position: absolute; bottom: -10vh; z-index: 1; width: 52vh; height: 82vh; pointer-events: none;
  background: radial-gradient(50% 46% at 50% 60%, oklch(0.82 0.13 78 / 0.22), transparent 70%);
  left: 0; transform: translateX(calc(var(--sx, 50vw) - 50%)); opacity: 0;
  transition: opacity 250ms var(--ease-out), transform 250ms var(--ease-out);
}
.scene--body[data-phase] .bdy-spot { opacity: 1; }
.scene--body[data-phase="0"] { --sx: 10vw; } .scene--body[data-phase="1"] { --sx: 30vw; }
.scene--body[data-phase="2"] { --sx: 46vw; } .scene--body[data-phase="3"] { --sx: 62vw; }
.scene--body[data-phase="4"] { --sx: 79vw; } .scene--body[data-phase="5"] { --sx: 91vw; }

/* edge vignettes hide the dancers' entrances */
.bdy-stage::before, .bdy-stage::after { content: ""; position: absolute; top: 0; bottom: 0; width: 14vw; z-index: 2; pointer-events: none; }
.bdy-stage::before { left: 0; background: linear-gradient(90deg, var(--ink-deep), transparent); }
.bdy-stage::after { right: 0; background: linear-gradient(270deg, var(--ink-deep), transparent); }
.bdy-floor { position: absolute; left: 0; right: 0; bottom: 0; height: 62%; z-index: 3; pointer-events: none;
  background: linear-gradient(transparent, oklch(0.10 0.02 300 / 0.55) 38%, oklch(0.08 0.02 300 / 0.96)); }
.bdy-floor::after { content: ""; position: absolute; left: 0; bottom: 0; width: min(58%, 44rem); height: 78%;
  background: radial-gradient(120% 100% at 0% 100%, oklch(0.07 0.02 300 / 0.85), transparent 70%); }

/* text layer */
.bdy-eyebrow { position: absolute; top: clamp(1.4rem, 5vh, 3rem); left: var(--page); z-index: 6; margin: 0; }
.bdy-beats { position: absolute; left: var(--page); bottom: clamp(5rem, 16vh, 9rem); z-index: 6; max-width: min(34rem, 74vw); display: grid; }
.bdy-beat { grid-area: 1 / 1; opacity: 0; transform: translateY(18px);
  transition: opacity 250ms var(--ease-out), transform 250ms var(--ease-out); }
.scene--body[data-phase="0"] .bdy-beat--0, .scene--body[data-phase="1"] .bdy-beat--0,
.scene--body[data-phase="2"] .bdy-beat--1, .scene--body[data-phase="3"] .bdy-beat--1,
.scene--body[data-phase="4"] .bdy-beat--2, .scene--body[data-phase="5"] .bdy-beat--2 { opacity: 1; transform: none; }
.bdy-beat strong { display: block; font-family: var(--font-display); font-weight: 830; font-stretch: 112%;
  font-size: clamp(2rem, 5.4vw, 4.2rem); line-height: 0.94; letter-spacing: -0.025em; text-transform: uppercase;
  text-shadow: 0 2px 22px oklch(0 0 0 / 0.7); }
.bdy-beat span { display: block; margin-top: 0.7rem; font-size: clamp(1rem, 1.5vw, 1.2rem); opacity: 0.86; max-width: 26rem;
  text-shadow: 0 1px 10px oklch(0 0 0 / 0.7); }
.bdy-scribble { position: absolute; z-index: 6; top: clamp(4.5rem, 14vh, 8rem); left: var(--page);
  rotate: -4deg; font-size: clamp(1rem, 1.6vw, 1.3rem); opacity: 0.9; }
.bdy-caption { position: absolute; right: var(--page); bottom: clamp(1.4rem, 5vh, 2.6rem); z-index: 6;
  font-size: 0.85rem; opacity: 0.72; text-align: right; max-width: min(30rem, 62vw); text-wrap: balance; }
.bdy-caption a { color: var(--marigold); text-underline-offset: 3px; white-space: nowrap; }
/* the three-beat meter */
.bdy-meter { position: absolute; right: var(--page); top: 5.5rem; z-index: 6; display: flex; gap: 0.5rem; }
.bdy-meter i { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: oklch(0.955 0.02 85 / 0.28); transition: background-color 300ms, transform 300ms; }
.scene--body[data-phase="0"] .bdy-meter i:nth-child(1),
.scene--body[data-phase="1"] .bdy-meter i:nth-child(2),
.scene--body[data-phase="2"] .bdy-meter i:nth-child(3),
.scene--body[data-phase="3"] .bdy-meter i:nth-child(4),
.scene--body[data-phase="4"] .bdy-meter i:nth-child(5),
.scene--body[data-phase="5"] .bdy-meter i:nth-child(6) { background: var(--marigold); transform: scale(1.5); }

@media (max-width: 720px) {
  /* keep all six — every one gets a lighting cue, so none may be hidden */
  .bdy-figure { --h: 54vh; }
  .f-kalbel { left: -6%; } .f-folk { left: 8%; } .f-bhangra { left: 24%; }
  .f-bolly { left: 40%; } .f-anarkali { left: 58%; } .f-garba { left: 72%; }
  .bdy-figure figcaption { font-size: 0.55rem; letter-spacing: 0.12em; }
  .bdy-beat span { max-width: 20rem; }
}
/* ============================== Marquee ============================== */

/* Local clip so the over-wide rotated bar never expands the document (mobile overflow). */
/* wrap gets the marquee's own pink, so the slight rotation never reveals the page colour
   behind it as a pale band between the two sections (that was the "border issue") */
.marquee-wrap { overflow: clip; background: var(--rani); }
.marquee {
  position: relative;
  background: var(--rani); color: var(--cream);
  rotate: -1.3deg; margin: 0 -2%; width: 104%;
  overflow: clip;
  z-index: 3;
}
.marquee__track {
  display: inline-flex; align-items: center; gap: 2.4rem;
  width: max-content;
  padding: 0.85rem 0;
  font-family: var(--font-display); font-weight: 760; font-stretch: 108%;
  font-size: clamp(1.1rem, 2.4vw, 1.7rem);
  text-transform: uppercase; letter-spacing: 0.01em;
  animation: marquee 24s linear infinite;
}
.marquee__track span { white-space: nowrap; padding-left: 2.4rem; }
.marquee__track i { font-style: normal; color: var(--marigold); }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ============================== Act II — The Call Sheet ==============================
   Three day-columns holding all nine classes; today's column auto-lit; open-level classes
   glow so newcomers find a way in. Cool pale paper (contrast to the warm gold Notes above).
   Colours section-scoped p2- so they never touch global tokens. */
.practice2 {
  --p2-paper: var(--bold-cobalt); --p2-ink: var(--cream);
  --p2-rani: var(--glow); --p2-gold: var(--glow);  /* glow-rose on cobalt was 3.1:1 */
  --p2-mono: ui-monospace, "SF Mono", Menlo, monospace;
  background: radial-gradient(120vmax 80vmax at 80% -10%, oklch(0.56 0.2 262), var(--p2-paper) 70%);
  color: var(--p2-ink);
  padding: clamp(2.5rem, 9vh, 6rem) var(--page) clamp(3rem, 10vh, 7rem);
}
.p2-intro { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 17rem); gap: clamp(1.5rem, 4vw, 4rem); align-items: end; margin-bottom: clamp(2rem, 6vh, 3.5rem); }
.practice2 .eyebrow { color: color-mix(in oklch, var(--p2-ink), transparent 35%); opacity: 1; margin-bottom: 0.9rem; }
.practice2 h2 { font-family: var(--font-display); font-weight: 840; font-stretch: 114%; font-size: clamp(2.2rem, 6vw, 4.4rem); line-height: 0.9; letter-spacing: -0.03em; text-transform: uppercase; margin: 0; color: var(--p2-ink); }
.practice2 h2 em { font-style: normal; font-weight: 320; font-stretch: 76%; color: var(--p2-rani); }
.p2-intro > div > p { margin-top: 1rem; max-width: 32rem; line-height: 1.6; opacity: 0.8; }
.p2-intro > div > p em { font-style: italic; }
.p2-portrait { justify-self: end; text-align: right; margin: 0; }
.p2-portrait img { width: min(15rem, 40vw); height: auto; max-width: none; aspect-ratio: 1; object-fit: cover; border-radius: 1rem; display: block; }
.p2-portrait figcaption { margin-top: 0.5rem; font-size: 0.78rem; opacity: 0.7; line-height: 1.4; }

.p2-sheet { border-top: 2px solid var(--p2-ink); }
.p2-bar { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding: 0.7rem 0;
  font-family: var(--p2-mono); font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase;
  border-bottom: 1px solid color-mix(in oklch, var(--p2-ink), transparent 82%); }
.p2-bar b { color: var(--p2-rani); }
.p2-days { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(0.8rem, 2vw, 1.8rem); margin-top: 1.4rem; }
.p2-day { border: 1px solid var(--hair); border-radius: 0.9rem;
  padding: clamp(0.9rem, 2vw, 1.3rem); background: var(--panel); }
.p2-day.is-today { border-color: var(--p2-rani); box-shadow: 0 0 0 2px color-mix(in oklch, var(--p2-rani), transparent 78%); }
.p2-dayhead { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem;
  padding-bottom: 0.7rem; margin-bottom: 0.5rem; border-bottom: 1px solid color-mix(in oklch, var(--p2-ink), transparent 88%); }
.p2-dayhead h3 { font-family: var(--font-display); font-weight: 820; font-stretch: 110%; font-size: clamp(1.2rem, 2.4vw, 1.7rem); text-transform: uppercase; letter-spacing: -0.01em; margin: 0; }
.p2-dayhead span { font-family: var(--p2-mono); font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.6; }
.p2-day.is-today .p2-dayhead span { color: var(--p2-rani); opacity: 1; font-weight: 600; }

.p2-call { display: grid; grid-template-columns: auto 1fr; gap: 0.2rem 0.8rem; align-items: baseline;
  padding: 0.65rem 0.3rem; border-radius: 0.5rem; color: inherit; text-decoration: none;
  transition: background-color 0.22s ease, transform 0.28s var(--ease-out); }
.p2-call time { font-family: var(--p2-mono); font-size: 0.82rem; font-weight: 600; color: var(--p2-rani); font-variant-numeric: tabular-nums; white-space: nowrap; }
.p2-call strong { font-family: var(--font-display); font-weight: 780; font-stretch: 104%; font-size: 1.02rem; line-height: 1.2; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.p2-lvl { font-family: var(--font-body); font-weight: 600; font-size: 0.66rem; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0.16rem 0.5rem; border-radius: 99px; white-space: nowrap;
  border: 1px solid color-mix(in oklch, var(--p2-ink), transparent 82%); color: color-mix(in oklch, var(--p2-ink), transparent 38%); }
.p2-call.is-open .p2-lvl { background: var(--p2-gold); border-color: var(--p2-gold); color: oklch(0.24 0.05 60); box-shadow: 0 0 0 3px color-mix(in oklch, var(--p2-gold), transparent 76%); }
.p2-call.is-open { background: color-mix(in oklch, var(--p2-gold), transparent 90%); }
.p2-wayin { display: block; margin-top: 0.3rem; font-size: 0.74rem; text-decoration: none; font-style: normal;
  color: var(--p2-rani); opacity: 0.9; padding-left: 0.55rem; border-left: 2px solid color-mix(in oklch, var(--p2-rani), transparent 60%); }
.p2-call small { grid-column: 2; font-size: 0.82rem; opacity: 0.66; line-height: 1.35; }
@media (hover: hover) and (pointer: fine) { .p2-call:hover { background: color-mix(in oklch, var(--p2-gold), transparent 72%); transform: translateX(3px); } }
.p2-call:focus-visible { outline: 2.5px solid var(--p2-rani); outline-offset: 1px; }
.p2-legend { display: flex; align-items: center; gap: 0.5rem; font-size: 0.78rem; opacity: 0.75; margin-top: 1rem; flex-wrap: wrap; }
.p2-legend i { width: 0.7rem; height: 0.7rem; border-radius: 99px; background: var(--p2-gold); display: inline-block; }
.p2-legend b { font-weight: 400; color: var(--p2-rani); }

.p2-aside { margin-top: clamp(1.6rem, 4vh, 2.6rem); display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.6rem; justify-content: space-between; }
.p2-aside p { line-height: 1.5; }
.p2-aside .scribble { color: var(--p2-rani); rotate: -2deg; font-size: 1.05rem; }
.p2-btn { display: inline-flex; align-items: center; gap: 0.6rem; background: var(--p2-ink); color: var(--p2-paper);
  border-radius: 99px; padding: 0.75rem 1.35rem; font-weight: 600; font-size: 0.92rem; text-decoration: none;
  transition: transform 0.16s var(--ease-out), background-color 0.2s; }
@media (hover: hover) and (pointer: fine) { .p2-btn:hover { background: var(--p2-rani); transform: scale(1.03); } }

@media (max-width: 900px) {
  .p2-intro { grid-template-columns: 1fr; }
  .p2-portrait { display: none; }
  .p2-days { grid-template-columns: 1fr; gap: 1rem; }
}
/* ============================== Act III — The Invitation (lobby cards) ==============================
   Scroll-driven horizontal case of workshop cards; each tilts in 3D by its distance from centre
   (JS sets --t/--a per frame). Bold pink ground, cream cards. Namespaced inv-. */
.inv-stage { display: grid; grid-template-rows: auto 1fr auto auto; padding: clamp(1.4rem, 4vh, 2.6rem) 0; overflow: clip; }
.inv-head { padding: 0 var(--page); position: relative; z-index: 3; }
.scene--invite .eyebrow { color: color-mix(in oklch, var(--ink-deep), transparent 20%); opacity: 1; margin-bottom: 0.7rem; }
.inv-head h2 { font-family: var(--font-display); font-weight: 850; font-stretch: 116%; font-size: clamp(2.2rem, 6.5vw, 4.8rem);
  line-height: 0.88; letter-spacing: -0.03em; text-transform: uppercase; margin: 0; color: var(--cream); }
.inv-head h2 em { font-style: normal; font-weight: 320; font-stretch: 76%; color: var(--glow); }
.inv-scribble { position: absolute; right: var(--page); top: 0; font-family: var(--font-hand); color: var(--cream);
  rotate: -4deg; font-size: clamp(0.95rem, 1.5vw, 1.2rem); line-height: 1.35; text-align: right; }

.inv-case { position: relative; min-height: 0; display: grid; align-items: center; perspective: 1500px; overflow: hidden; }
/* small leading pad so card 01 starts near the left with the next peeking in */
.inv-track { display: flex; gap: clamp(1rem, 2.4vw, 2rem); padding: 0 calc(50vw - min(15rem, 38vw)) 0 var(--page);
  transform: translate3d(calc(var(--progress) * (var(--inv-shift, 0px) * -1)), 0, 0); transform-style: preserve-3d; will-change: transform; }
.inv-card { flex: 0 0 auto; width: min(30rem, 76vw); background: var(--cream); color: var(--ink); border-radius: 1rem;
  padding: clamp(1.2rem, 2.6vw, 2rem); box-shadow: 0 24px 50px oklch(0 0 0/0.28);
  transform: rotateY(calc(var(--t, 0) * -20deg)) translateZ(calc(var(--a, 0) * -140px)) scale(calc(1 - var(--a, 0) * 0.1));
  opacity: calc(1 - var(--a, 0) * 0.45); transition: opacity 0.25s linear; transform-origin: center; backface-visibility: hidden; }
.inv-card span { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.72rem; letter-spacing: 0.16em; color: var(--rani); }
.inv-card h3 { font-family: var(--font-display); font-weight: 840; font-stretch: 112%; font-size: clamp(1.5rem, 3.2vw, 2.4rem);
  line-height: 0.95; text-transform: uppercase; letter-spacing: -0.02em; margin: 0.5rem 0 0.7rem; }
.inv-card p { font-size: clamp(0.9rem, 1.2vw, 1.02rem); line-height: 1.55; opacity: 0.82; }
.inv-card small { display: block; margin-top: 0.9rem; padding-top: 0.7rem; font-size: 0.78rem; opacity: 0.62;
  border-top: 1px solid color-mix(in oklch, var(--ink), transparent 86%); }

.inv-rail { margin: 0.9rem var(--page) 0; height: 2px; background: color-mix(in oklch, var(--cream), transparent 74%);
  position: relative; z-index: 3; border-radius: 2px; }
.inv-rail i { position: absolute; inset: 0 auto 0 0; width: 100%; transform-origin: left; transform: scaleX(calc(0.18 + var(--progress) * 0.82)); background: var(--cream); border-radius: 2px; }
/* Act III sold six dance forms and showed nothing. A programmer needs to see
   that this has been done before, for a room like theirs — so: the crowd, and
   the twelve cities it has actually happened in (derived from ABC's archive,
   workshops only, guest-taught dates excluded). */
.inv-proof { display: grid; grid-template-columns: minmax(0, 22rem) 1fr; gap: clamp(1rem, 2.5vw, 2rem);
  align-items: center; padding: 0 var(--page); margin-top: clamp(.6rem, 1.6vh, 1.2rem); }
.inv-proof-media { margin: 0; border-radius: 12px; overflow: hidden; aspect-ratio: 16 / 9;
  box-shadow: 0 20px 44px -26px oklch(0 0 0 / .6); }
.inv-proof-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.inv-proof-lead { margin: 0 0 .5rem; font-size: clamp(1rem, 1.5vw, 1.25rem); font-weight: 650; }
.inv-proof-cities { margin: 0; font-size: clamp(.85rem, 1.1vw, .98rem); line-height: 1.5; }
.inv-proof-cities b { display: block; font-weight: 800; }
@media (max-width: 820px) {
  .inv-proof { grid-template-columns: 1fr; }
  .inv-proof-media { max-width: 22rem; }
}

.inv-foot { display: flex; flex-wrap: wrap; gap: 1rem 2.2rem; align-items: center; justify-content: space-between;
  padding: 0 var(--page); position: relative; z-index: 3; margin-top: 0.9rem; color: var(--cream); }
.inv-formats { display: flex; flex-wrap: wrap; gap: 1rem 2rem; }
.inv-formats p strong { display: block; font-family: var(--font-display); font-weight: 820; font-size: 1.05rem; letter-spacing: -0.01em; }
.inv-formats p span { font-size: 0.8rem; opacity: 0.72; }
.inv-btn { display: inline-flex; align-items: center; gap: 0.6rem; background: var(--ink); color: var(--cream);
  border-radius: 99px; padding: 0.8rem 1.4rem; font-weight: 600; font-size: 0.92rem; text-decoration: none;
  transition: transform 0.16s var(--ease-out), background-color 0.2s; }
@media (hover: hover) and (pointer: fine) { .inv-btn:hover { background: var(--glow); color: var(--ink); transform: scale(1.03); } }

/* reduced-motion / no-JS: cards become a plain responsive grid */
html.no-js .inv-stage { display: block; padding: clamp(2.5rem, 8vh, 5rem) 0; }
html.no-js .inv-case { perspective: none; overflow: visible; }
html.no-js .inv-track { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  gap: 1rem; padding: 1.6rem var(--page) 0; transform: none; }
html.no-js .inv-card { width: auto; transform: none; opacity: 1; }
html.no-js .inv-scribble { position: static; text-align: left; margin-top: 1rem; }
html.no-js .inv-rail { display: none; }
html.no-js .inv-foot { margin-top: 2rem; }
@media (max-width: 720px) { .inv-scribble { display: none; } .inv-card { width: min(21rem, 82vw); } }
/* ============================== Act IV — The Reel (folk showreel) ==============================
   Four repertoire pieces play as one continuous reel, each loaded just-in-time, auto-advancing,
   with a 4-chapter progress bar. Ink ground (a film section). Namespaced rl-. */
.stage-reel { background: var(--ink-deep); color: var(--cream);
  padding: clamp(2.5rem, 9vh, 6rem) var(--page) clamp(3rem, 10vh, 7rem); position: relative; overflow: clip; }
.rl-ghost { position: absolute; right: -2vw; top: 5vh; z-index: 0; pointer-events: none; font-family: var(--font-display);
  font-weight: 880; font-stretch: 120%; font-size: min(24vw, 28vh); line-height: 0.8;
  color: oklch(0.84 0.155 82 / 0.045); text-transform: uppercase; }
.rl-head { position: relative; z-index: 2; max-width: 44rem; margin-bottom: clamp(1.4rem, 4vh, 2.2rem); }
.stage-reel .eyebrow { color: var(--marigold); opacity: 1; margin-bottom: 0.9rem; }
.stage-reel h2 { font-family: var(--font-display); font-weight: 840; font-stretch: 114%; font-size: clamp(2.2rem, 6vw, 4.4rem);
  line-height: 0.9; letter-spacing: -0.03em; text-transform: uppercase; margin: 0; }
.stage-reel h2 em { font-style: normal; font-weight: 320; font-stretch: 76%; color: var(--marigold); }
.rl-head p { margin-top: 1rem; line-height: 1.6; opacity: 0.8; max-width: 38rem; }

.rl-box { position: relative; z-index: 2; }
.rl-screen { position: relative; aspect-ratio: 16/9; border-radius: 0.5rem; overflow: hidden; background: #000; isolation: isolate;
  box-shadow: 0 0 0 1px color-mix(in oklch, var(--cream), transparent 88%), 0 40px 90px oklch(0 0 0/0.6), 0 0 120px oklch(0.84 0.155 82/0.08); }
.rl-screen video { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.rl-beam { position: absolute; inset: 0; z-index: 2; pointer-events: none; mix-blend-mode: screen;
  background: radial-gradient(120% 90% at 50% 120%, oklch(0.84 0.155 82/0.13), transparent 62%); }
.rl-grain { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0.07; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 160 160' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.rl-slate { position: absolute; left: 0; right: 0; bottom: 0; z-index: 4; padding: clamp(1rem, 3vw, 2rem);
  background: linear-gradient(transparent, oklch(0 0 0/0.86)); }
.rl-slate i { display: block; font-style: normal; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.66rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--marigold); margin-bottom: 0.25rem; }
.rl-slate b { font-family: var(--font-display); font-weight: 830; font-stretch: 112%; font-size: clamp(1.2rem, 3vw, 2.2rem);
  text-transform: uppercase; letter-spacing: -0.02em; display: block; line-height: 1; }
.rl-slate span { font-size: 0.9rem; opacity: 0.75; }
.rl-tc { position: absolute; right: clamp(1rem, 3vw, 2rem); top: clamp(1rem, 3vw, 2rem); z-index: 4;
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.7rem; letter-spacing: 0.14em; color: var(--marigold);
  background: oklch(0 0 0/0.45); padding: 0.3rem 0.6rem; border-radius: 0.3rem; }

.rl-chapters { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.5rem; margin-top: 0.6rem; }
.rl-chapter { position: relative; border: 0; padding: 0; background: none; cursor: pointer; text-align: left; color: inherit; }
.rl-chapter .rl-bar { height: 3px; border-radius: 3px; background: color-mix(in oklch, var(--cream), transparent 84%); overflow: hidden; }
.rl-chapter .rl-bar i { display: block; height: 100%; width: 0; background: var(--marigold); border-radius: 3px; }
.rl-chapter.is-done .rl-bar i { width: 100%; }
.rl-chapter em { display: block; font-style: normal; margin-top: 0.5rem; font-family: var(--font-display); font-weight: 790;
  font-size: clamp(0.85rem, 1.5vw, 1.05rem); text-transform: uppercase; letter-spacing: -0.01em; opacity: 0.5; transition: opacity 0.3s; }
.rl-chapter small { display: block; font-size: 0.72rem; opacity: 0.42; margin-top: 0.1rem; }
.rl-chapter.is-on em { opacity: 1; }
.rl-chapter.is-on small { opacity: 0.7; }
.rl-chapter:focus-visible { outline: 3px solid var(--marigold); outline-offset: 3px; border-radius: 0.3rem; }

.rl-cta { display: flex; flex-wrap: wrap; gap: 1rem 1.6rem; align-items: center; margin-top: clamp(1.4rem, 4vh, 2.4rem); position: relative; z-index: 2; }

/* reduced-motion / no-JS: posters + names, nothing autoplays */
.rl-stills { display: none; }
.rl-stills figure { margin: 0; }
.rl-stills img { width: 100%; height: auto; max-width: none; aspect-ratio: 16/9; object-fit: cover; border-radius: 0.4rem; display: block; }
.rl-stills figcaption { margin-top: 0.35rem; font-size: 0.8rem; opacity: 0.75; }
html.no-js .rl-screen video { display: none; }
html.no-js .rl-stills, html.no-js .rl-chapters { display: none; }
html.no-js .rl-stills { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 0.6rem; margin-top: 0.6rem; }
@media (max-width: 720px) { .rl-ghost { display: none; } .rl-chapters { grid-template-columns: repeat(2, 1fr); gap: 0.5rem 0.8rem; } }
/* ============================== Interlude — The Tour Board ==============================
   Departure board of upcoming dates; the destination city flips in split-flap style. Bold
   cobalt ground; the flap tiles stay near-black so they still read as flaps. Namespaced lb-.
   Past events are date-gated out in JS. */
.live-board { background: var(--bold-cobalt); color: var(--cream);
  padding: clamp(2.5rem, 9vh, 6rem) var(--page) clamp(3rem, 10vh, 7rem); }
.lb-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; flex-wrap: wrap;
  padding-bottom: 1.4rem; border-bottom: 1px solid color-mix(in oklch, var(--cream), transparent 78%); }
.live-board .eyebrow { color: var(--marigold); opacity: 1; margin-bottom: 0.9rem; }
.live-board h2 { font-family: var(--font-display); font-weight: 840; font-stretch: 114%; font-size: clamp(2.2rem, 6vw, 4.6rem);
  line-height: 0.9; letter-spacing: -0.03em; text-transform: uppercase; margin: 0; }
.live-board h2 em { font-style: normal; font-weight: 320; font-stretch: 76%; color: var(--marigold); }
.lb-boarding { display: inline-flex; align-items: center; gap: 0.6rem; font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--marigold); white-space: nowrap; }
.lb-boarding i { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--marigold); animation: lb-blink 1.6s steps(1) infinite; }
@keyframes lb-blink { 50% { opacity: 0.25; } }

.lb-cols { display: grid; grid-template-columns: 7.5rem minmax(0, 15rem) minmax(0, 1fr) auto; gap: clamp(0.8rem, 2vw, 2rem);
  padding: 0.9rem 0.2rem; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.66rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: color-mix(in oklch, var(--cream), transparent 55%); }
.lb-board { display: grid; perspective: 900px; }
.lb-row { display: grid; grid-template-columns: 7.5rem minmax(0, 15rem) minmax(0, 1fr) auto; gap: clamp(0.8rem, 2vw, 2rem);
  align-items: center; padding: clamp(0.9rem, 2vh, 1.4rem) 0.2rem; text-decoration: none; color: inherit;
  border-bottom: 1px solid color-mix(in oklch, var(--cream), transparent 86%);
  transition: background-color 0.25s ease, transform 0.35s var(--ease-out); }
.lb-row time { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.9rem; color: var(--marigold); white-space: nowrap; font-variant-numeric: tabular-nums; }
.lb-row time b { display: block; font-size: 1.35rem; font-weight: 700; letter-spacing: -0.01em; }
.lb-flap { display: flex; gap: 0.16rem; }
.lb-cell { --h: clamp(1.9rem, 4.2vw, 2.9rem); width: calc(var(--h) * 0.72); height: var(--h);
  display: grid; place-items: center; font-family: var(--font-display); font-weight: 900; font-size: calc(var(--h) * 0.58);
  color: var(--cream); background: linear-gradient(#26232b 0 49.5%, #141218 50% 100%); border-radius: 0.16em;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.05), 0 1px 2px rgba(0,0,0,0.5); transform-origin: center; backface-visibility: hidden; }
.lb-cell.gap { background: none; box-shadow: none; width: calc(var(--h) * 0.3); }
html.js .lb-board.is-live .lb-cell:not(.gap) { animation: lb-flip 0.5s var(--ease-out) both; animation-delay: var(--d, 0s); }
@keyframes lb-flip { 0% { transform: rotateX(-90deg); opacity: 0; } 55% { transform: rotateX(12deg); opacity: 1; } 100% { transform: rotateX(0); } }
.lb-what strong { display: block; font-family: var(--font-display); font-weight: 790; font-stretch: 106%; font-size: clamp(1.05rem, 2.1vw, 1.55rem); line-height: 1.15; letter-spacing: -0.015em; }
.lb-what span { display: block; margin-top: 0.15rem; font-size: 0.9rem; opacity: 0.7; }
.lb-status { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--marigold); white-space: nowrap; opacity: 0.85; }
.lb-empty { padding: 2rem 0.2rem; opacity: 0.75; }
@media (hover: hover) and (pointer: fine) {
@media (hover: hover) and (pointer: fine) {   .lb-row:hover { background: color-mix(in oklch, var(--cream), transparent 94%); transform: translateX(5px); } }
  .lb-row:hover .lb-cell:not(.gap) { background: linear-gradient(var(--marigold) 0 49.5%, #caa020 50% 100%); color: #1a1206; }
  .lb-row:hover .lb-status { opacity: 1; }
}
.lb-row:focus-visible { outline: 3px solid var(--marigold); outline-offset: -3px; }
@media (max-width: 820px) {
  .lb-cols { display: none; }
  .lb-row { grid-template-columns: 1fr auto; gap: 0.5rem 0.9rem; align-items: start; }
  .lb-row time { grid-column: 1; grid-row: 1; }
  .lb-flap { grid-column: 1 / -1; grid-row: 3; margin-top: 0.4rem; }
  .lb-what { grid-column: 1 / -1; grid-row: 2; }
  .lb-status { grid-column: 2; grid-row: 1; text-align: right; }
}
@media (prefers-reduced-motion: reduce) { html.js .lb-board.is-live .lb-cell:not(.gap) { animation: none; } .lb-boarding i { animation: none; } .lb-row:hover { transform: none; } }
/* ============================== Act V — The Thali ==============================
   A steel platter ringed with round dish cutouts; point at one and it serves into the centre.
   Bold orange ground; the metal platter and cream rings pop against it. Namespaced th-. */
.thali-act { background: var(--bold-orange); color: var(--ink-deep); overflow: clip; }
.th-bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding: 0.85rem var(--page); background: var(--ink-deep); color: var(--cream);
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase; }
.th-bar b { color: var(--marigold); display: inline-flex; align-items: center; gap: 0.5rem; }
.th-bar b i { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--marigold); animation: th-pulse 2.4s var(--ease-out) infinite; }
@keyframes th-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(0.82); } }
.th-grid { padding: clamp(2.2rem, 7vh, 4.5rem) var(--page) clamp(3rem, 10vh, 7rem);
  display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: clamp(1.6rem, 4vw, 4rem); align-items: center; }
.thali-act .eyebrow { color: color-mix(in oklch, var(--ink-deep), transparent 20%); opacity: 1; margin-bottom: 0.9rem; }
.thali-act h2 { font-family: var(--font-display); font-weight: 840; font-stretch: 114%; font-size: clamp(2rem, 5vw, 3.7rem);
  line-height: 0.92; letter-spacing: -0.03em; text-transform: uppercase; margin: 0; }
.thali-act h2 em { font-style: normal; font-weight: 320; font-stretch: 76%; color: var(--cream); }
.th-copy p { margin-top: 1.05rem; line-height: 1.65; opacity: 0.85; max-width: 30rem; }
.th-cta { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; margin-top: 1.5rem; }
.th-btn { display: inline-flex; align-items: center; gap: 0.6rem; background: var(--cream); color: var(--ink);
  border-radius: 99px; padding: 0.8rem 1.4rem; font-weight: 600; font-size: 0.92rem; text-decoration: none;
  transition: transform 0.16s var(--ease-out), background-color 0.2s; }
@media (hover: hover) and (pointer: fine) { .th-btn:hover { background: var(--glow); transform: scale(1.03); } }
.th-copy .scribble { color: var(--cream); rotate: -3deg; font-size: 1.05rem; }

.th-plate { position: relative; aspect-ratio: 1; width: min(46rem, 88vw); justify-self: center; display: grid; place-items: center;
  border-radius: 50%; background: radial-gradient(circle at 38% 32%, #fdfdfb, #e6e4dd 58%, #c9c6bd 78%, #a9a69c);
  box-shadow: 0 34px 70px oklch(0 0 0/0.32), inset 0 0 0 2px rgba(255,255,255,0.5), inset 0 -18px 40px rgba(0,0,0,0.13); }
.th-plate::after { content: ""; position: absolute; inset: 5.5%; border-radius: 50%; border: 1px solid rgba(0,0,0,0.09); pointer-events: none; }
.th-centre { position: relative; z-index: 3; width: 34%; aspect-ratio: 1; border-radius: 50%; overflow: hidden; margin: 0;
  box-shadow: 0 14px 30px oklch(0 0 0/0.3), 0 0 0 3px var(--cream); background: #ddd; }
.th-centre img { width: 100%; height: 100%; max-width: none; object-fit: cover; display: block; transition: transform 0.6s var(--ease-out); }
.th-centre figcaption { position: absolute; inset: auto 0 0 0; padding: 0.5rem; text-align: center;
  background: linear-gradient(transparent, rgba(0,0,0,0.72)); color: var(--cream); font-family: var(--font-hand); font-size: 0.9rem; }
/* --r is the ring radius in px, set from the platter width by JS (a % would be a % of the katori box) */
.th-katori { position: absolute; left: 50%; top: 50%; width: 19%; aspect-ratio: 1; margin: 0;
  transform: translate(-50%, -50%) rotate(calc(var(--i) * (360deg / var(--n)))) translateY(calc(var(--r, 0px) * -1)) rotate(calc(var(--i) * (-360deg / var(--n))));
  transition: transform 0.4s var(--ease-out); }
.th-katori button { width: 100%; aspect-ratio: 1; border-radius: 50%; overflow: hidden; padding: 0; border: 0; background: #ddd; cursor: pointer; display: block;
  box-shadow: 0 8px 18px oklch(0 0 0/0.28), 0 0 0 3px var(--cream); transition: transform 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out); }
.th-katori img { width: 100%; height: 100%; max-width: none; object-fit: cover; display: block; transition: filter 0.3s var(--ease-out), transform 0.5s var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .th-katori button:hover, .th-katori button:focus-visible { transform: scale(1.12); box-shadow: 0 14px 26px oklch(0 0 0/0.34), 0 0 0 3px var(--marigold); outline: none; } }
.th-katori.is-on button { box-shadow: 0 14px 26px oklch(0 0 0/0.34), 0 0 0 3px var(--rani); }
.th-katori.is-on img { transform: scale(1.06); }
.th-picked { position: absolute; left: 50%; bottom: -1.1rem; transform: translateX(-50%); z-index: 4;
  font-family: var(--font-hand); font-size: clamp(1rem, 1.8vw, 1.35rem); color: var(--ink);
  background: color-mix(in oklch, var(--cream), transparent 4%); padding: 0.3rem 0.9rem; border-radius: 99px;
  white-space: nowrap; box-shadow: 0 6px 16px oklch(0 0 0/0.18); pointer-events: none; }

@media (max-width: 960px) { .th-grid { grid-template-columns: 1fr; } .th-plate { width: min(30rem, 92vw); } }
@media (prefers-reduced-motion: reduce) { .th-katori, .th-katori button, .th-katori img, .th-centre img { transition: none; } .th-katori button:hover { transform: none; } }
html.no-js .th-picked { display: none; }
/* Footer site map */
.footer__map {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0.35rem 1.1rem;
  max-width: 46rem; margin-inline: auto;
}
.footer__map a { font-size: 0.82rem; opacity: 0.68; }
.footer__map a:hover { opacity: 1; color: var(--marigold); }

/* ============================== Curtain call — hello ============================== */

.hello { position: relative; padding: clamp(5rem, 13vh, 9rem) var(--page) 2.5rem; overflow: clip; background: var(--bold-cobalt); color: var(--cream); }
.hello__ghost {
  position: absolute; top: 0.5rem; left: 50%; transform: translateX(-50%);
  font-family: var(--font-display); font-weight: 850; font-stretch: 124%;
  font-size: clamp(7rem, 26vw, 23rem); line-height: 0.8; text-transform: uppercase;
  color: oklch(0.9 0.16 92 / 0.28); -webkit-text-stroke: 1.5px color-mix(in oklch, var(--cream), transparent 72%);
  pointer-events: none;
}
.hello__head { position: relative; z-index: 1; text-align: center; }
.hello__head h2 em { color: var(--marigold); }

.doors__noscript {
  position: relative; z-index: 1;
  max-width: 56rem; margin: clamp(2rem, 6vh, 4rem) auto 0;
  padding: 1rem 1.2rem;
  border: 1.5px dashed color-mix(in oklch, var(--cream), transparent 45%);
  border-radius: 0.9rem;
  color: var(--cream); font-size: 0.95rem;
}
.doors__noscript a { text-decoration: underline; text-underline-offset: 0.25em; text-decoration-color: var(--marigold); font-weight: 600; }

.doors {
  position: relative; z-index: 1;
  margin: clamp(2.5rem, 6vh, 4rem) auto 0;
  max-width: 56rem;
  background: var(--cream); color: var(--ink);
  border-radius: 1.8rem;
  padding: clamp(1.5rem, 4vw, 3rem);
  box-shadow: 0 30px 80px oklch(0 0 0 / 0.35);
  display: grid; gap: 1.8rem;
}
.doors__choices legend {
  font-size: 0.85rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  margin-bottom: 1rem; opacity: 0.75;
}
.doors__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(8.6rem, 1fr)); gap: 0.7rem; }
.door {
  position: relative;
  display: grid; gap: 0.15rem; align-content: center; justify-items: center;
  min-height: 4.6rem;
  padding: 0.7rem 0.5rem;
  border: 2px solid var(--ink); border-radius: 0.9rem;
  text-align: center;
  cursor: pointer;
  transition: background-color 200ms ease, color 200ms ease, transform 160ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.door:active { transform: scale(0.96); }
@media (hover: hover) and (pointer: fine) {
  .door:hover { box-shadow: 4px 4px 0 var(--ink); translate: 0 -2px; }
}
.door input { position: absolute; opacity: 0; pointer-events: none; }
.door span { font-family: var(--font-display); font-weight: 790; font-stretch: 108%; font-size: 1.15rem; text-transform: uppercase; }
.door small { font-size: 0.78rem; opacity: 0.72; }
.door:has(input:checked) { background: var(--ink); color: var(--cream); box-shadow: 4px 4px 0 var(--marigold); }
.door:has(input:focus-visible) { outline: 3px solid var(--rani); outline-offset: 3px; }
.door--wild { border-style: dashed; }
.door--wild:has(input:checked) { background: var(--rani); border-color: var(--rani); color: var(--cream); }

.doors__prompt { display: grid; gap: 0.25rem; padding: 1rem 1.2rem; background: color-mix(in oklch, var(--marigold), var(--cream) 55%); border-radius: 0.9rem; }
.doors__prompt strong { font-family: var(--font-display); font-weight: 790; font-stretch: 106%; font-size: 1.25rem; text-transform: uppercase; }
.doors__prompt span { font-size: 0.95rem; opacity: 0.8; }

.doors__styles legend { font-size: 0.8rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 0.8rem; opacity: 0.75; }
.doors__checks { display: flex; flex-wrap: wrap; gap: 0.55rem; }
.doors__checks label {
  display: inline-flex; align-items: center;
  border: 1.5px solid var(--ink); border-radius: 99px;
  padding: 0.45rem 0.95rem;
  font-size: 0.88rem; font-weight: 500;
  cursor: pointer;
  transition: background-color 180ms ease, color 180ms ease, transform 140ms var(--ease-out);
}
.doors__checks label:active { transform: scale(0.95); }
.doors__checks input { position: absolute; opacity: 0; pointer-events: none; }
.doors__checks label:has(input:checked) { background: var(--ink); color: var(--cream); }
.doors__checks label:has(input:focus-visible) { outline: 3px solid var(--rani); outline-offset: 2px; }

.doors__fields { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.2rem; }
.doors__fields label, .doors__message { display: grid; gap: 0.4rem; }
.doors__fields span, .doors__message span { font-size: 0.82rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.75; }
.doors input[type="text"], .doors input[type="email"], .doors input[type="date"], .doors textarea {
  width: 100%;
  font: inherit; color: var(--ink);
  background: white;
  border: 2px solid var(--ink); border-radius: 0.7rem;
  padding: 0.7rem 0.85rem;
  transition: box-shadow 180ms var(--ease-out);
}
.doors input:focus-visible, .doors textarea:focus-visible { outline: none; box-shadow: 4px 4px 0 var(--marigold); }
.doors textarea { resize: vertical; min-height: 7rem; }
.doors ::placeholder { color: color-mix(in oklch, var(--ink), transparent 55%); }

.is-form-hidden { display: none !important; }

.doors__finish { display: grid; gap: 0.8rem; justify-items: start; }
.doors__finish p { font-size: 0.85rem; opacity: 0.65; max-width: 30rem; }

/* ============================== Buttons & links ============================== */

.button {
  display: inline-flex; align-items: center; gap: 0.7rem;
  padding: 0.95rem 1.6rem;
  border-radius: 99px;
  border: 2.5px solid currentColor;
  font-weight: 600; font-size: 0.98rem;
  cursor: pointer;
  transition: background-color 200ms ease, color 200ms ease, transform 160ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.button:active { transform: scale(0.96); }
.button span, .button b { transition: transform 220ms var(--ease-out); font-weight: 700; }
@media (hover: hover) and (pointer: fine) {
@media (hover: hover) and (pointer: fine) {   .button:hover span, .button:hover b { transform: translateX(3px); } }
}

.button--ink { background: var(--ink); color: var(--cream); border-color: var(--ink); }
@media (hover: hover) and (pointer: fine) {
  .button--ink:hover { background: var(--rani); border-color: var(--rani); color: var(--cream); box-shadow: 5px 5px 0 oklch(0 0 0 / 0.2); }
}
.button--paper { background: var(--cream); color: var(--ink); border-color: var(--cream); }
@media (hover: hover) and (pointer: fine) {
  .button--paper:hover { background: var(--marigold); border-color: var(--marigold); }
}

.action-pair { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; margin-top: 0.6rem; }
.text-link {
  font-weight: 600;
  text-decoration: underline; text-underline-offset: 0.32em; text-decoration-thickness: 2px;
  text-decoration-color: var(--marigold);
  transition: text-underline-offset 180ms var(--ease-out), color 180ms ease;
}
.text-link:hover { text-underline-offset: 0.45em; color: var(--marigold); }

/* ============================== Footer ============================== */

.footer {
  position: relative; z-index: 1;
  margin-top: clamp(3.5rem, 9vh, 6rem);
  padding-top: 2rem;
  border-top: 1.5px solid color-mix(in oklch, var(--cream), transparent 60%);
  display: grid; gap: 1.1rem; justify-items: center; text-align: center;
}
.footer .scribble { rotate: -3deg; }
.footer nav { display: flex; flex-wrap: wrap; gap: 1.6rem; justify-content: center; }
.footer nav a {
  font-weight: 600; font-size: 0.95rem;
  text-decoration: underline; text-underline-offset: 0.3em; text-decoration-color: var(--marigold);
  transition: color 180ms ease;
}
.footer nav a:hover { color: var(--marigold); }
.footer__venue, .footer p:last-child { font-size: 0.82rem; opacity: 0.6; }

/* ============================== Curtain call — the form's ending ==============================
   Shown by app.js after submit, in place of the form. The doors card is cream (paper you write
   on); this one is ink (the curtain came down) so the change of state reads instantly. */

.curtain {
  position: relative; z-index: 1;
  margin: clamp(2.5rem, 6vh, 4rem) auto 0;
  max-width: 56rem;
  background: var(--ink); color: var(--cream);
  border-radius: 1.8rem;
  border-top: 3px solid var(--marigold);
  padding: clamp(1.6rem, 4vw, 3rem);
  box-shadow: 0 30px 80px oklch(0 0 0 / 0.42);
  display: grid; gap: 1.1rem;
}
.curtain:focus { outline: none; }
.curtain__eyebrow {
  font-size: 0.8rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--marigold);
}
.curtain__title {
  font-family: var(--font-display); font-weight: 810; font-stretch: 108%;
  font-size: clamp(1.9rem, 5.2vw, 3.1rem); line-height: 0.9;
  letter-spacing: -0.03em; text-transform: uppercase; text-wrap: balance;
}
.curtain__title em { font-style: normal; font-weight: 320; font-stretch: 76%; color: var(--marigold); }
.curtain__lede { max-width: 34rem; opacity: 0.82; }

.curtain__summary {
  margin: 0.3rem 0 0;
  max-height: 22rem; overflow: auto;
  padding: 1.1rem 1.2rem;
  background: oklch(1 0 0 / 0.06);
  border: 1.5px dashed color-mix(in oklch, var(--cream), transparent 62%);
  border-radius: 0.9rem;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.86rem; line-height: 1.6;
  white-space: pre-wrap; overflow-wrap: anywhere;
  -webkit-user-select: text; user-select: text;
}
.curtain__summary:focus-visible { outline: 3px solid var(--marigold); outline-offset: 3px; }

.curtain__acts { display: flex; flex-wrap: wrap; gap: 0.8rem 1rem; align-items: center; margin-top: 0.4rem; }
.curtain__acts .button--paper { border-color: var(--cream); }
@media (hover: hover) and (pointer: fine) {
  .curtain__acts .button:not(.button--paper):hover { background: var(--marigold); border-color: var(--marigold); color: var(--ink); }
}
.curtain__hint { font-size: 0.88rem; opacity: 0.65; max-width: 34rem; }
.curtain__hint.is-copied { opacity: 1; color: var(--marigold); font-weight: 600; }

html.js .curtain:not([hidden]) { animation: curtain-drop 640ms var(--ease-out) both; }
@keyframes curtain-drop {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .curtain:not([hidden]) { animation: none; }
}

/* ============================== Sticky mobile CTA ==============================
   A whisper, not a shout: phone widths only, and only once the Overture is behind you.
   Sits under the top bar / progress rail (z 130+) and under the cameo (z 300).
   Deliberately NOT tied to --house: the acts paint their own grounds (a cream "house"
   can sit under a cobalt section), so an ink pill with cream type is the only palette
   that stays legible over all nine of them. */

.cta-pill {
  position: fixed; z-index: 120;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  display: none;
  align-items: center; gap: 0.45rem;
  padding: 0.7rem 1.1rem;
  border-radius: 99px;
  border: 1.5px solid color-mix(in oklch, var(--marigold), transparent 62%);
  background: color-mix(in oklch, var(--ink-deep), transparent 8%);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: var(--cream);
  font-size: 0.86rem; font-weight: 600; letter-spacing: 0.01em;
  box-shadow: 0 10px 26px oklch(0 0 0 / 0.3);
  opacity: 0; transform: translateY(10px); pointer-events: none;
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.cta-pill b { font-weight: 700; color: var(--marigold); }
.cta-pill:focus-visible { outline: 3px solid var(--marigold); outline-offset: 3px; }

@media (max-width: 720px) {
  .cta-pill { display: inline-flex; }
  /* On stage after the Overture; off again once you have arrived at the Curtain call. */
  body[data-act]:not([data-act="overture"]):not([data-act="hello"]) .cta-pill {
    opacity: 1; transform: none; pointer-events: auto;
  }
  body.menu-open .cta-pill { opacity: 0; transform: translateY(10px); pointer-events: none; }
  /* Act I's credit line is pinned bottom-right for the whole act — lift it clear of the pill
     so the Shoonya credit is never sitting underneath it. */
  .bdy-caption { bottom: 5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .cta-pill { transform: none; transition: opacity 220ms linear; }
  body[data-act]:not([data-act="overture"]):not([data-act="hello"]) .cta-pill { transform: none; }
}

/* ============================== Cameo (surprise door) ============================== */

.cameo {
  position: fixed; z-index: 300; bottom: 0; left: 0;
  pointer-events: none; opacity: 0;
}
.cameo img { height: min(38vh, 20rem); width: auto; }
.cameo.play { animation: cameo-leap 1.7s var(--ease-io) forwards; }
@keyframes cameo-leap {
  0%   { opacity: 0; transform: translate3d(-30vw, 4vh, 0) rotate(-8deg); }
  12%  { opacity: 1; }
  35%  { transform: translate3d(22vw, -14vh, 0) rotate(3deg); }
  60%  { transform: translate3d(55vw, -4vh, 0) rotate(-3deg); }
  88%  { opacity: 1; }
  100% { opacity: 0; transform: translate3d(112vw, -12vh, 0) rotate(8deg); }
}

/* ============================== Reveals ============================== */

html.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
html.js .reveal.is-visible { opacity: 1; transform: translateY(0); }
.ticket.reveal:nth-child(2) { --reveal-delay: 60ms; }
.ticket.reveal:nth-child(3) { --reveal-delay: 120ms; }
.ticket.reveal:nth-child(4) { --reveal-delay: 180ms; }
.ticket.reveal:nth-child(5) { --reveal-delay: 240ms; }

html.js .plate {
  opacity: 0; scale: 0.92;
  transition: opacity 700ms var(--ease-out), scale 700ms var(--ease-out);
}
html.js .plate.is-visible { opacity: 1; scale: 1; }
.plate--chole { transition-delay: 80ms; }
.plate--pakora { transition-delay: 160ms; }
.plate--roti { transition-delay: 240ms; }

/* ============================== Responsive ============================== */

@media (max-width: 1100px) {
  .table { grid-template-columns: 1fr; }
  .table__copy { max-width: 36rem; }
  .table__setting { max-width: 36rem; }
}

@media (max-width: 900px) {
  .topbar__context { display: none; }
  .poster__wall { grid-template-columns: 1fr 1fr; }
  .ticket a { grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto; row-gap: 0.5rem; }
  .ticket strong { grid-column: 1; grid-row: 2; justify-self: start; }
  .ticket small { grid-column: 2; grid-row: 2; justify-self: end; }
}

@media (max-width: 820px) {
  /* Act III unpins: the strip becomes a native swipe gallery */
  .scene--invite { height: auto; }
  .scene--invite .scene__pin { position: static; height: auto; min-height: 0; padding-bottom: 3rem; }
  .invite__viewport { overflow-x: auto; overflow-y: clip; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
  .invite__track { transform: none !important; }
  .invite__card { scroll-snap-align: center; width: min(21rem, 78vw); }
  .invite__scribble { position: static; margin-top: 0.8rem; rotate: -2deg; text-align: left; }

  .scene--hero { --len: 165; }
  .scene--body { --len: 700; }
  .scene--watch { --len: 190; }

  .hero__dancer img { height: min(44svh, 24rem); }
  .hero__scribble { top: 11vh; left: auto; right: 6vw; }
  .hero__place { display: none; }

  .watch__iris { clip-path: circle(calc(10% + var(--progress) * 78%) at 55% 40%); }
  .watch__scribble { display: none; }

  .doors__fields { grid-template-columns: 1fr; }
  .marquee { rotate: -2deg; }
}

@media (max-width: 640px) {
  body { font-size: 1rem; }
  .hero__title {
    font-size: clamp(2.9rem, 16.5vw, 5.2rem);
    /* line-height is 0.88 — tighter than the font — so glyph boxes bleed into
       the neighbouring grid rows. On desktop `is` sits absolutely in the left
       gutter and never meets them; in the mobile stack it does, and landed on
       top of CHOREO. Space the rows rather than nudging one child. */
    gap: 0.2em;
  }
  .hero__line--2 {
    /* `static` drops the z-index, and the dancer sits at translateZ(120px), so
       the word painted underneath the costume and vanished. `relative` keeps it
       in flow between the two words but restores stacking; the translateZ puts
       it in front of the dancer in the 3D context. */
    position: relative;
    /* the base rule's top/left are absolute-positioning coordinates; under
       `relative` they become OFFSETS and shoved `is` 35px down into CHOREO. */
    inset: auto;
    z-index: 6;
    rotate: -4deg;
    /* The big words have a tight line-height, so a 0.06em margin left `is`
       sitting inside CHOREO's line box. Give it its own band, and hold it left
       the way the desktop composition does rather than centring it over the
       letter mass. */
    display: block;
    line-height: 1;
    margin: 0;
    /* 0.38em of a 143px desktop h1 is 55px and holds its own; the same ratio on
       a 64px mobile h1 is 24px, which disappears between two full-width words
       and over the dancer. Give it presence at phone widths. */
    font-size: 0.52em;
    transform: translateZ(140px) scale(calc(1 + max(0, calc((var(--progress) - 0.05) / 0.95)) * 1.4));
    opacity: calc(1 - max(0, calc((var(--progress) - 0.05) / 0.95)) * 1.35);
  }
  .hero__note { font-size: 0.92rem; }
  .bdy-beat { max-width: 78vw; }
  .invite__head h2 { font-size: clamp(2.4rem, 11vw, 4rem); }
  .poster__wall { grid-template-columns: 1fr; max-width: 24rem; }
  .doors__grid { grid-template-columns: 1fr 1fr; }
  .footer nav { gap: 1rem; }
}

@media (max-height: 700px) and (min-width: 821px) {
  .hero__dancer img { height: 48svh; }
  .hero__title { font-size: clamp(3rem, 11vw, 8rem); }
  .invite__card { min-height: 0; }
  .invite__head h2 { font-size: clamp(2.2rem, 5.5vw, 4rem); }
}

/* ============================== Reduced motion ============================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .scene { height: auto !important; }
  .scene__pin { position: static; height: auto; min-height: 0; overflow: visible; padding-top: 6rem; padding-bottom: 3rem; }

  .preload { display: none; }

  .hero { min-height: 100svh; --q: 0; --q2: 0; perspective: none; }
  .hero__depth { transform: none; perspective: none; opacity: 1; transform-style: flat; height: auto; min-height: 100svh; }
  .hero__title { --q: 0; }
  .hero__line--1, .hero__line--3, .hero__dancer, .hero__note, .hero__scribble, .hero__eyebrow, .hero__place { transform: none !important; }
  .hero__line--2 { transform: translate(-50%, -50%); opacity: 1; }
  .hero__beam--l, .hero__beam--r { animation: none; }
  .hero__lights { filter: none; transform: none; }
  .hero__cue b { animation: none; }
  .hero__cue { transform: translateX(-50%); }
  .hero__cue, .hero__note, .hero__eyebrow, .hero__place { opacity: 1; }
  html.js [data-in] { opacity: 1 !important; transform: none !important; transition: none; }

  /* the reel collapses to its contact sheet */
  .scenereel .scene__pin { display: none; }
  .srl__sheet { display: grid; }

  /* Notes credit-roll collapses to a static printed list (no --p to drive the roll) */
  .notes-credits .scene__pin { grid-template-columns: 1fr; align-content: start; }
  .nts-year, .nts-markline, .nts-rolllabel { display: none; }
  .nts-roll { height: auto; overflow: visible; -webkit-mask-image: none; mask-image: none; }
  .nts-track { transform: none; padding: 0; gap: 1.6rem; }
  .nts-credit { opacity: 1; transform: none; }

  /* Act I tableau collapses to a static, fully-lit company row + all three beats */
  .bdy-ghost, .bdy-spot, .bdy-floor, .bdy-meter, .bdy-scribble { display: none; }
  .bdy-troupe { position: static; display: flex; justify-content: center; align-items: flex-end; gap: 3vw; margin: 2rem 0 1.5rem; pointer-events: none; overflow-x: auto; }
  .bdy-figure { position: static; height: min(38svh, 20rem); filter: none; opacity: 1; transform: none; flex: 0 0 auto; }
  .bdy-figure img { height: 100%; }
  .bdy-figure figcaption { position: static; transform: none; opacity: 0.9; text-align: center; margin-top: 0.4rem; }
  .bdy-eyebrow, .bdy-beats, .bdy-caption { position: static; }
  .bdy-beats { display: block; max-width: none; margin-top: 1.5rem; }
  .bdy-beat { position: static; opacity: 1; transform: none; margin-bottom: 1.4rem; }

  .marquee__track { animation: none; }

  /* Act III lobby cards collapse to a static grid (no --p to slide the track) */
  .inv-stage { display: block; }
  .inv-case { perspective: none; overflow: visible; }
  .inv-track { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)); gap: 1rem; padding: 1.6rem var(--page) 0; transform: none; }
  .inv-card { width: auto; transform: none; opacity: 1; }
  .inv-rail { display: none; }
  .watch__iris::after { opacity: 1; }
  .watch__ghost { opacity: 0.55; }

  .plate.drift { transform: none !important; }
  html.js .plate { opacity: 1; scale: 1; transition: none; }

  html.js .reveal { opacity: 1; transform: none; transition: opacity 240ms ease; }

  .cameo.play { animation: none; opacity: 0; }
  .followspot { display: none; }

  .menu li a { transition: color 200ms ease, opacity 240ms ease; transform: none; }

  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
}

/* Restoration review: retain the staged scenes, give the quieter sections breathing room. */
html.no-js form[data-needs-js] { display: none; }
[hidden] { display: none !important; }
.followspot { display: none; }
.marquee__track, .srl__rec i, .lb-boarding i, .th-bar b i { animation: none; }
.srl__bg { transition: opacity 500ms var(--ease-out); }
.srl__bg.is-on { transform: none; }
.lb-row { transition-duration: 200ms; }
.menu, .menu.is-open { transition-duration: 200ms; }
.menu li a { transition-delay: 0ms !important; }
@media (prefers-reduced-motion: no-preference) {
  .button:active, .p2-btn:active, .inv-btn:active { transform: scale(0.97); transition-duration: 160ms; }
}

/* Mobile uses the current inv-* components, not the retired invite__* selectors. */
.hero__depth { grid-template-columns: minmax(0, 1fr); }
.hero__note { max-width: min(44rem, 100%); }
body.is-settled .hero__depth { transition: none; }
@media (max-width: 820px) {
  .inv-case { display: block; overflow-x: auto; overflow-y: hidden; perspective: none; scroll-snap-type: x proximity; }
  .inv-track { transform: none !important; padding: 1rem var(--page) 1.5rem; }
  .inv-card { transform: none !important; opacity: 1; scroll-snap-align: center; }
  .inv-scribble { display: none; }
  .inv-rail { display: none; }
}
@media (max-width: 640px) {
  .hero__note { width: calc(100% - 2rem); max-width: calc(100% - 2rem); font-size: 0.92rem; }
  .bdy-figure figcaption { white-space: normal; max-width: 9ch; font-size: 0.65rem; }
}

.lb-row > time.sr-only { position: absolute; }

@media (min-width: 821px) { .inv-stage { padding-top: 6rem; } }
.bdy-eyebrow { top: 5.5rem; }

/* The caption and scroll cue occupy a real row below the 3D stage. */
.hero { grid-template-rows: minmax(0, 1fr) auto; }
.hero__depth { min-height: 0; grid-template-rows: 1fr auto 0.45fr; padding-bottom: 2rem; }
.hero__title { font-size: clamp(2.6rem, min(10.8vw, 17svh), 12rem); }
.hero__dancer { bottom: 6rem; }
.hero__dancer img { height: min(48svh, 31rem); }
.hero__footer { position: relative; z-index: 6; width: 100%; display: grid; justify-items: center; gap: 1rem; padding: 0 var(--page) max(1.5rem, env(safe-area-inset-bottom)); }
.hero__footer .hero__note { width: 100%; max-width: 48rem; margin: 0; transform: none; }
.hero__footer .hero__cue { position: relative; inset: auto; transform: none; margin: 0; }
@media (max-width: 640px) {
  .hero__title { font-size: clamp(2.9rem, 16.5vw, 5.2rem); }
  .hero__depth { padding-top: 5rem; padding-bottom: 1.5rem; }
  .hero__dancer img { height: min(39svh, 22rem); }
  .hero__footer { gap: 0.9rem; }
  .hero__footer .hero__note { font-size: 0.9rem; line-height: 1.45; }
}
@media (prefers-reduced-motion: reduce) {
  .hero { display: block; }
  .hero__footer .hero__cue { transform: none; }
}
html.no-js .hero { display: block; }
html.no-js .hero__footer .hero__cue { transform: none; }

/* Said before the send button, not in small print underneath it. */
.doors__privacy {
  margin: 0 0 0.9rem; max-width: 52ch;
  font-size: 0.94rem; line-height: 1.55;
  color: color-mix(in oklch, var(--cream), transparent 32%);
}
.doors__privacy a { color: var(--marigold); border-bottom: 1px solid color-mix(in oklch, var(--marigold), transparent 55%); }
@media (hover: hover) and (pointer: fine) { .doors__privacy a:hover { border-color: var(--marigold); } }

/* Photography credit — quieter than the nav, louder than nothing. */
.footer__credits {
  margin-top: 0.35rem;
  font-size: 0.86rem; line-height: 1.5;
  color: color-mix(in oklch, var(--cream), transparent 45%);
}
