/* ============================================================
   BUGGED OUT! presents SVEN VATH - Document, Bristol
   Signup page.

   Visual language taken straight off the supplied artwork: a
   brutalist concrete bunker with a single eye watching from the
   arch, acid yellow, flat graphic blacks. Every colour below is
   SAMPLED from that file, not chosen:
     #E9F41C acid  /  #EAEAEA sheet ground  /  #050502 olive-black

   The direction inverts the house pattern. Every recent build in
   this fleet is a dark panel floating over a photographic scene;
   this artwork is flat, graphic and loud, so a photographic dusk
   scene would fight it. Instead the client's own art panel is
   defocused into a field of acid, the poster sits on it as a
   flyposted sheet, and the sign-up panel is a solid ink slab.

   Three materials, three values, nothing else: acid field, grey
   paper, ink slab. The contrast between them is the layout - there
   is no scrim and no glass anywhere on the page.

   Signature: inside the ink panel, acid is rationed to four
   appearances - the eyebrow rule, the panel's leading spine, the
   primary button, and the focus ring. Nothing else inside the
   panel is yellow, so the eye goes field -> poster -> button.
   ============================================================ */

/* Figtree (OFL) - stands in for the client's Safiro SemiBold, an atipo
   foundry commercial licence we do not hold. One variable file covers
   the whole range; swap this single block when the licensed woff2 lands. */
@font-face {
  font-family: "Figtree";
  src: url("/assets/fonts/Figtree-var.woff2?v=20260804-11") format("woff2");
  font-weight: 300 900; font-style: normal; font-display: swap;
}
/* Archivo (OFL) - the utility voice: micro-labels, eyebrows, footer */
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/Archivo-var.woff2?v=20260804-11") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}

:root {
  --acid:       #E9F41C;                  /* sampled from the artwork panel */
  --acid-dim:   #9CA313;                  /* the artwork's shadowed acid */
  --ink:        #050502;                  /* olive-black, not neutral black */
  --sheet:      #EAEAEA;                  /* the poster's own ground */
  --light:      #EAEAEA;
  --muted:      rgba(234, 234, 234, 0.64);
  --err:        #FF8A78;

  /* The field is now an OPAQUE recessed slot, cut INTO the panel rather than
     tinted on top of it - a 5.5% white wash on near-black read as nothing at
     all (Adam, 2026-08-04: "the sign up boxes are boring"). Being opaque also
     makes the Chrome autofill box-shadow trivially correct: there is no stack
     to flatten any more, the two values are simply the same colour. */
  --field-bg:   #121210;
  --field-flat: #121210;
  --field-hi:   #191916;                  /* the same slot, focused */

  --font:       "Figtree", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-util:  "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* html carries the base colour; body stays transparent so it can never
   paint over the z-index:-1 background layer (gotcha 16) */
html { background: var(--ink); }
body {
  position: relative;
  background: transparent;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

.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;
}

/* Honeypot - display:none ONLY. Off-screen positioning gets autofilled by
   Chrome/Edge, which silently blocks real signups (gotcha 2). */
.hp-row { display: none !important; }

/* ============================================================
   BACKGROUND - the client's clean art panel, heavily defocused
   (client-supplied bg.png, 3024x3028, Adam 2026-08-04).

   Two earlier attempts are worth remembering so nobody retries
   them: a mirror-tiled crop of the artwork's concrete produced a
   visible kaleidoscope diamond motif, and fine synthetic noise
   read as digital static rather than concrete. At full-page scale
   a tiled grain always reads as dirt.

   The blur is baked into the asset, NOT done with filter/
   backdrop-filter: a CSS blur on a full-viewport fixed layer is
   repainted on every scroll and is the single most expensive thing
   you can put behind a form. Baked also means the file is tiny -
   blurred at 25% then scaled back up, the desktop webp is ~8KB,
   and the browser upscaling an already-defocused image costs
   nothing visually.

   HEAVILY SCRIMMED. Run at full strength the acid field was far
   too yellow (Adam, 2026-08-04): a saturated #E9F41C covering the
   whole viewport overpowers both the poster and the form, and the
   yellow stops meaning anything once it is everywhere. The scrim
   drops it to embers - the artwork still reads, the acid still
   glows at the edges, but the page is a dark room again and the
   poster is the brightest thing in it.
   ============================================================ */
.bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: url("/assets/images/bg-mobile.webp?v=20260804-11") center center / cover no-repeat,
              var(--ink);
}
@media (min-aspect-ratio: 7/10) {
  .bg { background-image: url("/assets/images/bg-desktop.webp?v=20260804-11"); }
}
/* Flat scrim + vignette. The flat layer does the work; the radial keeps a
   little life in the middle so it does not flatten into a plain dark fill. */
.bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(115% 95% at 50% 44%,
      rgba(5, 5, 2, 0.58) 0%,
      rgba(5, 5, 2, 0.72) 52%,
      rgba(5, 5, 2, 0.86) 100%);
}

/* ============================================================
   SHEET / STAGE
   ============================================================ */
.sheet {
  position: relative;
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}
.stage {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  width: 100%;
}
.stage__inner {
  flex: 1 0 auto;
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: clamp(26px, 4vw, 56px) clamp(18px, 5vw, 60px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(24px, 4vw, 44px);
}

/* ============================================================
   POSTER - the client artwork as a flyposted sheet.
   A real, soft, offset shadow (paper lifting off a wall), never a
   blur filter on the image: drop-shadow computed from aliased alpha
   flashes a dark halo during decode (gotcha 9).
   ============================================================ */
.poster {
  width: 100%;
  display: flex;
  justify-content: center;
  min-width: 0;
}
.poster__art {
  display: block;
  width: 100%;
  max-width: min(90vw, 480px);
  height: auto;                 /* paired with width:100% - never aspect-ratio */
  background: var(--sheet);
  box-shadow:
    0 1px 1px rgba(5, 5, 2, 0.16),
    0 12px 26px rgba(5, 5, 2, 0.17),
    0 34px 60px rgba(5, 5, 2, 0.12);
}

/* ============================================================
   ON-SALE DATES + COUNTDOWN
   Lives INSIDE the sign-up panel, between the lede and the form,
   which is where this fleet always puts it. That means it must NOT
   carry its own surface: it is already on the ink slab, so a second
   background here would read as a box inside a box. It gets hairline
   rules and the panel's own field tint instead.

   The acid rule above the clock is the one new use of the accent.
   It marks the only live, moving element on the page, which is
   exactly what the rationing rule reserves it for.
   ============================================================ */
.onsale {
  margin: 0 0 22px;
  padding: 14px 0 0;
  border-top: 1px solid rgba(234, 234, 234, 0.12);
}
.onsale__dates { margin: 0; }
.onsale__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
}
.onsale__row + .onsale__row { border-top: 1px solid rgba(234, 234, 234, 0.09); }
.onsale__dates dt {
  font-family: var(--font-util);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(234, 234, 234, 0.62);
}
.onsale__dates dd {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--light);
  white-space: nowrap;      /* "Tue 11 Aug, 10am" must never break */
}

.onsale__count {
  margin-top: 13px;
  padding-top: 13px;
  border-top: 2px solid var(--acid);
}
.onsale__label {
  margin: 0 0 9px;
  font-family: var(--font-util);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--acid);
}
.onsale__clock { display: flex; gap: 6px; }
.onsale__unit {
  flex: 1 1 0;              /* equal boxes, so a digit change cannot reflow the row */
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 11px 4px 9px;
  background: var(--field-bg);
  /* an acid hairline on every cell - at 5.5% white the cells were effectively
     invisible and the clock read as four floating numbers */
  box-shadow: inset 0 0 0 1px rgba(233, 244, 28, 0.26);
}
.onsale__num {
  /* was 19-24px in --light. The countdown is the only live, moving thing on
     the page and it was the quietest: it now takes the acid and roughly half
     as much size again. This is a deliberate exception to the rationing note
     at the top of the file - the accent marks what is urgent, and nothing on
     this page is more urgent than the clock. */
  font-size: clamp(27px, 6.2vw, 35px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  /* tabular figures stop the seconds jittering the box on every tick */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  color: var(--acid);
}
.onsale__cap {
  font-family: var(--font-util);
  font-style: normal;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: rgba(234, 234, 234, 0.68);
}
.onsale__now {
  margin: 11px 0 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--acid);
}

