/* ============================================================
   The Sound of West End Musicals
   Clifton Downs, Bristol - Friday 6 August 2027
   Presented by Feast Live.

   The palette is sampled from the client's own materials, not
   chosen: the cream is the lockup's paper, the gold is the pyro
   fan in the supplied film, the rose is the site flags, the dusk
   is the sky. The ground is the poster's own black.

   Layer order (gotcha 16: `html` carries the colour, `body` stays
   transparent or it paints over the z-index:-N scene layers):
     -3  .bg      still photograph, and the film on wide viewports
     -2  .scrim   contrast floor for the type
     -1  .rays    the sunburst from last year's poster, reworked as stage
                  beams. ABOVE the scrim: they are light, and under it the
                  scrim simply dimmed them back out again.
      0  content
   ============================================================ */

:root {
  --ink:       #000000;   /* the poster's own ground                 */
  --cream:     #F2F0E6;   /* sampled from the lockup letterforms     */
  --cream-dim: #C9C5B8;
  --gold:      #F5D06A;   /* sampled from the pyro fans in the film  */
  --gold-deep: #C79A3A;
  --rose:      #B73B4D;   /* sampled from the site flags             */
  --dusk:      #2E5B7E;   /* sampled from the dusk sky               */

  --panel-bg:   rgba(6, 5, 7, .94);
  /* No field boxes at all: type sits on the panel over a gold rule. The
     autofill shadow therefore has to disappear INTO the panel, so this is the
     flattened opaque equivalent of panel-over-film. The panel is .94 opaque
     precisely so that flatten stays stable whatever frame the film is on. */
  --field-flat: #090809;

  --panel-w: 29.5rem;
  --font-marquee: "Big Shoulders Display", "Oswald", "Haettenschweiler",
                  "Arial Narrow", system-ui, sans-serif;
  /* The lede was Bodoni Moda Italic. Two rounds of "the descriptive text is
     hard to read" on mobile ended it: a Didone's hairlines are the first thing
     the pyro frames of the film eat, and only one weight (Italic 600) is
     self-hosted, so there was nothing left to thicken. The lede is now the
     system sans, upright - the only stack on the page with no hairlines at
     all. BOTH pages read this one variable, so they cannot drift apart.
     (The Bodoni @font-face below is now unused - an unused face is never
     fetched - and is kept only so this is a one-line revert.) */
  --font-lede:    -apple-system, BlinkMacSystemFont, "Helvetica Neue",
                  Helvetica, Arial, sans-serif;
  --font-body:    -apple-system, BlinkMacSystemFont, "Helvetica Neue",
                  Helvetica, Arial, sans-serif;
}

/* ---------- fonts: OFL, self-hosted, subset to latin ---------- */
@font-face {
  font-family: "Big Shoulders Display";
  src: url("/assets/fonts/BigShouldersDisplay-700.woff2?v=20260908-6") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Big Shoulders Display";
  src: url("/assets/fonts/BigShouldersDisplay-800.woff2?v=20260908-6") format("woff2");
  font-weight: 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Bodoni Moda";
  src: url("/assets/fonts/BodoniModa-Italic-600.woff2?v=20260908-6") format("woff2");
  font-weight: 600; font-style: italic; font-display: swap;
}

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

html {
  background: var(--ink);          /* base colour lives here, not on body */
  color: var(--cream);
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}
body {
  margin: 0;
  background: transparent;         /* gotcha 16 */
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  min-height: 100svh;
  overflow-x: clip;
}

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

/* ============================================================
   Scene
   ============================================================ */
.bg, .scrim { position: fixed; inset: 0; pointer-events: none; }

.bg {
  z-index: -3;
  background: var(--ink) url("/assets/images/bg-mobile-sm.webp?v=20260908-6") center / cover no-repeat;
}
@media (min-width: 501px) and (max-aspect-ratio: 7/10) {
  .bg { background-image: url("/assets/images/bg-mobile.webp?v=20260908-6"); }
}
@media (min-aspect-ratio: 7/10) and (max-width: 1500px) {
  .bg { background-image: url("/assets/images/bg-desktop-sm.webp?v=20260908-6"); }
}
@media (min-aspect-ratio: 7/10) and (min-width: 1501px) {
  .bg { background-image: url("/assets/images/bg-desktop.webp?v=20260908-6"); }
}

/* The film. app.js only attaches it on wide viewports, and never under
   reduced-motion or Save-Data, so phones keep the still and never pay
   3MB on cellular. It sits ON the still, so the still is the poster
   frame underneath it and there is no flash at the swap. */
.bg__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.bg__video.is-ready { opacity: 1; }

/* ---- The sunburst, carried over from last year's poster ----
   Last year it was flat pastel paper behind the lockup. Here it is
   the same geometry rendered as light: `screen` blend so the crowd
   and the stage read straight through the beams, and a radial mask
   so they fall off with distance the way real beams do. The origin
   sits behind the lockup at every breakpoint. */
