/* ============================================================
   Electric Bay 2027: PETE TONG IBIZA CLASSICS sign-up, /petetong/
   Client: Louder Entertainment. Biggest client, flagship show.

   DIRECTION: golden hour over Tor Bay. (15 Oct: now the client's own
   backgrounds + artwork overlay, Desktop 1 / Mob / Overlay-28; the notes
   below about rebuilding the poster from layers are history.)
   The page IS the poster, rebuilt live from the client's layers
   (sky, Pete Tong + orchestra, stage + crowd, type) instead of a
   flat image in a box. On desktop the sky layer also runs edge to
   edge behind everything, so the poster column dissolves into it.

   SIGNATURE (the one bold thing): a sunrise. On load Pete Tong and
   the orchestra rise up through the haze from behind the stage,
   a sun blooms behind them and a ray burst turns very slowly.
   Everything else is still. All of it is off under
   prefers-reduced-motion.

   COLOUR - literal pixels from the supplied layers:
     #F2E79E  sun gold, sky at 19% height       (background.png)
     #F8EFE1  haze band above the sea           (background.png)
     #483D33  lockup ink                        (top.png)
     #47A0A1  Tor Bay teal, the sea band        (background.png)
     #225866  deep water                        (background.png)
     #07101E  night, the poster's foot          (background.png)
   The panel is the bay at dusk (deep water into night) with gold
   type: gold on the panel measures over 14:1, so one accent carries
   headings, the button and focus. Teal is lifted to #74C9C6 for
   completed steps only.

   TYPE - one family, Mona Sans (OFL, variable width 75-125 and
   weight 200-900), self-hosted. The poster lockup is a heavy, wide
   grotesque; headings take Mona Sans at its widest and heaviest to
   echo it, body copy sits at normal width.
   ============================================================ */

@font-face {
  font-family: "Mona Sans";
  src: url("../fonts/MonaSans-var.woff2?v=20261015-1") format("woff2");
  font-weight: 200 900;
  font-stretch: 75% 125%;
  font-style: normal;
  font-display: swap;
}

/* Outfit (OFL, variable 100-900), self-hosted: the closest free match to
   the poster's "IBIZA CLASSICS" lockup face (round geometric C, compact S,
   tight spacing), measured against the artwork 15 Oct. Panel titles only. */
@font-face {
  font-family: "Outfit";
  src: url("../fonts/Outfit-var.woff2?v=20261015-1") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --sun:      #F2E79E;
  --haze:     #F8EFE1;
  --sepia:    #483D33;
  --teal:     #47A0A1;
  --teal-hi:  #74C9C6;   /* completed steps, 8.9:1 on the panel */
  --deep:     #225866;
  --night:    #07101E;
  --field:    #0D2130;   /* form field - OPAQUE on purpose, see the autofill rule */
  --mist:     #D3DCDA;   /* body copy on the panel, ~13:1 */
  --mist-dim: #97AAAD;   /* secondary copy, ~7:1 */
  --danger:   #FFB4A8;

  --font: "Mona Sans", "Helvetica Neue", Arial, sans-serif;
  --font-title: "Outfit", "Mona Sans", "Helvetica Neue", Arial, sans-serif;

  /* two-column geometry (used inside the desktop media block) */
  --panel: clamp(360px, 30vw, 440px);
  --gap:   clamp(28px, 4vw, 72px);
  --gut:   clamp(16px, 3vw, 48px);
  --foot:  58px;          /* desktop footer band height, reserved by the layout */
}

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

/* The `hidden` attribute is only display:none in the UA stylesheet, the
   weakest layer, so ANY author rule that sets display beats it. Keep this
   ABOVE everything that sets display, and never remove it. */
[hidden] { display: none !important; }

/* Ground colour lives on html, NOT body: an opaque body paints over the
   fixed .sky layer and the plate disappears. */
