/* ============================================================
   Electric Bay Festival 2027 - sign-up. Client: Louder Entertainment.
   "We're back in 2027 for our 5th anniversary."

   DIRECTION
   The client's artwork is a night beach lit by giant glowing
   jellyfish, with magenta orbs drifting through the sky. It is the
   page ground as-is (Desktop-scaled.jpg / Mobile.jpg from the old
   WordPress site, Adam-specified), with the logo on it as the h1.
   Layout is the fleet standard Adam asked for: logo + details on
   the left, sign-up on the right.

   COLOUR - literal pixels from the supplied files:
     #080C1A  night beach, average of the darkest pixels (Desktop)
     #11102A  logo ink navy                              (Overlay.png)
     #13244C  logo shadow navy                           (Overlay.png)
     #CA5FD0  magenta orb core                           (Desktop)
     #59E7EC  jellyfish tentacle cyan                    (Desktop)
   The orb is lifted to #E27CF2 for anything that carries text or the
   button: ink on it measures 7.42:1, and it reads 7.4:1 as text on
   the panel. Cyan is used for focus and completed steps only.

   TYPE - one family, Jost (OFL, variable). The logo is a heavy
   condensed athletic italic, present as an image; the live chrome
   takes the opposite register: round geometric bowls that echo the
   jellyfish bells and the orbs, sentence case, no forced capitals.

   SIGNATURE - the panel is a jellyfish bell: frosted glass over the
   artwork, with one bioluminescent edge (cyan into magenta) along the
   top. Everything else stays quiet.
   ============================================================ */

@font-face {
  font-family: "Jost";
  src: url("/assets/fonts/Jost-var.woff2?v=20260928-1") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --abyss:    #080C1A;   /* page ground */
  --ink:      #11102A;   /* logo ink - panel base, text on the button */
  --tide:     #13244C;   /* logo shadow - structure */
  --field:    #161836;   /* form field - OPAQUE on purpose, see autofill note */
  --orb:      #E27CF2;   /* lifted orb - accent text AND cta (7.42:1) */
  --orb-core: #CA5FD0;   /* literal orb - structure only */
  --glow:     #59E7EC;   /* jellyfish cyan - focus + completed steps */
  --foam:     #FFFFFF;   /* logo white - headings */
  --mist:     #AEB8D6;   /* body copy, 9.4:1 on the panel */
  --mist-dim: #8F9AC0;   /* secondary copy, 6.7:1 */
  --danger:   #FF9DB0;

  --font: "Jost", "Helvetica Neue", Arial, sans-serif;

  --maxw: 1180px;
}

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

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

/* Ground colour lives on html, NOT body: an opaque body background paints over
   the z-index:-2 .bg layer and the artwork disappears. */
html {
  -webkit-text-size-adjust: 100%;
  background: var(--abyss);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  font-family: var(--font);
  color: var(--mist);
  background: transparent;
  display: flex;
  flex-direction: column;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------- the artwork as the page ground ----------
   Four plates, chosen by aspect ratio rather than width alone: width-only
   breakpoints leave a gap at squarish window shapes where neither the phone
   nor the desktop plate applies. The <link rel=preload> conditions in the
   head mirror these four rules exactly, so nothing preloads unused. */
.bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background-color: var(--abyss);
  background-image: url("/assets/images/bg-mobile-sm.webp?v=20260928-1");
  background-position: center;
  background-size: cover;
}
@media (max-aspect-ratio: 7/10) and (min-width: 501px) {
  .bg { background-image: url("/assets/images/bg-mobile.webp?v=20260928-1"); }
}
@media (min-aspect-ratio: 7/10) {
  .bg { background-image: url("/assets/images/bg-desktop-sm.webp?v=20260928-1"); }
}
@media (min-aspect-ratio: 7/10) and (min-width: 1501px) {
  .bg { background-image: url("/assets/images/bg-desktop.webp?v=20260928-1"); }
}

/* Scrim: a light even veil so white type holds over the brightest jellyfish,
   deepening towards the foot so the footer band sits on dark sand. */
.bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(8,12,26,.22) 0%, rgba(8,12,26,.14) 45%, rgba(8,12,26,.62) 100%);
}

/* ---------- motion 0: the slow drift ----------
   The whole artwork layer (plate + glow + scrim, which are its pseudo
   elements) zooms in a few percent and drifts, then eases back, so the
   jellyfish seem to float towards you. Scale never drops below 1, so the
   edges can never show. Origin sits on the jellyfish line, not the centre,
   so they stay put while the sky and sand move around them. transform only,
   one composited layer. Off under prefers-reduced-motion. */