/* ============================================================
   PANEL - a solid ink slab. Deliberately opaque: there is no scene
   behind it to blur, and an opaque panel is what makes the autofill
   shadow colour exactly computable rather than a guess.
   The acid spine on the leading edge is the panel's only ornament.
   ============================================================ */
.signup {
  width: 100%;
  display: flex;
  justify-content: center;
  min-width: 0;
}
.panel {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  background: var(--ink);
  color: var(--light);
  box-shadow:
    inset 0 0 0 1px rgba(234, 234, 234, 0.13),
    0 2px 6px rgba(5, 5, 2, 0.30),
    0 22px 54px rgba(5, 5, 2, 0.42);
}
/* The spine. Top edge in the stacked flow, left edge in the two-column
   layout - it always sits on the side the eye arrives from. */
.panel::before {
  content: "";
  position: absolute;
  z-index: 0;
  pointer-events: none;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--acid);
}
.panel__inner {
  position: relative;
  z-index: 1;                 /* content clears the spine layer */
  padding: clamp(26px, 4vw, 38px) clamp(20px, 3.4vw, 34px) clamp(28px, 4vw, 38px);
}

/* --- state machine: exactly one state visible --- */
.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; }

/* --- panel type --- */
.panel__eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 16px;
  font-family: var(--font-util);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--acid);
}
.panel__eyebrow-hair {
  flex: 0 0 26px;
  height: 2px;
  background: var(--acid);
}
.panel__title {
  margin: 0 0 14px;
  font-family: var(--font);
  font-size: clamp(30px, 4.2vw, 43px);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.032em;
  text-wrap: balance;
  color: var(--light);
}
.panel__title em {
  font-style: normal;
  color: var(--muted);        /* the second line steps back; acid stays rationed */
}
/* Class-based only. A state-scoped element rule (.panel__success p {...})
   would out-specify .panel__eyebrow and silently restyle it (gotcha 7). */
.panel__lede {
  margin: 0 0 24px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.55;
}
.panel__lede strong { color: var(--light); font-weight: 600; }
/* The success state runs two stacked paragraphs (confirm-your-email, then the
   WhatsApp prompt). The 24px lede gap is sized to separate the lede from the
   form below it, and between two paragraphs it reads as a break rather than a
   pause - so pull the second one up. Adjacent-sibling, not a state-scoped
   rule, so it cannot out-specify .panel__eyebrow (gotcha 7). */
.panel__lede + .panel__lede { margin-top: -11px; }
.panel__success-note {
  margin: 0 0 12px;
  color: var(--acid);
  font-size: 15px;
}

/* ============================================================
   FORM
   ============================================================ */
.form { margin: 0; }
.form__row { margin: 0 0 16px; }
.form__label {
  display: block;
  margin: 0 0 7px;
  font-family: var(--font-util);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(234, 234, 234, 0.72);
}
/* Machined slots, not boxes. Three things give them character without adding
   a new material: an opaque recess darker than the panel, a light top edge so
   they read as cut in rather than drawn on, and a 3px leading edge that turns
   acid on focus. That last one is the panel's own spine repeated at component
   scale, so the accent is doing structural work rather than decorating. */
.form__input {
  display: block;
  width: 100%;
  padding: 13px 14px;
  background: var(--field-bg);
  border: 1px solid rgba(234, 234, 234, 0.14);
  border-left: 3px solid rgba(234, 234, 234, 0.38);
  border-radius: 0;
  box-shadow: inset 0 1px 0 rgba(234, 234, 234, 0.10);
  color: var(--light);
  font-family: var(--font);
  font-size: 16px;            /* >=16px stops iOS zoom-on-focus */
  line-height: 1.3;
  transition: border-color 0.14s ease, background-color 0.14s ease, box-shadow 0.14s ease;
}
.form__input::placeholder { color: rgba(234, 234, 234, 0.32); }
.form__input:hover:not(:focus) { border-left-color: rgba(234, 234, 234, 0.45); }
.form__input:focus {
  outline: none;
  background: var(--field-hi);
  border-color: rgba(233, 244, 28, 0.42);
  border-left-color: var(--acid);
  box-shadow: inset 0 1px 0 rgba(234, 234, 234, 0.10),
              0 0 0 1px rgba(233, 244, 28, 0.25);
}
.form__input--otp {
  letter-spacing: 0.42em;
  font-weight: 700;
  font-size: 22px;
  text-align: center;
}

