/* ============================================================
   DJ EZ · NX Newcastle

   Same grammar as the East End Dubs build, re-derived from this
   poster rather than recoloured from that one.

   The artwork bills by FILL vs OUTLINE: DJ EZ sits in a solid
   box, ARTHI / DIFFRENT / FONZO / + MORE TBA in outlined boxes
   butted against each other with ragged right edges. Filled
   means "the name that sells the ticket". That rule runs the
   page: a solid bar for the venue, an outlined box butted under
   it for everything secondary, a submit button that is filled at
   rest and inverts to outline on hover, and a field label that
   promotes from ghost outline to solid chip when you focus it.

   POLARITY IS INVERTED against East End Dubs: DJ EZ is a dark box
   on a light ground where East End Dubs was ink on acid. What
   carries over is the contrast RELATIONSHIP, not the literal
   values - so on this dark page the filled bar is ice-on-ink.

   WHAT IS DELIBERATELY NOT HERE (2026-08-13, client): the panel
   sets the venue bar and nothing else. Earlier cuts also set the
   line-up as a stack of butted boxes and the date as an outlined
   box under the bar; both were pulled - the line-up because the
   artwork beside the panel already carries the full billing and
   setting it twice read as a duplicate, the date because the
   client withdrew it. The outlined box under the bar is the
   growth slot for whichever returns first. If the date comes
   back, the JSON-LD has to become a dated MusicEvent in the same
   change, and the OG card and llms.txt have to be rebuilt.

   Consequences of taking the poster seriously: no border-radius,
   no gradients, no glow. The source is hard-edged flat colour,
   so the page is too. Grain sits at .11 - roughly 3x a normal
   dither pass - because the artwork genuinely is that noisy and
   a clean surface next to it reads as a mistake.

   Type: Archivo (display) is a tighter, squarer neo-grotesque
   than Instrument Sans and sits closer to this poster's own
   lettering, which is noticeably more condensed than East End
   Dubs'. Body is the system Helvetica stack - that same genre,
   at no cost.

   Palette sampled from the supplied artwork. #95B6D7 is not a
   guess: it is the DJ EZ letterform, the NX mark and the NX LOVE
   mark, i.e. the one colour the poster uses three times.
   ============================================================ */

:root {
  --ice:      #95B6D7;   /* the DJ EZ letterform - the accent */
  --ice-hi:   #BBD6E7;   /* the "A-Z" tint, lifted: active press state */
  --ice-lo:   #7E93A5;   /* where grain darkens it: muted meta text */
  --ink:      #0B121C;   /* page base - cold near-black, not warm */
  --ink-2:    #131C28;   /* panel */
  --ink-3:    #1B2530;   /* field wells (opaque - see the autofill note) */
  --line:     #2B3A4B;   /* hairline, navy so it stays in the family */
  --bone:     #E6EEF5;   /* body copy on ink - cool white, not cream */
  --body-dim: #AFC0CF;   /* lede / secondary copy */
  --danger:   #FF8B6E;
  --whatsapp: #25D366;

  --display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --body:    "Helvetica Neue", Helvetica, Arial, sans-serif;

  --maxw: 1180px;
}

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

/* Base 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(--ink);
}

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

/* ---------- background: the poster, blurred into an ink field ---------- */
.bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background-color: var(--ink);
  background-image: url("/assets/images/bg-mobile.jpg?v=20260813-1");
  background-image: image-set(
    url("/assets/images/bg-mobile.webp?v=20260813-1") type("image/webp"),
    url("/assets/images/bg-mobile.jpg?v=20260813-1")  type("image/jpeg"));
  background-position: center;
  background-size: cover;
}
@media (min-width: 768px) and (min-aspect-ratio: 7/10) {
  .bg {
    background-image: url("/assets/images/bg-desktop.jpg?v=20260813-1");
    background-image: image-set(
      url("/assets/images/bg-desktop.webp?v=20260813-1") type("image/webp"),
      url("/assets/images/bg-desktop.jpg?v=20260813-1")  type("image/jpeg"));
  }
}
/* An ink wash rather than black: this field is derived from the poster, so
   it is atmosphere, not artwork, and it has to sit well behind ice type
   without going grey. */
.bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(11,18,28,.62) 0%,
    rgba(11,18,28,.82) 52%,
    rgba(11,18,28,.94) 100%);
}

