/* ===========================================================
   BO Musik — DJ Bernard Ollivier
   Dark re-key of the v3 handoff. Geometry, type and copy are
   the approved design; only the colour ground is inverted so
   the four film pieces sit native instead of as bright holes.
   Radius is 0 everywhere. No exceptions.
   =========================================================== */

:root {
  /* Ground */
  --ground:      #0c0d14;   /* page — matches the Archive film bed */
  --ground-2:    #12131c;   /* raised band, chips */
  --ground-3:    #1a1b26;   /* input wells */

  /* Ink is now light */
  --ink:         #f2efe6;
  --ink-70:      rgba(242, 239, 230, .70);
  --ink-55:      rgba(242, 239, 230, .55);
  --ink-40:      rgba(242, 239, 230, .40);

  /* Rules do the organising — same 2px geometry, inverted */
  --rule:        rgba(242, 239, 230, .62);
  --rule-soft:   rgba(242, 239, 230, .18);

  /* --- Brand: sampled from his own BO Musik logo (see films/shush/bo-lockup.js).
     These are the colours in the films. The handoff's teal #0f9ba3 was a duller
     stand-in for the cyan and appeared nowhere in his branding — replaced, and
     it reads far harder on the dark ground (11.7:1 against 5.76:1). --- */
  --cyan:        #3bdde6;   /* the logo's own blue-green — live/now signals */
  --lime:        #c9f27a;   /* the equaliser bars — "on air" */
  --pale:        #dfffb4;

  /* --- Era coding, kept from the handoff: these say "1980s poster" and
     they earn their place --- */
  --pink:        #e5245e;   /* display type + swatches — large, so AA-fine */
  --pink-lit:    #f0396e;   /* small pink text — AA on ground */
  --pink-deep:   #a80d40;   /* pink SURFACES that carry text. On #e5245e the
                               handoff's own cream is 3.97:1 and its gold stars
                               2.74:1 — both fail. Deepened: 6.73 and 4.64. */
  --tangerine:   #f4801f;
  --gold:        #ffc21a;
  --plum:        #35194c;
  --teal-deep:   #0a5158;   /* booking field — AA with cream */
  --action:      #ec3013;
  --action-hover:#ff4a2a;

  --container:   1180px;
  --font: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* the archive film's own typeface — the site's "record" voice: dates,
     times, stamps, phone numbers. Archivo stays the poster voice. */
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

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

html { scroll-behavior: smooth; scroll-padding-top: 66px; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
button { font: inherit; color: inherit; border-radius: 0; cursor: pointer; }
a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--action);
  outline-offset: 2px;
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 20px;
}

/* ---------- 44px touch targets ----------
   Drawn as a centred pseudo-element rather than real padding: the design's
   geometry (chip and button padding) stays exactly as specified, and the
   header does not reflow. */
.nav a, .brand, .chip--tel, .type-chip, .event__poster,
.lightbox__bar button, .toast__bar a, .toast__bar button { position: relative; }
.nav a::after, .brand::after, .chip--tel::after, .type-chip::after,
.lightbox__bar button::after,
.toast__bar a::after, .toast__bar button::after {
  content: "";
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 100%; height: 100%;
  min-width: 44px; min-height: 44px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--gold); color: #0c0d14;
  padding: 12px 16px; font-weight: 800; text-decoration: none;
}
.skip:focus { left: 0; }

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

/* ---------- shared type ---------- */

.kicker {
  font-weight: 800; font-size: 11px; letter-spacing: .2em;
  text-transform: uppercase; margin: 0 0 10px;
}

.h1 {
  font-weight: 900; font-size: clamp(38px, 6vw, 84px);
  line-height: .86; letter-spacing: -.045em; text-transform: uppercase;
  margin: 0;
}
.h2 {
  font-weight: 900; font-size: clamp(34px, 5.5vw, 60px);
  line-height: .9; letter-spacing: -.04em; text-transform: uppercase;
  margin: 0;
}
.h3 {
  font-weight: 900; font-size: clamp(20px, 2.6vw, 30px);
  line-height: 1.02; letter-spacing: -.03em; text-transform: uppercase;
  margin: 0 0 8px;
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: space-between;
  gap: 14px; border: 2px solid transparent; text-decoration: none;
  font-weight: 800; text-transform: uppercase;
  transition: background .17s ease, color .17s ease, border-color .17s ease;
}
.btn svg { flex: none; }