.rays {
  /* Anchored ON the beams' vanishing point and made far larger than the
     viewport, because a viewport-sized rectangle rotates its OWN straight
     edge into shot - that is the hard line sweeping across. Rotating about
     the element's own centre, with the mask fading to nothing (~75vmax) long
     before the element's edge (100vmax), means there is no edge to see at
     any angle. */
  position: fixed;
  left: 50%;
  top: 30%;
  width: 200vmax;
  height: 200vmax;
  z-index: -1;
  pointer-events: none;
  mix-blend-mode: screen;
  /* Feathered stops, not hard wedges. Hard `0deg 3.4deg` sectors screen over
     a dark film as high-contrast spokes, which reads as a starburst graphic
     rather than light. Ramping each beam up and back down gives a soft edge
     with none of the cost of a blur filter. */
  background: repeating-conic-gradient(
      from 0deg at 50% 50%,
      rgba(245, 208, 106, 0)    0deg,
      rgba(245, 208, 106, .26)  3.2deg,
      rgba(245, 208, 106, 0)    6.4deg,
      rgba(245, 208, 106, 0)    13deg);
  /* Sized in vmax, not %, so the falloff is identical at every aspect ratio. */
  -webkit-mask-image: radial-gradient(circle 110vmax at 50% 50%,
      #000 0%, rgba(0,0,0,.82) 20%, rgba(0,0,0,.32) 45%, transparent 68%);
          mask-image: radial-gradient(circle 110vmax at 50% 50%,
      #000 0%, rgba(0,0,0,.82) 20%, rgba(0,0,0,.32) 45%, transparent 68%);
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%);
  animation: sweep 19s ease-in-out infinite alternate;
  will-change: transform, opacity;
}
/* Beams sweep, they do not spin: a full rotation reads as a loading
   spinner. The translate must be repeated in every keyframe or the layer
   jumps off-centre the moment the animation takes over `transform`. */
@keyframes sweep {
  from { transform: translate(-50%, -50%) rotate(-8.5deg); opacity: .68; }
  50%  { opacity: 1; }
  to   { transform: translate(-50%, -50%) rotate(8.5deg);  opacity: .74; }
}

.scrim {
  z-index: -2;
  background:
    linear-gradient(180deg, rgba(0,0,0,.20) 0%, rgba(0,0,0,.04) 36%, rgba(0,0,0,.40) 100%),
    radial-gradient(125% 95% at 50% 34%, transparent 40%, rgba(0,0,0,.20) 100%);
}

@media (prefers-reduced-motion: reduce) {
  .rays { animation: none; transform: translate(-50%, -50%) rotate(0deg); }
  .bg__video { display: none; }
}

/* ============================================================
   Sheet / stage
   ============================================================ */
.sheet { position: relative; min-height: 100svh; display: flex; flex-direction: column; }

.stage {
  flex: 1 0 auto;
  display: flex;
  padding: clamp(1rem, 5vw, 3rem) clamp(1.1rem, 4.5vw, 2.5rem) 1.4rem;
}
.stage__inner {
  margin: 0 auto;
  width: 100%;
  max-width: 68rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.7rem, 4.5vw, 2.6rem);
}

/* ---------- Brand column ----------
   .col-lede groups the lockup, the details and the countdown into a SINGLE
   grid child. As three siblings the countdown was placed into the panel's
   track and pushed the panel onto a second row. */
.col-lede {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 2.2rem);
  width: 100%;
  max-width: 34rem;
}
.brand { text-align: center; width: 100%; }
.brand__mark { position: relative; }
.brand__lockup {
  display: block;
  /* Fluid so phones get the compact lockup the client asked for without
     shrinking it on portrait tablets, which also land in the single-column
     branch (an 820x1180 iPad is aspect 0.695, just under the 7/10 threshold).

     Floor lowered 17rem -> 15rem -> 13rem on 2026-09-10: the client asked
     for a smaller logo if that is what it takes to land on the sign-up
     panel, then asked for smaller twice more (17 -> 15 -> 13 -> 11.5rem).
     Only phones ever hit the floor - 46vw already exceeds 11.5rem by 400px
     wide - so tablets and everything above are untouched. Measured on a
     390px phone: lockup 272x254 -> 184x172. */
  width: min(100%, clamp(11.5rem, 46vw, 26rem));
  height: auto;
  margin: 0 auto;
}

/* No `filter: drop-shadow` on the lockup - it recomputes from the
   aliased alpha during decode and flashes a dark halo (gotcha 9).
   The lift comes from a static glow painted behind it instead. */
.brand__halo {
  position: absolute;
  z-index: -1;
  /* Horizontal inset is 0, NOT negative. A negative % inset made this 24%
     wider than its parent, which on a phone is wider than the screen - and
     that was the whole of the 30px sideways scroll. The glow keeps its
     spread by widening the gradient's own radius instead of the box. */
  inset: -16% 0 -24%;
  background: radial-gradient(74% 52% at 50% 46%,
      rgba(245, 208, 106, .18) 0%, rgba(245, 208, 106, .06) 46%, transparent 74%);
  pointer-events: none;
}