.bg {
  transform-origin: 50% 42%;
  will-change: transform;
  animation: drift 28s ease-in-out infinite alternate;
}
/* Pared back (Adam, 2026-09-28): the ripple now carries the jellyfish
   motion, so the drift is only a slow breath of the whole scene. */
@keyframes drift {
  0%   { transform: scale(1)     translate3d(0, 0, 0); }
  100% { transform: scale(1.05)  translate3d(-.4%, -.6%, 0); }
}

/* ---------- motion 0b: underwater ripple on the jellyfish ----------
   .jelly is a second copy of the plate (same four rules as .bg, so it lines
   up at every aspect ratio), masked to the jellyfish with a feathered PNG
   drawn in the PLATE's own coordinates and sized/positioned exactly like the
   background (cover, centre), then run through the #ripple SVG filter.
   Stacking inside .bg: plate, .jelly (0), glow ::before (1), scrim ::after (2).
   Desktop + fine pointer only: the filter repaints on the CPU every frame. */
.jelly { display: none; }
@media (min-width: 900px) and (min-aspect-ratio: 7/10) and (hover: hover) {
  .jelly {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: url("/assets/images/bg-desktop-sm.webp?v=20260928-1");
    background-position: center;
    background-size: cover;
    -webkit-mask-image: url("/assets/images/jelly-mask-desktop.png?v=20260928-1");
            mask-image: url("/assets/images/jelly-mask-desktop.png?v=20260928-1");
    -webkit-mask-size: cover;         mask-size: cover;
    -webkit-mask-position: center;    mask-position: center;
    -webkit-mask-repeat: no-repeat;   mask-repeat: no-repeat;
    filter: url(#ripple);
  }
}
@media (min-width: 1501px) and (min-aspect-ratio: 7/10) and (hover: hover) {
  .jelly { background-image: url("/assets/images/bg-desktop.webp?v=20260928-1"); }
}
.bg::before { z-index: 1; }
.bg::after  { z-index: 2; }
.fx-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------- motion 1: bioluminescent breathing ----------
   Soft glows placed where the jellyfish sit in each plate, pulsing slowly
   like living light. Screen-blended under the scrim, kept faint on purpose:
   the glow is not traced to each jellyfish, so a strong pulse would read as
   the whole image flickering. Positions: desktop plate jellyfish at ~11%,
   50% and 80% across; the mobile plate has one, centred. */
.bg::before {
  content: "";
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
  background:
    radial-gradient(34% 36% at 50% 40%, rgba(226,124,242,.62), rgba(226,124,242,0) 70%),
    radial-gradient(40% 22% at 50% 72%, rgba(89,231,236,.34), rgba(89,231,236,0) 70%);
  opacity: .25;
  animation: breathe 7s ease-in-out infinite;
}
@media (min-aspect-ratio: 7/10) {
  .bg::before {
    background:
      radial-gradient(16% 28% at 11% 38%, rgba(226,124,242,.58), rgba(226,124,242,0) 70%),
      radial-gradient(18% 30% at 50% 36%, rgba(226,124,242,.62), rgba(226,124,242,0) 70%),
      radial-gradient(16% 28% at 80% 38%, rgba(226,124,242,.58), rgba(226,124,242,0) 70%),
      radial-gradient(55% 18% at 50% 74%, rgba(89,231,236,.30), rgba(89,231,236,0) 70%);
  }
}
@keyframes breathe {
  0%, 100% { opacity: .25; }
  50%      { opacity: 1; }
}

/* ---------- motion 2: drifting orbs ----------
   Each span carries its own lane (--x), size (--s), speed (--d), start
   offset (--dl) and sideways sway (--sw) inline. transform + opacity only,
   so it stays on the compositor and is cheap on phones. Glow is a radial
   gradient, not filter:blur, for the same reason. */
.orbs {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.orb {
  position: absolute;
  left: var(--x);
  top: 100%;
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  opacity: 0;
  will-change: transform, opacity;
  animation: rise var(--d) linear var(--dl) infinite;
}
.orb--o { background: radial-gradient(circle, rgba(240,170,250,.95) 0%, rgba(226,124,242,.75) 38%, rgba(202,95,208,0) 72%); }
.orb--c { background: radial-gradient(circle, rgba(190,250,252,.95) 0%, rgba(89,231,236,.7) 38%, rgba(89,231,236,0) 72%); }
@keyframes rise {
  0%   { transform: translate3d(0, 0, 0);                              opacity: 0; }
  12%  { opacity: .85; }
  50%  { transform: translate3d(var(--sw), -60vh, 0); }
  85%  { opacity: .7; }
  100% { transform: translate3d(0, -118vh, 0);                         opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bg { animation: none; }
  .jelly { display: none !important; }
  .orbs { display: none; }
  .bg::before { animation: none; opacity: .5; }
}

/* ============================================================
   STAGE
   ============================================================ */
.stage {
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;                 /* auto at EVERY breakpoint - never plain 0 */
  padding: clamp(22px, 4vw, 54px) clamp(16px, 4vw, 40px);
  display: flex;
  align-items: center;
}
.stage__inner {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(22px, 4vw, 54px);
  align-items: center;
}

/* ---------- the bill: logo + the 2027 line ---------- */
.bill {
  justify-self: center;
  width: 100%;
  max-width: 560px;
  text-align: center;
}
/* The h1 is the logo image; its alt text carries the name. */
.bill__h1 { margin: 0; }
.bill__logo {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 18px 30px rgba(8,12,26,.55));
  animation: riseIn .9s cubic-bezier(.16,.84,.36,1) both;
}
.bill__line {
  margin: clamp(16px, 2.4vw, 26px) auto 0;
  max-width: 20ch;
  font-weight: 700;
  font-size: clamp(1.5rem, 3vw, 2.15rem);
  line-height: 1.16;
  letter-spacing: -.01em;
  color: var(--foam);
  text-wrap: balance;
  /* dark halo for legibility over the jellyfish, then the orb glow */
  text-shadow:
    0 1px 3px rgba(8,12,26,.9),
    0 2px 16px rgba(8,12,26,.8),
    0 0 26px rgba(226,124,242,.55);
  animation: riseIn .9s .2s cubic-bezier(.16,.84,.36,1) both;
}
/* the panel's bioluminescent edge, repeated under the line so the two
   halves of the page read as one */
.bill__line::after {
  content: "";
  display: block;
  width: min(140px, 40%);
  height: 3px;
  margin: clamp(12px, 1.6vw, 16px) auto 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--glow), var(--orb));
  box-shadow: 0 0 14px rgba(89,231,236,.6), 0 0 22px rgba(226,124,242,.4);
}
.bill__sub {
  margin: clamp(10px, 1.4vw, 14px) 0 0;
  font-weight: 500;
  font-size: clamp(1rem, 1.5vw, 1.15rem);
  letter-spacing: .01em;
  color: var(--mist);
  text-shadow: 0 1px 3px rgba(8,12,26,.9), 0 2px 14px rgba(8,12,26,.8);
  animation: riseIn .9s .28s cubic-bezier(.16,.84,.36,1) both;
}
@keyframes riseIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   SIGNUP PANEL - the jellyfish bell
   ============================================================ */