/* ---------- grain ----------
   The poster is heavily grained; matching it is the point, so this sits
   far higher than the usual dither pass. */
.grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .11;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================
   STAGE LAYOUT
   ============================================================ */
.stage {
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(20px, 4vw, 56px) clamp(16px, 4vw, 40px);
  display: flex;
  align-items: center;
}
.stage__inner {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(26px, 4vw, 52px);
  align-items: center;
}

/* ---------- the poster ----------
   Hard shadow, no frame: the artwork already has its own edge. */
.poster {
  justify-self: center;
  width: 100%;
  max-width: 600px;
}
.poster__frame {
  position: relative;
  box-shadow: 0 18px 44px -14px rgba(0,0,0,.85);
  animation: posterIn .8s cubic-bezier(.16,.84,.36,1) both;
}
.poster img {
  display: block;
  width: 100%;
  height: auto;
}
@keyframes posterIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   SIGNUP PANEL
   ============================================================ */
.panel {
  justify-self: center;
  width: 100%;
  max-width: 520px;
  position: relative;
  isolation: isolate;                 /* keeps the flag dropdown clickable */
  background: rgba(19,28,40,.94);
  border: 1px solid var(--line);
  box-shadow: 0 30px 64px -28px rgba(0,0,0,.9);
  animation: panelIn .8s .1s cubic-bezier(.16,.84,.36,1) both;
  overflow: visible;
}
/* the ice edge — a printed rule, not a gradient bar */
.panel::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--ice);
  z-index: 0;
}
@keyframes panelIn {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
.panel__inner { position: relative; z-index: 1; padding: clamp(26px, 3.4vw, 40px); }

/* --- 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="success"] .panel__success { display: block; }

/* ============================================================
   THE BILLING BLOCK — the poster's fill/outline rule
   A solid ice bar for the fact that sells (the venue), an
   outlined box butted under it sharing its edge, the way the
   support boxes butt under DJ EZ on the poster.
   ============================================================ */
.billing { margin: 0 0 18px; }
.billing__row { display: block; }

.billing__bar {
  display: inline-block;
  margin: 0;
  padding: 7px 12px 6px;
  background: var(--ice);
  color: var(--ink);
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(13px, 3.2vw, 15px);
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.1;
}

/* Butted against the bar above, sharing its edge. */
.billing__box {
  display: inline-block;
  margin: -1px 0 0;
  padding: 5px 11px 4px;
  border: 1px solid var(--ice);
  color: var(--ice);
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(11.5px, 2.9vw, 13px);
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.15;
}
/* ---------- title ---------- */
.panel__title {
  margin: 0 0 14px;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2rem, 5.6vw, 2.65rem);
  line-height: 1.0;
  letter-spacing: -.03em;
  color: var(--bone);
  text-wrap: balance;
}

/* visually hidden but kept for screen readers + SEO */
.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;
}

.panel__lede {
  margin: 0 0 10px;
  font-size: 15.5px;
  color: var(--body-dim);
  max-width: 46ch;
}
.panel__lede--last { margin-bottom: 24px; }
.panel__lede strong { color: var(--bone); font-weight: 700; }
.panel__success-note {
  margin: 0 0 12px;
  color: var(--ice);
  font-size: 15px;
}

/* ============================================================
   FORM
   ============================================================ */
.form__row { position: relative; margin: 0 0 16px; }
/* the focused row must sit above later rows so the country dropdown
   is not painted over by the consent block or the submit button */
.form__row:focus-within { z-index: 20; }

/* --- THE LABEL CHIP ---
   At rest a ghost outline; on focus it fills ice. The same fill/outline
   promotion the poster uses, applied to whichever field you are in. */
.form__label {
  display: inline-block;
  margin: 0 0 7px;
  padding: 3px 8px 2px;
  border: 1px solid var(--line);
  background: transparent;
  font-family: var(--display);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ice-lo);
  transition: background-color .12s linear, color .12s linear, border-color .12s linear;
}
.form__row:focus-within .form__label {
  background: var(--ice);
  border-color: var(--ice);
  color: var(--ink);
}

