/* ═══════════════════════════════════════════════════════════════════════
   abhayvirxmedia

   Palette: cool studio neutrals with a single signal accent. The neutrals are
   biased blue rather than pure grey so they read as chosen; the orange is the
   colour of a record/render indicator and is spent only on state — active
   selection, the live dot, focus — never on decoration.

   Theming follows the three real states: bare :root carries the complete light
   palette, prefers-color-scheme handles the un-stamped default, and
   [data-theme] stamps win in both directions. Components only ever read tokens,
   so no colour is defined solely inside a media query.

   Performance: backdrop-filter appears exactly twice — the header and the
   lightbox scrim. Blurring every card is what made earlier versions stutter;
   surfaces here are solid and cost nothing to composite.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  color-scheme: light;

  --ground: #f3f4f6;
  --ground-2: #e9ebef;
  --surface: #ffffff;
  --surface-2: #fafbfc;
  --line: rgba(13, 16, 20, 0.11);
  --line-2: rgba(13, 16, 20, 0.06);

  --ink: #0d1014;
  --ink-2: #4d5563;
  --ink-3: #7b8492;

  --accent: #0b62e4;
  --accent-ink: #ffffff;
  --accent-wash: rgba(11, 98, 228, 0.09);

  --shadow-1: 0 1px 2px rgba(13, 16, 20, 0.06), 0 4px 14px rgba(13, 16, 20, 0.05);
  --shadow-2: 0 2px 6px rgba(13, 16, 20, 0.07), 0 18px 44px rgba(13, 16, 20, 0.1);
  --scrim: rgba(233, 235, 239, 0.82);

  --wrap: 1180px;
  --gut: clamp(1.25rem, 4.5vw, 3rem);
  --band: clamp(4.5rem, 11vh, 8.5rem);
  --r: 14px;
  --r-lg: 20px;

  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --press: 110ms;
}

/* un-stamped default: only the OS preference separates the two */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;

    --ground: #0b0d11;
    --ground-2: #10131a;
    --surface: #14181f;
    --surface-2: #191e26;
    --line: rgba(255, 255, 255, 0.13);
    --line-2: rgba(255, 255, 255, 0.07);

    --ink: #eef1f5;
    --ink-2: #a3acba;
    --ink-3: #737d8c;

    --accent: #4a9dff;
    --accent-ink: #0a1018;
    --accent-wash: rgba(74, 157, 255, 0.15);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 14px rgba(0, 0, 0, 0.3);
    --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.45);
    --scrim: rgba(11, 13, 17, 0.86);
  }
}

/* explicit choice wins over the OS in both directions */
:root[data-theme='dark'] {
  color-scheme: dark;
  /* accent tokens repeated below with the rest of the dark set */

  --ground: #0b0d11;
  --ground-2: #10131a;
  --surface: #14181f;
  --surface-2: #191e26;
  --line: rgba(255, 255, 255, 0.13);
  --line-2: rgba(255, 255, 255, 0.07);

  --ink: #eef1f5;
  --ink-2: #a3acba;
  --ink-3: #737d8c;

  --accent: #4a9dff;
  --accent-ink: #0a1018;
  --accent-wash: rgba(74, 157, 255, 0.15);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 14px rgba(0, 0, 0, 0.3);
  --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.45), 0 18px 44px rgba(0, 0, 0, 0.45);
  --scrim: rgba(11, 13, 17, 0.86);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* The hero reel column deliberately overflows to the right. `clip` contains
     it without creating a scroll container — `hidden` on body alone does not
     stop the root element scrolling, and `hidden` here would break
     position: sticky. */
  overflow-x: clip;
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--ground);
  color: var(--ink);
  font-family: 'Instrument Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 1rem;
  line-height: 1.6;
  overflow-x: hidden;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  touch-action: manipulation;
  transition: background-color 0.5s var(--ease-soft), color 0.5s var(--ease-soft);
}

img, video, svg { display: block; max-width: 100%; }
h1, h2, h3, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }

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

/* Mono is reserved for machine-ish data — counts, prices, dates, timecodes.
   It is a signal that a value is exact, not a decorative face. */
.mono {
  font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

:where(a, button):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ── 3D stage ───────────────────────────────────────────────────────── */

.stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s var(--ease-soft);
}
.stage.is-ready { opacity: 1; }

.blobstage {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.4s var(--ease-soft);
}
.blobstage.is-ready { opacity: 1; }

/* ── background: sheen + grain ──────────────────────────────────────
   Two fixed layers under everything. The sheen is a slow-drifting soft
   highlight that gives the page a lit surface rather than a flat fill; the
   grain is a tiny tiling SVG noise that breaks up the gradient banding and is
   what actually reads as "texture".

   Both use transform/opacity only, and the grain never animates — an animated
   full-viewport filter is the thing that would cost frames. */

.bg-sheen {
  position: fixed;
  inset: -20%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(46% 38% at 22% 14%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 68%),
    radial-gradient(40% 34% at 82% 26%, color-mix(in srgb, var(--ink) 12%, transparent), transparent 70%),
    radial-gradient(52% 44% at 64% 88%, color-mix(in srgb, var(--accent) 13%, transparent), transparent 72%);
  opacity: 0.85;
  will-change: transform;
  animation: sheen 32s var(--ease-soft) infinite alternate;
}
@keyframes sheen {
  0%   { transform: scale(1) translate3d(0, 0, 0); }
  100% { transform: scale(1.08) translate3d(-2%, 1.5%, 0); }
}

