/* ═══════════════════════════════════════════════════════════════════════════
   05 - COMPONENTS
   Everything reusable: buttons, pills, frames, cards, forms, and the global
   chrome (preloader, header, menu, marquee, player, lightbox, cursor…).

   House rules, enforced throughout this file:
   · every interactive thing has rest / hover / focus-visible / active
   · transitions name their properties - never `transition: all`
   · nothing smaller than 44×44px is a tap target
   ═══════════════════════════════════════════════════════════════════════════ */

@layer components {

/* ───────────────────────────────────────────────────────────────────────────
   BUTTONS
   ─────────────────────────────────────────────────────────────────────────── */

.btn {
  --btn-pad-x: var(--sp-6);
  --btn-pad-y: 14px;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  min-height: var(--touch);
  padding: var(--btn-pad-y) var(--btn-pad-x);
  border-radius: var(--r-pill);
  font-family: var(--ff-ui);
  font-size: var(--fs-meta);
  font-weight: 500;
  line-height: 1;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  isolation: isolate;
  overflow: hidden;
  /* Same reason as .link-arrow: a button inside a .stack must not stretch. */
  justify-self: start;
  align-self: start;
  transition:
    color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.btn .icon { font-size: 1.15em; }

.btn:active { transform: translateY(1px); }

.btn[disabled],
.btn[aria-disabled='true'] {
  cursor: not-allowed;
  opacity: .45;
  pointer-events: none;
}

/* Filled gold - the primary action. One per viewport (§4.1). */
.btn--gold {
  background: var(--action);
  color: var(--on-action);
  border: 1px solid var(--action);
  font-weight: 600;
}

.btn--gold:hover,
.btn--gold:focus-visible {
  background: var(--action-hover);
  border-color: var(--action-hover);
}

/* Ghost - a hairline outline that fills from the bottom on hover (§7.2). */
.btn--ghost {
  border: 1px solid var(--hairline-hot);
  color: var(--gold-300);
  background: transparent;
}

.btn--ghost::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--action);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform var(--dur) var(--ease-out);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
  color: var(--on-action);
  border-color: var(--action);
}

.btn--ghost:hover::before,
.btn--ghost:focus-visible::before { transform: scaleY(1); }

/* Quiet - for secondary rows and admin-ish contexts. */
.btn--quiet {
  border: 1px solid var(--hairline);
  color: var(--ivory-200);
}

.btn--quiet:hover,
.btn--quiet:focus-visible {
  border-color: var(--hairline-hot);
  color: var(--ivory-100);
}

.btn--sm { --btn-pad-x: var(--sp-5); --btn-pad-y: 10px; font-size: var(--fs-micro); }
.btn--lg { --btn-pad-x: var(--sp-7); --btn-pad-y: 18px; }
.btn--block { width: 100%; }

/* The three-dot loading state used by the contact form (§9.6). */
.btn.is-loading { pointer-events: none; color: transparent; }

.btn.is-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 42px;
  height: 6px;
  background:
    radial-gradient(circle 3px at 3px 3px, currentColor 96%, transparent) 0 0 / 18px 6px repeat-x;
  color: var(--ink-950);
  animation: btn-dots 1s steps(3) infinite;
}

@keyframes btn-dots {
  0%   { clip-path: inset(0 100% 0 0); }
  100% { clip-path: inset(0 0 0 0); }
}

/* ───────────────────────────────────────────────────────────────────────────
   PILLS AND TAGS
   ─────────────────────────────────────────────────────────────────────────── */

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 6px 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--ink-800) 70%, transparent);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--ls-pill);
  text-transform: uppercase;
  color: var(--ivory-500);
  white-space: nowrap;
}

/* Small enough to sit two or three to a card without becoming the card. */
.pill--sm { padding: 3px 10px; gap: var(--sp-1); }

.pill--upcoming { color: var(--gold-400); border-color: var(--hairline-hot); }
.pill--sold-out { color: var(--sindoor-lift); border-color: color-mix(in srgb, var(--sindoor) 55%, transparent); }
.pill--cancelled { color: var(--ivory-500); text-decoration: line-through; }
.pill--past { color: var(--ivory-500); }
.pill--sample { color: var(--gold-400); border-color: var(--hairline-hot); }

/* Filter pills are buttons (§9.2, §9.3). */
.pill-filter {
  min-height: var(--touch);
  padding: 10px 20px;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline);
  font-size: var(--fs-meta);
  font-weight: 500;
  letter-spacing: .06em;
  color: var(--ivory-300);
  background: transparent;
  transition:
    color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out);
}

.pill-filter:hover {
  color: var(--ivory-100);
  border-color: var(--hairline-hot);
}

.pill-filter[aria-pressed='true'],
.pill-filter.is-active {
  color: var(--on-action);
  background: var(--action);
  border-color: var(--action);
  font-weight: 600;
}

.pill-filter:active { transform: translateY(1px); }

/* ───────────────────────────────────────────────────────────────────────────
   FRAMES AND ORNAMENTS (§4.4)
   ─────────────────────────────────────────────────────────────────────────── */

.frame-ornate {
  position: relative;
  isolation: isolate;
}

.frame-ornate::before {
  content: '';
  position: absolute;
  inset: 10px;
  z-index: 2;
  border: 1px solid var(--hairline);
  pointer-events: none;
}

/* Corner brackets, top-left and bottom-right only - the asymmetry is the
   point; a symmetrical frame reads as a border, not as an ornament. */
.frame-ornate::after {
  content: '';
  position: absolute;
  inset: 10px;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(var(--gold-500), var(--gold-500)) 0 0 / 14px 1px no-repeat,
    linear-gradient(var(--gold-500), var(--gold-500)) 0 0 / 1px 14px no-repeat,
    linear-gradient(var(--gold-500), var(--gold-500)) 100% 100% / 14px 1px no-repeat,
    linear-gradient(var(--gold-500), var(--gold-500)) 100% 100% / 1px 14px no-repeat;
}

.frame-ornate--tight::before,
.frame-ornate--tight::after { inset: 6px; }

.frame-ornate--none::before,
.frame-ornate--none::after { content: none; }

/* A caption strip under a framed image. */
.frame-caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--hairline);
  font-size: var(--fs-micro);
  color: var(--ivory-500);
}

/* The sympathetic string running down a timeline (§4.4). */
.taar-line {
  position: relative;
  padding-left: clamp(var(--sp-6), 6vw, var(--sp-8));
}

.taar-line::before {
  content: '';
  position: absolute;
  left: 6px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: linear-gradient(
    180deg,
    transparent 0,
    var(--hairline) 6%,
    var(--hairline) 94%,
    transparent 100%
  );
}

/* ───────────────────────────────────────────────────────────────────────────
   CARDS
   ─────────────────────────────────────────────────────────────────────────── */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  background: var(--ink-800);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  container-type: inline-size;
  transition:
    transform var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

.card:hover,
.card:focus-within {
  transform: translateY(-6px);
  border-color: transparent;
  box-shadow: var(--shadow-lift);
}