.btn--primary {
  background: var(--action); color: #0c0d14;
  padding: 16px 20px; font-size: 14px; letter-spacing: .06em;
}
.btn--primary:hover { background: var(--action-hover); }

.btn--ghost {
  background: transparent; color: var(--ink);
  border-color: var(--rule);
  padding: 16px 20px; font-size: 14px; letter-spacing: .06em;
}
.btn--ghost:hover { background: var(--gold); color: #0c0d14; border-color: var(--gold); }

.btn--ink {
  background: var(--ink); color: #0c0d14;
  padding: 13px 16px; font-size: 12px; letter-spacing: .08em;
}
.btn--ink:hover { background: var(--action); color: #0c0d14; }

/* ---------- header ---------- */

.header {
  position: sticky; top: 0; z-index: 50;
  height: 66px; background: var(--ground);
  border-bottom: 2px solid var(--rule);
}
.header__in {
  height: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
}
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.brand__mark {
  width: 34px; height: 34px; background: var(--pink-deep); color: #f7f2e8;
  display: grid; place-items: center;
  font-weight: 900; font-size: 13px; letter-spacing: .02em;
}
.brand__name {
  font-weight: 900; font-size: 15px; text-transform: uppercase; letter-spacing: -.01em;
}
.nav { display: flex; align-items: center; gap: 22px; }
.nav a {
  font-weight: 700; font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; text-decoration: none;
  transition: color .16s ease;
}
.nav a:hover { color: var(--pink-lit); }
.nav__cta {
  background: var(--action); color: #0c0d14;
  padding: 11px 15px; font-weight: 800; font-size: 12px;
  letter-spacing: .12em; text-transform: uppercase; text-decoration: none;
  transition: background .16s ease;
}
.nav__cta:hover { background: var(--action-hover); }
@media (max-width: 860px) { .nav { gap: 18px; } .nav__agenda { display: none; } }
/* Below 640 the three text links no longer fit beside the wordmark and the
   CTA. Brand + Réserver only — the sections are a scroll away. */
@media (max-width: 640px) {
  .nav { gap: 12px; }
  .nav a:not(.nav__cta) { display: none; }
  .brand__name { font-size: 13.5px; }
  .brand { gap: 10px; }
  .nav__cta { padding: 11px 13px; letter-spacing: .08em; }
}

/* ---------- hero ----------
   Title block, then the film full width at 16:9, then the offer. */

.hero { border-bottom: 2px solid var(--rule); }

.hero__title { padding: 30px 20px 26px; }
/* two lines, each its own block — the surname must never break */
.hero__title .h1 span { display: block; white-space: nowrap; }

.hero__stage {
  position: relative; overflow: hidden;
  /* width:100% is load-bearing. With aspect-ratio and only a max-height, the
     box shrinks its WIDTH to keep the ratio and leaves a black gap beside it. */
  width: 100%; aspect-ratio: 16 / 9;
  background: #05060a;                 /* the film's own bed — never a colour
                                          that could flash before it paints */
  border-top: 2px solid var(--rule); border-bottom: 2px solid var(--rule);
  display: flex; align-items: flex-end; justify-content: flex-start;
}
/* must match the aspect js hands the film — see data-film-narrow */
@media (max-width: 760px) {
  .hero__stage { width: 100%; aspect-ratio: 9 / 16; justify-content: center; }
  .hero__portrait { max-width: 88%; margin-left: 0; }
}

.hero__offer {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px 34px; align-items: center;
  padding-top: 28px; padding-bottom: 34px;
}

.hero .kicker { color: var(--cyan); font-size: 12px; }
.hero__h1--pink { color: var(--pink); }
.hero__lead {
  font-size: clamp(17px, 2.2vw, 21px); font-weight: 500; line-height: 1.3;
  max-width: 26ch; margin: 0 0 10px;
}
.hero__sub { font-size: 14px; color: var(--ink-55); max-width: 40ch; margin: 0; }
.hero__btns { display: flex; flex-wrap: wrap; gap: 12px; }
@media (min-width: 761px) { .hero__btns { justify-content: flex-end; } }

/* The still under the hero is the film's OWN first frame — same photograph,
   same black, roughly the same place in the frame. Whatever the loading state,
   nothing appears that is not part of the film. The mock's sunburst panel,
   mirror ball and "BO Musik" tag used to live here; they flashed orange on
   every load and are gone. */
.hero__portrait {
  position: relative; height: 100%; width: auto; max-width: 42%;
  object-fit: contain; object-position: left bottom;
  margin-left: 3%;                     /* matches the film's 16:9 frame x-offset */
}

/* film layer, shared by the hero and the archive stage */
.film {
  position: absolute; inset: 0; z-index: 2;
  /* short dissolve: the film layer is opaque, so a long fade reads as a
     double exposure against the designed panel behind it */
  opacity: 0; transition: opacity .4s ease;
  background: #05060a; pointer-events: none;
}
.film iframe { width: 100%; height: 100%; border: 0; display: block; }
.film.is-ready { opacity: 1; }

/* Once a film is up it carries its own titles and lockup, so the still
   fallback's furniture gets out of the way. */
.archive__scrim, .archive__label { transition: opacity .7s ease; }
.archive__stage:has(.film.is-ready) .archive__scrim,
.archive__stage:has(.film.is-ready) .archive__label {
  opacity: 0; pointer-events: none;
}

/* ---------- marquee ---------- */

.marquee {
  background: var(--pink-deep); border-bottom: 2px solid var(--rule); overflow: hidden;
}
.marquee__row {
  display: flex; width: max-content; gap: 34px; padding: 11px 34px 11px 0;
}
@media (prefers-reduced-motion: no-preference) {
  .marquee__row { animation: marquee 26s linear infinite; }
}
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.marquee__row span {
  font-weight: 900; font-size: 13px; letter-spacing: .2em;
  text-transform: uppercase; color: #f7f2e8; white-space: nowrap;
}
.marquee__row .star { color: var(--gold); }

/* ---------- the dial: 1985 → now ----------
   A tuning dial is the one object that says "radio" and "then to now" at the
   same moment, so the timeline is built as one. Warm tungsten backlight behind
   the glass, a graduated frequency scale, and a lit needle parked on today.
   Housing keeps the design's square corners — plenty of 70s tuners were slabs.

   Reading order is unchanged: it is still an <ol> of five stops. Everything
   the dial adds is decorative and aria-hidden. */

.dial {
  position: relative; overflow: hidden;
  border: 2px solid var(--rule);
  background:
    linear-gradient(180deg, #14100c 0%, #0d0b0a 55%, #0a0908 100%);
  margin: 34px 0 40px;
  padding: 26px 22px 24px;
}

/* the glass: a slab highlight across the top, and the tungsten bloom rising
   from behind the scale */
.dial__glass, .dial__lamp { position: absolute; inset: 0; pointer-events: none; }
.dial__glass {
  background:
    linear-gradient(180deg, rgba(255, 236, 200, .075) 0, rgba(255, 236, 200, 0) 38%),
    linear-gradient(180deg, rgba(0,0,0,0) 78%, rgba(0,0,0,.35) 100%);
}
.dial__lamp {
  background:
    radial-gradient(150% 90% at 50% 108%, rgba(255, 176, 74, .22), rgba(255,176,74,0) 62%),
    radial-gradient(70% 60% at 88% 96%, rgba(201, 242, 122, .16), rgba(201,242,122,0) 64%);
}
@media (prefers-reduced-motion: no-preference) {
  /* valve warmth — a slow, shallow breathe, never a flicker */
  .dial__lamp { animation: dialWarm 7s ease-in-out infinite; }
}
@keyframes dialWarm { 0%, 100% { opacity: .88; } 50% { opacity: 1; } }

/* the maker's band printed on the glass, as a tuner would carry it */
.dial__band {
  position: absolute; top: 8px; right: 22px; pointer-events: none;
  font-family: var(--mono); font-size: 9px; letter-spacing: .22em;
  text-transform: uppercase; color: rgba(255, 208, 150, .34);
}

.line {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(160px, 1fr);
  position: relative;
  overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
}
.line::-webkit-scrollbar { display: none; }

.line__stop { position: relative; }
.line__n {
  display: block; font-weight: 900; font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1; letter-spacing: -.04em;
  padding: 0 20px 18px 0;
}

/* THE SCALE. Two background layers on the label: the rule itself, then the
   graduated ticks hanging off it every 11px — the thing that makes a strip of
   numbers read as a frequency scale rather than a timeline. Backgrounds paint
   across the padding box, so the segments join into one continuous scale. */
.line__l {
  display: block; position: relative;
  background-image:
    linear-gradient(rgba(255, 226, 186, .55), rgba(255, 226, 186, .55)),
    repeating-linear-gradient(90deg, rgba(255, 226, 186, .30) 0 1px, transparent 1px 11px);
  background-size: 100% 2px, 100% 8px;
  background-position: 0 0, 0 2px;
  background-repeat: no-repeat, repeat-x;
  padding: 20px 20px 0 0;
  font-family: var(--mono); font-size: 11px; line-height: 1.5;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-55);
}
/* the major tick: every named station gets a full-height graduation */
.line__l::before {
  content: ""; position: absolute; left: 0; top: -2px;
  width: 2px; height: 15px; background: rgba(255, 233, 199, .85);
}

/* the two ends carry the story: where it started, and that it has not stopped */
.line__stop--start .line__n { color: var(--gold); }
.line__stop--start .line__l,
.line__stop--now   .line__l { color: var(--ink-70); }

/* TODAY — the needle is parked here, lit and humming */
.line__stop--now .line__n { color: var(--lime); }
.line__stop--now .line__l {
  background-image:
    linear-gradient(var(--lime), var(--lime)),
    repeating-linear-gradient(90deg, rgba(201, 242, 122, .45) 0 1px, transparent 1px 11px);
}
.line__stop--now .line__l::before {
  background: var(--lime); height: 26px; top: -13px; width: 3px;
  box-shadow: 0 0 10px rgba(201, 242, 122, .9), 0 0 22px rgba(201, 242, 122, .45);
}
.line__stop--now .line__l::after {          /* the lamp behind the needle */
  content: ""; position: absolute; left: -14px; top: -30px;
  width: 30px; height: 60px; pointer-events: none;
  background: radial-gradient(closest-side, rgba(201, 242, 122, .40), rgba(201,242,122,0) 100%);
}
@media (prefers-reduced-motion: no-preference) {
  .line__stop--now .line__l::after { animation: nowPulse 2.4s ease-in-out infinite; }
}
/* was shared with the hero's on-air badge; the badge went with the station,
   so the keyframe lives with its one remaining user */
@keyframes nowPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .25; transform: scale(.6); }
}