.brand__where,
.brand__date {
  margin: 0;
  font-family: var(--font-marquee);
  font-weight: 800;
  text-transform: uppercase;
  line-height: 1.05;
  color: var(--cream);
  text-shadow: 0 2px 3px rgba(0, 0, 0, .85), 0 0 20px rgba(0, 0, 0, .6);
}
.brand__where {
  margin-top: clamp(.7rem, 3.2vw, 1.5rem);
  font-size: clamp(1.32rem, 4.9vw, 1.78rem);
  letter-spacing: .095em;
}
.brand__date {
  margin-top: .3rem;
  font-size: clamp(1.32rem, 4.9vw, 1.78rem);
  letter-spacing: .055em;
  color: var(--gold);
}

/* Featured shows, added 2026-09-10 at the client's request: a supporting
   bill under the date on BOTH layouts. Marquee register so it belongs to
   the date block rather than to the paragraph below, but a clear step down
   in size and weight - at .brand__date's size it competed with the date
   itself. Same text-shadow as the two lines above so all three sit on the
   film the same way; no backing plate (see .brand__line). */
.brand__shows {
  margin: clamp(.5rem, 2.1vw, .75rem) auto 0;
  max-width: 27rem;
  font-family: var(--font-marquee);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(.98rem, 3.45vw, 1.14rem);
  letter-spacing: .085em;
  line-height: 1.3;
  color: var(--gold);
  text-shadow: 0 2px 3px rgba(0, 0, 0, .85), 0 0 20px rgba(0, 0, 0, .6);
  text-wrap: balance;
}
.brand__line {
  /* Positioned so it can be stacked above the panel on phones. The lede is
     ordered BELOW the panel, and .panel is positioned while a bare <p> is
     not - so the panel's ambient shadow (0 60px 120px) painted in a later
     step, straight over the paragraph's first line. It read as a gradient
     wash across the opening words. Positioning the lede puts it in the same
     paint step, and order-modified document order (order 5 vs the panel's 4)
     then puts it on top. */
  position: relative;
  z-index: 0;
  margin: clamp(.9rem, 2.6vw, 1.2rem) auto 0;
  max-width: 26rem;
  font-family: var(--font-lede);
  font-weight: 500;
  font-size: clamp(1.05rem, 3.6vw, 1.24rem);
  line-height: 1.55;
  color: var(--cream);
  /* No backing plate. A plate darkens a whole rectangle and reads as a
     smudge over the photograph - which is exactly what was reported. These
     hug the letterforms instead, so the paragraph stays legible over any
     frame of the film without painting a visible shape behind it. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, .95),
               0 2px 9px rgba(0, 0, 0, .85),
               0 0 22px rgba(0, 0, 0, .7);
  text-wrap: pretty;
}

/* ---------- Countdown: a marquee rail, not four cards ----------
   The bulbs are the structural device and they carry meaning: this
   is a front-of-house sign counting down to the box office opening.
   The numerals are the only thing that moves. */
.clock { width: 100%; max-width: 30rem; margin: 0 auto; }
.clock__bulbs {
  height: 9px;
  background-image: radial-gradient(circle at 50% 50%,
      var(--gold) 0 2.1px, rgba(199, 154, 58, .34) 2.1px 3.1px, transparent 3.2px);
  background-size: 22px 9px;
  background-repeat: repeat-x;
  background-position: center;
  opacity: .9;
}
.clock__face {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid rgba(199, 154, 58, .42);
  border-bottom: 1px solid rgba(199, 154, 58, .42);
  margin: 7px 0;
  background: rgba(0, 0, 0, .34);
}
.clock__unit { padding: .55rem .2rem .5rem; text-align: center; }
.clock__unit + .clock__unit { border-left: 1px solid rgba(199, 154, 58, .26); }
.clock__n {
  display: block;
  font-family: var(--font-marquee);
  font-weight: 800;
  font-size: clamp(1.85rem, 7.4vw, 2.5rem);
  line-height: 1;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}
.clock__l {
  display: block;
  margin-top: .28rem;
  font-family: var(--font-marquee);
  font-weight: 700;
  font-size: .72rem;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.clock__cap {
  margin: .55rem 0 0;
  text-align: center;
  font-family: var(--font-marquee);
  font-weight: 700;
  font-size: clamp(.82rem, 3vw, .93rem);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold);
}
/* Once the presale opens the rail stops counting and becomes a sign. */
.clock.is-open .clock__face { display: none; }
.clock.is-open .clock__cap { color: var(--cream); font-size: clamp(.95rem, 3.6vw, 1.1rem); }

/* In the panel the rail is a strip above the form, so it fills the panel
   width and sizes down to sit under the lede rather than compete with it. */
.panel .clock { max-width: none; margin: 0 0 1.2rem; }
.panel .clock__n   { font-size: clamp(1.5rem, 6vw, 1.95rem); }
.panel .clock__l   { font-size: .64rem; letter-spacing: .16em; }
.panel .clock__unit { padding: .45rem .15rem .42rem; }
.panel .clock__cap { margin-top: .6rem; text-align: center; font-size: clamp(.72rem, 2.7vw, .8rem); letter-spacing: .11em; }

/* ============================================================
   Sign-up panel
   ============================================================ */
.signup { width: 100%; max-width: var(--panel-w); }

.panel {
  /* NO `isolation: isolate` here. Gotcha 5 prescribes it against an absolutely
     positioned pseudo-element FRAME stacking over the form children - this
     build has no such frame, it uses the inset hairline the gotcha offers as
     the alternative, and `.panel__inner { z-index: 1 }` below already does the
     lifting. Isolating instead did harm: it trapped the country dropdown
     (z-index 3) inside the panel, so on phones - where the lede is ordered
     BELOW the panel and has to out-paint its shadow - the lede covered the
     open country list. Without isolation the dropdown competes at the root
     and wins, and the panel's shadow still passes under the lede. */
  position: relative;
  background: var(--panel-bg);
  border: 1px solid rgba(242, 240, 230, .13);
  /* Layered rather than one big blur: a tight contact shadow, a mid lift and
     a wide ambient pool read as real depth, where a single 60px blur just
     looks like fog. The gold hairline along the top edge is the light
     catching the panel's lip. */
  box-shadow: 0 1px 0 rgba(245, 208, 106, .2) inset,
              0 2px 5px rgba(0, 0, 0, .45),
              0 10px 22px rgba(0, 0, 0, .5),
              0 30px 60px rgba(0, 0, 0, .62),
              0 60px 120px rgba(0, 0, 0, .55);
  padding: clamp(1.4rem, 5vw, 1.9rem) clamp(1.15rem, 4.6vw, 1.7rem) clamp(1.3rem, 4.4vw, 1.7rem);
}
.panel__inner { position: relative; z-index: 1; }

.panel__state { display: none; }
.panel[data-form-state="idle"]    .panel__idle,
.panel[data-form-state="success"] .panel__success { display: block; }

.panel__eyebrow {
  display: flex; align-items: center; gap: .7rem;
  margin: 0 0 .55rem;
  font-family: var(--font-marquee);
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold);
}
.panel__eyebrow-hair { flex: 1; height: 1px; background: rgba(199, 154, 58, .4); }