.form__input {
  width: 100%;
  font-family: var(--body);
  font-size: 16px;             /* >=16px stops iOS zoom-on-focus */
  color: var(--bone);
  background: var(--ink-3);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 13px 14px;
  transition: border-color .12s linear;
}
.form__input::placeholder { color: #7E93A5; }
.form__input:focus {
  outline: none;
  border-color: var(--ice);
}
.form__input[aria-invalid="true"] { border-color: var(--danger); }

/* --- Chrome autofill ---
   :-webkit-autofill ignores background/background-color, so the only
   reliable override is a huge inset box-shadow. The shadow colour must be
   the flattened OPAQUE equivalent of the field's rendered stack. Here the
   field well (--ink-3) is already an opaque hex sitting on the panel, so
   the flattened value IS #1B2530 - no compositing needed. If the well is
   ever changed to an rgba(), this literal has to be recomputed against
   whatever ends up behind it. The 9999s transition stops Chrome flashing
   its lavender in before the shadow paints. */
.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 #1B2530 inset !important;
          box-shadow: 0 0 0 1000px #1B2530 inset !important;
  -webkit-text-fill-color: var(--bone) !important;
  caret-color: var(--bone);
  transition: background-color 9999s ease-in-out 0s;
}

.form__error {
  margin: 6px 0 0;
  color: var(--danger);
  font-size: 13px;
}
.form__error--global { margin-top: 12px; }

/* ---------- honeypot (spam trap) ----------
   display:none, NOT left:-9999px: off-screen honeypots get autofilled by
   Chrome/Edge and silently block real signups. */
.hp-row { display: none !important; }

/* ---------- consent ---------- */
.form__row--check { margin-top: 4px; }
.form__check {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin: 0 0 22px;
  cursor: pointer;
  font-size: 13px;
  color: #9DB0C1;
  line-height: 1.55;
}
.form__check input {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  accent-color: var(--ice);
  cursor: pointer;
}
.form__check a { color: var(--ice); text-underline-offset: 2px; }

/* ---------- submit: filled at rest, inverts on hover ----------
   The one flourish on the page. Filled = primary, so the button starts
   filled; hovering flips it to the outlined state and back, which is the
   poster's own billing rule played as an interaction. */
.btn-signup {
  display: block;
  width: 100%;
  cursor: pointer;
  color: var(--ink);
  background: var(--ice);
  border: 1px solid var(--ice);
  border-radius: 0;
  padding: 0;
  transition: background-color .09s linear, color .09s linear;
}
.btn-signup .btn__text {
  display: block;
  padding: 15px 18px;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.18rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.btn-signup:hover:not(:disabled) {
  background: transparent;
  color: var(--ice);
}
.btn-signup:active:not(:disabled) { background: var(--ice-hi); color: var(--ink); }
.btn-signup:disabled {
  background: transparent;
  border-color: var(--line);
  color: var(--ice-lo);
  cursor: default;
}

/* ---------- success state ---------- */
.panel__success { text-align: left; }
.panel__success .panel__lede { margin-bottom: 16px; }

/* The WhatsApp incentive: a rule in the group's own green ties the line to
   the button under it, so the "30 minutes early" hook reads as one unit
   with the CTA rather than as more body copy. */
.wa-hook {
  margin: 0 0 12px;
  padding-left: 12px;
  border-left: 3px solid var(--whatsapp);
  font-size: 14px;
  line-height: 1.5;
  color: var(--bone);
}
.wa-hook strong { color: var(--whatsapp); font-weight: 700; white-space: nowrap; }

.btn-whatsapp {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--whatsapp);
  color: #06130a;
  text-decoration: none;
  text-align: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .02em;
  padding: 13px 20px;
  border: 1px solid var(--whatsapp);
  transition: background-color .09s linear, color .09s linear;
}
.btn-whatsapp:hover { background: transparent; color: var(--whatsapp); }
.btn-whatsapp svg { flex: 0 0 auto; }

/* Invite link not supplied yet: app.js strips the href and stamps
   [data-pending]. The button stays visible (the "30 minutes early" offer is
   the point) but must not look or behave clickable - so it drops to the
   outlined state permanently, with no hover and a default cursor. */
.btn-whatsapp[data-pending] {
  background: transparent;
  color: var(--whatsapp);
  border-color: rgba(37,211,102,.55);
  opacity: .8;
  cursor: default;
}
.btn-whatsapp[data-pending]:hover {
  background: transparent;
  color: var(--whatsapp);
}

/* ============================================================
   intl-tel-input (v25) — squared dark theme + searchable dropdown
   ============================================================ */