/* On a phone the row would need a sideways scroll, which buries 2026 — and
   2026 is the whole point. Stand the dial up and read it downwards; the
   scale's graduations rotate with it. */
@media (max-width: 760px) {
  .dial { padding: 22px 18px 20px; margin: 26px 0 32px; }
  .dial__band { font-size: 8px; letter-spacing: .18em; top: 7px; right: 16px; }
  .line { grid-auto-flow: row; grid-auto-columns: auto; overflow-x: visible; }
  .line__stop { padding: 0 0 22px 24px; }
  .line__stop:last-child { padding-bottom: 4px; }
  .line__n { padding: 0 0 6px; font-size: 34px; }
  .line__l {
    background-image:
      linear-gradient(rgba(255, 226, 186, .55), rgba(255, 226, 186, .55)),
      repeating-linear-gradient(0deg, rgba(255, 226, 186, .30) 0 1px, transparent 1px 11px);
    background-size: 2px 100%, 8px 100%;
    background-position: -24px 0, -22px 0;
    background-repeat: no-repeat, repeat-y;
    padding: 0; max-width: 30ch;
  }
  .line__l::before { left: -24px; top: 0; width: 15px; height: 2px; }
  /* the label's background ticks paint inside its own box, so at a negative
     offset they were clipped away entirely — upright, the graduated ladder has
     to hang off the stop instead. */
  .line__stop::before {
    content: ""; position: absolute; left: 2px; top: 0; bottom: 0; width: 9px;
    background: repeating-linear-gradient(0deg,
      rgba(255, 226, 186, .30) 0 1px, transparent 1px 11px);
  }
  .line__stop--now::before {
    background: repeating-linear-gradient(0deg,
      rgba(201, 242, 122, .45) 0 1px, transparent 1px 11px);
    bottom: auto; height: 30px;
  }
  .line__stop--now .line__l {
    background-image:
      linear-gradient(var(--lime), var(--lime)),
      repeating-linear-gradient(0deg, rgba(201, 242, 122, .45) 0 1px, transparent 1px 11px);
  }
  .line__stop--now .line__l::before { width: 26px; left: -37px; height: 3px; top: 0; }
  .line__stop--now .line__l::after { left: -39px; top: -14px; width: 60px; height: 30px; }
  /* the scale has to carry on past each numeral, not just beside the label */
  .line__stop::after {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0;
    width: 2px; background: rgba(255, 226, 186, .55);
  }
  .line__stop--now::after { background: var(--lime); bottom: auto; height: 30px; }
}