.bg-grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.4;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}
/* No mix-blend-mode, deliberately. A blend mode on a fixed full-viewport layer
   forces the compositor to re-blend the entire page on every frame anything
   moves — with rolling reels and a WebGL canvas running, that is a constant
   tax. Plain alpha costs nothing and, at this opacity, is indistinguishable. */
:root:not([data-theme='dark']) .bg-grain { opacity: 0.16; }
:root[data-theme='dark'] .bg-grain { opacity: 0.1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .bg-grain { opacity: 0.1; }
}

/* ── typographic scale ──────────────────────────────────────────────
   One scale, used everywhere. Tracking is size-specific: display sizes tighten
   as they grow (letters read too far apart at size), body sits at zero, and
   small uppercase labels open up because tight capitals at 11px are unreadable.
   A single letter-spacing value across a scale is wrong somewhere in it. */

:root {
  --t-display: clamp(2.7rem, 7.6vw, 5.8rem);
  --t-h2:      clamp(1.9rem, 4.4vw, 3.2rem);
  --t-h3:      clamp(1.15rem, 1.9vw, 1.4rem);
  --t-lead:    clamp(1.02rem, 1.5vw, 1.2rem);
  --t-body:    1rem;
  --t-small:   0.88rem;
  --t-label:   0.72rem;

  --tr-display: -0.04em;
  --tr-h2:      -0.032em;
  --tr-h3:      -0.022em;
  --tr-body:    -0.005em;
  --tr-label:   0.13em;
}

/* ── highlighted words ──────────────────────────────────────────────
   The load-bearing word in a line gets weight, the accent colour and a soft
   bloom behind it. Used sparingly — one or two per sentence. Highlighting
   everything highlights nothing. */

.hl {
  font-weight: 700;
  color: var(--accent);
  text-shadow: 0 0 22px color-mix(in srgb, var(--accent) 45%, transparent),
    0 0 44px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* on body copy the glow would smear, so it gets a tinted underlay instead */
.hl--mark {
  font-weight: 600;
  color: var(--ink);
  background: linear-gradient(
    to bottom,
    transparent 62%,
    color-mix(in srgb, var(--accent) 32%, transparent) 62%
  );
  padding: 0 0.08em;
  border-radius: 2px;
}

/* eyebrow: the smallest, quietest step — sets the top of the hierarchy */
.eyebrow {
  font-size: var(--t-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.9rem;
}

/* ── cursor ───────────────────────────────────────────────────────── */

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 80;
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
  border-radius: 50%;
  border: 1.5px solid var(--ink-3);
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transition: width 0.3s var(--ease), height 0.3s var(--ease), margin 0.3s var(--ease),
    opacity 0.25s linear, border-color 0.3s var(--ease), background-color 0.3s var(--ease);
}
.cursor.is-live { opacity: 1; }
.cursor.is-hot {
  width: 70px;
  height: 70px;
  margin: -35px 0 0 -35px;
  border-color: var(--accent);
  background: var(--accent-wash);
}
@media (hover: none), (pointer: coarse) { .cursor { display: none; } }

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

.chrome {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem var(--gut);
  background: var(--scrim);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  border-bottom: 1px solid var(--line-2);
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-decoration: none;
}
.mark__glyph {
  width: 20px;
  height: 20px;
  flex: none;
  /* currentColor drives the dark strip, so the mark inverts with the theme
     while the accent strip stays put */
  color: var(--ink);
}
.mark__x { color: var(--accent); }

.chrome__right {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* Brand badge balancing the right side of the bar, which otherwise held a
   single small toggle floating in a lot of empty space. */
.badge {
  display: block;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  overflow: hidden;
  flex: none;
  box-shadow: var(--shadow-1);
  transition: transform var(--press) var(--ease), box-shadow 0.3s var(--ease);
}
.badge svg { width: 100%; height: 100%; display: block; }
.badge:hover { transform: translateY(-1px); box-shadow: var(--shadow-2); }
.badge:active { transform: scale(0.94); }

.theme {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease), transform var(--press) var(--ease);
}
.theme:hover { color: var(--ink); border-color: var(--ink-3); }
.theme:active { transform: scale(0.92); }
.theme svg { width: 17px; height: 17px; fill: currentColor; }
.theme__moon { display: none; }
:root[data-theme='dark'] .theme__sun { display: none; }
:root[data-theme='dark'] .theme__moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .theme__sun { display: none; }
  :root:not([data-theme='light']) .theme__moon { display: block; }
}

/* ── shell ──────────────────────────────────────────────────────────── */

main { position: relative; z-index: 1; }

.wrap {
  width: min(var(--wrap), 100% - var(--gut) * 2);
  margin-inline: auto;
}

.band { padding: var(--band) 0; }
.band--last { padding-bottom: clamp(2.5rem, 6vh, 4rem); }

/* Bidirectional: the same transition runs on the way out, so scrolling back up
   feels like the page is breathing rather than snapping. */
/* Visible by default. The hidden-until-revealed state is scoped to `js-anim`,
   which only exists while the module is confirmed to be running — see the
   inline script in index.html. Without that guard a dead script means a blank
   page rather than a still one. */
.reveal { transition: opacity 0.75s var(--ease), transform 0.75s var(--ease); }
.js-anim .reveal {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
}
.js-anim .reveal.is-in { opacity: 1; transform: none; }

/* ── hover glow ─────────────────────────────────────────────────────
   One treatment shared by every panel: the border lights to the accent and a
   soft aura blooms behind it. Applied via a custom property so each component
   keeps its own resting shadow and only ADDS the glow. */