.signup { justify-self: center; width: 100%; max-width: 480px; }
.panel {
  width: 100%;
  position: relative;
  isolation: isolate;             /* keeps the country dropdown above the top edge */
  background: rgba(17,16,42,.80);
  -webkit-backdrop-filter: blur(16px) saturate(135%);
          backdrop-filter: blur(16px) saturate(135%);
  border: 1px solid rgba(89,231,236,.22);
  border-radius: 18px;
  box-shadow:
    0 30px 70px -30px rgba(0,0,0,.9),
    0 0 44px -18px rgba(202,95,208,.55);
  animation: riseIn .9s .12s cubic-bezier(.16,.84,.36,1) both;
  overflow: visible;
}
/* The bioluminescent 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: 22px; right: 22px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg,
    rgba(89,231,236,0), var(--glow) 22%, var(--orb) 78%, rgba(226,124,242,0));
  box-shadow: 0 0 14px rgba(89,231,236,.55), 0 0 22px rgba(226,124,242,.35);
  z-index: 0;
}
.panel__inner { position: relative; z-index: 1; padding: clamp(24px, 3.2vw, 34px); }
/* Thin glass at EVERY size (Adam, 2026-09-28: phones first, then "try that
   on desktop as well"): the panel is thinner and less blurred so the
   jellyfish show through. Fields stay OPAQUE (--field), so the typed text and
   the autofill rule are unaffected; copy keeps a soft dark halo for contrast.
   The media query below is always true, kept as the one place to scope it
   back to phones: (max-width: 899px), (max-aspect-ratio: 7/10). */
@media all {
  .panel {
    background: rgba(17,16,42,.52);
    -webkit-backdrop-filter: blur(6px) saturate(140%);
            backdrop-filter: blur(6px) saturate(140%);
  }
  .panel__title, .panel__lede, .form__check, .spine__step, .form__resend, .wa-hook {
    text-shadow: 0 1px 2px rgba(8,12,26,.85), 0 0 12px rgba(8,12,26,.6);
  }
}