html {
  -webkit-text-size-adjust: 100%;
  background: var(--night);
  /* No rubber-band bounce past the page ends (Adam, 15 Oct: the bounce
     looked like the footer stretching / a second background). */
  overscroll-behavior: none;
}
body { overscroll-behavior: none; }
body {
  margin: 0;
  min-height: 100svh;
  font-family: var(--font);
  font-stretch: 100%;
  color: var(--mist);
  background: transparent;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { max-width: 100%; }

/* ---------- the client's backgrounds, full screen ----------
   "Mob" 1080x1920 on phones / portrait, "Desktop 1" 1920x1080 on
   landscape windows (Adam, 15 Oct). The poster's stage under the golden
   sky and halo rings, no type. Fixed, so the scene stays put while the
   sign-up scrolls over it on phones. */
.sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--night) url("../images/bg-mobile-sm.webp?v=20261015-1") 50% 40% / cover no-repeat;
}
@media (min-width: 721px), (min-resolution: 2dppx) and (min-width: 361px) {
  .sky { background-image: url("../images/bg-mobile.webp?v=20261015-1"); }
}

/* ============================================================
   THE ARTWORK
   The client's overlay (Overlay-28.png) trimmed below "+ many more":
   title, date + venue, Pete Tong and the orchestra, IBIZA, the
   line-up. 1041 x 1068. On phones it is the top of the page; the
   two-column block makes it the left column.
   ============================================================ */
.art {
  position: relative;
  width: min(100%, 620px);
  margin: 0 auto;
  padding: 18px 10px 0;
}
.art__h1 { position: relative; z-index: 1; margin: 0; }
/* A soft dusk patch behind the line-up only (lower third of the overlay):
   the white names keep their contrast where they land on pale sky
   (Desktop 2 puts "5th Anniversary" / "Plus guests" on it). */
.art::after {
  content: "";
  position: absolute;
  left: 8%; right: 8%; top: 54%; bottom: -2%;
  z-index: 0;
  background: radial-gradient(closest-side, rgba(7,16,30,.42), rgba(7,16,30,.18) 60%, rgba(7,16,30,0));
  pointer-events: none;
}
.art__h1 img { display: block; width: 100%; height: auto; }

/* the two promoter logos + the licence line, together under the
   sign-up box on every layout (Adam, 15 Oct) */
.side-promoters {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 32px;
  margin-top: 30px;
}
.side-promoters img {
  display: block; width: auto; height: 40px;
  /* white logos over a light sky/stage (Adam, 15 Oct: "can't see them"):
     a tight dark edge plus a soft wide glow, in the poster's night */
  filter: drop-shadow(0 1px 1px rgba(7,16,30,.95)) drop-shadow(0 0 10px rgba(7,16,30,.75));
}
.licence {
  margin: 14px 0 0;
  font-size: 11px;
  letter-spacing: .02em;
  color: var(--haze);
  text-align: center;
  text-shadow: 0 1px 2px rgba(7,16,30,.95), 0 0 10px rgba(7,16,30,.8);
}

/* ---------- the sunrise ----------
   Behind the overlay: a sun blooms on Pete Tong's face (48% across,
   32% down the overlay) and a ray burst turns very slowly; the overlay
   itself rises in. transform + opacity only on phones; on desktop the
   overlay also burns in through the haze once. All off under
   prefers-reduced-motion. */