.card,
.cat,
.tier,
.step,
.contact__card,
.faq__item,
.booker__cal,
.booker__side {
  --glow: 0 0 0 0 transparent;
  box-shadow: var(--shadow-1), var(--glow);
  transition: transform 0.45s var(--ease), box-shadow 0.45s var(--ease),
    border-color 0.35s var(--ease), background-color 0.35s var(--ease);
}
.card:hover,
.cat:hover,
.tier:hover,
.step:hover,
.contact__card:hover,
.faq__item:hover,
.booker__cal:hover,
.booker__side:hover,
.card:focus-visible,
.cat:focus-visible,
.contact__card:focus-visible {
  border-color: var(--accent);
  --glow: 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent),
    0 12px 42px -10px color-mix(in srgb, var(--accent) 45%, transparent);
}
.reveal[data-delay='1'] { transition-delay: 0.07s; }
.reveal[data-delay='2'] { transition-delay: 0.14s; }
.reveal[data-delay='3'] { transition-delay: 0.21s; }
.reveal[data-delay='4'] { transition-delay: 0.28s; }

/* ── hero ───────────────────────────────────────────────────────────── */

/* The 3D rig sits centred in the lower half of the hero, so the copy is centred
   above it rather than beside it — otherwise the two compete for the middle. */
/* Copy left, reels right. The reel column is the visual anchor, so the text
   column is held to a comfortable measure rather than stretching to meet it. */
.hero {
  min-height: 96svh;
  display: grid;
  align-items: center;
  padding: clamp(6.5rem, 15vh, 9.5rem) 0 clamp(3rem, 8vh, 5rem);
}
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.8fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.hero__copy { max-width: 40rem; }

/* ── hero deck ──────────────────────────────────────────────────────
   A stack of reels, front one playing. Position is driven entirely by the
   --slot custom property, so moving a card is a single property change and the
   transition does the rest — no keyframes, no per-frame JS. */

.deck {
  position: relative;
  height: clamp(360px, 58svh, 560px);
  perspective: 1200px;
  pointer-events: none;
}

.deck__card {
  --slot: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(180px, 20vw, 268px);
  aspect-ratio: 9 / 16;
  margin: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--surface-2);
  /* each card sits further back, lower, and slightly rotated than the one in
     front of it — all derived from --slot so the fan stays even */
  transform:
    translate(-50%, -50%)
    translateX(calc(var(--slot) * -22px))
    translateY(calc(var(--slot) * 14px))
    scale(calc(1 - var(--slot) * 0.07))
    rotate(calc(var(--slot) * -3deg));
  opacity: calc(1 - var(--slot) * 0.16);
  z-index: calc(10 - var(--slot));
  box-shadow: 0 18px 50px -18px color-mix(in srgb, var(--ink) 45%, transparent);
  transition: transform 0.85s var(--ease), opacity 0.85s var(--ease),
    box-shadow 0.85s var(--ease);
}
/* Depth only — no accent ring. A 1px coloured outline on a video card reads as
   a stray blue bar down its edge, not as emphasis. */
.deck__card.is-front {
  box-shadow: 0 26px 70px -20px color-mix(in srgb, var(--ink) 55%, transparent);
}
/* the wrap to the back happens instantly, behind the other cards, so it is
   never seen travelling across the stack */
.deck__card.is-recycling { transition: none; opacity: 0; }

.deck__card .card__media { position: absolute; inset: 0; aspect-ratio: auto; }
.deck__card img,
.deck__card video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.deck__card video { opacity: 0; transition: opacity 0.5s var(--ease-soft); }
.deck__card.is-front video { opacity: 1; }

/* ── horizontal rolls ───────────────────────────────────────────────
   The one motion that has worked from the start: rows of vertical reels
   travelling sideways, alternating direction, masked at both ends so they
   emerge and vanish instead of starting and stopping.

   Pure CSS transform on a duplicated track — nothing per-frame in JS, which is
   why this is smoother than any canvas version of the same idea. */

.roll {
  position: relative;
  overflow: hidden;
  padding: 0.35rem 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.roll__track {
  display: flex;
  gap: 8px;
  width: max-content;
  will-change: transform;
  animation: rollX var(--roll-speed, 64s) linear infinite;
}
.roll--rev .roll__track { animation-direction: reverse; }
.roll:hover .roll__track { animation-play-state: paused; }

/* One third, because the track holds three copies of the set — travelling
   exactly one copy-width lands on an identical frame, so the loop is seamless. */
@keyframes rollX {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-33.3333%, 0, 0); }
}

/* ── drag layer ─────────────────────────────────────────────────────
   The auto-roll animates `.roll__track`; manual dragging transforms
   `.roll__drag`. They have to be separate elements — a single element cannot
   be CSS-animated and JS-transformed on the same property without one
   clobbering the other. */

.roll { cursor: grab; touch-action: pan-y; }
.roll.is-held { cursor: grabbing; }
.roll.is-held .roll__track { animation-play-state: paused; }

/* Scrolled out of sight: stop animating. A compositor animation is cheap but
   not free, and it keeps a very wide layer alive for no one to look at. */
.roll.is-offscreen .roll__track,
.marquee.is-offscreen .marquee__track { animation-play-state: paused; }
.roll__drag { will-change: transform; }