/* --- 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
   Three cells driven by the same data-form-state the form logic
   sets. Numbered because it is genuinely a sequence: form, SMS
   code, email link. Sits OUTSIDE the state wrappers.
   ============================================================ */
.spine {
  display: flex;
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  border: 1px solid rgba(89,231,236,.20);
  border-radius: 10px;
  overflow: hidden;
  background: rgba(8,12,26,.45);
}
.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: 500;
  font-size: 13px;
  letter-spacing: .01em;
  color: var(--mist-dim);
  transition: color .25s ease, background-color .25s ease;
}
.spine__step + .spine__step { border-left: 1px solid rgba(89,231,236,.16); }
.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: 600;
  line-height: 1;
}
.spine__t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* current step */
.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(--orb);
  background: rgba(226,124,242,.10);
}
.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(--orb);
  border-color: var(--orb);
  color: var(--ink);
}
/* completed steps: the numeral is replaced by a cyan tick */
.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(--glow);
}
.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(--glow);
  background: rgba(89,231,236,.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(--glow);
  border-top: 0;
  border-right: 0;
  transform: rotate(-45deg) translate(1px, -1px);
}
@media (max-width: 400px) {
  .spine__step { font-size: 12px; gap: 5px; padding: 8px 3px 7px; }
  .spine__n { width: 16px; height: 16px; }
}

/* ============================================================
   PANEL COPY
   ============================================================ */
.panel__title {
  margin: 0 0 10px;
  font-weight: 600;
  font-size: clamp(1.55rem, 3.6vw, 1.9rem);
  line-height: 1.08;
  letter-spacing: -.005em;
  color: var(--foam);
  text-wrap: balance;
}
/* House pattern across the fleet: the second line of the title carries the
   accent. <em> so the emphasis is in the markup, reset from italic. */
.panel__title em { font-style: normal; color: var(--orb); }
.panel__lede {
  margin: 0 0 10px;
  font-size: 16px;
  color: var(--mist);
  max-width: 44ch;
}
.panel__lede--last { margin-bottom: 20px; }
.panel__success-note { margin: 0 0 12px; color: var(--orb); 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(--foam);
  background: var(--field);       /* OPAQUE - see the autofill rule below */
  border: 1px solid rgba(143,154,192,.34);
  border-radius: 10px;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.form__input::placeholder { color: #6E7699; }
.form__input:focus {
  outline: none;
  border-color: var(--glow);
  box-shadow: 0 0 0 3px rgba(89,231,236,.18);
}
.form__input--otp {
  font-weight: 600;
  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 trivially --field here because the field was made opaque on purpose; keep
   it opaque, or this value has to be recomputed by compositing field over the
   glass panel over the artwork. */
.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(--foam) !important;
  caret-color: var(--foam);
  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 19px; }
.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(--orb);
  cursor: pointer;
}
.form__check a { color: var(--foam); text-decoration: underline; text-underline-offset: 2px; }
.form__check a:hover { color: var(--orb); }

.form__resend {
  margin: 14px 0 0;
  font-size: 14px;
  color: var(--mist-dim);
  text-align: center;
}
.form__resend-btn {
  font: inherit;
  color: var(--orb);
  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-weight: 600;
  font-size: 1.06rem;
  letter-spacing: .01em;
  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; }
/* Ink on the lifted orb: 7.42:1. White here would be 2.5:1. */
.btn--primary {
  color: var(--ink);
  background: var(--orb);
  box-shadow: 0 12px 30px -12px rgba(226,124,242,.75);
}
.btn--primary:hover:not(:disabled) {
  filter: brightness(1.06);
  box-shadow: 0 14px 34px -12px rgba(226,124,242,.9);
}
/* 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(--foam); font-weight: 600; }

/* ============================================================
   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(--ink);
  border: 1px solid rgba(89,231,236,.30);
  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. A
     padding SHORTHAND that drops them puts the magnifier on top of the
     placeholder text. Set the vertical values, keep the horizontal ones. */
  padding: 10px 30px 10px 32px;
  width: 100%;
  font-family: var(--font);
  font-size: 15px;
  color: var(--foam);
  background: var(--field);
  border: 0;
  border-bottom: 1px solid rgba(89,231,236,.24);
}
.iti__search-input::placeholder { color: #6E7699; }
.iti__search-input:focus { outline: none; background: #1B1E42; }
.iti__country-list { background: var(--ink); max-height: 240px; }
.iti__country {
  padding: 9px 12px;
  font-family: var(--font);
  font-size: 15px;
  color: var(--foam);
}
.iti__country:hover,
.iti__country.iti__highlight { background: rgba(226,124,242,.14); }
.iti__dial-code { color: var(--mist-dim); }
.iti__country-name { color: var(--foam); }
.iti__selected-country { border-radius: 10px 0 0 10px; }
.iti__selected-country:hover,
.iti__selected-country-primary:hover { background: rgba(226,124,242,.10); }
.iti__selected-dial-code { color: var(--foam); 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 - standard fleet band (basslayerz pattern, credit in a pill)
   ============================================================ */
.foot {
  flex-shrink: 0;
  width: 100%;
  margin: 0;
  padding: 18px clamp(16px, 4vw, 40px) 26px;
  background: rgba(8,12,26,.72);
  border-top: 1px solid rgba(89,231,236,.16);
  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: 13px; color: var(--mist-dim); letter-spacing: .01em; }
.foot__legal a { color: var(--mist-dim); text-decoration: none; }
.foot__legal a:hover { color: var(--orb); }
.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(143,154,192,.30);
  border-radius: 999px;
  transition: border-color .18s ease, color .18s ease;
}
.site-built a:hover { color: var(--orb); border-color: var(--orb); }
.site-built img { display: block; opacity: .9; }

/* ============================================================
   RESPONSIVE
   Aspect-ratio thresholds, not width alone.
   ============================================================ */

/* --- two column: logo + details left, panel right --- */
@media (min-width: 900px) and (min-aspect-ratio: 7/10) {
  .stage__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 480px);
    gap: clamp(36px, 5vw, 72px);
    align-items: center;
  }
  .bill   { justify-self: center; max-width: 560px; }
  .signup { justify-self: end; }
  .foot   { justify-content: space-between; }
}

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