.panel__title {
  margin: 0 0 .5rem;
  font-family: var(--font-marquee);
  font-weight: 800;
  font-size: clamp(2rem, 8vw, 2.55rem);
  line-height: .96;
  letter-spacing: .012em;
  text-transform: uppercase;
  text-wrap: balance;              /* gotcha 8: never white-space:nowrap */
  color: var(--cream);
}
/* The success pane's title is a full sentence, not the idle pane's two-word
   marquee line, so it cannot carry the same display size - at clamp(2rem, 8vw,
   2.55rem) it ran to four lines in a 29.5rem panel. Scoped to .panel__success
   so the idle title ("Early access. Best price.") is untouched. */
.panel__success .panel__title {
  font-size: clamp(1.4rem, 5.6vw, 1.75rem);
  line-height: 1.04;
  margin-bottom: .7rem;
}
.panel__lede {
  margin: 0 0 1.15rem;
  font-size: .935rem;
  line-height: 1.55;
  color: var(--cream-dim);
}
.panel__lede strong { color: var(--cream); font-weight: 600; }

/* ---------- form ---------- */
.form__row { margin-bottom: .95rem; }

/* Labels in the BODY sans, not the condensed marquee face. A condensed face
   at ~11px with .19em tracking is hard to read, which is exactly what it was.
   Sentence-spaced caps in cream at 12.5px is legible at a glance. */
.form__label {
  display: block;
  margin: 0 0 .34rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: .78rem;
  letter-spacing: .085em;
  text-transform: uppercase;
  color: rgba(242, 240, 230, .84);
}

/* ---------- Fine gold rule around the field ----------
   A hairline gold frame, no fill of its own. The frame lives on the WRAPPER
   so it encloses the whole row including the country trigger, which
   intl-tel-input pins to the left of the phone field - on the input alone it
   would draw a box around only part of the control. */
.field {
  position: relative;
  border: 1px solid rgba(199, 154, 58, .58);
  border-radius: 2px;
  background: rgba(0, 0, 0, .22);
  transition: border-color .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.field:hover {
  border-color: rgba(245, 208, 106, .85);
  background: rgba(0, 0, 0, .3);
}
.field:focus-within {
  border-color: var(--gold);
  background: rgba(0, 0, 0, .34);
  box-shadow: 0 0 0 3px rgba(245, 208, 106, .18);
}

.form__input {
  width: 100%;
  padding: .8rem .85rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--cream);
  background: transparent;
  border: 0;
  border-radius: 0;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.form__input::placeholder { color: rgba(201, 197, 184, .45); }

/* Chrome paints autofilled fields pale lavender and ignores
   `background`. The inset shadow has to be the FLATTENED opaque
   colour of field-over-panel, or an autofilled field will not match
   the empty one beside it. */
.form__input:-webkit-autofill,
.form__input:-webkit-autofill:hover,
.form__input:-webkit-autofill:focus,
.form__input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--field-flat) inset !important;
          box-shadow: 0 0 0 1000px var(--field-flat) inset !important;
  -webkit-text-fill-color: var(--cream) !important;
  caret-color: var(--cream);
  transition: background-color 9999s ease-in-out 0s;
}