.art__sun,
.art__rays {
  position: absolute;
  left: 48%;
  top: 32%;
  aspect-ratio: 1;
  pointer-events: none;
  z-index: 0;
}
.art__sun {
  width: 95%;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    rgba(255,250,224,.9) 0%, rgba(255,242,186,.55) 42%, rgba(255,234,156,0) 100%);
  transform: translate(-50%, -50%);
  animation:
    sun-bloom 3.2s cubic-bezier(.2,.75,.25,1) .1s both,
    sun-breathe 9s ease-in-out 3.4s infinite alternate;
}
.art__rays {
  width: 175%;
  background: repeating-conic-gradient(from 0deg,
    rgba(255,248,218,0) 0deg 5deg,
    rgba(255,248,218,.75) 8.5deg,
    rgba(255,248,218,0) 12deg 18deg);
  -webkit-mask-image: radial-gradient(closest-side, rgba(0,0,0,0) 9%, #000 22%, rgba(0,0,0,.35) 52%, rgba(0,0,0,0) 78%);
          mask-image: radial-gradient(closest-side, rgba(0,0,0,0) 9%, #000 22%, rgba(0,0,0,.35) 52%, rgba(0,0,0,0) 78%);
  opacity: .45;
  transform: translate(-50%, -50%);
  animation:
    rays-in 2.4s ease-out 1.1s both,
    rays-turn 240s linear infinite;
}
.art__h1 img { animation: rise 2.4s cubic-bezier(.19,.8,.22,1) .15s both; }
@keyframes sun-bloom {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.35); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes sun-breathe {
  from { opacity: 1; }
  to   { opacity: .72; }
}
@keyframes rays-in {
  from { opacity: 0; }
  to   { opacity: .45; }
}
@keyframes rays-turn {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes rise {
  from { opacity: 0; transform: translate3d(0, 4%, 0) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@media (min-width: 900px) and (hover: hover) {
  .art__h1 img { animation-name: rise-haze; }
  @keyframes rise-haze {
    0%   { opacity: 0; transform: translate3d(0, 4%, 0) scale(.98); filter: blur(8px) brightness(1.4); }
    60%  { filter: blur(0) brightness(1.08); }
    100% { opacity: 1; transform: none; filter: none; }
  }
}

/* ============================================================
   STAGE + SIDE COLUMN (phones / portrait first)
   ============================================================ */
/* overflow: clip, so the sun-ray layer behind the artwork (1.75x the
   artwork's width, overhanging it) can never add page length or width.
   Before this it made every desktop window 26-95px too tall to fit, which
   was the scroll + "second background" under the footer (measured 15 Oct).
   clip, not hidden: hidden would make .stage a scroll container. */
.stage { display: block; overflow: hidden; overflow: clip; }
.side {
  padding: 6px 16px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.signup { width: 100%; max-width: 480px; }

/* ============================================================
   SIGN-UP PANEL: the bay at dusk
   ============================================================ */
.panel {
  width: 100%;
  position: relative;
  isolation: isolate;             /* keeps the country dropdown above the edge line */
  background: linear-gradient(172deg, #1C4B59 0%, #0D2433 42%, #08131F 100%);
  border: 1px solid rgba(242,231,158,.20);
  border-radius: 16px;
  box-shadow: 0 34px 80px -34px rgba(0,0,0,.85), 0 0 0 1px rgba(7,16,30,.4);
  overflow: visible;
}
/* The horizon: one line of low sun on the water along the top edge. Inset
   from the corners so it never has to follow the radius, which keeps
   overflow visible for the country dropdown. */
.panel::before {
  content: "";
  position: absolute;
  top: -1px; left: 26px; right: 26px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(242,231,158,0), var(--sun) 35%, #FFF8DC 50%, var(--sun) 65%, rgba(242,231,158,0));
  box-shadow: 0 0 18px rgba(242,231,158,.55);
  z-index: 0;
}
.panel__inner { position: relative; z-index: 1; padding: clamp(24px, 3vw, 34px); }

/* --- state machine (app.js flips data-form-state on .panel) --- */
.panel__state { display: none; }
.panel[data-form-state="idle"]    .panel__idle    { display: block; }
.panel[data-form-state="otp"]     .panel__otp     { display: block; }
.panel[data-form-state="success"] .panel__success { display: block; }

/* ---------- step spine ---------- */
.spine {
  display: flex;
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
  border: 1px solid rgba(242,231,158,.18);
  border-radius: 10px;
  overflow: hidden;
  background: rgba(7,16,30,.42);
}
.spine__step {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 6px 8px;
  font-weight: 520;
  font-size: 13px;
  color: var(--mist-dim);
  transition: color .25s ease, background-color .25s ease;
}
.spine__step + .spine__step { border-left: 1px solid rgba(242,231,158,.14); }
.spine__n {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  display: grid;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
}
.spine__t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.panel[data-form-state="idle"]    .spine__step:nth-child(1),
.panel[data-form-state="otp"]     .spine__step:nth-child(2),
.panel[data-form-state="success"] .spine__step:nth-child(3) {
  color: var(--sun);
  background: rgba(242,231,158,.08);
}
.panel[data-form-state="idle"]    .spine__step:nth-child(1) .spine__n,
.panel[data-form-state="otp"]     .spine__step:nth-child(2) .spine__n,
.panel[data-form-state="success"] .spine__step:nth-child(3) .spine__n {
  background: var(--sun);
  border-color: var(--sun);
  color: var(--night);
}
.panel[data-form-state="otp"]     .spine__step:nth-child(1),
.panel[data-form-state="success"] .spine__step:nth-child(1),
.panel[data-form-state="success"] .spine__step:nth-child(2) { color: var(--teal-hi); }
.panel[data-form-state="otp"]     .spine__step:nth-child(1) .spine__n,
.panel[data-form-state="success"] .spine__step:nth-child(1) .spine__n,
.panel[data-form-state="success"] .spine__step:nth-child(2) .spine__n {
  font-size: 0;                    /* hide the digit, keep the ring */
  border-color: var(--teal-hi);
  background: rgba(116,201,198,.14);
}
.panel[data-form-state="otp"]     .spine__step:nth-child(1) .spine__n::after,
.panel[data-form-state="success"] .spine__step:nth-child(1) .spine__n::after,
.panel[data-form-state="success"] .spine__step:nth-child(2) .spine__n::after {
  content: "";
  width: 7px; height: 4px;
  border: 1.5px solid var(--teal-hi);
  border-top: 0;
  border-right: 0;
  transform: rotate(-45deg) translate(1px, -1px);
}

/* ---------- panel copy ---------- */
/* Capitals in the poster lockup's face (Adam, 15 Oct). The words stay
   sentence case in the markup; the capitals are styling only. */
.panel__title {
  margin: 0 0 12px;
  font-family: var(--font-title);
  font-weight: 860;
  font-size: clamp(2rem, 2.7vw, 2.6rem);
  line-height: .98;
  letter-spacing: -.01em;
  text-transform: uppercase;
  color: var(--haze);
  text-wrap: balance;
}
/* House pattern: the second line carries the accent. <em> so the emphasis is
   in the markup, reset from italic. */
.panel__title em { font-style: normal; color: var(--sun); }
.panel__lede {
  margin: 0 0 10px;
  font-size: 16px;
  color: var(--mist);
  max-width: 44ch;
}
.panel__lede--last { margin-bottom: 22px; }
.panel__success-note { margin: 0 0 12px; color: var(--sun); font-size: 15px; }

/* ---------- form ---------- */
.form__row { margin: 0 0 13px; }
/* labels stay for screen readers; placeholders carry the meaning visually */
.form__label {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.form__input {
  width: 100%;
  padding: 13px 15px;
  font-family: var(--font);
  font-size: 16px;                /* 16px minimum or iOS zooms the page on focus */
  color: var(--haze);
  background: var(--field);       /* OPAQUE - see the autofill rule below */
  border: 1px solid rgba(151,170,173,.32);
  border-radius: 10px;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.form__input::placeholder { color: #71878C; }
.form__input:focus {
  outline: none;
  border-color: var(--sun);
  box-shadow: 0 0 0 3px rgba(242,231,158,.18);
}
.form__input--otp {
  font-weight: 650;
  font-size: 22px;
  letter-spacing: .42em;
  text-align: center;
  text-indent: .42em;             /* re-centres text that tracking pushes left */
}

/* Chrome paints autofilled inputs pale lavender and IGNORES background /
   background-color on :-webkit-autofill; a huge inset box-shadow is the only
   reliable override. A box-shadow cannot be semi-transparent, so the colour
   must be the FLATTENED OPAQUE equivalent of the field's rendered stack. That
   is exactly --field because the field is opaque on purpose; keep it opaque,
   or this value has to be recomputed. */
.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) inset !important;
          box-shadow: 0 0 0 1000px var(--field) inset !important;
  -webkit-text-fill-color: var(--haze) !important;
  caret-color: var(--haze);
  transition: background-color 9999s ease-in-out 0s;   /* stops the lavender flashing in */
}

.form__error { margin: 7px 0 0; font-size: 14px; color: var(--danger); }
.form__error--global { margin-top: 14px; }

/* Honeypot. display:none ONLY - off-screen positioning stays an autofill
   target in Chrome/Edge, which fills it and silently blocks real signups.
   The markup also carries the `hidden` attribute as a second guard. */
.hp-row { display: none !important; }

.form__row--check { margin: 17px 0 20px; }
.form__check {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--mist);
  cursor: pointer;
}
.form__check input {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  margin: 1px 0 0;
  accent-color: var(--sun);
  cursor: pointer;
}
.form__check a { color: var(--haze); text-decoration: underline; text-underline-offset: 2px; }
.form__check a:hover { color: var(--sun); }

.form__resend { margin: 14px 0 0; font-size: 14px; color: var(--mist-dim); text-align: center; }
.form__resend-btn {
  font: inherit;
  color: var(--sun);
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.form__resend-btn:disabled { color: var(--mist-dim); cursor: default; text-decoration: none; }

/* ---------- buttons ---------- */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 15px 18px;
  font-family: var(--font);
  font-stretch: 112%;
  font-weight: 760;
  font-size: 1.06rem;
  letter-spacing: .005em;
  white-space: nowrap;            /* shrink the type before it can ever wrap */
  text-align: center;
  text-decoration: none;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  transition: transform .12s ease, filter .18s ease, box-shadow .18s ease;
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .6; cursor: default; }
/* Night on sun gold: 15.6:1. */
.btn--primary {
  color: var(--night);
  background: var(--sun);
  box-shadow: 0 14px 34px -14px rgba(242,231,158,.7);
}
.btn--primary:hover:not(:disabled) {
  filter: brightness(1.05);
  box-shadow: 0 16px 38px -12px rgba(242,231,158,.85);
}
/* WhatsApp brand green; dark green type on it, as fleet-wide. */
.btn--whatsapp { color: #06301A; background: #25D366; margin-top: 4px; }
.btn--whatsapp:hover { filter: brightness(1.06); }
.btn__icon { flex: 0 0 auto; width: 20px; height: 20px; }

.wa-hook { margin: 18px 0 12px; font-size: 15px; color: var(--mist); }
.wa-hook strong { color: var(--haze); font-weight: 650; }

/* ============================================================
   intl-tel-input v25
   ============================================================ */
.iti { width: 100%; display: block; }
/* app.js re-measures and sets padding-left inline; this is the sane default
   before it runs. Anything >= 80px breaks 320-390px viewports. */
.iti input.form__input { padding-left: calc(52px + 0.7rem); }
.iti__country-container { z-index: 3; }
.iti--inline-dropdown .iti__dropdown-content { z-index: 50; }
/* Until the vendor stylesheet loads, the hidden state does not exist and the
   whole list plus search box flashes open on first paint. */
.iti__dropdown-content.iti__hide { display: none !important; }
.iti__dropdown-content {
  background: var(--night);
  border: 1px solid rgba(242,231,158,.26);
  border-radius: 10px;
  box-shadow: 0 26px 56px -18px rgba(0,0,0,.94);
  overflow: hidden;
}
.iti__search-input {
  /* Keep the vendor's horizontal padding reservation: 30px left clears the
     absolutely positioned search icon, 28px right clears the clear button. */
  padding: 10px 30px 10px 32px;
  width: 100%;
  font-family: var(--font);
  font-size: 15px;
  color: var(--haze);
  background: var(--field);
  border: 0;
  border-bottom: 1px solid rgba(242,231,158,.22);
}
.iti__search-input::placeholder { color: #71878C; }
.iti__search-input:focus { outline: none; background: #12293A; }
.iti__country-list { background: var(--night); max-height: 240px; }
.iti__country { padding: 9px 12px; font-family: var(--font); font-size: 15px; color: var(--haze); }
.iti__country:hover,
.iti__country.iti__highlight { background: rgba(242,231,158,.12); }
.iti__dial-code { color: var(--mist-dim); }
.iti__country-name { color: var(--haze); }
.iti__selected-country { border-radius: 10px 0 0 10px; }
.iti__selected-country:hover,
.iti__selected-country-primary:hover { background: rgba(242,231,158,.08); }
.iti__selected-dial-code { color: var(--haze); font-family: var(--font); font-size: 16px; }
.iti__arrow { border-top-color: var(--mist-dim); }
.iti__arrow--up { border-bottom-color: var(--mist-dim); }

/* ============================================================
   FOOTER - fleet pattern, credit in a pill. Sits on night.
   ============================================================ */
/* A full-width band along the foot of the page (Adam, 15 Oct): night,
   with the same faint gold line as the panel edges. */
.foot {
  position: relative;
  z-index: 2;
  width: 100%;
  margin: 26px 0 0;
  padding: 16px var(--gut) 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px 22px;
  flex-wrap: wrap;
  text-align: center;
  background: rgba(7,16,30,.9);
  border-top: 1px solid rgba(242,231,158,.14);
}
.foot__left { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: center; }
.foot__legal { margin: 0; font-size: 13px; color: var(--mist-dim); }
.foot__legal a { color: var(--mist-dim); text-decoration: none; }
.foot__legal a:hover { color: var(--sun); }
.foot__links { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; }
.site-built { margin: 0; }
.site-built a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  font-size: 12.5px;
  color: var(--mist-dim);
  text-decoration: none;
  border: 1px solid rgba(151,170,173,.30);
  border-radius: 999px;
  transition: border-color .18s ease, color .18s ease;
}
.site-built a:hover { color: var(--sun); border-color: var(--sun); }
.site-built img { display: block; opacity: .9; }

/* Phones: stack the footer rather than relying on the flex row wrapping. */
@media (max-width: 480px) {
  .foot { flex-direction: column; gap: 10px; }
  .foot__left { flex-direction: column; gap: 10px; }
}

/* ============================================================
   TWO COLUMNS: artwork left, sign-up right.
   Desktop (900px+ wide, not portrait) and landscape phones. The
   artwork is as tall as the window allows above the footer band, or
   narrower when the window cannot fit both columns. The desktop
   background takes over from the mobile one.
   ============================================================ */
@media (min-width: 900px) and (min-aspect-ratio: 7/10),
       (min-width: 640px) and (min-aspect-ratio: 1/1) and (max-height: 520px) {
  :root {
    --apad: 28px;                                   /* artwork's top/bottom breathing room */
    --aw: min(calc((100svh - var(--foot) - 2 * var(--apad)) * 1041 / 1068),
              calc(100vw - var(--panel) - var(--gap) - 2 * var(--gut)));
  }
  /* "Desktop 2" (Adam, 15 Oct; chosen over Desktop 1): the whole bay, stage
     between the artwork and the sign-up box. Fills the WHOLE window: .sky is
     position:fixed, so stopping it at the footer band left a fixed dark strip
     at the foot of the screen that stayed put while the page scrolled. */
  /* Desktop: the scene belongs to the content area, NOT the window. As a
     position:fixed layer it stayed put while the page scrolled on short
     windows, and showed again beneath the footer like a second background
     (Adam's screenshot, 15 Oct). Absolute inside .stage, it scrolls with the
     page and ends at the footer's top edge, the sea just above the band. */
  .sky {
    position: absolute;
    inset: 0;
    background-image: url("../images/bg-desktop-sm.webp?v=20261015-2");
    background-position: 50% 100%;
  }
  .stage {
    position: relative;
    display: grid;
    grid-template-columns: var(--aw) var(--panel);
    column-gap: var(--gap);
    justify-content: center;
    align-items: center;
    min-height: calc(100svh - var(--foot));
    padding: 0 var(--gut);
  }
  .art {
    width: var(--aw);
    margin: 0;
    padding: 0;
    position: sticky;
    top: var(--apad);
  }
  .side-promoters { gap: clamp(28px, 3vw, 48px); margin-top: 26px; }
  .side-promoters img { height: clamp(40px, 4.6vh, 56px); }
  .side {
    position: relative;
    z-index: 1;
    min-height: calc(100svh - var(--foot));
    padding: 28px 0;
    align-items: stretch;
    justify-content: center;
  }
  .signup { max-width: none; }
  /* one row, edge to edge: legal + credit left, links right */
  .foot {
    min-height: var(--foot);
    margin: 0;
    padding: 12px var(--gut);
    justify-content: space-between;
    text-align: left;
  }
  .foot__left { justify-content: flex-start; }
}
@media (min-width: 900px) and (min-aspect-ratio: 7/10) and (min-width: 1500px),
       (min-width: 900px) and (min-aspect-ratio: 7/10) and (min-resolution: 2dppx) {
  .sky { background-image: url("../images/bg-desktop.webp?v=20261015-2"); }
}

/* --- see-through sign-up box, EVERY layout (Adam, 15 Oct: phones first,
   then "the same transparent on desktop as well") ---
   The dusk gradient at ~70% with a light blur, so the stage shows through.
   Fields stay OPAQUE (--field), so typed text and the autofill rule are
   unchanged; copy gets a faint dark halo to stay crisp over the stage. */
@media all {
  .panel {
    background: linear-gradient(172deg, rgba(28,75,89,.68) 0%, rgba(13,36,51,.72) 42%, rgba(8,19,31,.78) 100%);
    -webkit-backdrop-filter: blur(7px) saturate(130%);
            backdrop-filter: blur(7px) saturate(130%);
  }
  .panel__title, .panel__lede, .form__check, .spine__step, .form__resend, .wa-hook {
    text-shadow: 0 1px 2px rgba(7,16,30,.8), 0 0 12px rgba(7,16,30,.5);
  }
}

/* --- short desktop windows: FIT, never scroll (Adam, 15 Oct) ---
   Desktop is one screen, no scrolling. At 1440x900 everything fits; on
   short windows (e.g. 1800x598) the sign-up column used to run ~600px and
   push the page into a scroll. These two steps tighten the column so it
   fits above the footer band instead. */
@media (min-width: 900px) and (min-aspect-ratio: 7/10) and (max-height: 760px) {
  .side { padding: 14px 0; }
  .panel__inner { padding: 20px 24px; }
  .spine { margin-bottom: 14px; }
  .spine__step { padding: 6px 4px; }
  .panel__title { font-size: 1.75rem; margin-bottom: 8px; }
  .panel__lede { font-size: 14.5px; line-height: 1.45; }
  .panel__lede--last { margin-bottom: 14px; }
  .form__row { margin-bottom: 9px; }
  .form__input { padding: 10px 13px; }
  .form__row--check { margin: 10px 0 12px; }
  .form__check { font-size: 12.5px; line-height: 1.4; }
  .btn { padding: 12px 16px; }
  .side-promoters { margin-top: 14px; }
  .side-promoters img { height: 34px; }
  .licence { margin-top: 8px; }
  :root { --apad: 16px; }
}
@media (min-width: 900px) and (min-aspect-ratio: 7/10) and (max-height: 640px) {
  .spine { display: none; }
  .panel__inner { padding: 16px 22px; }
  .panel__title { font-size: 1.5rem; }
  .panel__lede { font-size: 13.5px; margin-bottom: 6px; }
  .panel__lede--last { margin-bottom: 10px; }
  .form__row--check { margin: 8px 0 10px; }
  .form__check { font-size: 12px; }
  .side-promoters { margin-top: 10px; }
  .side-promoters img { height: 28px; }
  .wa-hook { margin: 10px 0 8px; }
}

/* --- landscape phones are a first-class layout ---
   A rotated phone (844x390, 932x430, 667x375) has almost no height, so the
   poster column is ~290px wide and the panel tightens. Placed AFTER the
   desktop block so it wins at equal specificity. */
@media (min-width: 640px) and (min-aspect-ratio: 1/1) and (max-height: 520px) {
  .stage { --panel: min(400px, 54vw); --gap: 20px; --gut: 12px; }
  .side { padding-top: 12px; }
  .panel__inner { padding: 16px 18px; }
  .spine { margin-bottom: 12px; }
  .spine__step { padding: 6px 4px; font-size: 12px; }
  .panel__title { font-size: 1.4rem; margin-bottom: 6px; }
  .panel__lede { font-size: 14px; margin-bottom: 7px; }
  .panel__lede--last { margin-bottom: 12px; }
  .form__row { margin-bottom: 9px; }
  .form__input { padding: 10px 13px; }
  .form__row--check { margin: 11px 0 12px; }
  .form__check { font-size: 12.5px; }
  .btn { padding: 12px 16px; }
  .iti__country-list { max-height: 150px; }
  :root { --foot: 48px; }   /* = the compact footer's real height (measured), so short windows fit exactly */
  .foot { padding: 8px var(--gut); }
}

/* --- small phones --- */
@media (max-width: 400px) {
  .panel__inner { padding: 22px 18px; }
  .spine__step { font-size: 12px; gap: 5px; padding: 8px 3px 7px; }
  .spine__n { width: 16px; height: 16px; }
}

/* ============================================================
   ACCESSIBILITY
   ============================================================ */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
:focus-visible { outline: 2px solid var(--sun); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .art__sun, .art__rays, .art__h1 img { animation: none !important; }
  .art__rays { opacity: .4; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