.roll__hint {
  margin-top: 0.9rem;
  font-size: var(--t-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Row timing mirrors the reference: alternating directions at slightly
   different speeds so the two rows never line up into one moving block. */
.showreel { display: grid; gap: 0.5rem; margin-top: clamp(2rem, 5vw, 3.2rem); }
.showreel .roll { --roll-speed: 30s; }
.showreel .roll:nth-child(2) { --roll-speed: 35s; }
.showreel .card--roll { width: clamp(168px, 19vw, 262px); }
.showreel .card--roll.card--wide { width: clamp(300px, 34vw, 466px); }

.card--roll { flex: none; }

.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-2);
  padding: 0.4em 0.9em 0.4em 0.75em;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
}
.rec {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
  animation: pulse 2.4s var(--ease-soft) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* Tracking is size-specific: display sizes tighten, body sits near zero.
   One letter-spacing value across a scale is wrong somewhere in the scale. */
/* Display: the one place weight, size and tight tracking all peak together.
   Line-height goes BELOW 1 because large type needs less leading, not more. */
.hero__title {
  margin-top: clamp(1.2rem, 2.6vw, 1.8rem);
  max-width: 15ch;
  margin-inline: auto;
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700;
  font-size: var(--t-display);
  line-height: 0.94;
  letter-spacing: var(--tr-display);
  text-wrap: balance;
}
/* second line drops in weight and colour — hierarchy inside a single sentence */
.hero__accent {
  display: block;
  font-weight: 400;
  color: var(--ink-3);
  letter-spacing: -0.035em;
}

.hero__sub {
  margin-top: clamp(1.2rem, 2.4vw, 1.7rem);
  max-width: 54ch;
  color: var(--ink-2);
  font-size: var(--t-lead);
  line-height: 1.5;
  letter-spacing: var(--tr-body);
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: clamp(1.8rem, 3.5vw, 2.4rem);
}

/* ── buttons ────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.72em 1.35em;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: transform var(--press) var(--ease), border-color 0.3s var(--ease),
    background-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.btn:hover { border-color: var(--ink-3); box-shadow: var(--shadow-2); }
.btn:active { transform: scale(0.972); }

.btn--solid {
  background: var(--ink);
  color: var(--ground);
  border-color: var(--ink);
}
.btn--solid:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.btn--block { width: 100%; }
.btn.is-disabled {
  opacity: 0.42;
  pointer-events: none;
}

.ghost {
  appearance: none;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink-2);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.42em 0.95em;
  cursor: pointer;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease), transform var(--press) var(--ease);
}
.ghost:hover { color: var(--ink); border-color: var(--ink-3); }
.ghost:active { transform: scale(0.95); }
.ghost--icon { padding: 0; width: 32px; height: 32px; display: grid; place-items: center; }
.ghost--icon svg { width: 16px; height: 16px; }

/* ── section heads ──────────────────────────────────────────────────── */

.head {
  display: grid;
  gap: 0.5rem;
  margin-bottom: clamp(2rem, 4.5vw, 3.2rem);
  max-width: 60ch;
}
.idx {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--t-label);
  color: var(--accent);
  letter-spacing: var(--tr-label);
}
.head__title {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700;
  font-size: var(--t-h2);
  line-height: 1.02;
  letter-spacing: var(--tr-h2);
  text-wrap: balance;
}
.head__note {
  color: var(--ink-2);
  font-size: var(--t-lead);
  line-height: 1.5;
  max-width: 52ch;
}

/* ── stats ──────────────────────────────────────────────────────────
   Numbers count up when they scroll into view. The mono face and tabular
   figures matter here: proportional digits jitter horizontally as they tick. */

.stats-band {
  padding: clamp(2rem, 5vh, 3.5rem) 0;
  border-block: 1px solid var(--line-2);
}
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
  margin: 0;
}
.stat { display: grid; gap: 0.15rem; }
.stat__num {
  font-size: clamp(2.4rem, 6vw, 4rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}
.stat__label {
  font-size: 0.82rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ── process ────────────────────────────────────────────────────────
   Numbered because these genuinely are sequential — step 03 cannot happen
   before step 02. Numbering that does not encode order is just decoration. */

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 0.75rem;
  counter-reset: step;
  padding: 0;
  margin: 0;
  list-style: none;
}
.step {
  padding: 1.3rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
  display: grid;
  gap: 0.4rem;
  align-content: start;
  transition: transform 0.4s var(--ease), border-color 0.3s var(--ease), box-shadow 0.35s var(--ease);
}
.step:hover { transform: translate3d(0, -3px, 0); border-color: var(--ink-3); box-shadow: var(--shadow-2); }
.step__n {
  font-size: var(--t-label);
  color: var(--accent);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
}
.step__title {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700;
  font-size: var(--t-h3);
  line-height: 1.15;
  letter-spacing: var(--tr-h3);
}
.step__body { font-size: var(--t-small); color: var(--ink-2); line-height: 1.55; }

/* ── sound gate ─────────────────────────────────────────────────────── */

.gate {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background: var(--ground);
  opacity: 0;
  transition: opacity 0.5s var(--ease-soft);
}
.gate[hidden] { display: none; }
.gate.is-open { opacity: 1; }

.gate__inner {
  display: grid;
  justify-items: center;
  gap: 1.1rem;
  text-align: center;
  padding: var(--gut);
  transform: translateY(10px);
  opacity: 0;
  transition: transform 0.7s var(--ease) 0.1s, opacity 0.7s var(--ease) 0.1s;
}
.gate.is-open .gate__inner { transform: none; opacity: 1; }

.gate__mark { width: 58px; height: 58px; color: var(--ink); }
.gate__mark svg { width: 100%; height: 100%; }
.gate__line {
  font-size: 0.86rem;
  letter-spacing: 0.02em;
  color: var(--ink-2);
}
.gate__row {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  justify-content: center;
  animation: gateIn 0.5s var(--ease);
}
.gate__row[hidden] { display: none; }
@keyframes gateIn {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }
  to   { opacity: 1; transform: none; }
}