.card__media {
  position: relative;
  overflow: hidden;
  background: var(--ink-850);
}

.card__media .picture,
.card__media img {
  width: 100%;
  height: 100%;
  transition: transform var(--dur-slow) var(--ease-out);
}

.card:hover .card__media img { transform: scale(1.04); }

.card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5);
  flex: 1;
}

.card__title {
  font-family: var(--ff-display);
  font-size: clamp(1.125rem, 1rem + .4vw, 1.375rem);
  line-height: 1.2;
  color: var(--ivory-100);
  max-width: none;
}

.card__meta {
  font-size: var(--fs-meta);
  color: var(--ivory-500);
  font-variant-numeric: tabular-nums;
}

/* The pill-shaped footer strip (§8 H5). */
.card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: auto;
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--ink-850) 80%, transparent);
  font-size: var(--fs-micro);
  color: var(--ivory-500);
}

/* A whole-card link that keeps the inner links clickable. */
.card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

.card__foot a,
.card__foot button { position: relative; z-index: 2; }

/* The same lift for anything sitting on the artwork.
   .card__link::after spreads a z-index:1 sheet over the whole card so that a
   click anywhere on it opens the release - but that sheet also covered the
   play mark on the cover, which therefore could not be pressed at all. The
   foot already had this exception; the media never did. */
.card__media a,
.card__media button { z-index: 2; }

/* Narrow columns get a tighter body - a container query, not a breakpoint,
   because these cards appear in three different column widths (§14). */
@container (max-width: 280px) {
  .card__body { padding: var(--sp-4); gap: var(--sp-2); }
  .card__title { font-size: 1.0625rem; }
}

/* Small icon card used by the "pillars" grid (§8 H3) and services (§9.5). */
.mini-card {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--ink-800) 55%, transparent);
  transition: border-color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
}

.mini-card:hover {
  border-color: var(--hairline-hot);
  background: var(--ink-800);
}

.mini-card__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--hairline-hot);
  border-radius: var(--r-pill);
  color: var(--gold-500);
  font-size: 18px;
}

.mini-card__icon--lg { width: 56px; height: 56px; font-size: 22px; }

.mini-card__title {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
}

/* ───────────────────────────────────────────────────────────────────────────
   PLAY TRIGGER (§8 H1, H6)
   ─────────────────────────────────────────────────────────────────────────── */

.play-trigger {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--play-size, 72px);
  height: var(--play-size, 72px);
  border-radius: 50%;
  border: 1px solid var(--gold-500);
  color: var(--gold-300);
  background: color-mix(in srgb, var(--ink-950) 45%, transparent);
  backdrop-filter: blur(6px);
  font-size: calc(var(--play-size, 72px) * .28);
  transition:
    color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.play-trigger .icon { margin-left: .12em; }   /* optical centring of a triangle */

.play-trigger:hover,
.play-trigger:focus-visible {
  color: var(--on-action);
  background: var(--action);
  transform: scale(1.06);
}

.play-trigger:active { transform: scale(1); }

.play-trigger--lg { --play-size: 96px; }
.play-trigger--sm { --play-size: 52px; }

/* Two rings expanding on a 2.4s loop. */
.play-trigger--pulse::before,
.play-trigger--pulse::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--gold-500);
  animation: pulse-ring 2.4s var(--ease-out) infinite;
  pointer-events: none;
}

.play-trigger--pulse::after { animation-delay: 1.2s; }

@keyframes pulse-ring {
  0%   { transform: scale(1); opacity: .7; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* Cards reveal their trigger on hover. */
.play-trigger--reveal {
  position: absolute;
  inset: 0;
  margin: auto;
  opacity: 0;
  transform: scale(.9);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.card:hover .play-trigger--reveal,
.card:focus-within .play-trigger--reveal,
.play-trigger--reveal:focus-visible {
  opacity: 1;
  transform: scale(1);
}

/* Always on the artwork, dead centre, not waiting for a hover: this one is
   telling the reader the release has a film, which is worth knowing while
   scanning a row of cards rather than after touching one. Centred the same way
   --reveal is, so the two sit in exactly the same place on a card. */
.play-trigger--always {
  position: absolute;
  inset: 0;
  margin: auto;
  --play-size: 64px;
  /* Lighter in the middle than a play-trigger normally is.
     The default 45% ink over a warm sleeve, blurred by the backdrop filter,
     set as a solid brown disc on the artwork - the ring and the ripple are
     what say "film" here, so the fill only has to keep the triangle legible
     and can otherwise let the cover through.

     The blur is eased off for the same reason: at 6px it averages whatever is
     behind into one flat tone, which is most of why the middle read as a
     coloured patch rather than as a window onto the sleeve. */
  background: color-mix(in srgb, var(--ink-950) 26%, transparent);
  backdrop-filter: blur(2px);
  /* The mark draws itself. See .play-trigger--always .icon below - the
     animation lives on the triangle, not on this button, so the button itself
     holds perfectly still while the line is traced. */
}

/* The self-drawing triangle.
   The outline is one closed path carrying pathLength="100", which tells the
   browser to treat its length as 100 units whatever it really measures - so
   the dash below is exact without anyone having to measure the path. The dash
   is then one solid run of 100 with a 100 gap, and moving the offset from 100
   to 0 walks the ink around the triangle from its first corner to its last.

   dasharray and dashoffset are inherited properties, which is why setting them
   on the <svg class="icon"> reaches the <path> inside the sprite's <symbol>:
   ordinary CSS cannot select into a <use>, but inheritance crosses into it.

   The hold is deliberate. In the reference the line is traced quickly and the
   finished triangle then rests for most of the loop - about a third drawing,
   two thirds still - so it reads as a mark that occasionally redraws itself
   rather than as something permanently in motion. */
.play-trigger--always .icon {
  /* Bigger inside the ring than a play-trigger's usual .28, to match the
     proportion the reference gives it. */
  font-size: inherit;
  width: calc(var(--play-size) * .42);
  height: calc(var(--play-size) * .42);
  stroke-dasharray: 100;
  /* A gentle ease in and out, not the site's --ease-out: that curve is
     cubic-bezier(.16,1,.3,1) and spends nearly all its travel in the first
     tenth of the time, which would snap the line into place rather than draw
     it. The reference traces at a steady pace, so this stays close to one. */
  animation: play-draw 2.6s cubic-bezier(.65, 0, .35, 1) infinite;
}

@keyframes play-draw {
  0%        { stroke-dashoffset: 100; }
  34%, 100% { stroke-dashoffset: 0; }
}

/* Ground for the mark.
   A gold line on a warm sleeve is a gold line on gold. So the middle of the
   square is darkened, softly and only where the mark actually sits, and the
   traced triangle has something to be seen against whatever the cover happens
   to be. It lifts on hover, when the artwork is what the reader is looking
   at. */
.card__media--film::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;                    /* over the artwork, under the mark (z-index 2) */
  pointer-events: none;
  background: radial-gradient(closest-side at 50% 50%,
              rgba(7, 6, 5, .34), rgba(7, 6, 5, .10) 60%, transparent 76%);
  transition: opacity var(--dur) var(--ease-out);
}

.card:hover .card__media--film::after { opacity: .35; }

/* A release with no cover art sets its title in the middle of the square
   instead - which is exactly where the play mark goes. Rather than print one
   over the other, the sleeve steps back and lets the mark be the foreground.
   Nothing is lost: the title is set again, at full strength, directly below. */
.card__media--film .sleeve {
  opacity: .6;
  transition: opacity var(--dur) var(--ease-out);
}

.card:hover .card__media--film .sleeve { opacity: .9; }

/* ───────────────────────────────────────────────────────────────────────────
   PRELOADER (§7.1)
   ─────────────────────────────────────────────────────────────────────────── */

.preloader {
  position: fixed;
  inset: 0;
  z-index: var(--z-preloader);
  display: grid;
  place-content: center;
  gap: var(--sp-6);
  justify-items: center;
  background: var(--ink-950);
  transition: transform var(--dur-slow) var(--ease-in-out);
}

.preloader.is-done {
  transform: translateY(-100%);
  pointer-events: none;
}

.preloader__mark { width: clamp(88px, 16vw, 132px); color: var(--gold-500); }

.preloader__mark path,
.preloader__mark circle,
.preloader__mark line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.preloader__bar {
  width: clamp(140px, 26vw, 240px);
  height: 1px;
  background: var(--ink-600);
  overflow: hidden;
}

.preloader__fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--grad-gold);
  transition: width var(--dur) var(--ease-out);
}