/* MANDATORY (gotcha 30): Chrome paints autofilled inputs pale lavender and
   :-webkit-autofill ignores `background` / `background-color` outright. The
   only override that holds is a huge inset box-shadow, and its colour must be
   the FLATTENED OPAQUE equivalent of the field's rendered stack - here
   rgba(234,234,234,.055) over the opaque #050502 panel = #12120F. The 9999s
   transition stops Chrome flashing 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 var(--field-flat) inset !important;
          box-shadow: 0 0 0 1000px var(--field-flat) inset !important;
  -webkit-text-fill-color: var(--light) !important;
  caret-color: var(--light);
  transition: background-color 9999s ease-in-out 0s;
}

.form__row--check { margin-top: 18px; }
.form__check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  cursor: pointer;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.45;
}
.form__check input {
  flex: 0 0 auto;
  width: 17px; height: 17px;
  margin: 2px 0 0;
  accent-color: var(--acid);
  cursor: pointer;
}
.form__check a { color: var(--acid); text-decoration: underline; }

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

.form__resend {
  margin: 14px 0 0;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}
.form__resend-btn {
  background: none;
  border: none;
  padding: 0;
  color: var(--acid);
  font-family: var(--font);
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
}
.form__resend-btn:disabled { opacity: 0.5; cursor: default; }

/* --- buttons --- */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  margin: 22px 0 0;
  padding: 16px 18px;
  border: 0;
  border-radius: 0;
  font-family: var(--font-util);
  font-weight: 700;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.btn--primary {
  background: var(--acid);
  color: var(--ink);
  /* shrink type before it can wrap - never let a CTA break to two lines (gotcha 26) */
  white-space: nowrap;
  font-size: clamp(0.85rem, 3.4vw, 1.02rem);
  letter-spacing: clamp(0.06em, 0.5vw, 0.16em);
  text-transform: uppercase;
}
/* Hard, unblurred offset: a screenprint registration shift, which is the
   language the poster is already speaking. Pressing it closes the offset. */