/* loading readout — a real percentage, not a fake timer */
.gate__load { display: grid; gap: 0.55rem; justify-items: center; width: min(260px, 70vw); }
.gate__bar {
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}
.gate__bar span {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width 0.35s var(--ease-soft);
}
.gate__pct { font-size: var(--t-label); color: var(--ink-3); letter-spacing: var(--tr-label); }
.gate__load.is-done { opacity: 0; transition: opacity 0.35s var(--ease-soft); }

/* ── sound toggle ───────────────────────────────────────────────────── */

.snd-off { display: none; }
.theme[aria-pressed='false'] .snd-on { display: none; }
.theme[aria-pressed='false'] .snd-off { display: block; }
#soundToggle[aria-pressed='true'] { color: var(--accent); border-color: var(--accent); }

/* ── reels gallery ──────────────────────────────────────────────────── */

.views {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1rem;
}
.view {
  appearance: none;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 500;
  padding: 0.45em 1em;
  border-radius: 999px;
  cursor: pointer;
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
    background-color 0.3s var(--ease), transform var(--press) var(--ease);
}
.view:hover { color: var(--ink); border-color: var(--ink-3); }
.view:active { transform: scale(0.95); }
.view.is-on {
  color: var(--accent-ink);
  background: var(--ink);
  border-color: var(--ink);
}
.views__hint {
  margin-left: auto;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Already a direct child of the section, so it is full-width without help.
   The usual `width:100vw; margin-inline:calc(50% - 50vw)` full-bleed trick is
   wrong here — 100vw counts the scrollbar the content box does not, which
   pushes the page into horizontal scroll. */
/* ── view toggle (retired) ──────────────────────────────────────────
   The spiral/wall switch is gone; the rows are the gallery now. Rules kept
   only so any stray markup does not fall back to unstyled defaults. */
.views { display: none; }

/* ── marquee ────────────────────────────────────────────────────────── */

.marquee {
  --speed: 78s;
  position: relative;
  overflow: hidden;
  padding: 0.45rem 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee__track {
  display: flex;
  gap: 0.9rem;
  width: max-content;
  will-change: transform;
  animation: slide var(--speed) linear infinite;
}
.marquee--reverse .marquee__track { animation-direction: reverse; }
.marquee:hover .marquee__track { animation-play-state: paused; }

@keyframes slide {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.marquee .card { width: clamp(158px, 19vw, 226px); flex: none; }
.marquee .card--wide { width: clamp(280px, 34vw, 402px); }

/* ── liquid-glass note ──────────────────────────────────────────────
   The one genuinely translucent element in the body. It stays a small pill
   rather than a full-width panel on purpose: backdrop-filter cost scales with
   the blurred area, so a 500px pill is affordable where a banner would not be.

   The Apple read comes from three layers, not the blur alone — a bright top
   edge where light catches the lip, a soft inner glow, and a shadow that sits
   under it so it reads as floating above the page rather than cut into it. */

.note-glass {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: fit-content;
  max-width: 100%;
  margin: clamp(1.6rem, 4vw, 2.6rem) auto 0;
  padding: 0.72rem 1.4rem;
  border-radius: 999px;
  font-size: clamp(0.86rem, 1.25vw, 0.98rem);
  text-align: center;
  color: var(--ink);
  background: color-mix(in srgb, var(--surface) 62%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  backdrop-filter: blur(18px) saturate(180%);
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  box-shadow: 0 1px 0 color-mix(in srgb, #fff 65%, transparent) inset,
    0 -1px 0 color-mix(in srgb, var(--ink) 6%, transparent) inset,
    0 10px 30px -12px color-mix(in srgb, var(--ink) 30%, transparent);
}

/* the wet lip — a hairline of light along the top curve */
.note-glass::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, #fff 80%, transparent),
    transparent 45%,
    color-mix(in srgb, var(--accent) 22%, transparent)
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0.9;
}

.note-glass__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
  background: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 16%, transparent);
}
.note-glass__soft { color: var(--ink-3); }

@media (prefers-reduced-transparency: reduce) {
  .note-glass {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--surface);
  }
  .note-glass::before { display: none; }
}

/* ── cards ──────────────────────────────────────────────────────────── */

.card {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  background: var(--surface-2);
  box-shadow: var(--shadow-1);
  cursor: pointer;
  appearance: none;
  font: inherit;
  color: inherit;
  transition: transform 0.45s var(--ease), box-shadow 0.45s var(--ease), border-color 0.3s var(--ease);
}
.card:hover, .card:focus-visible {
  transform: translate3d(0, -4px, 0);
  box-shadow: var(--shadow-2);
  border-color: var(--ink-3);
}
.card:active, .grid .card.is-in:active {
  transform: scale(0.984);
  transition-duration: var(--press);
}

.card__media {
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: var(--ground-2);
}
.card--wide .card__media { aspect-ratio: 16 / 9; }

.card__media video,
.card__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card__media video { opacity: 0; transition: opacity 0.45s var(--ease-soft); }
.card.is-playing .card__media video { opacity: 1; }

.card__fallback[hidden] { display: none; }
.card__fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  color: var(--ink-3);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.card__play {
  position: absolute;
  right: 0.55rem;
  bottom: 0.55rem;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  opacity: 0;
  transform: scale(0.85);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  pointer-events: none;
}
.card__play svg { width: 12px; height: 12px; margin-left: 2px; fill: var(--ink); }
.card:hover .card__play, .card:focus-visible .card__play { opacity: 1; transform: scale(1); }

/* ── categories ─────────────────────────────────────────────────────── */

.cats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(238px, 1fr));
  gap: 0.75rem;
}