/* ---------- section frame ---------- */

.section { padding: 44px 0; border-bottom: 2px solid var(--rule); }
.section__head {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px 24px;
  margin-bottom: 26px;
}
.section__note { font-size: 13px; color: var(--ink-55); max-width: 42ch; }

/* ---------- agenda ---------- */

.agenda { border-top: 2px solid var(--rule); }
.event {
  display: grid; grid-template-columns: 96px minmax(0, 1fr) auto;
  gap: 18px; padding: 16px 0;
  border-bottom: 2px solid var(--rule-soft);
  align-items: start;
}
@media (max-width: 720px) {
  .event { grid-template-columns: 76px minmax(0, 1fr); }
  .event__cta { grid-column: 1 / -1; justify-self: start; }
}
@media (prefers-reduced-motion: no-preference) {
  .event { opacity: 0; }
  .event.is-in { animation: fadeUp .45s ease both; }
}
@keyframes fadeUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

.event__poster {
  padding: 0; background: none; border: 2px solid var(--rule);
  height: 118px; overflow: hidden; transition: border-color .16s ease;
}
.event__poster:hover { border-color: var(--pink-lit); }
.event__poster img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 25%; }

.event__kind {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px;
  font-weight: 800; font-size: 11px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-70);
}
.event__swatch { width: 11px; height: 11px; flex: none; }
.event__when { font-family: var(--mono); font-size: 13px; letter-spacing: -.01em; }
.event__where { font-size: 13.5px; color: var(--ink-55); }
.event__detail {
  font-size: 13px; color: var(--ink-70); max-width: 62ch;
  border-left: 2px solid var(--gold); padding-left: 10px; margin: 10px 0 0;
}
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.chip {
  background: var(--ground-2); color: var(--ink);
  font-size: 12px; font-weight: 700; padding: 8px 11px;
}
.chip--tel {
  display: inline-flex; align-items: center; gap: 7px;
  background: transparent; border: 2px solid var(--rule);
  text-decoration: none; transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.chip--tel:hover { background: var(--gold); color: #0c0d14; border-color: var(--gold); }

/* ---------- archive film — 1985 ---------- */

.archive { background: var(--ground); }
.archive__stage {
  position: relative; aspect-ratio: 16 / 9;
  border: 2px solid var(--rule); overflow: hidden;
  background: #0a0b11;
}
.archive__stage img.archive__poster {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 35%;
  filter: saturate(.86) contrast(1.04);
}
.archive__scrim {
  position: absolute; inset: 0; z-index: 3;
  background: linear-gradient(0deg, rgba(6,7,12,.92), rgba(6,7,12,.25) 55%, rgba(6,7,12,.55));
  pointer-events: none;
}
.archive__label {
  position: absolute; left: 0; bottom: 0; z-index: 4;
  padding: 20px; max-width: 46ch;
}
.archive__stamp {
  font-family: var(--mono);
  font-size: 11px; letter-spacing: .18em; color: var(--gold); margin-bottom: 8px;
}
.archive__year {
  font-weight: 900; font-size: clamp(44px, 9vw, 108px); line-height: .82;
  letter-spacing: -.05em; margin: 0;
}
.archive__cap { font-size: 13.5px; color: var(--ink-70); margin: 10px 0 0; }

.strip {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(170px, 1fr);
  gap: 2px; margin-top: 2px; overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: thin;
}
/* Tall enough that a portrait frame is not sliced through the face. The few
   that still need help carry their own object-position in the markup. */
.strip button {
  padding: 0; background: none; border: 2px solid var(--rule-soft);
  height: 150px; overflow: hidden; transition: border-color .16s ease;
}
.strip button:hover { border-color: var(--gold); }
.strip img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.8) contrast(1.05) brightness(.92);
  transition: filter .2s ease;
}
.strip button:hover img { filter: none; }