.iti { width: 100%; display: block; }
.iti input.form__input { padding-left: calc(52px + 0.7rem); } /* re-measured by repadPhone() */
/* Transparent, not a colour of its own: the country selector overlays the
   input's left padding, so anything but transparent paints a darker slab
   inside the field with a visible seam where it meets the well. */
.iti__selected-country {
  background: transparent;
  border-radius: 0;
  color: var(--bone);
}
.iti__selected-country:hover,
.iti__selected-country-primary:hover { background: #223040; }
.iti--separate-dial-code .iti__selected-dial-code { color: var(--bone); }
.iti__selected-dial-code { color: var(--body-dim); font-size: 15px; }
.iti__arrow { border-top-color: var(--ice); }
.iti__arrow--up { border-bottom-color: var(--ice); }

.iti__dropdown-content {
  background: var(--ink-2);
  border: 1px solid var(--ice);
  border-radius: 0;
  box-shadow: 0 26px 54px -16px rgba(0,0,0,.92);
  color: var(--bone);
  overflow: hidden;
}

/* --- the country search box ---
   The magnifying glass is KEPT and coloured into the palette rather than
   hidden. That means the vendor's reserved horizontal padding has to be
   preserved: .iti__search-icon is absolutely positioned at left:8px and
   .iti__search-clear at right:4px, so a padding SHORTHAND that resets
   padding-left/right drops the glyph straight on top of the word being
   typed. Set the vertical padding, keep the horizontal reservation. */
.iti__search-input {
  width: 100%;
  background: var(--ink-3);
  color: var(--bone);
  border: none;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 12px 30px 12px 34px;
  font-family: var(--body);
  font-size: 15px;
  letter-spacing: .01em;
}
.iti__search-input::placeholder { color: #7E93A5; }
.iti__search-input:focus {
  outline: none;
  box-shadow: inset 0 -2px 0 var(--ice);
}
.iti__search-icon { color: var(--ice-lo); opacity: .9; }
.iti__search-input:focus ~ .iti__search-icon,
.iti__search-input:not(:placeholder-shown) ~ .iti__search-icon { color: var(--ice); }

.iti__country-list { background: var(--ink-2); }
.iti__country { color: var(--bone); padding: 9px 12px; }
.iti__country:hover,
.iti__country.iti__highlight { background: var(--ice); color: var(--ink); }
.iti__country:hover .iti__country-name,
.iti__country.iti__highlight .iti__country-name,
.iti__country:hover .iti__dial-code,
.iti__country.iti__highlight .iti__dial-code { color: var(--ink); }
.iti__dial-code { color: var(--ice-lo); }
.iti__country-name { color: var(--bone); }
/* the divider under the preferred (GB/IE) block */
.iti__divider { border-bottom-color: var(--line); }
/* the dropdown must sit above the panel */
.iti--inline-dropdown .iti__dropdown-content { z-index: 50; }
/* Hidden state must not depend on the vendor stylesheet having loaded, or
   the full list + search box flash open on first paint */
.iti__dropdown-content.iti__hide { display: none !important; }

/* ============================================================
   FOOTER (full width, basslayerz design)
   ============================================================ */
.foot {
  flex-shrink: 0;
  width: 100%;
  margin: 0;
  padding: 18px clamp(16px, 4vw, 40px) 26px;
  background: rgba(9,14,22,.72);
  border-top: 1px solid var(--line);
  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: #8FA3B4; letter-spacing: .02em; }
.foot__legal a { color: #8FA3B4; text-decoration: none; }
.foot__legal a:hover { color: var(--ice); }
.site-built { margin: 0; }
.site-built a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  letter-spacing: .04em;
  color: #8FA3B4;
  text-decoration: none;
  padding: 5px 11px;
  border: 1px solid var(--line);
}
.site-built a:hover { border-color: var(--ice); color: var(--bone); }
.site-built img { display: block; opacity: .9; }

/* ============================================================
   RESPONSIVE — two columns

   Aspect-ratio thresholds, not width alone: a width-only breakpoint
   leaves a gap at "in-between" window shapes (squarish desktop windows
   around 570-900px) where neither the phone nor the desktop treatment
   applies. Anything at least 768px wide AND at least 7:10 wide-to-tall
   gets the split; everything else stacks.
   ============================================================ */
@media (min-width: 768px) and (min-aspect-ratio: 7/10) {
  .stage__inner {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    align-items: center;
  }
  .poster { justify-self: end; max-width: 540px; }
  .panel  { justify-self: start; }
  .foot { justify-content: space-between; }
}

@media not all and (min-width: 768px) and (min-aspect-ratio: 7/10) {
  .foot { justify-content: center; text-align: center; }
  .foot__left { justify-content: center; }
}

/* very narrow screens: keep the title off two awkward lines */
@media (max-width: 360px) {
  .panel__title { font-size: 1.75rem; }
}

/* ============================================================
   PHONE LANDSCAPE / SHORT VIEWPORTS
   A sideways phone (844x390, 932x430, 667x375) satisfies the
   two-column conditions above but has almost no height, so the
   poster sized off viewport WIDTH would push the form under the
   fold. Size it off the HEIGHT instead and compress the panel so
   the billing block through Sign Up clears a 375px-tall fold.
   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: 10px clamp(14px, 3vw, 28px); align-items: center; }
  .stage__inner {
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    gap: clamp(16px, 3vw, 32px);
    align-items: start;
  }

  /* width:auto + max-height lets the browser scale the poster
     proportionally to whichever constraint bites first */
  .poster { justify-self: end; width: auto; max-width: none; min-height: 0; }
  .poster img {
    width: auto;
    height: auto;
    max-width: 38vw;
    max-height: calc(100svh - 40px);
  }

  .panel { justify-self: start; max-width: 560px; min-height: 0; }
  .panel__inner { padding: 12px 16px; }

  .billing { margin-bottom: 8px; }
  .billing__bar { padding: 5px 10px 4px; font-size: 12px; }
  .billing__box { padding: 4px 9px 3px; font-size: 10.5px; }
  .panel__title { margin-bottom: 6px; font-size: 1.3rem; }
  .panel__lede { margin-bottom: 5px; font-size: 12px; max-width: none; }
  .panel__lede--last { margin-bottom: 9px; }

  .form__row { margin-bottom: 8px; }
  .form__label { margin-bottom: 3px; padding: 2px 7px 1px; font-size: 9.5px; }
  .form__input { padding: 9px 12px; }   /* font-size stays 16px: iOS zoom guard */
  .form__check { margin-bottom: 9px; gap: 8px; font-size: 11px; line-height: 1.4; }
  .form__check input { width: 16px; height: 16px; }
  .btn-signup .btn__text { padding: 9px 14px; font-size: .95rem; }

  /* success state has to clear the fold too */
  .panel__success-note { margin-bottom: 8px; font-size: 13px; }
  .wa-hook { margin-bottom: 9px; padding-left: 10px; font-size: 12px; }
  .btn-whatsapp { padding: 10px 16px; font-size: 14px; }

  .foot { padding: 10px clamp(14px, 3vw, 28px) 12px; }
}

/* Smallest landscape phones (667x375, 736x414). The panel is narrower here,
   so the consent paragraph wraps to three lines and pushes Sign Up under the
   fold even after the block above. Give the panel more width by shrinking the
   poster, and tighten type one more notch. Input font-size stays 16px - the
   iOS zoom-on-focus guard is not negotiable. */
@media (min-aspect-ratio: 7/10) and (max-height: 420px) and (max-width: 740px) {
  .poster img { max-width: 32vw; }
  .billing { margin-bottom: 6px; }
  .billing__bar { padding: 4px 9px 3px; font-size: 11px; }
  .panel__title { margin-bottom: 5px; font-size: 1.15rem; }
  .panel__lede { margin-bottom: 4px; font-size: 11px; }
  .panel__lede--last { margin-bottom: 7px; }
  .form__row { margin-bottom: 6px; }
  .form__input { padding: 7px 10px; }
  .form__check { margin-bottom: 7px; gap: 7px; font-size: 10px; line-height: 1.35; }
  .form__check input { width: 14px; height: 14px; }
  .btn-signup .btn__text { padding: 8px 12px; font-size: .88rem; }
}

/* ============================================================
   ACCESSIBILITY
   ============================================================ */
a:focus-visible,
button:focus-visible,
input:focus-visible,
.iti__selected-country:focus-visible {
  outline: 2px solid var(--ice);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .poster__frame, .panel { animation: none; }
  .btn-signup, .btn-whatsapp, .form__label, .form__input { transition: none; }
  * { scroll-behavior: auto; }
}