.preloader__label {
  font-family: var(--ff-deva);
  font-size: 13px;
  /* No tracking: it breaks the headstroke (shirorekha) that joins a
     Devanagari word, and the name falls apart into loose glyphs. */
  letter-spacing: 0;
  color: var(--ivory-500);
}

/* ───────────────────────────────────────────────────────────────────────────
   HEADER (§7.2)
   ─────────────────────────────────────────────────────────────────────────── */

.header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition:
    height var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    backdrop-filter var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.header.is-stuck {
  height: var(--header-h-shrunk);
  background: rgba(10, 9, 8, .72);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border-bottom-color: var(--hairline);
}

/* Hidden while scrolling down past 400px, back on scroll-up. */
.header.is-hidden { transform: translateY(-100%); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  width: 100%;
}

/* ── Wordmark ── */

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--touch);
}

/* The portrait disc, cut to a circle by tools/make-brand-icons.php. It takes
   the place of the gold diamond the wordmark used to carry; the diamond's
   hover turn becomes a gold ring. alt="" because the name sits beside it. */
.wordmark__logo {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  transition: box-shadow var(--dur) var(--ease-out);
}

.wordmark:hover .wordmark__logo,
.wordmark:focus-visible .wordmark__logo { box-shadow: 0 0 0 2px var(--gold-500); }

@media (min-width: 1024px) {
  .wordmark__logo { width: 46px; height: 46px; }
}

.wordmark__text {
  display: block;
  font-family: var(--ff-display);
  font-size: clamp(1.0625rem, 1rem + .5vw, 1.375rem);
  line-height: 1;
  letter-spacing: .01em;
  color: var(--ivory-100);
}

.wordmark__deva {
  display: none;
  margin-top: 2px;
  font-family: var(--ff-deva);
  /* 13px and ivory-300 are the least it takes for bha (U+092D) to read
     apart from ma (U+092E); any smaller or dimmer and the name changes. */
  font-size: 13px;
  /* Devanagari hangs matras above the line and a halant below, so it needs
     more leading than the Latin wordmark above it or the marks clip. */
  line-height: 1.5;
  /* No tracking, for the same reason as .preloader__label. */
  letter-spacing: 0;
  color: var(--ivory-300);
}

@media (min-width: 1024px) {
  .wordmark__deva { display: block; }
}

/* ── Inline nav ── */

.nav-inline {
  display: none;
  gap: clamp(var(--sp-4), 2vw, var(--sp-6));
}

@media (min-width: 1200px) {
  .nav-inline { display: flex; }
}

.nav-inline__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch);
  font-size: var(--fs-meta);
  font-weight: 500;
  letter-spacing: .06em;
  color: var(--ivory-300);
  transition: color var(--dur) var(--ease-out);
}

.nav-inline__link:hover,
.nav-inline__link[aria-current='page'] { color: var(--ivory-100); }

/* ── Header actions ── */

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.header .btn--ghost { display: none; }

@media (min-width: 768px) {
  .header .btn--ghost { display: inline-flex; }
}

/* The 3×3 dot-grid menu trigger, visible at every breakpoint (§7.2). */
.dot-trigger {
  display: grid;
  grid-template-columns: repeat(3, 3px);
  grid-auto-rows: 3px;
  gap: 4px;
  place-content: center;
  width: var(--touch);
  height: var(--touch);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  transition: border-color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
}

.dot-trigger span {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--ivory-300);
  transition: background-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.dot-trigger:hover,
.dot-trigger:focus-visible { border-color: var(--hairline-hot); }
.dot-trigger:hover span { background: var(--gold-400); }

/* The four corner dots pull outward a hair on hover. */
.dot-trigger:hover span:nth-child(1) { transform: translate(-1px, -1px); }
.dot-trigger:hover span:nth-child(3) { transform: translate(1px, -1px); }
.dot-trigger:hover span:nth-child(7) { transform: translate(-1px, 1px); }
.dot-trigger:hover span:nth-child(9) { transform: translate(1px, 1px); }

.dot-trigger:active { background: color-mix(in srgb, var(--gold-500) 12%, transparent); }

/* ───────────────────────────────────────────────────────────────────────────
   OFF-CANVAS MENU (§7.3)
   ─────────────────────────────────────────────────────────────────────────── */

.menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  visibility: hidden;
  pointer-events: none;
}

.menu.is-open {
  visibility: visible;
  pointer-events: auto;
}

/* Two panels wiping in from the left and right, meeting at the centre. */
.menu__panel {
  position: absolute;
  inset-block: 0;
  width: 50.2%;   /* a sliver of overlap so no seam shows mid-animation */
  background: rgba(7, 6, 5, .98);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  transition: transform var(--dur-slow) var(--ease-in-out);
}

.menu__panel--l { left: 0; transform: translateX(-101%); }
.menu__panel--r { right: 0; transform: translateX(101%); }

.menu.is-open .menu__panel { transform: translateX(0); }

.menu__inner {
  position: relative;
  z-index: 2;
  height: 100%;
  display: grid;
  align-content: center;
  gap: var(--sp-7);
  padding: calc(var(--header-h) + var(--sp-6)) var(--gutter) var(--sp-7);
  overflow-y: auto;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out) 120ms;
}

.menu.is-open .menu__inner { opacity: 1; }