.form__error { margin: .4rem 0 0; font-size: .82rem; line-height: 1.4; color: #F09AA6; }
.form__error--global { margin-top: .75rem; text-align: center; }

/* Honeypot: display:none, NEVER off-screen positioning. Chrome and
   Edge autofill treat an off-screen field as a live target, fill it,
   and the submit handler then silently drops every real signup. */
.hp-row { display: none !important; }

.form__row--check { margin: 1rem 0 1.15rem; }
.form__check {
  display: flex;
  gap: .65rem;
  align-items: flex-start;
  font-size: .8rem;
  line-height: 1.5;
  color: var(--cream-dim);
  cursor: pointer;
}
.form__check input {
  flex: none;
  width: 1.05rem; height: 1.05rem;
  margin: .14rem 0 0;
  accent-color: var(--gold);
  cursor: pointer;
}
.form__check a { color: var(--gold); text-underline-offset: 2px; }
.form__check a:hover { color: var(--cream); }

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  width: 100%;
  padding: .88rem 1rem;
  font-family: var(--font-marquee);
  font-weight: 800;
  font-size: clamp(1rem, 4vw, 1.15rem);
  letter-spacing: clamp(.06em, .5vw, .13em);
  text-transform: uppercase;
  white-space: nowrap;             /* gotcha 26: shrink type, never wrap */
  color: #14100A;
  background: linear-gradient(180deg, #FBDE8A 0%, var(--gold) 52%, #D9AE4C 100%);
  border: 0;
  border-radius: 2px;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  transition: filter .16s ease, transform .12s ease;
}
.btn:hover  { filter: brightness(1.07); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .62; cursor: default; }
.btn:focus-visible { outline: 3px solid rgba(245, 208, 106, .55); outline-offset: 3px; }

.panel__success-note { margin: 0 0 .9rem; font-size: .9rem; color: var(--gold); }
/* DEAD since 2026-09-08: the thank-you lockup was removed from the success
   pane at the client's request ("not required"). The rules and the
   thank-you-600.webp/png assets are kept so restoring it is one <picture>
   block, the same call made for the .soon* rules after the cutover.
   The landscape block below carries a second .panel__thanks rule. */
.panel__thanks { display: block; width: 100%; height: auto; margin: .2rem 0 1rem; }

/* ============================================================
   intl-tel-input v25
   ============================================================ */
.iti { width: 100%; display: block; }
.iti__country-container { z-index: 3; }
/* Until the vendor stylesheet lands, the dropdown paints open with its
   search box and full country list (gotcha 19). */
.iti__dropdown-content.iti__hide { display: none !important; }

.iti__selected-dial-code { color: var(--cream); font-size: .97rem; }
.iti__selected-country-primary { padding: 0 .35rem 0 .6rem; }
.iti__selected-country { background: transparent; }
.iti__selected-country:hover,
.iti__selected-country[aria-expanded="true"] { background: rgba(245, 208, 106, .1); }

.iti__dropdown-content {
  background: #100D11;
  border: 1px solid rgba(242, 240, 230, .18);
  border-radius: 3px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .7);
  font-family: var(--font-body);
}
/* Vertical padding only. A `padding` SHORTHAND wipes the vendor's reserved
   padding-left:30px and the magnifier lands on top of the word "Search"
   (gotcha 33). */
.iti__search-input {
  padding: 9px 30px 9px 32px;
  color: var(--cream);
  background: rgba(255, 255, 255, .05);
  border: 0;
  border-bottom: 1px solid rgba(242, 240, 230, .14);
  font-size: .92rem;
}
.iti__search-input::placeholder { color: rgba(201, 197, 184, .55); }
.iti__country { color: var(--cream); font-size: .92rem; }
.iti__country.iti__highlight,
.iti__country:hover { background: rgba(245, 208, 106, .16); }
.iti__dial-code { color: var(--cream-dim); }

/* ============================================================
   Footer - standard fleet format, ported from basslayerz.

   .foot__left is a ROW: the copyright and the "built by" pill sit on
   ONE line, wrapping only when there is genuinely no room. The Furiosa
   link is a pill (padded, hairline border, fully rounded), not bare text.
   ============================================================ */
.foot {
  flex-shrink: 0;
  width: 100%;
  margin: 0;
  padding: 18px clamp(16px, 4vw, 40px) 26px;
  background: rgba(0, 0, 0, .62);
  border-top: 1px solid rgba(242, 240, 230, .14);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}