.cat {
  appearance: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  padding: 1.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
  transition: border-color 0.3s var(--ease), box-shadow 0.35s var(--ease);
}
.cat:hover { border-color: var(--ink-3); box-shadow: var(--shadow-2); }
.cat[aria-expanded='true'] {
  border-color: var(--accent);
  background: var(--accent-wash);
}
.cat--all { grid-column: 1 / -1; }

.cat__name {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700;
  font-size: var(--t-h3);
  line-height: 1.15;
  letter-spacing: var(--tr-h3);
}
.cat__blurb { color: var(--ink-2); font-size: var(--t-small); line-height: 1.55; }
.cat__foot {
  margin-top: auto;
  padding-top: 0.9rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-top: 1px solid var(--line-2);
}
.cat__count { font-size: 0.75rem; color: var(--ink-3); }
.cat__open { font-size: 0.78rem; font-weight: 500; color: var(--accent); }

/* ── panel + grid ───────────────────────────────────────────────────── */

.panel { margin-top: 1.5rem; overflow-anchor: none; }
.panel[hidden] { display: none; }

.panel__bar {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
  padding-bottom: 0.9rem;
  margin-bottom: 1.2rem;
  border-bottom: 1px solid var(--line);
}
.panel__title {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: -0.02em;
}
.panel__count { font-size: 0.75rem; color: var(--ink-3); }
.panel__bar .ghost { margin-left: auto; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(196px, 100%), 1fr));
  gap: 0.75rem;
  overflow-anchor: none;
}
.grid .card--wide { grid-column: span 2; }
/* Last resort, set by the reveal failsafe. Removing `js-anim` alone is not
   enough for an element already mid-transition: the transition keeps ownership
   of the property and, if it is not advancing, holds it at 0. `transition:
   none` hands the value back to the cascade immediately. */
.js-dead .reveal,
.js-dead .grid .card {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* Same guard as .reveal — hidden only while the module is confirmed running. */
.js-anim .grid .card {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
}
.js-anim .grid .card.is-in { opacity: 1; transform: none; }
.grid .card:hover { transform: translate3d(0, -4px, 0); }

/* ── pricing ────────────────────────────────────────────────────────── */

.tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr));
  gap: 0.75rem;
}

.tier {
  padding: 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
  position: relative;
}
.tier--featured { border-color: var(--accent); }
.tier__flag {
  position: absolute;
  top: -1px;
  right: 1.1rem;
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  padding: 0.28em 0.6em;
  border-radius: 0 0 7px 7px;
  background: var(--accent);
  color: var(--accent-ink);
}
.tier__name {
  font-size: 0.74rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-3);
}
.tier__price {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: clamp(1.7rem, 3.4vw, 2.3rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.tier__price.is-text { font-size: clamp(1.05rem, 2vw, 1.3rem); }
.tier__unit { font-size: 0.78rem; color: var(--ink-3); }
.tier__blurb { font-size: 0.9rem; color: var(--ink-2); }
.tier__list {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding-top: 0.9rem;
  margin-top: auto;
  border-top: 1px solid var(--line-2);
}
.tier__list li {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  font-size: 0.85rem;
  color: var(--ink-2);
  line-height: 1.45;
}
.tier__list svg { width: 13px; height: 13px; flex: none; margin-top: 0.3em; color: var(--accent); }

/* ── booking ────────────────────────────────────────────────────────── */

.booker {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
}

.booker__cal,
.booker__side {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: 1.2rem;
}

.booker__side { display: flex; flex-direction: column; gap: 0.75rem; min-height: 100%; }

.cal__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.cal__month { font-size: 0.9rem; font-weight: 500; }

.cal__dow,
.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.cal__dow {
  margin-bottom: 6px;
  font-size: 0.68rem;
  color: var(--ink-3);
  text-align: center;
}

.day {
  appearance: none;
  font: inherit;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.86rem;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease),
    border-color 0.2s var(--ease), transform var(--press) var(--ease);
}
.day:hover:not(:disabled) { background: var(--ground-2); }
.day:active:not(:disabled) { transform: scale(0.9); }
.day:disabled { color: var(--ink-3); opacity: 0.38; cursor: default; }
.day--empty { pointer-events: none; }
.day[aria-pressed='true'] {
  background: var(--ink);
  color: var(--ground);
  border-color: var(--ink);
}
/* today reads as a marker, not a selection */
.day--today:not([aria-pressed='true']) { border-color: var(--accent); color: var(--accent); }

.booker__label {
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
}

.zone {
  appearance: none;
  font: inherit;
  font-size: 0.88rem;
  width: 100%;
  padding: 0.55em 2.2em 0.55em 0.8em;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  transition: border-color 0.3s var(--ease);
}
.zone:hover { border-color: var(--ink-3); }

/* Studio hours run 04:00–23:00, so the slot list is long — cap it and scroll
   rather than pushing the confirm button off the bottom of the card. */
.slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 5px;
  max-height: 268px;
  overflow-y: auto;
  padding-right: 2px;
  scrollbar-width: thin;
}
.slot--shift { display: grid; line-height: 1.15; }
.slot--shift em {
  font-style: normal;
  font-size: 0.62rem;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.slot[aria-pressed='true'] em { color: inherit; opacity: 0.8; }
.slot {
  appearance: none;
  font: inherit;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  padding: 0.55em 0.3em;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease),
    border-color 0.2s var(--ease), transform var(--press) var(--ease);
}
.slot:hover { border-color: var(--ink-3); }
.slot:active { transform: scale(0.94); }
.slot[aria-pressed='true'] {
  background: var(--ink);
  color: var(--ground);
  border-color: var(--ink);
}
.slots:empty::after {
  content: 'Pick a date first';
  grid-column: 1 / -1;
  color: var(--ink-3);
  font-size: 0.85rem;
}