/* ---------- disco years wall ---------- */

.wall { position: relative; overflow: hidden; background: #07080d; padding: 4px 0 0; }
.wall__row { display: flex; gap: 4px; width: max-content; padding-bottom: 4px; }
@media (prefers-reduced-motion: no-preference) {
  .wall__row { animation: drift var(--dur, 90s) linear infinite; }
  .wall__row--rev { animation-direction: reverse; }
  /* Deliberately NOT paused on hover: stopping the row left photos stranded
     off-screen and made the wall feel broken. Keyboard focus still pauses,
     or a tile could drift away from under the cursor before it is activated. */
  .wall:focus-within .wall__row { animation-play-state: paused; }
}
@keyframes drift { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.wall__row button {
  padding: 0; background: none; border: 0; flex: none;
  width: clamp(150px, 22vw, 280px); height: clamp(124px, 17vw, 210px);
  overflow: hidden; position: relative;
}
.wall__row img {
  width: 100%; height: 100%; object-fit: cover;
  /* these are all photographs of people; faces sit in the upper third, so a
     centre crop takes the tops of heads off. */
  object-position: 50% 30%;
  filter: saturate(.9) brightness(.82); transition: filter .25s ease, transform .5s ease;
}
.wall__row button:hover img,
.wall__row button:focus-visible img { filter: none; transform: scale(1.04); }

.beam {
  height: 2px; margin: 4px 0;
  background: linear-gradient(90deg, transparent, var(--beam, var(--cyan)) 18%, var(--gold) 50%, var(--beam, var(--pink)) 82%, transparent);
  opacity: .5;
}
@media (prefers-reduced-motion: no-preference) {
  .beam { animation: beat 2.4s ease-in-out infinite; }
  .beam--b { animation-delay: -1.2s; }
}
@keyframes beat { 0%, 100% { opacity: .28; } 50% { opacity: .9; } }

/* ---------- booking ---------- */

.booking {
  background: var(--teal-deep);
  border-top: 2px solid var(--rule); border-bottom: 2px solid var(--rule);
}
.booking__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 30px; padding: 46px 0;
}
.booking .kicker { color: rgba(242,239,230,.7); }
.booking__p { font-size: 16px; color: rgba(242,239,230,.82); max-width: 34ch; }
.tel-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--ink); color: #0c0d14; padding: 13px 15px; margin-top: 8px;
  text-decoration: none; transition: background .16s ease;
}
.tel-row:hover { background: var(--gold); }
.tel-row b { font-family: var(--mono); font-size: 14px; }
.tel-row span { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; opacity: .55; }