@media (min-width: 1024px) {
  .menu__inner {
    grid-template-columns: 58fr 42fr;
    gap: clamp(var(--sp-7), 6vw, var(--sp-10));
    align-items: center;
  }
}

/* ── Nav list ── */

.menu-nav {
  display: grid;
  gap: clamp(var(--sp-2), 1.4vw, var(--sp-4));
}

.menu-nav__item {
  opacity: 0;
  transform: translateY(24px);
}

.menu.is-open .menu-nav__item {
  animation: menu-in var(--dur-slow) var(--ease-out) forwards;
  animation-delay: calc(160ms + var(--i, 0) * var(--stagger));
}

@keyframes menu-in {
  to { opacity: 1; transform: translateY(0); }
}

.menu-nav__link {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  padding-block: var(--sp-2);
  min-height: var(--touch);
}

.menu-nav__index {
  flex: none;
  width: 2.4em;
  font-family: var(--ff-ui);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .1em;
  color: var(--ivory-500);
  transition: color var(--dur) var(--ease-out);
}

.menu-nav__label {
  font-family: var(--ff-display);
  font-size: var(--fs-h1);
  line-height: 1.02;
  letter-spacing: var(--ls-display);
  color: var(--ivory-100);
  transition: color var(--dur) var(--ease-out);
}

.menu-nav__link:hover .menu-nav__label,
.menu-nav__link:focus-visible .menu-nav__label {
  color: transparent;
  -webkit-text-stroke: 1px var(--gold-500);
  text-stroke: 1px var(--gold-500);
}

.menu-nav__link:hover .menu-nav__index,
.menu-nav__link:focus-visible .menu-nav__index { color: var(--gold-500); }

.menu-nav__link[aria-current='page'] .menu-nav__index { color: var(--gold-500); }

/* ── Preview panel ── */

.menu-aside {
  display: none;
  gap: var(--sp-6);
}

@media (min-width: 1024px) {
  .menu-aside { display: grid; align-content: center; }
}

.menu-preview {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--ink-850);
}

.menu-preview__img {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}

.menu-preview__img.is-active { opacity: 1; }

.menu-preview__img img { width: 100%; height: 100%; }

/* ── Close ── */

.menu__close {
  position: absolute;
  top: var(--sp-4);
  right: var(--gutter);
  z-index: 3;
  display: grid;
  place-items: center;
  width: var(--touch);
  height: var(--touch);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  color: var(--ivory-200);
  font-size: 16px;
  transition:
    transform var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out);
}

.menu__close:hover,
.menu__close:focus-visible {
  transform: rotate(90deg);
  color: var(--gold-400);
  border-color: var(--hairline-hot);
}

/* ───────────────────────────────────────────────────────────────────────────
   MARQUEE (§7.4)
   ─────────────────────────────────────────────────────────────────────────── */

.marquee {
  position: relative;
  overflow: hidden;
  height: 64px;
  background: var(--action);
  color: var(--on-action);
  user-select: none;
}

.marquee__track {
  display: flex;
  align-items: center;
  height: 100%;
  width: max-content;
  will-change: transform;
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-5);
  /* One side only. Each copy already ends on a dot, so padding on both sides
     put two paddings back to back at the seam between copies - a double gap
     in front of the first word every lap. With it on the start alone, the
     seam measures the same as every other gap, and a static (reduced-motion)
     band still opens with its first word off the edge. */
  padding-inline-start: var(--sp-5);
  font-family: var(--ff-display);
  font-size: clamp(1.0625rem, .9rem + .7vw, 1.625rem);
  line-height: 1;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.marquee__dot {
  width: 7px;
  height: 7px;
  background: var(--ink-900);
  transform: rotate(45deg);
  flex: none;
}

@media (max-width: 479px) {
  .marquee { height: 52px; }
}

/* ───────────────────────────────────────────────────────────────────────────
   MINI PLAYER (§7.5)
   ─────────────────────────────────────────────────────────────────────────── */

.player {
  position: fixed;
  left: var(--sp-5);
  bottom: var(--sp-5);
  z-index: var(--z-player);
  width: min(320px, calc(100vw - var(--sp-5) * 2));
  padding: var(--sp-3);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  background: var(--ink-800);
  box-shadow: var(--shadow-pop);
  transform: translateY(calc(100% + var(--sp-7)));
  opacity: 0;
  visibility: hidden;
  transition:
    transform var(--dur-slow) var(--ease-out),
    opacity var(--dur) var(--ease-out),
    visibility 0s linear var(--dur-slow);
}

.player.is-visible {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.player__top {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: var(--sp-3);
}

.player__thumb {
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--ink-700);
}

.player__meta { min-width: 0; }

.player__title {
  font-family: var(--ff-display);
  font-size: 14px;
  line-height: 1.2;
  color: var(--ivory-100);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.player__sub {
  font-size: 11px;
  line-height: 1.3;
  color: var(--ivory-500);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.player__close {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: var(--r-pill);
  color: var(--ivory-500);
  font-size: 12px;
  transition: color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
}

.player__close:hover,
.player__close:focus-visible {
  color: var(--ivory-100);
  background: var(--ink-700);
}

.player__wave {
  display: block;
  width: 100%;
  height: 28px;
  margin-block: var(--sp-3) var(--sp-2);
  opacity: .55;
}

.player__controls {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.player__btn {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  color: var(--ivory-200);
  font-size: 13px;
  transition:
    color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out);
}

.player__btn:hover,
.player__btn:focus-visible {
  color: var(--gold-400);
  border-color: var(--hairline-hot);
}

.player__btn--play {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
}

.player__btn--play:hover,
.player__btn--play:focus-visible {
  background: var(--action-hover);
  border-color: var(--action-hover);
  color: var(--on-action);
}

/* The scrub bar and its mizrab handle. */
.player__scrub {
  position: relative;
  flex: 1;
  height: var(--touch);
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;
}

.player__scrub::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  height: 2px;
  background: var(--ink-600);
  border-radius: var(--r-pill);
}

.player__progress {
  position: absolute;
  left: 0;
  height: 2px;
  width: var(--p, 0%);
  background: var(--gold-500);
  border-radius: var(--r-pill);
}

.player__handle {
  position: absolute;
  left: var(--p, 0%);
  width: 9px;
  height: 9px;
  background: var(--gold-400);
  transform: translateX(-50%) rotate(45deg);
  transition: transform var(--dur-fast) var(--ease-out);
}

.player__scrub:hover .player__handle,
.player__scrub:focus-visible .player__handle {
  transform: translateX(-50%) rotate(45deg) scale(1.35);
}

.player__time {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ivory-500);
  white-space: nowrap;
}

/* Volume popover. */
.player__volume { position: relative; }

.player__volume-pop {
  position: absolute;
  bottom: calc(100% + var(--sp-2));
  left: 50%;
  transform: translateX(-50%);
  padding: var(--sp-3);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  background: var(--ink-700);
  box-shadow: var(--shadow-pop);
}