.foot__left { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.foot__legal { margin: 0; font-size: 12px; color: rgba(201, 197, 184, .72); letter-spacing: .02em; }
.foot__legal a { color: rgba(201, 197, 184, .72); text-decoration: none; }
.foot__legal a:hover { color: var(--gold); }
.site-built { margin: 0; }
.site-built a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  letter-spacing: .04em;
  color: rgba(201, 197, 184, .72);
  text-decoration: none;
  padding: 5px 11px;
  border: 1px solid rgba(242, 240, 230, .14);
  border-radius: 999px;
}
.site-built a:hover { border-color: var(--gold); color: var(--cream); }
.site-built img { display: block; opacity: .9; }

@media (max-width: 879px) {
  .foot { justify-content: center; text-align: center; }
  .foot__left { justify-content: center; }
}

/* ============================================================
   Single column (portrait phones and portrait-ish windows).

   Flattening the two wrapper divs with `display: contents` promotes the
   lockup, venue, date, panel and lede to siblings of .stage__inner, so a
   plain `order` sets the phone stack independently of the DOM and of the
   desktop grid. No DOM change, and the desktop grid never sees it.

   ORDER HISTORY - do not silently reverse any step:
   2026-09-02 the lede was moved BELOW the form (order 5), because sitting
   between the lockup and the form it pushed the panel 620px down a
   390x844 phone and you landed on the page seeing no form at all.
   2026-09-08 the CLIENT asked for it back under the logo and dates, so it
   is order 4 again and the panel is order 5. That reinstates the taller
   stack above the form on purpose; it is a copy decision, not a bug.
   2026-09-10 the client asked for it BELOW the form again, citing the
   conversion rate, and supplied a mockup: logo, venue, date, shows, form,
   description. So the lede is order 6 and the panel order 5, and the new
   .brand__shows line takes order 4. The shows line is deliberately the
   only thing added above the form - it is short, and it is the copy that
   sells the show, so it earns the ~2 lines it costs the panel.

   `display: contents` keeps inheritance, so .brand's `text-align: center`
   still reaches these children - only the boxes go, not the cascade.

   These conditions are the exact complement of the two-column and
   landscape-phone blocks below (aspect < 7/10, OR narrow AND tall), so
   the three can never apply together. That matters: `display: contents`
   leaking into either grid layout would collapse it.
   ============================================================ */
@media (max-aspect-ratio: 699/1000),
       (max-width: 767px) and (min-height: 521px) {
  .col-lede,
  .brand        { display: contents; }
  .stage__inner { gap: 0; }          /* spacing now comes from item margins */

  .brand__mark,
  .brand__where,
  .brand__date,
  .brand__shows,
  .brand__line  { width: 100%; }

  /* Client, 2026-09-10: the bulb rails read as clutter at phone width.
     They are purely decorative (aria-hidden in the markup), so hiding
     them costs nothing structurally - the face keeps its own gold top and
     bottom borders, so the countdown is still framed. Desktop and
     landscape phones keep the rails. */
  .clock__bulbs { display: none; }
  .clock__face  { margin: 0; }

  /* Client, 2026-09-10: the countdown was too tall on a phone. Trimmed on
     every axis that costs height - numerals, cell padding, labels and the
     gaps above the caption and below the block. These must keep the
     `.panel` prefix to outrank the `.panel .clock__*` sizes set earlier
     (0,2,0); a bare `.clock__n` here would silently lose. */
  /* Client, 2026-09-10: "Early access. Best price." on ONE line, never
     wrapping. Two parts, and both are needed.

     The <br> is in the markup, so CSS neutralises it rather than the HTML
     changing shape between layouts.

     This deliberately overrides gotcha 8 ("never white-space: nowrap") on
     the IDLE title only. nowrap alone would just overflow the panel and
     give phones sideways scroll, so the size is derived from the actual
     text metrics instead of picked: the string measures 935px at a 100px
     font, and the narrowest supported phone (320px) leaves 246px of usable
     panel width, i.e. a 26.3px ceiling. 8vw is 25.6px there, and the
     ratio only improves as the viewport grows because the panel's padding
     is fixed - so if it fits at 320 it fits everywhere in this branch. The
     2.2rem cap stops it ballooning at the top of the range.

     Scoped to .panel__idle: the success pane's title is a full sentence
     and MUST keep wrapping. */
  .panel__idle .panel__title    { white-space: nowrap; font-size: min(7.8vw, 2.2rem); }
  .panel__idle .panel__title br { display: none; }

  .panel .clock       { margin-bottom: .95rem; }
  .panel .clock__n    { font-size: clamp(1.25rem, 5vw, 1.5rem); }
  .panel .clock__l    { font-size: .58rem; letter-spacing: .14em; }
  .panel .clock__unit { padding: .3rem .15rem .28rem; }
  .panel .clock__cap  { margin-top: .45rem; font-size: clamp(.68rem, 2.5vw, .75rem); }

  .brand__mark  { order: 1; }
  .brand__where { order: 2; }
  .brand__date  { order: 3; }
  .brand__shows { order: 4; }

  .signup       { order: 5; margin-top: clamp(1.2rem, 3.8vw, 1.7rem); }

  /* Keep the EXPLICIT positive z-index. .panel is positioned and a bare
     <p> is not, so the panel and its shadow paint in a later step whatever
     the order values say, and the lede would be painted over. That is the
     defect the client once read as "a gradient covering the first line".
     With the lede back BELOW the panel the ambient shadow's positive Y
     offset points straight at it, so this matters more here than it did
     while the lede sat above. z-index 1 beats the panel's auto/0. */
  .brand__line  { order: 6; margin-top: clamp(1.3rem, 4.2vw, 1.8rem); z-index: 1; }

  /* Second line of defence: the lede sits directly under the panel on
     phones, right where the ambient shadow's 60px Y offset points, so
     drop the widest ambient layer. There is far less shadow to land on
     the text even if stacking is defeated some other way, and at
     full-bleed width that outer pool was barely visible anyway. */
  .panel {
    box-shadow: 0 1px 0 rgba(245, 208, 106, .2) inset,
                0 2px 5px rgba(0, 0, 0, .45),
                0 10px 22px rgba(0, 0, 0, .5),
                0 22px 44px rgba(0, 0, 0, .5);
  }
}