.booker__foot {
  margin-top: auto;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line-2);
  display: grid;
  gap: 0.65rem;
}
.booker__pick { font-size: 0.85rem; color: var(--ink-2); }
.booker__pick strong { color: var(--ink); font-weight: 600; }

/* ── FAQ ────────────────────────────────────────────────────────────
   Native <details>: keyboard accessible, searchable with ctrl-F, and open
   without JS. The +/− is drawn from two pseudo-element bars so there is no icon
   file and it animates cleanly. */

.faq { display: grid; gap: 0.6rem; }

.faq__item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  padding: 1.05rem 1.25rem;
  cursor: pointer;
  list-style: none;
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 600;
  font-size: var(--t-h3);
  line-height: 1.3;
  letter-spacing: var(--tr-h3);
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }

.faq__sign {
  position: relative;
  width: 15px;
  height: 15px;
  flex: none;
  color: var(--accent);
}
.faq__sign::before,
.faq__sign::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.8px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.35s var(--ease);
}
.faq__sign::after { transform: rotate(90deg); }
.faq__item[open] .faq__sign::after { transform: rotate(0deg); }

.faq__a {
  padding: 0 1.25rem 1.15rem;
  color: var(--ink-2);
  font-size: var(--t-small);
  line-height: 1.65;
  max-width: 68ch;
}
.faq__item[open] .faq__a { animation: faqIn 0.4s var(--ease); }
@keyframes faqIn {
  from { opacity: 0; transform: translate3d(0, -6px, 0); }
  to   { opacity: 1; transform: none; }
}

/* ── contact ────────────────────────────────────────────────────────── */

.contact {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.75rem;
}
.contact__card {
  display: grid;
  gap: 0.2rem;
  padding: 1.3rem;
  text-decoration: none;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
  position: relative;
  transition: transform 0.4s var(--ease), border-color 0.3s var(--ease), box-shadow 0.35s var(--ease);
}
.contact__card:hover { transform: translate3d(0, -3px, 0); border-color: var(--ink-3); box-shadow: var(--shadow-2); }
.contact__card:active { transform: scale(0.985); transition-duration: var(--press); }
.contact__kind { font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.contact__value { font-size: clamp(0.98rem, 1.7vw, 1.18rem); font-weight: 500; letter-spacing: -0.015em; overflow-wrap: anywhere; }
.contact__go {
  position: absolute;
  top: 1.3rem;
  right: 1.3rem;
  color: var(--accent);
  transition: transform 0.35s var(--ease);
}
.contact__card:hover .contact__go { transform: translateX(4px); }

.foot {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--line-2);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.4rem;
  justify-content: space-between;
  font-size: 0.8rem;
  color: var(--ink-3);
}

/* ── booking review sheet ───────────────────────────────────────────── */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 2.5rem);
  background: var(--scrim);
  -webkit-backdrop-filter: blur(0px);
  backdrop-filter: blur(0px);
  opacity: 0;
  transition: opacity 0.3s var(--ease-soft), backdrop-filter 0.4s var(--ease-soft),
    -webkit-backdrop-filter 0.4s var(--ease-soft);
}
.sheet[hidden] { display: none; }
.sheet.is-open {
  opacity: 1;
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  backdrop-filter: blur(20px) saturate(150%);
}

.sheet__panel {
  position: relative;
  width: min(100%, 440px);
  max-height: 88svh;
  overflow-y: auto;
  padding: clamp(1.4rem, 3vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  transform: translateY(14px) scale(0.97);
  transition: transform 0.42s var(--ease);
}
.sheet.is-open .sheet__panel { transform: none; }

.sheet__close { position: absolute; top: 0.8rem; right: 0.8rem; width: 34px; height: 34px; }
.sheet__close svg { width: 15px; height: 15px; }

.sheet__body { display: grid; gap: 0.85rem; }
.sheet__heading {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.35rem;
  letter-spacing: -0.025em;
}

.sheet__rows {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0.9rem 0;
  border-block: 1px solid var(--line-2);
}
.sheet__rows > div { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; }
.sheet__rows dt { font-size: 0.8rem; color: var(--ink-3); }
.sheet__rows dd { margin: 0; font-size: 0.85rem; text-align: right; }

.field { display: grid; gap: 0.3rem; }
.field > span { font-size: 0.78rem; color: var(--ink-3); }
.field input,
.field textarea {
  font: inherit;
  font-size: 0.9rem;
  width: 100%;
  padding: 0.6em 0.75em;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  resize: vertical;
  transition: border-color 0.25s var(--ease);
}
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-3); }
.field input:focus,
.field textarea:focus { outline: none; border-color: var(--accent); }