.player__volume-pop input[type='range'] {
  width: 96px;
  accent-color: var(--gold-500);
}

@media (max-width: 640px) {
  .player {
    left: var(--sp-3);
    right: var(--sp-3);
    bottom: var(--sp-3);
    width: auto;
  }
}

/* ───────────────────────────────────────────────────────────────────────────
   LIGHTBOX (§9.3)
   ─────────────────────────────────────────────────────────────────────────── */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: rgba(7, 6, 5, .96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease-out), visibility 0s linear var(--dur);
}

.lightbox.is-open {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--gutter);
}

.lightbox__counter {
  font-size: var(--fs-meta);
  font-variant-numeric: tabular-nums;
  letter-spacing: .12em;
  color: var(--ivory-500);
}

.lightbox__stage {
  position: relative;
  display: grid;
  place-items: center;
  padding-inline: var(--gutter);
  min-height: 0;
}

.lightbox__figure {
  display: grid;
  gap: var(--sp-4);
  justify-items: center;
  max-height: 100%;
}

/* The direct child only. A film in here is a .vplayer, which brings its own
   sizing and has an <img> of its own inside it - the still - that must fill
   the frame rather than be shrunk to fit the viewer. */
.lightbox__figure > img {
  max-height: 76vh;
  max-width: 100%;
  width: auto;
  border-radius: var(--r-sm);
}

.lightbox__caption {
  max-width: 62ch;
  text-align: center;
  font-size: var(--fs-meta);
  color: var(--ivory-300);
}

.lightbox__credit {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--fs-micro);
  color: var(--ivory-500);
}

.lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  color: var(--ivory-200);
  background: color-mix(in srgb, var(--ink-900) 60%, transparent);
  transition:
    color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out);
}

.lightbox__nav:hover,
.lightbox__nav:focus-visible {
  color: var(--gold-400);
  border-color: var(--hairline-hot);
  background: var(--ink-800);
}

.lightbox__nav--prev { left: var(--sp-3); }
.lightbox__nav--next { right: var(--sp-3); }

.lightbox__strip {
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--gutter);
  overflow-x: auto;
  scrollbar-width: none;
}

.lightbox__strip::-webkit-scrollbar { display: none; }

.lightbox__thumb {
  flex: none;
  width: 64px;
  height: 48px;
  border-radius: var(--r-sm);
  overflow: hidden;
  opacity: .4;
  border: 1px solid transparent;
  transition: opacity var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}

.lightbox__thumb:hover { opacity: .8; }

.lightbox__thumb[aria-current='true'] {
  opacity: 1;
  border-color: var(--gold-500);
}

.lightbox__thumb img { width: 100%; height: 100%; }

/* ───────────────────────────────────────────────────────────────────────────
   CAROUSEL (§8 H9)
   ─────────────────────────────────────────────────────────────────────────── */

.carousel { position: relative; }

.carousel__viewport { overflow: hidden; }

.carousel__slide {
  display: grid;
  gap: var(--sp-5);
  justify-items: center;
  text-align: center;
}

.carousel__slide[hidden] { display: none; }

.carousel__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
}

.carousel__btn {
  display: grid;
  place-items: center;
  width: var(--touch);
  height: var(--touch);
  border: 1px solid var(--hairline);
  border-radius: 50%;
  color: var(--ivory-200);
  transition:
    color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.carousel__btn:hover,
.carousel__btn:focus-visible {
  color: var(--gold-400);
  border-color: var(--hairline-hot);
}

.carousel__btn--prev:hover { transform: translateX(-2px); }
.carousel__btn--next:hover { transform: translateX(2px); }

.carousel__dots {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.carousel__dot {
  display: grid;
  place-items: center;
  width: var(--touch);
  height: var(--touch);
}

.carousel__dot span {
  width: var(--dot);
  height: var(--dot);
  background: var(--ivory-700);
  transform: rotate(45deg);
  transition: background-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.carousel__dot:hover span { background: var(--ivory-500); }

.carousel__dot[aria-current='true'] span {
  background: var(--gold-500);
  transform: rotate(45deg) scale(1.3);
}

/* ───────────────────────────────────────────────────────────────────────────
   TABS AND ACCORDION (§9.4, §9.5)
   ─────────────────────────────────────────────────────────────────────────── */

.tabs {
  display: flex;
  gap: var(--sp-2);
  border-bottom: 1px solid var(--hairline);
}

.tab {
  position: relative;
  min-height: var(--touch);
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--fs-meta);
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ivory-500);
  transition: color var(--dur) var(--ease-out);
}

.tab::after {
  content: '';
  position: absolute;
  left: var(--sp-5);
  right: var(--sp-5);
  bottom: -1px;
  height: 1px;
  background: var(--gold-500);
  transform: scaleX(0);
  transition: transform var(--dur) var(--ease-out);
}

.tab:hover { color: var(--ivory-200); }

.tab[aria-selected='true'] {
  color: var(--ivory-100);
}

.tab[aria-selected='true']::after { transform: scaleX(1); }

.accordion { border-top: 1px solid var(--hairline); }

.accordion__item { border-bottom: 1px solid var(--hairline); }

.accordion__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  min-height: 64px;
  padding-block: var(--sp-4);
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
  transition: color var(--dur) var(--ease-out);
}

.accordion__summary:hover { color: var(--gold-300); }

.accordion__mark {
  position: relative;
  flex: none;
  width: 22px;
  height: 22px;
  transition: transform var(--dur) var(--ease-out);
}

.accordion__mark::before,
.accordion__mark::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--gold-500);
}

.accordion__mark::before { width: 100%; height: 1px; }
.accordion__mark::after  { width: 1px; height: 100%; }

.accordion__item[open] .accordion__mark { transform: rotate(135deg); }

.accordion__panel {
  overflow: hidden;
  padding-bottom: var(--sp-5);
  color: var(--ivory-300);
}

/* ───────────────────────────────────────────────────────────────────────────
   FORMS (§9.6)
   ─────────────────────────────────────────────────────────────────────────── */

/* A field has to look like somewhere you can type. The first version was a
   baseline and nothing else - a single hairline at 8% opacity over the page's
   own near-black - and on the contact page the whole form read as a ghost:
   labels floating in space with no telling where the typing would land. The
   control is a filled, outlined box now. The label still floats, up into the
   band that --field-pad-top reserves above it. */
.field {
  --field-pad-top: var(--sp-5);   /* the band the floated label rises into */
  --field-bg: var(--ink-700);
  --field-bg-lift: color-mix(in srgb, var(--ink-700) 88%, var(--ivory-100));
  --field-line: rgba(246, 241, 231, .16);

  position: relative;
  display: block;
  padding-top: var(--field-pad-top);
}

.field__control,
.field select,
.field textarea {
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  min-height: var(--touch);
  background: var(--field-bg);
  border: 1px solid var(--field-line);
  border-radius: var(--r-sm);
  color: var(--ivory-100);
  font-size: var(--fs-body);
  transition:
    border-color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out);
}