.form { border-left: 2px solid rgba(242,239,230,.25); padding-left: 30px; }
@media (max-width: 720px) { .form { border-left: 0; padding-left: 0; } }
.field { margin-bottom: 14px; }
.field label,
.field .label {
  display: block; margin-bottom: 6px;
  font-weight: 800; font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(242,239,230,.8);
}
.field input, .field textarea {
  width: 100%; background: var(--ground-3); color: var(--ink);
  border: 2px solid var(--rule); padding: 13px 14px;
  /* ⚠️ 16px is a FUNCTIONAL minimum, not a taste call. iOS Safari zooms the
     whole page when you focus an input under 16px and never zooms back out,
     so at 15px the visitor filled this form on a zoomed, side-scrolled page
     with the header clipped. Do not drop it back. */
  font-size: 16px;
  font-family: inherit; border-radius: 0;
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-40); }
.field--split { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.type-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.type-chip {
  background: transparent; color: var(--ink); border: 2px solid var(--rule);
  padding: 10px 13px; font-size: 12.5px; font-weight: 700;
  transition: background .16s ease, color .16s ease;
}
.type-chip[aria-pressed="true"] { background: var(--ink); color: #0c0d14; }
.submit {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  background: var(--ink); color: #0c0d14; border: 0;
  padding: 17px 19px; font-weight: 800; font-size: 15px;
  letter-spacing: .05em; text-transform: uppercase;
  transition: background .16s ease, color .16s ease;
}
.submit:hover { background: var(--action); color: #0c0d14; }

/* ---------- finale — une nuit ---------- */

.finale { position: relative; background: #05060a; border-bottom: 2px solid var(--rule); }
.finale__stage {
  /* same trap as the hero: without width:100% the max-height narrowed the box */
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  overflow: hidden; background: #05060a;
}
.finale__stage video {
  width: 100%; height: 100%; object-fit: cover; display: block;
  background: #05060a;
  /* The flyover. --fly is scrubbed from the section's own progress through
     the viewport: the shot comes in wide and settles as you arrive on it,
     like a drone dropping onto the floor. His footage and his framing are
     untouched — the motion is on the presentation, not the content. */
  transform: scale(var(--fly, 1));
  transform-origin: 50% 46%;
  will-change: transform;
}
/* the edges tighten as it settles, so the frame closes around the night */
.finale__stage::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background: radial-gradient(120% 88% at 50% 46%, transparent 42%, rgba(5,6,10,.72) 100%);
  opacity: var(--vig, .5);
}
@media (prefers-reduced-motion: reduce) {
  .finale__stage video { transform: none; }
  .finale__stage::after { opacity: .5; }
}
.finale__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(5,6,10,.92), rgba(5,6,10,.15) 52%, rgba(5,6,10,.6));
  transition: opacity .5s ease;
}
.finale.is-playing .finale__scrim,
.finale.is-playing .finale__label { opacity: 0; pointer-events: none; }
.finale__label {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 26px 0 30px; transition: opacity .5s ease;
}
.finale__title {
  font-weight: 900; font-size: clamp(34px, 7vw, 86px); line-height: .86;
  letter-spacing: -.05em; text-transform: uppercase; margin: 0;
}
.play {
  display: inline-flex; align-items: center; gap: 12px; margin-top: 16px;
  background: var(--gold); color: #0c0d14; border: 0;
  padding: 14px 18px; font-weight: 800; font-size: 13px;
  letter-spacing: .1em; text-transform: uppercase;
  transition: background .16s ease;
}
.play:hover { background: var(--ink); }

/* ---------- footer ---------- */

.footer { background: #07080d; color: var(--ink); padding: 34px 20px 40px; }
.footer__grid {
  max-width: var(--container); margin: 0 auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 26px;
}
.footer__brand { font-weight: 900; font-size: 22px; text-transform: uppercase; }
.footer__blurb { font-size: 13.5px; color: var(--ink-55); max-width: 30ch; margin-top: 8px; }
.footer h2 {
  font-weight: 800; font-size: 10.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-40); margin: 0 0 10px;
}
.footer a { color: var(--gold); text-decoration: none; transition: color .16s ease; }
.footer a:hover { color: var(--ink); }

/* Studio signature. It must read as a credit, not a second brand, so it
   opts out of the footer's gold link colour and sits at --ink-40 — the
   same weight as the "Contact" label above the numbers. The hairline
   underline is what makes it legible as a link at that opacity. */
.footer__sig { font-size: 12px; color: var(--ink-40); margin-top: 20px; }
.footer__sig a {
  position: relative; color: var(--ink-40);
  border-bottom: 1px solid rgba(242, 239, 230, .18);
}
.footer__sig a:hover { color: var(--ink-70); border-bottom-color: rgba(242, 239, 230, .40); }
/* 44px touch area without reflowing the paragraph — pseudo-pad, not padding.
   The link box is 14px tall, so -15px top/bottom is what makes 44. */
.footer__sig a::after { content: ""; position: absolute; inset: -15px -8px; }
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { font-size: 14px; }
/* real padding here — the footer has the room, and it keeps the 44px
   targets from overlapping each other the way pseudo-pads would */
.footer li a { display: inline-block; padding: 14px 0; }

/* ---------- lightbox ---------- */

.lightbox {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(6,5,10,.94);
  display: grid; place-items: center; padding: 20px;
  animation: fadeIn .2s ease both;
}
.lightbox[hidden] { display: none; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.lightbox__box { max-width: 860px; width: 100%; }
.lightbox img {
  max-height: 76vh; width: auto; margin: 0 auto;
  object-fit: contain; border: 2px solid var(--ink);
}
.lightbox__cap { font-size: 13px; color: rgba(242,239,230,.8); max-width: 46ch; margin: 14px 0 0; }
.lightbox__bar { display: flex; gap: 8px; margin-top: 14px; }
.lightbox__bar button {
  background: var(--ink); color: #0c0d14; border: 0;
  padding: 11px 15px; font-weight: 800; font-size: 12px;
  letter-spacing: .08em; text-transform: uppercase;
  transition: background .16s ease;
}
.lightbox__bar button:hover { background: var(--gold); }
.lightbox__bar .ghost { background: transparent; color: var(--ink); border: 2px solid var(--rule); }
.lightbox__bar .ghost:hover { background: var(--ink); color: #0c0d14; }

/* ---------- toast ---------- */

.toast {
  position: fixed; bottom: 108px; left: 50%; z-index: 95;
  width: calc(100% - 36px); max-width: 420px;
  background: var(--ground-2); color: var(--ink);
  border: 2px solid var(--rule); padding: 16px;
  transform: translateX(-50%);
  animation: riseIn .32s cubic-bezier(.2, .9, .25, 1) both;
}
.toast[hidden] { display: none; }
/* the translate must ride along or the centring breaks */
@keyframes riseIn {
  from { transform: translateX(-50%) translateY(120%); }
  to   { transform: translateX(-50%); }
}
.toast__t { font-weight: 900; font-size: 15px; text-transform: uppercase; }
.toast__b { font-size: 13.5px; color: var(--ink-70); margin: 6px 0 12px; }
.toast__bar { display: flex; gap: 8px; }
.toast__bar a, .toast__bar button {
  padding: 10px 14px; font-weight: 800; font-size: 12px;
  letter-spacing: .08em; text-transform: uppercase; text-decoration: none;
  border: 2px solid transparent;
}
.toast__wa { background: var(--cyan); color: #0c0d14; }
.toast__x { background: transparent; color: var(--ink); border-color: var(--rule); }