/* ============================================================
   Two-column layout.

   Aspect-ratio thresholds, not width alone: width-only breakpoints
   leave a gap at squarish window shapes (~570-900px) where neither
   the phone nor the desktop treatment applies (gotcha 20).
   ============================================================ */
@media (min-width: 768px) and (min-aspect-ratio: 7/10) {
  .stage { align-items: center; }
  .stage__inner {
    display: grid;
    /* The panel track is DEFINITE. Leave it `auto` and the brand
       track's 1fr has no basis to distribute from (gotcha 35). */
    grid-template-columns: minmax(0, 1fr) var(--panel-w);
    align-items: center;
    gap: clamp(2rem, 5vw, 4rem);
    max-width: 66rem;
  }
  .col-lede { align-items: flex-start; max-width: none; }
  .brand { text-align: left; }
  .brand__lockup { margin: 0; width: min(100%, 24rem); }
  /* Both of these are max-width blocks with `auto` side margins, which
     would centre them inside the left column while .brand is text-align
     left. Kill the left auto margin so they hang off the same edge as the
     lockup and the date. */
  .brand__shows  { margin-left: 0; }
  .brand__line   { margin-left: 0; }
  .signup        { max-width: none; width: 100%; }
  /* Scoped to the sign-up page: the holding page is centred, so moving the
     beams' vanishing point off to the left would miss its lockup entirely. */
  /* The film is at its busiest behind the left column, where the lockup and
     the lede sit. Weight the scrim to that side so the type always has a
     calm ground, without flattening the stage on the right. */
  .page-signup .scrim {
    background:
      linear-gradient(90deg, rgba(0,0,0,.34) 0%, rgba(0,0,0,.16) 40%, rgba(0,0,0,0) 64%, rgba(0,0,0,.06) 100%),
      linear-gradient(180deg, rgba(0,0,0,.10) 0%, rgba(0,0,0,0) 38%, rgba(0,0,0,.30) 100%);
  }
  /* Scoped to the sign-up page: the holding page is centred, so moving the
     beams' vanishing point off to the left would miss its lockup entirely.
     Only the ANCHOR moves now - the gradient and mask stay centred on the
     element, which is what keeps the rotation edgeless. */
  .page-signup .rays { left: 33%; top: 46%; }
}

/* ============================================================
   Landscape phones are a first-class layout (gotcha 27). A rotated
   phone satisfies the width + aspect conditions above but has almost
   no height, so the desktop treatment renders cramped. Placed AFTER
   the desktop block so it wins at equal specificity.
   ============================================================ */
@media (min-width: 640px) and (min-aspect-ratio: 7/10) and (max-height: 520px) {
  .stage { align-items: start; padding: .9rem 1.1rem .8rem; }
  .stage__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 22rem;
    align-items: start;
    gap: 1.4rem;
    min-height: 0;
  }
  .col-lede { align-items: flex-start; max-width: none; gap: .55rem; }
  .brand { text-align: left; }
  .brand__lockup {
    margin: 0;
    width: auto;
    max-width: 100%;
    /* Reserve bumped 250 -> 288px on 2026-09-10 to pay for .brand__shows,
       which is up to two lines here. Without it the lockup keeps its old
       height and the shows line runs off the bottom of a 360px-tall phone. */
    max-height: calc(100svh - 288px);
  }
  .brand__where { margin-top: .6rem; font-size: 1.08rem; }
  .brand__date  { font-size: 1.08rem; }
  /* Kept visible, unlike the lede: this is the left column, so it costs the
     form no vertical space at all, and it is the copy that sells the show. */
  .brand__shows { margin-top: .45rem; font-size: .8rem; letter-spacing: .07em; }
  .brand__line  { display: none; }
  .panel .clock       { margin-bottom: .7rem; }
  .panel .clock__n    { font-size: 1.32rem; }
  .panel .clock__l    { font-size: .55rem; letter-spacing: .12em; }
  .panel .clock__unit { padding: .28rem .15rem .26rem; }
  .panel .clock__cap  { font-size: .66rem; }

  .signup { max-width: none; }
  .panel  { padding: .95rem 1rem 1rem; }
  .panel__title   { font-size: 1.5rem; }
  /* Higher specificity than the line above, so it must be repeated here
     or the success title would ignore the landscape shrink entirely. */
  .panel__success .panel__title { font-size: 1.12rem; margin-bottom: .5rem; }
  .panel__lede    { font-size: .82rem; margin-bottom: .8rem; }
  .panel__eyebrow { font-size: .68rem; margin-bottom: .35rem; }
  .form__row      { margin-bottom: .6rem; }
  .form__label    { font-size: .57rem; letter-spacing: .15em; margin-bottom: .18rem; }
  .form__input    { padding: .58rem .7rem; font-size: .95rem; }
  .form__input::placeholder { font-size: .95rem; }
  .form__row--check { margin: .7rem 0 .8rem; }
  .form__check    { font-size: .72rem; }
  .btn            { padding: .68rem 1rem; font-size: .95rem; }
  .panel__thanks  { max-width: 17rem; }
  .foot           { padding: 10px 1.1rem 12px; }
  .foot__left     { gap: 12px; }
}