.field:hover .field__control,
.field:hover select,
.field:hover textarea { border-color: var(--hairline-hot); }

.field:focus-within .field__control,
.field:focus-within select,
.field:focus-within textarea {
  border-color: var(--gold-500);
  background: var(--field-bg-lift);
}

.field__control::placeholder { color: transparent; }

/* The label floats up when the field is focused or filled - CSS only. At rest
   it sits exactly where the control's own text does, so its offset is built
   from the same two paddings rather than restated as a number: a field that
   changes --field-pad-top keeps the two in step. */
.field__label {
  position: absolute;
  left: var(--sp-4);
  top: calc(var(--field-pad-top) + var(--sp-3) + 1px);
  font-size: var(--fs-body);
  color: var(--ivory-500);
  pointer-events: none;
  transform-origin: left top;
  transition:
    transform var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out),
    letter-spacing var(--dur) var(--ease-out);
}

.field__control:focus + .field__label,
.field__control:not(:placeholder-shown) + .field__label,
.field select:focus + .field__label,
.field select.has-value + .field__label,
.field textarea:focus + .field__label,
.field textarea:not(:placeholder-shown) + .field__label {
  transform: translateY(-2.05em) scale(.68);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--gold-500);
}

/* Focus. The gold border above carries it for everyone; the ring here is for
   the keyboard, and sits on the control rather than on the whole field so it
   traces the box and not the label band over it. This replaces a gold rule
   that used to wipe along the baseline - handsome, but it was the only thing
   marking focus on a control that had no edges of its own. */
.field__control:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
}

.field textarea { min-height: 9rem; line-height: 1.7; }

/* Restyled select and date, no native chrome. */
.field select {
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--gold-500) 50%),
    linear-gradient(135deg, var(--gold-500) 50%, transparent 50%);
  background-position: right 10px center, right 5px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: var(--sp-6);
}

.field select option { background: var(--ink-800); color: var(--ivory-100); }

.field input[type='date'] { color-scheme: dark; }
.field input[type='date']::-webkit-calendar-picker-indicator {
  filter: invert(72%) sepia(38%) saturate(560%) hue-rotate(9deg) brightness(92%);
  cursor: pointer;
}

/* ── The date picker (§9.6) ──────────────────────────────────────────────── */

/* The native picker is drawn by the operating system and no rule in here can
   reach inside it, so assets/js/datepicker.js replaces it with the panel
   below. Nothing here has to hide the system's own button: that script turns
   the control into a text input, which takes the indicator with it. A visitor
   whose JavaScript never arrives keeps the real date input, its icon and its
   calendar - worse looking than this, and far better than no way to give a
   date. The padding is what both of them need: room at the right end. */
.field--date .field__control { padding-right: calc(var(--sp-4) + 34px); }

.datepicker__toggle {
  position: absolute;
  right: var(--sp-2);
  bottom: 0;
  display: grid;
  place-items: center;
  width: 40px;
  height: var(--touch);
  border: 0;
  background: none;
  color: var(--gold-400);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}

.datepicker__toggle:hover { color: var(--ivory-100); }
.field--date.is-picking .datepicker__toggle { color: var(--ivory-100); }

.datepicker {
  position: absolute;
  z-index: 20;
  top: calc(100% + var(--sp-2));
  left: 0;
  width: min(20rem, calc(100vw - var(--sp-5) * 2));
  padding: var(--sp-4);
  border: 1px solid var(--hairline-hot);
  border-radius: var(--r-md);
  background: var(--ink-800);
  box-shadow: var(--shadow-lift);
}

/* Flipped by the script when the panel would fall off the bottom. */
.datepicker.is-above { top: auto; bottom: calc(100% + var(--sp-2)); }

.datepicker__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}

.datepicker__month {
  margin: 0;
  font-family: var(--ff-display);
  font-size: 1rem;
  color: var(--ivory-100);
}

.datepicker__nav {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  background: none;
  color: var(--ivory-300);
  cursor: pointer;
  transition:
    color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.datepicker__nav:hover,
.datepicker__nav:focus-visible {
  color: var(--gold-400);
  border-color: var(--hairline-hot);
}

.datepicker__grid {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.datepicker__grid th {
  padding-bottom: var(--sp-2);
  font-size: var(--fs-micro);
  font-weight: 400;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ivory-500);
}

.datepicker__grid th abbr { text-decoration: none; }

.datepicker__day {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: none;
  color: var(--ivory-300);
  font-size: var(--fs-meta);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition:
    color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

/* The days either side of the month are kept, not blanked: a six-row grid that
   never changes height is steadier than one that jumps between months. */
.datepicker__day.is-outside { color: var(--ivory-500); opacity: .45; }

.datepicker__day:hover:not(:disabled) {
  background: rgba(246, 241, 231, .08);
  color: var(--ivory-100);
}

.datepicker__day.is-today { border-color: var(--hairline-hot); }

.datepicker__day.is-selected {
  background: var(--action);
  border-color: var(--action);
  color: var(--on-action);
  opacity: 1;
}

.datepicker__day:disabled {
  color: var(--ivory-500);
  opacity: .3;
  cursor: not-allowed;
}

.datepicker__foot {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--hairline);
}

.datepicker__action {
  padding: var(--sp-1) var(--sp-2);
  border: 0;
  border-radius: var(--r-sm);
  background: none;
  color: var(--ivory-500);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}

.datepicker__action:hover,
.datepicker__action:focus-visible { color: var(--gold-400); }

@media (prefers-reduced-motion: reduce) {
  .datepicker__day,
  .datepicker__nav,
  .datepicker__toggle,
  .datepicker__action { transition: none; }
}

.field__hint,
.field__error {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--fs-micro);
  line-height: 1.5;
}

.field__hint { color: var(--ivory-500); }
.field__error { color: var(--sindoor-lift); }

.field [aria-invalid='true'] { border-color: var(--sindoor); }

/* The counter shares the label's band, at the other end of it. */
.field__counter {
  position: absolute;
  right: 0;
  top: 2px;
  font-size: var(--fs-micro);
  font-variant-numeric: tabular-nums;
  color: var(--ivory-500);
}

/* Checkbox - a mizrab that fills. */
.check {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  min-height: var(--touch);
  cursor: pointer;
  font-size: var(--fs-meta);
  color: var(--ivory-300);
}

.check input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.check__box {
  flex: none;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  border: 1px solid var(--hairline-hot);
  border-radius: 3px;
  transition: background-color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}

.check__box::after {
  content: '';
  width: 8px;
  height: 8px;
  background: var(--ink-950);
  transform: rotate(45deg) scale(0);
  transition: transform var(--dur) var(--ease-out);
}

.check input:checked + .check__box { background: var(--gold-500); border-color: var(--gold-500); }
.check input:checked + .check__box::after { transform: rotate(45deg) scale(1); }
.check input:focus-visible + .check__box { outline: var(--focus-ring); outline-offset: 3px; }