/* Secondary hand-off. Quieter than the WhatsApp button so the pair reads as one
   primary choice with a fallback, not two competing ones. */
.sheet__alt { margin-top: 0.55rem; }
.sheet__fine { font-size: 0.76rem; color: var(--ink-3); line-height: 1.5; margin-top: 0.7rem; }

.field__req { font-style: normal; color: var(--ink-3); font-weight: 400; }

.sheet__error {
  font-size: 0.8rem;
  color: var(--accent);
  padding: 0.5em 0.75em;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: 9px;
  background: var(--accent-wash);
}
.sheet__error[hidden] { display: none; }

#bookSend:disabled { opacity: 0.55; pointer-events: none; }

/* the confirmation state swaps in once the visitor hands off to their mail app */
.sheet__done { display: none; text-align: center; gap: 0.6rem; padding: 1rem 0 0.5rem; }
.sheet.is-sent .sheet__body { display: none; }
.sheet.is-sent .sheet__done { display: grid; justify-items: center; }
.sheet__tick {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--accent-ink);
  background: var(--accent);
}
.sheet__tick svg { width: 24px; height: 24px; }
.sheet__done h3 {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: -0.02em;
}
.sheet__done p { font-size: 0.88rem; color: var(--ink-2); max-width: 30ch; }

/* ── lightbox ───────────────────────────────────────────────────────── */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: var(--scrim);
  -webkit-backdrop-filter: blur(0px);
  backdrop-filter: blur(0px);
  opacity: 0;
  transition: opacity 0.3s var(--ease-soft), backdrop-filter 0.4s var(--ease-soft),
    -webkit-backdrop-filter 0.4s var(--ease-soft);
}
.lightbox[hidden] { display: none; }
.lightbox.is-open {
  opacity: 1;
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  backdrop-filter: blur(22px) saturate(150%);
}

/* flies from the card that opened it — main.js seeds --from */
.lightbox__stage {
  width: min(100%, 430px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  padding: 0.55rem;
  transform: var(--from, scale(0.95) translateY(10px));
  transition: transform 0.44s var(--ease);
  will-change: transform;
}
.lightbox.is-wide .lightbox__stage { width: min(100%, 980px); }
.lightbox.is-open .lightbox__stage { transform: none; }

.lightbox__stage video {
  width: 100%;
  max-height: min(70svh, 800px);
  border-radius: 12px;
  background: var(--ground-2);
}
.lightbox__meta { padding: 0.75rem 0.5rem 0.3rem; }
.lightbox__meta h3 { font-size: 1rem; font-weight: 600; letter-spacing: -0.015em; }
.lightbox__meta p { font-size: 0.84rem; color: var(--ink-2); }

.lightbox__close {
  position: absolute;
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 3vw, 2rem);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  transition: transform 0.35s var(--ease), border-color 0.3s var(--ease);
}
.lightbox__close:hover { transform: rotate(90deg); border-color: var(--ink-3); }
.lightbox__close:active { transform: rotate(90deg) scale(0.92); }
.lightbox__close svg { width: 18px; height: 18px; }

/* ── responsive ─────────────────────────────────────────────────────── */

@media (max-width: 1000px) {
  /* stacked: copy first, deck beneath and centred */
  .hero__grid { grid-template-columns: 1fr; }
  .hero__copy { max-width: none; }
  .deck { height: clamp(320px, 46svh, 440px); margin-top: clamp(1.5rem, 5vw, 2.5rem); }
}

@media (max-width: 900px) {
  .booker { grid-template-columns: 1fr; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }
  .tiers { grid-template-columns: repeat(2, 1fr); }
  .reelstage { height: clamp(420px, 62svh, 620px); }
}

@media (max-width: 640px) {
  .hero { min-height: auto; padding-top: clamp(6rem, 15vh, 8rem); }
  .grid { grid-template-columns: repeat(2, 1fr); }
  .grid .card--wide { grid-column: span 2; }
  .tiers, .cats, .contact { grid-template-columns: 1fr; }
  .row .btn { flex: 1 1 100%; }
  .marquee { --speed: 48s; }
  .slots { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 340px) {
  .grid { grid-template-columns: 1fr; }
  .grid .card--wide { grid-column: span 1; }
}

/* ── accessibility fallbacks ────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal, .grid .card { opacity: 1 !important; transform: none !important; }
  .rail__track, .bg-sheen { animation: none; }
  .cursor, .blobstage { display: none; }
  .lightbox { transition: opacity 200ms ease !important; }
  .lightbox__stage { transform: none !important; }
}

@media (prefers-reduced-transparency: reduce) {
  .chrome, .lightbox, .sheet { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .chrome { background: var(--surface); }
  .lightbox, .sheet { background: var(--ground); }
  .hero__reels { -webkit-mask-image: none; mask-image: none; }
  .bg-grain { display: none; }
}

@media (prefers-contrast: more) {
  :root { --line: rgba(13, 16, 20, 0.55); --ink-2: #22262e; --ink-3: #3d444f; }
  :root[data-theme='dark'] { --line: rgba(255, 255, 255, 0.6); --ink-2: #dfe4ea; --ink-3: #b9c1cb; }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) { --line: rgba(255, 255, 255, 0.6); --ink-2: #dfe4ea; --ink-3: #b9c1cb; }
  }
  .card, .cat, .tier, .contact__card, .booker__cal, .booker__side { border-width: 2px; }
}