/* ============================================================
   Coming-soon page (index.html)
   ============================================================ */
.soon {
  flex: 1 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1.6rem, 4.5vw, 2.4rem) clamp(1.1rem, 4.5vw, 2.5rem);
  text-align: center;
}
.soon__inner { width: 100%; max-width: 40rem; }
.soon__mark  { position: relative; }
.soon__lockup {
  display: block;
  margin: 0 auto;
  /* `height: auto` is mandatory, not decoration: the <img> carries a height
     attribute and that presentational hint otherwise beats the aspect ratio. */
  width: auto;
  height: auto;
  max-width: min(100%, 34rem);
  /* Sized by what is LEFT, so the whole holding page fits one screen - the
     client reported the desktop lockup pushing "Coming Soon" and everything
     below it off the bottom. The reserve covers headline + rule + lede +
     footer + padding. */
  max-height: calc(100svh - 25rem);
}
/* The holding page's one loud line. It replaces the venue and date block:
   the show is a year away and the client wants the page to say only this. */
.soon__headline {
  text-shadow: 0 2px 4px rgba(0, 0, 0, .85), 0 0 22px rgba(0, 0, 0, .6);
  margin: clamp(.9rem, 2.6vw, 1.2rem) 0 0;
  font-family: var(--font-marquee);
  font-weight: 800;
  text-transform: uppercase;
  line-height: .94;
  font-size: clamp(2.7rem, 12vw, 4.3rem);
  letter-spacing: .045em;
  color: var(--gold);
  text-wrap: balance;
}
.soon__rule {
  width: min(15rem, 62%);
  height: 1px;
  margin: clamp(1rem, 3vw, 1.25rem) auto;
  background: linear-gradient(90deg, transparent, rgba(199, 154, 58, .75), transparent);
}
.soon__line {
  /* z-index 0 makes this its own stacking context, so the plate below is
     trapped BEHIND the text but still in front of the film and the beams.
     Without it, `z-index: -1` would escape and fight .rays (also -1). */
  position: relative;
  z-index: 0;
  margin: 0 auto;
  max-width: 34rem;                /* wider = two lines on desktop, not three */
  text-wrap: pretty;               /* no orphan on the last line */
  font-family: var(--font-lede);
  font-weight: 500;
  /* Second round of "the descriptive text is quite hard to read" on mobile.
     Size and the plate below were not enough while the face was a Didone, so
     the FACE went (see --font-lede) - the sizes on both pages are untouched.
     This one stays larger than the .brand__line lede because it was the only
     copy on the holding page.

     DEAD SINCE THE 2026-09-08 CUTOVER: the holding page is gone, signup.html
     was promoted to index.html, and no page uses .soon or .soon__line any
     more. Kept rather than stripped so the cutover was a content move only.
     Safe to delete as a separate tidy-up. */
  font-size: clamp(1.2rem, 4.4vw, 1.42rem);
  line-height: 1.55;
  color: var(--cream);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .95),
               0 2px 9px rgba(0, 0, 0, .85),
               0 0 22px rgba(0, 0, 0, .7);
  text-shadow: 0 0 3px rgba(0, 0, 0, .95),
               0 1px 2px rgba(0, 0, 0, .95),
               0 0 18px rgba(0, 0, 0, .72);
}
/* A soft plate so a Didone italic holds over moving footage. Feathered to
   nothing, so it reads as shade rather than a box.
   HORIZONTAL INSET IS 0. A negative one makes this wider than its parent and
   pushes the document past the viewport - that was the 30px sideways scroll
   on .brand__halo. Spread comes from the gradient's radius instead. */

/* Desktop has more furniture below the lockup relative to its height, so it
   needs a slightly smaller reserve than phones (shorter footer, two-line lede). */
@media (min-width: 700px) {
  .soon__lockup { max-height: calc(100svh - 24rem); }
}