/* Honeypot (§9.6) - must not be reachable by keyboard or announced. */
.hp-field {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Inline newsletter: one field, one circular submit. */
.subscribe {
  display: flex;
  /* Bottom, not centre: the field is taller than its control by the band the
     floated label needs, and centring hung the button above the box. Both the
     button and the control are --touch tall, so their bottom edges line up. */
  align-items: flex-end;
  gap: var(--sp-3);
  max-width: 380px;
}

/* The band above the control is not a spacing choice - the floated label has
   to land in it - so this keeps the field's own. */
.subscribe .field { flex: 1; }

.subscribe__submit {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--touch);
  height: var(--touch);
  border: 1px solid var(--gold-500);
  border-radius: 50%;
  color: var(--gold-400);
  transition:
    color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.subscribe__submit:hover,
.subscribe__submit:focus-visible {
  color: var(--on-action);
  background: var(--action);
  transform: translateX(2px);
}

.form-status {
  margin-top: var(--sp-3);
  font-size: var(--fs-meta);
  min-height: 1.4em;
}

.form-status--ok { color: var(--gold-300); }
.form-status--error { color: var(--sindoor-lift); }

/* Success panel replacing the form. */
.form-success {
  display: grid;
  gap: var(--sp-5);
  justify-items: start;
  padding: clamp(var(--sp-6), 5vw, var(--sp-8));
  border: 1px solid var(--hairline-hot);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--gold-500) 5%, var(--ink-800));
}

.form-success__mark {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border: 1px solid var(--gold-500);
  border-radius: 50%;
  color: var(--gold-400);
  font-size: 20px;
}

/* ───────────────────────────────────────────────────────────────────────────
   UTILITY CHROME (§7.7)
   ─────────────────────────────────────────────────────────────────────────── */

/* Back to top with a scroll-depth progress ring. */
.to-top {
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  z-index: var(--z-sticky);
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink-800) 88%, transparent);
  backdrop-filter: blur(8px);
  color: var(--gold-400);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition:
    opacity var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out),
    visibility 0s linear var(--dur),
    color var(--dur) var(--ease-out);
}

.to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition-delay: 0s;
}

.to-top:hover { color: var(--gold-300); }

.to-top__ring {
  position: absolute;
  inset: 0;
  transform: rotate(-90deg);
}

.to-top__ring circle {
  fill: none;
  stroke-width: 1.5;
}

.to-top__track { stroke: var(--ink-600); }

.to-top__bar {
  stroke: var(--gold-500);
  stroke-linecap: round;
  transition: stroke-dashoffset 120ms linear;
}

.to-top .icon { position: relative; z-index: 1; font-size: 15px; }

/* Section-progress rail, desktop only. */
.progress-rail {
  position: fixed;
  right: var(--sp-5);
  top: 50%;
  transform: translateY(-50%);
  z-index: var(--z-sticky);
  display: none;
  flex-direction: column;
  gap: var(--sp-3);
}

@media (min-width: 1440px) {
  .progress-rail { display: flex; }
}

.progress-rail__dot {
  position: relative;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
}

.progress-rail__dot span {
  width: 5px;
  height: 5px;
  border: 1px solid var(--ivory-700);
  border-radius: 50%;
  transition: background-color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}

.progress-rail__dot[aria-current='true'] span {
  background: var(--gold-500);
  border-color: var(--gold-500);
  transform: scale(1.4);
}

.progress-rail__label {
  position: absolute;
  right: calc(100% + var(--sp-2));
  white-space: nowrap;
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ivory-500);
  opacity: 0;
  transform: translateX(6px);
  pointer-events: none;
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.progress-rail__dot:hover .progress-rail__label,
.progress-rail__dot:focus-visible .progress-rail__label {
  opacity: 1;
  transform: translateX(0);
}

/* Custom cursor - pointer-fine devices only. */
.cursor,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  will-change: transform;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.cursor {
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--gold-400);
}

.cursor-ring {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin: -16px 0 0 -16px;
  border: 1px solid var(--gold-500);
  border-radius: 50%;
  font-family: var(--ff-ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .14em;
  color: transparent;
  transition:
    width var(--dur) var(--ease-out),
    height var(--dur) var(--ease-out),
    margin var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out),
    opacity var(--dur) var(--ease-out);
}

.has-cursor .cursor,
.has-cursor .cursor-ring { opacity: 1; }

.has-cursor.cursor-link .cursor-ring {
  width: 70px;
  height: 70px;
  margin: -35px 0 0 -35px;
  background: var(--gold-veil);
}

.has-cursor.cursor-label .cursor-ring {
  width: 72px;
  height: 72px;
  margin: -36px 0 0 -36px;
  background: var(--gold-veil);
  color: var(--gold-300);
}

.has-cursor.cursor-label .cursor { opacity: 0; }

@media (hover: none), (pointer: coarse) {
  .cursor, .cursor-ring { display: none; }
}

/* Page-transition curtain (§7.7). */
.curtain {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-preloader) - 1);
  background: var(--grad-gold);
  transform: translateY(100%);
  pointer-events: none;
}

.curtain.is-in {
  animation: curtain-in var(--dur-slow) var(--ease-in-out) forwards;
}

.curtain.is-out {
  animation: curtain-out var(--dur-slow) var(--ease-in-out) forwards;
}

@keyframes curtain-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

@keyframes curtain-out {
  from { transform: translateY(0); }
  to   { transform: translateY(-100%); }
}

/* ───────────────────────────────────────────────────────────────────────────
   SOCIAL ROW
   ─────────────────────────────────────────────────────────────────────────── */

.socials {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

/* The element is the 44px target (§14); the 36px circle is drawn inside it by
   ::before. Sizing it the other way round - a 36px box with an invisible
   overlay - works in a browser but cannot be measured, and a target you cannot
   measure is a target nobody checks. */
.social {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--touch);
  height: var(--touch);
  color: var(--ivory-300);
  font-size: 15px;
  transition:
    color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.social::before {
  content: '';
  position: absolute;
  inset: 4px;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  transition: border-color var(--dur) var(--ease-out);
}

.social .icon { position: relative; }

.social:hover,
.social:focus-visible {
  color: var(--gold-400);
  transform: translateY(-2px);
}

.social:hover::before,
.social:focus-visible::before { border-color: var(--hairline-hot); }

.social:active { transform: translateY(0); }

/* Spacing so two 44px targets never overlap each other. */
.socials--pad { gap: var(--sp-2); }

/* ───────────────────────────────────────────────────────────────────────────
   PRINT
   ─────────────────────────────────────────────────────────────────────────── */

@media print {
  .header, .menu, .player, .to-top, .progress-rail, .cursor, .cursor-ring,
  .curtain, .preloader, .marquee, .lightbox, .dot-trigger, .skip-link {
    display: none !important;
  }
  .card, .mini-card { box-shadow: none; border-color: rgba(0, 0, 0, .2); break-inside: avoid; }

  /* The print block in 01-tokens flips the ground to white but leaves the ink
     scale alone, and a field's fill is taken from it - so say it here. */
  .field {
    --field-bg: #fff;
    --field-bg-lift: #fff;
    --field-line: rgba(0, 0, 0, .35);
  }
}

}