.btn--primary { box-shadow: 5px 5px 0 var(--acid-dim); }
.btn--primary:hover:not(:disabled) { background: #F3FC58; box-shadow: 7px 7px 0 var(--acid-dim); }
.btn--primary:active:not(:disabled) { box-shadow: 0 0 0 var(--acid-dim); transform: translate(3px, 3px); }
.btn--primary:disabled { opacity: 0.62; cursor: wait; }
.btn--whatsapp {
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(234, 234, 234, 0.32);
  color: var(--light);
  white-space: nowrap;
  font-size: clamp(0.78rem, 3.2vw, 0.92rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.btn--whatsapp:hover { background: rgba(234, 234, 234, 0.09); }
.btn__icon { width: 20px; height: 20px; flex: 0 0 auto; }

/* ============================================================
   intl-tel-input - ink theme, styled searchable dropdown,
   no full-screen popup on mobile (set in app.js).
   ============================================================ */
.iti { width: 100%; }
.iti input.form__input { padding-left: calc(52px + 0.7rem); } /* repadPhone() re-measures */

.iti__selected-country { background: transparent; color: var(--light); }
.iti__selected-country:hover { background: rgba(234, 234, 234, 0.06); }
.iti__selected-dial-code { color: var(--muted); font-size: 15px; }
.iti__arrow { border-top-color: var(--acid); }
.iti__arrow--up { border-bottom-color: var(--acid); }

.iti__dropdown-content {
  background: #0E0E0B;
  border: 1px solid rgba(234, 234, 234, 0.18);
  border-radius: 0;
  color: var(--light);
  box-shadow: 0 22px 52px rgba(5, 5, 2, 0.55);
}
/* The horizontal padding here is NOT free (gotcha 33): the vendor reserves
   padding-left:30px / padding-right:28px to clear the absolutely positioned
   .iti__search-icon (left:8px) and .iti__search-clear (right:4px). A padding
   SHORTHAND wipes that reservation and the magnifying glass lands on top of
   the word "Search". Set the vertical padding, keep the horizontal. */
.iti__search-input {
  padding: 11px 30px 11px 32px;
  background: rgba(234, 234, 234, 0.05);
  border: none;
  border-bottom: 1px solid rgba(234, 234, 234, 0.18);
  color: var(--light);
  font-family: var(--font);
  font-size: 15px;
}
.iti__search-input::placeholder { color: rgba(234, 234, 234, 0.36); }
.iti__search-input:focus { outline: none; border-bottom-color: var(--acid); }
.iti__country-list { background: transparent; }
.iti__country { padding: 9px 13px; font-size: 14.5px; }
.iti__country.iti__highlight { background: rgba(233, 244, 28, 0.16); }
.iti__country:hover { background: rgba(233, 244, 28, 0.09); }
.iti__dial-code { color: var(--muted); }
.iti--inline-dropdown .iti__dropdown-content { z-index: 50; }
/* hidden state must not wait on the vendor stylesheet, or the country list
   flashes open on first paint (gotcha 19) */
.iti__dropdown-content.iti__hide { display: none !important; }

/* ============================================================
   FOOTER - basslayerz pattern, full width. Ink on concrete here,
   since the page ground is light.
   ============================================================ */
.foot {
  flex-shrink: 0;
  width: 100%;
  margin: 0;
  padding: 16px clamp(16px, 4vw, 40px) 20px;
  border-top: 1px solid rgba(234, 234, 234, 0.14);
  background: rgba(5, 5, 2, 0.82);
  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-family: var(--font-util); font-size: 12px; color: var(--muted); letter-spacing: 0.02em; }
.foot__legal a { color: var(--muted); text-decoration: none; }
.foot__legal a:hover { color: var(--acid); text-decoration: underline; }
.site-built { margin: 0; }
.site-built a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-util);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-decoration: none;
  padding: 5px 11px;
  border: 1px solid rgba(234, 234, 234, 0.22);
  border-radius: 999px;
}
.site-built a:hover { border-color: var(--acid); color: var(--light); }
.site-built img { display: block; opacity: 0.88; }
@media (max-width: 640px) {
  .foot { justify-content: center; text-align: center; }
  .foot__left { justify-content: center; }
}

/* ============================================================
   LAYOUT - two columns in landscape, stacked in portrait.
   Aspect-ratio thresholds, not width alone: width-only breakpoints
   leave gaps at squarish window shapes where neither treatment
   applies (gotcha 20). Test 596 / 792 / 888 / 955-wide windows.
   ============================================================ */
@media (min-width: 768px) and (min-aspect-ratio: 7/10) {
  .stage__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
    align-items: center;
    gap: clamp(30px, 5vw, 68px);
  }
  .poster { justify-content: flex-end; }
  .poster__art {
    max-width: none;
    width: min(46vw, 470px);
    /* never taller than the window, or the sheet crops out of frame */
    max-height: calc(100svh - 150px);
    object-fit: contain;
  }
  .signup { justify-content: flex-start; }
  /* margin-left/right stay explicit here - never `margin: 0`, which is what
     left-shifts the panel at a single breakpoint (gotcha 10) */
  .panel { margin-left: 0; margin-right: auto; }
  /* the spine moves to the leading edge in the two-column reading order */
  .panel::before {
    top: 0; bottom: 0; left: 0; right: auto;
    width: 4px; height: auto;
  }
}

/* Portrait tablets: single column, scaled up */
@media (min-width: 768px) and (max-aspect-ratio: 7/10) {
  .poster__art { max-width: min(62vw, 430px); }
  .panel { max-width: 560px; }
}

/* Phones: panel runs the full frame width */
@media (max-width: 767px) {
  .stage__inner { padding-left: 14px; padding-right: 14px; }
  .panel { max-width: none; }
  .poster__art { max-width: min(84vw, 380px); }
}

/* Landscape phones are a first-class layout, not an afterthought (gotcha 27):
   a rotated phone satisfies the desktop width/aspect conditions but has almost
   no height. Placed AFTER the desktop blocks so it wins at equal specificity. */