/* Phones: stack the footer rather than relying on the flex row wrapping.
   Around 390px the copyright + "built by" row is JUST wide enough to fill the
   band, so centring it is indistinguishable from it running edge to edge - it
   reads as left-aligned. Below 480px, force a centred column. */
@media (max-width: 480px) {
  .foot {
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding-bottom: 22px;
  }
  .foot__left {
    flex-direction: column;
    align-items: center;
    gap: 10px;
  }
  /* Portrait phones: hold the logo back so the form clears the fold. */
  .bill { max-width: min(400px, 86vw); }
  .stage { padding-top: clamp(18px, 4vw, 54px); }
  .stage__inner { gap: 20px; }
}

/* --- landscape phones are a first-class layout ---
   A rotated phone (844x390, 932x430, 667x375) satisfies the two-column
   conditions while having almost no height. Compact side-by-side, tighter
   type. 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 { padding: 14px clamp(12px, 3vw, 26px); align-items: flex-start; }
  .stage__inner {
    grid-template-columns: minmax(0, .9fr) minmax(0, 1fr);
    gap: 22px;
    align-items: center;
  }
  .bill { justify-self: center; max-width: none; min-height: 0; }
  .bill__logo { max-height: 38svh; width: auto; max-width: 100%; margin: 0 auto; }
  .bill__line { font-size: 1.2rem; margin-top: 10px; }
  .bill__line::after { margin-top: 8px; height: 2px; }
  .bill__sub { font-size: .92rem; margin-top: 6px; }
  .signup { justify-self: stretch; max-width: none; min-height: 0; }
  .panel__inner { padding: 16px 18px; }
  .spine { margin-bottom: 12px; }
  .panel__title { font-size: 1.3rem; margin-bottom: 6px; }
  .panel__lede { font-size: 14px; margin-bottom: 7px; }
  .panel__lede--last { margin-bottom: 12px; }
  .form__row { margin-bottom: 10px; }
  .form__input { padding: 10px 13px; }
  .form__row--check { margin: 12px 0 13px; }
  .btn { padding: 12px 16px; }
  .iti__country-list { max-height: 150px; }
}

/* --- small phones --- */
@media (max-width: 400px) {
  .panel__inner { padding: 22px 18px; }
}

/* ============================================================
   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(--glow);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   HOLDING PAGE (index.html while signup.html is staged)
   The logo alone, centred on the artwork, with the same orbs and
   breathing glow as the sign-up page.
   ============================================================ */
.hold__stage {
  flex: 1 0 auto;
  display: grid;
  place-items: center;
  padding: 24px 16px;
}
.hold__logo { width: min(720px, 86vw); }
@media (min-aspect-ratio: 7/10) and (max-height: 520px) {
  .hold__logo { width: auto; max-width: 70vw; max-height: 60svh; }
}