/* ───────────────────────────────────────────────────────────────────────────
   VIDEO PLAYER (§9.3)

   A YouTube film wearing this site's clothes. Three layers do the hiding, and
   each covers what the others cannot: the player parameters take away the
   control bar, the crop below takes away what has no parameter, and the
   shield makes sure a click never reaches anything underneath.
   ─────────────────────────────────────────────────────────────────────────── */

.vplayer {
  --vp-crop: 140px;             /* how much of the top and bottom edge to lose */
  --vp-max-h: 72vh;             /* the tallest the picture may stand */

  display: grid;
  justify-items: center;
  gap: var(--sp-3);

  /* The height cap is spent as width here rather than taken off the frame
     further down. A box with an aspect ratio ignores `stretch` and sizes
     itself, so capping the frame's height left it narrower than the bar
     beneath it and standing against the left edge of the room left over.
     Deriving the width from the same cap keeps picture and controls exactly
     as wide as one another, and the pair centred. */
  width: min(1100px, 92vw, calc(var(--vp-max-h) * 16 / 9));
  max-width: 100%;
  margin-inline: auto;
}

/* The frame. Everything inside is bigger than this and this hides the rest. */
.vplayer__wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: #000;
}

/* The crop.
   The iframe is built taller than its frame and the frame hides the overflow,
   so YouTube's title bar - which rides the top edge of the player - and its
   watermark along the bottom both fall outside the picture. Neither can be
   turned off by any parameter; putting them past the edge is the only way.

   Height only, deliberately. YouTube letterboxes the film inside whatever box
   it is given, so a box 140px taller than 16:9 holds the same picture at the
   same size with a 70px black band above and below - and those bands are
   exactly what the crop then removes. The film is never zoomed and nothing of
   it is lost. Growing the width too would crop the sides of the picture
   instead, which is what a hero wants (it has to cover) and a viewer does not
   (it has to show the whole frame). */
.vplayer__frame {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: calc(100% + var(--vp-crop));
  transform: translate(-50%, -50%);
  border: 0;
}

/* The still holds the frame until the film has painted, so the viewer opens on
   a picture rather than on black. */
.vplayer__still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--dur-base) var(--ease-out);
}

.vplayer.has-played .vplayer__still { opacity: 0; }

/* The shield: the whole surface, and the only thing a click can land on. */
.vplayer__shield {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--ivory-100);
}

/* The big mark in the middle. It is there while the film is stopped and gets
   out of the way while it runs - a film should be a film, not a control. */
.vplayer__big {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  border-radius: var(--r-pill);
  background: rgba(10, 9, 8, .55);
  backdrop-filter: blur(6px);
  transform: scale(1);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

.vplayer.is-playing .vplayer__big {
  opacity: 0;
  transform: scale(.9);
}

/* Coming back on hover is what makes the whole picture a pause button without
   anything sitting on it while it plays. A touch screen has no hover, so
   there the control bar below is the way in. */
.vplayer.is-playing .vplayer__shield:hover .vplayer__big,
.vplayer.is-playing .vplayer__shield:focus-visible .vplayer__big {
  opacity: 1;
  transform: scale(1);
}

/* ── the control bar ─────────────────────────────────────────────────────── */

.vplayer__bar {
  display: grid;
  gap: var(--sp-2);
  width: 100%;
}

.vplayer__seek {
  position: relative;
  height: 4px;
  border-radius: var(--r-pill);
  background: rgba(246, 241, 231, .18);
  cursor: pointer;
  touch-action: none;          /* a drag here scrubs; it must not also scroll */
}

/* A bigger target than the line is thick - four pixels is a hard thing to
   hit, and impossible with a finger. */
.vplayer__seek::before {
  content: '';
  position: absolute;
  inset: -10px 0;
}

.vplayer__seek-fill {
  position: relative;         /* the head below hangs off its END, not the bar's */
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--gold-400);
}

/* The head of the bar, so the position is readable at a glance. */
.vplayer__seek-fill::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 100%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-radius: var(--r-pill);
  background: var(--gold-400);
  transform: translateY(-50%) scale(0);
  transition: transform var(--dur-fast) var(--ease-out);
}

.vplayer__seek:hover .vplayer__seek-fill::after,
.vplayer__seek:focus-visible .vplayer__seek-fill::after {
  transform: translateY(-50%) scale(1);
}

.vplayer__row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.vplayer__btn {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ivory-300);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}

.vplayer__btn:hover,
.vplayer__btn:focus-visible {
  color: var(--ivory-100);
  background: rgba(246, 241, 231, .10);
}

.vplayer__btn--main {
  width: 42px;
  height: 42px;
  color: var(--ivory-100);
  background: rgba(246, 241, 231, .10);
}

.vplayer__time {
  margin: 0;
  font-size: var(--fs-meta);
  color: var(--ivory-500);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The clock takes the middle so sound and full screen sit at the far end,
   away from the transport controls. */
.vplayer__time { margin-inline: auto var(--sp-1); }

.vplayer__volume {
  width: 88px;
  accent-color: var(--gold-400);
  cursor: pointer;
}

/* Full screen puts the player itself on the black, not the iframe - so these
   controls go with it and YouTube's never come back. */
.vplayer:fullscreen {
  width: 100vw;
  align-content: center;
  gap: 0;
  padding: 0;
  background: #000;
}

.vplayer:fullscreen .vplayer__wrap {
  height: 100vh;
  border-radius: 0;
}

/* Over the picture rather than under it, and out of the way until wanted. */
.vplayer:fullscreen .vplayer__bar {
  position: fixed;
  inset: auto 0 0;
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
  background: linear-gradient(to top, rgba(10, 9, 8, .85), transparent);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.vplayer:fullscreen:hover .vplayer__bar,
.vplayer:fullscreen:focus-within .vplayer__bar,
.vplayer:fullscreen:not(.is-playing) .vplayer__bar { opacity: 1; }

/* A film that will not load leaves the still and says nothing. */
.vplayer.is-broken .vplayer__frame,
.vplayer.is-broken .vplayer__bar { display: none; }

.vplayer.is-broken .vplayer__still { opacity: 1; }

@media (max-width: 767px) {
  .vplayer {
    --vp-crop: 90px;           /* less picture to spare on a small screen */
    width: 100%;
  }

  .vplayer__big { width: 60px; height: 60px; }
  .vplayer__btn { width: 32px; height: 32px; }
  .vplayer__btn--main { width: 38px; height: 38px; }
  .vplayer__volume { display: none; }   /* the mute button is enough here */
}

@media (prefers-reduced-motion: reduce) {
  .vplayer__still,
  .vplayer__big,
  .vplayer__seek-fill::after,
  .vplayer:fullscreen .vplayer__bar { transition: none; }
}