@media (min-width: 640px) and (min-aspect-ratio: 7/10) and (max-height: 520px) {
  .stage__inner {
    display: grid;
    grid-template-columns: minmax(0, 0.72fr) minmax(0, 1fr);
    align-items: start;
    gap: clamp(18px, 3vw, 30px);
    padding: 14px clamp(14px, 3vw, 28px);
    min-height: 0;
  }
  .poster { justify-content: center; align-self: center; }
  .poster__art {
    width: auto;
    max-width: 100%;
    max-height: calc(100svh - 40px);
    object-fit: contain;
  }
  /* The on-sale block is inside the panel now, so it competes with the form
     for the ~390px of height a rotated phone has. Measured: with the block
     added at its portrait size the panel ran ~50px past the fold and buried
     the CTA, so two things give way here.

     1. The lede goes. Same call the engine makes for the brand line: on a
        390px-tall viewport every line of prose is a form field pushed under
        the fold, and this lede largely restates what the poster beside it
        already says. The <h2> keeps the context.
     2. The two date rows go side by side instead of stacked. */
  .panel__lede { display: none; }

  .onsale { margin: 6px 0 7px; padding: 6px 0 0; }
  .onsale__dates { display: flex; gap: 14px; }
  .onsale__row {
    flex: 1 1 0;
    min-width: 0;
    display: block;              /* label above value, not baseline-spread */
    padding: 0;
  }
  .onsale__row + .onsale__row { border-top: 0; }
  .onsale__dates dt { font-size: 8px; letter-spacing: 0.14em; }
  .onsale__dates dd { font-size: 11.5px; margin-top: 1px; }
  .onsale__count { margin-top: 6px; padding-top: 6px; }
  .onsale__label { margin-bottom: 5px; font-size: 8px; letter-spacing: 0.14em; }
  .onsale__clock { gap: 5px; }
  .onsale__unit { padding: 3px 2px; gap: 0; }
  .onsale__num { font-size: 12.5px; }
  .onsale__cap { font-size: 7px; letter-spacing: 0.08em; }
  .onsale__now { margin-top: 7px; font-size: 12px; }
  .panel__inner { padding: 11px 14px 12px; }
  .panel__title { font-size: clamp(15px, 2.1vw, 19px); margin-bottom: 4px; line-height: 1.02; }
  .panel__lede { margin-bottom: 10px; font-size: 12.5px; line-height: 1.4; }
  .panel__eyebrow { margin-bottom: 5px; font-size: 9px; letter-spacing: 0.18em; }
  .panel__eyebrow-hair { flex-basis: 18px; }
  .form__row { margin-bottom: 6px; }
  .form__label { font-size: 9px; margin-bottom: 2px; }
  .form__input { padding: 7px 11px; font-size: 16px; }
  .form__check { font-size: 11px; line-height: 1.3; }
  .form__row--check { margin-top: 7px; }
  .btn { margin-top: 8px; padding: 9px 14px; }
  .foot { padding: 8px 20px 10px; }
}

/* Very short rotated phones (iPhone SE landscape, 667x375). At 390px the
   block above fits; at 375 the CTA still clipped, so the panel takes width
   back off the poster column - a wider panel wraps the consent sentence in
   fewer lines, which is where the last ~15px comes from. */
@media (min-width: 640px) and (min-aspect-ratio: 7/10) and (max-height: 400px) {
  .stage__inner {
    grid-template-columns: minmax(0, 0.52fr) minmax(0, 1fr);
    padding: 10px 14px;
    gap: 16px;
  }
  .panel__inner { padding: 9px 12px 10px; }
  .onsale__num { font-size: 11.5px; }
  .onsale__unit { padding: 2px; }
  .btn { margin-top: 6px; padding: 8px 12px; }
}

/* ============================================================
   MOTION - one orchestrated page-load reveal, nothing else
   ============================================================ */
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.poster { animation: rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) both; }
.signup { animation: rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.14s both; }

/* ============================================================
   ACCESSIBILITY
   ============================================================ */
a:focus-visible,
button:focus-visible,
input:focus-visible,
.iti__selected-country:focus-visible {
  outline: 2px solid var(--acid);
  outline-offset: 2px;
}
/* footer sits on ink now, so the acid ring applies there too - no override */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}
