/* ============================================================
   4AM KRU - Cardiff & Birmingham, autumn/winter 2026
   PullUp Recordings / Sell Out Events. Sign-up page.

   Visual language taken straight from the supplied artwork: a
   blown-out, heavily grained black-and-white live photograph with
   pure acid green (#0EFF00, sampled - not guessed) type sitting on
   top of it, glowing like an over-exposed laser. Nothing is warm,
   nothing is rounded, nothing is soft-edged: the artwork is a photo-
   copied rave flyer and the page should feel printed the same way.

   Signature: the bloom. One glow recipe (--bloom) drives the
   wordmark, the selected show card and the primary button, and
   NOTHING else glows. It is the artwork's own defining gesture, so
   spending the page's boldness there is the whole design.
   ============================================================ */

/* Archivo (OFL) - one variable file, wdth 62-125 + wght 100-900.
   Display is wdth 125 / wght 900 (Archivo Expanded Black), the closest
   free match to the wide heavy grotesque in the artwork lockup. */
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/Archivo-var.woff2?v=20260825-9") format("woff2");
  font-weight: 100 900; font-stretch: 62% 125%; font-style: normal; font-display: swap;
}

:root {
  /* sampled from the artwork type, not picked */
  --acid:      #0EFF00;
  --acid-hi:   #86FF7C;
  --acid-deep: #0AC900;
  --acid-line: rgba(14, 255, 0, 0.38);
  --acid-dim:  rgba(14, 255, 0, 0.10);

  --void:      #000000;                       /* the artwork is TRUE black */
  --paper:     #FFFFFF;
  --ash:       rgba(255, 255, 255, 0.66);
  --ash-dim:   rgba(255, 255, 255, 0.40);
  --err:       #FF5F4A;

  --panel-bg:  rgba(0, 0, 0, 0.80);
  --field-bg:  rgba(255, 255, 255, 0.055);
  /* Flattened opaque equivalent of field-over-panel-over-scene. Chrome's
     :-webkit-autofill ignores background entirely and can only be overridden
     with an inset box-shadow, and a shadow cannot be translucent - so this is
     the computed single colour, NOT the field's own rgba value. */
  --field-flat: #141414;

  --bloom:     0 0 6px rgba(14, 255, 0, 0.55),
               0 0 18px rgba(14, 255, 0, 0.42),
               0 0 44px rgba(14, 255, 0, 0.26);
  --bloom-sm:  0 0 5px rgba(14, 255, 0, 0.5),
               0 0 14px rgba(14, 255, 0, 0.3);

  --font:      "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  /* the lockup setting; applied with font-variation-settings where used */
  --disp-var:  "wdth" 125, "wght" 900;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  color: var(--paper);
  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 */
html { background: var(--void); }
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. */
.hp-row { display: none !important; }

/* ============================================================
   BACKGROUND - the client scene, greyscaled and crushed
   ============================================================ */
/* PORTRAIT: absolutely positioned (not fixed) so the scene scrolls away with
   the page rather than parking the performers under scrolling content. */
.bg {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 118svh;
  z-index: -1;
  background: url("/assets/images/bg-mobile.webp?v=20260825-9") center top / cover no-repeat,
              var(--void);
}
/* The photograph is already dark; this only deepens the lower half so the
   panel has something solid to sit against and the page resolves to true
   black at the fold rather than stopping on a hard image edge. */
.bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0.34) 0%,
    rgba(0, 0, 0, 0.16) 20%,
    rgba(0, 0, 0, 0.52) 48%,
    rgba(0, 0, 0, 0.80) 72%,
    rgba(0, 0, 0, 0.95) 88%,
    var(--void) 100%);
}
@media (max-aspect-ratio: 7/10) and (max-width: 500px) {
  .bg { background-image: url("/assets/images/bg-mobile-sm.webp?v=20260825-9"); }
}

/* Landscape: the wide frame. Keyed on aspect ratio ALONE, deliberately -
   gating on min-width too would strand landscape phones (667x375) on the
   tall portrait crop. */
@media (min-aspect-ratio: 7/10) {
  .bg {
    position: fixed;
    inset: 0;
    height: auto;
    /* anchored left: the two performers sit left-of-centre in the wide crop,
       so this keeps them clear of the panel on the right */
    background: url("/assets/images/bg-desktop.webp?v=20260825-9") left center / cover no-repeat,
                var(--void);
  }
  .bg::after {
    background:
      linear-gradient(90deg, rgba(0, 0, 0, 0.20) 0%, rgba(0, 0, 0, 0.10) 34%, rgba(0, 0, 0, 0.74) 100%),
      linear-gradient(180deg, rgba(0, 0, 0, 0.30) 0%, rgba(0, 0, 0, 0) 34%, rgba(0, 0, 0, 0.58) 100%);
  }
}
@media (min-aspect-ratio: 7/10) and (max-width: 1500px) {
  .bg { background-image: url("/assets/images/bg-desktop-sm.webp?v=20260825-9"); }
}

/* ============================================================
   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;
  gap: clamp(22px, 4vw, 40px);
}

/* ============================================================
   BRAND - the lockup rebuilt in live type over the scene
   ============================================================ */
.brand { text-align: center; }

.brand__presents {
  margin: 0 0 clamp(8px, 1.2vw, 12px);
  font-size: clamp(10px, 1.35vw, 12.5px);
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--paper);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.9);
}

/* The wordmark. This is the one element allowed to shout. */
.brand__mark {
  margin: 0;
  font-family: var(--font);
  font-variation-settings: var(--disp-var);
  font-size: clamp(46px, 12.5vw, 104px);
  line-height: 0.92;
  /* the name never breaks - "4AM / KRU" splits the act in half, and the
     artwork sets it on one line. Sized off vw so nowrap can never overflow. */
  white-space: nowrap;
  letter-spacing: -0.005em;
  color: var(--acid);
  text-shadow: var(--bloom);
}

.brand__season {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 1.4vw, 15px);
  width: fit-content;
  max-width: 100%;
  margin: clamp(11px, 1.7vw, 16px) auto 0;
  font-size: clamp(10px, 1.3vw, 12px);
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--paper);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.9);
}
.brand__season > span:nth-child(2) { white-space: nowrap; }
.brand__hair {
  flex: 0 1 clamp(20px, 4vw, 48px);
  height: 1px;
  background: linear-gradient(90deg, var(--acid-line), rgba(14, 255, 0, 0));
}
.brand__hair:first-child {
  background: linear-gradient(270deg, var(--acid-line), rgba(14, 255, 0, 0));
}

/* The two shows, set as the artwork sets them: one line each, acid, wide and
   heavy. Slash separators rather than the artwork's hyphens because these
   wrap on phones and a hyphen mid-wrap reads as a broken word. */
.brand__dates {
  list-style: none;
  margin: clamp(13px, 1.9vw, 19px) 0 0;
  padding: 0;
}
.brand__dates li {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0 clamp(7px, 0.9vw, 11px);
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: clamp(15px, 3.5vw, 27px);
  line-height: 1.24;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  color: var(--acid);
  text-shadow: var(--bloom-sm);
}
.brand__sep { color: rgba(14, 255, 0, 0.45); font-variation-settings: "wght" 500; }
.brand__day { white-space: nowrap; }

.brand__line {
  margin: clamp(13px, 2vw, 19px) auto 0;
  max-width: 48ch;
  font-size: clamp(14px, 1.5vw, 15.5px);
  color: var(--ash);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.95), 0 0 18px rgba(0, 0, 0, 0.8);
}

/* ============================================================
   PANEL - flat black over the scene, hard acid hairline.
   No chamfer, no radius: the artwork is a photocopied flyer and
   every edge in it is a straight cut.
   ============================================================ */
.panel {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  background: var(--panel-bg);
  backdrop-filter: blur(14px) saturate(1.05);
  -webkit-backdrop-filter: blur(14px) saturate(1.05);
  /* inset shadow rather than a pseudo-element frame: a positioned frame
     stacks above the form children and swallows clicks on the country
     dropdown */
  box-shadow: inset 0 0 0 1px var(--acid-line);
}
.panel__inner {
  position: relative;
  z-index: 1;
  padding: clamp(24px, 3.6vw, 36px) clamp(19px, 3.2vw, 32px) clamp(26px, 3.8vw, 36px);
}

/* --- state machine: exactly one state visible --- */
.panel__state { display: none; }
.panel[data-form-state="idle"]    .panel__idle    { 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 14px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--acid);
}
.panel__eyebrow-hair {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--acid-line), rgba(14, 255, 0, 0));
}
.panel__eyebrow-hair:first-child {
  background: linear-gradient(270deg, var(--acid-line), rgba(14, 255, 0, 0));
}
.panel__title {
  margin: 0 0 12px;
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: clamp(27px, 3.8vw, 37px);
  line-height: 1.04;
  letter-spacing: -0.004em;
  text-transform: uppercase;
  text-wrap: balance;
}
.panel__title em {
  font-style: normal;          /* the acid IS the emphasis */
  color: var(--acid);
}
/* Class-based only. A state-scoped element rule (.panel__success p {...})
   would out-specify .panel__eyebrow and silently restyle it. */
.panel__lede {
  margin: 0 0 22px;
  color: var(--ash);
  font-size: 15px;
}
.panel__lede strong { color: var(--paper); font-weight: 600; }
.panel__success-note {
  margin: 0 0 12px;
  color: var(--acid);
  font-size: 15px;
}
.panel__foot-note {
  margin: 16px 0 0;
  color: var(--ash-dim);
  font-size: 12.5px;
}

/* ============================================================
   COUNTDOWN - to GENERAL SALE.

   Reworked 25 Aug: the first pass was a filled box with four
   stacked numerals, which read as a bolted-on widget. This is a
   digital readout instead - hairline rules top and bottom, no
   fill, colon separators, and one pulsing dot on the label. The
   flyer language on this build is RULES, not boxes, and the
   glowing readout leans on the bloom that already carries the
   page rather than introducing a second idea.

   Ships hidden and is revealed by JS, so a visitor with JS off
   never sees a frozen "--" clock.
   ============================================================ */
.countdown {
  margin: 0 0 22px;
  padding: 13px 0 12px;
  border-top: 1px solid var(--acid-line);
  border-bottom: 1px solid var(--acid-line);
}
.countdown__label {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 10px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ash);
}
/* the one moving part: a slow pulse, so the strip reads as live rather than
   as a printed date */
.countdown__dot {
  width: 6px; height: 6px;
  flex: 0 0 auto;
  background: var(--acid);
  box-shadow: var(--bloom-sm);
  animation: cd-pulse 2s ease-in-out infinite;
}
@keyframes cd-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

.countdown__clock {
  display: flex;
  align-items: flex-start;
  gap: clamp(4px, 1.4vw, 9px);
}
.countdown__unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1 1 0;
  min-width: 0;
  gap: 4px;
}
.countdown__unit b {
  font-variation-settings: "wdth" 112, "wght" 800;
  /* tabular figures: without them the digits change width every second and
     the whole row jitters */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: clamp(26px, 7.4vw, 40px);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--acid);
  text-shadow: var(--bloom);
}
.countdown__unit i {
  font-style: normal;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
/* Sized like the digits so it sits on their baseline without any nudging;
   the label row below it is what makes the units taller. */
.countdown__sep {
  flex: 0 0 auto;
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: clamp(26px, 7.4vw, 40px);
  line-height: 1;
  color: rgba(14, 255, 0, 0.42);
  animation: cd-blink 1s steps(1, end) infinite;
}
@keyframes cd-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.25; } }

.countdown__live {
  margin: 0;
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: clamp(17px, 4.4vw, 21px);
  text-transform: uppercase;
  color: var(--acid);
  text-shadow: var(--bloom);
}
@media (min-width: 640px) and (min-aspect-ratio: 7/10) and (max-height: 520px) {
  .countdown { margin-bottom: 10px; padding: 8px 0 7px; }
  .countdown__label { font-size: 8.5px; margin-bottom: 6px; letter-spacing: 0.18em; }
  .countdown__unit b, .countdown__sep { font-size: 20px; }
  .countdown__unit i { font-size: 7.5px; }
  .countdown__dot { width: 5px; height: 5px; }
}

/* ============================================================
   SHOW PICKER - the CRM `dates` select, as two radio cards.
   Native radios: keyboard, required and screen-reader semantics
   come from the platform, and FormData submits the checked value
   under `dates` with no syncing code to get wrong.
   ============================================================ */
.dates {
  margin: 0 0 20px;
  padding: 0;
  border: 0;
}
.dates__legend {
  display: block;
  padding: 0;
  margin: 0 0 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--acid);
}
/* "Pick one or both" - the legend has to say the picker is multi-select,
   because two square boxes still read as a choose-one to most people. */
.dates__hint {
  margin-left: 6px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--ash-dim);
}
.dates__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px;
}
.date { display: block; cursor: pointer; }
/* The input stays in the layout (not display:none) so it remains focusable
   and reachable by assistive tech; it is the FACE that is painted. */
.date input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.date__face {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  height: 100%;
  padding: 12px 13px 13px;
  background: var(--field-bg);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  transition: background-color 0.15s ease, box-shadow 0.15s ease;
}
.date__city {
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: clamp(15px, 3.4vw, 18px);
  line-height: 1.1;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  color: var(--paper);
  transition: color 0.15s ease;
}
.date__venue {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ash);
}
.date__when {
  margin-top: 3px;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
/* City and tick share a flex row rather than the tick being positioned over
   the card: absolutely positioned, it overlapped "BIRMINGHAM" at 390px. In a
   row the city shrinks instead of colliding. */
.date__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.date__tick {
  position: relative;
  flex: 0 0 auto;
  width: 15px; height: 15px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.24);
  transition: box-shadow 0.15s ease, background-color 0.15s ease;
}
.date__tick::after {
  content: "";
  position: absolute;
  top: 2px; left: 5px;
  width: 4px; height: 8px;
  border: solid var(--void);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0.4);
  opacity: 0;
  transition: opacity 0.14s ease, transform 0.14s ease;
}
.date:hover .date__face { background: rgba(255, 255, 255, 0.09); }
.date input:checked + .date__face {
  background: var(--acid-dim);
  box-shadow: inset 0 0 0 1px var(--acid), var(--bloom-sm);
}
.date input:checked + .date__face .date__city { color: var(--acid); }
.date input:checked + .date__face .date__tick {
  background: var(--acid);
  box-shadow: inset 0 0 0 1px var(--acid);
}
.date input:checked + .date__face .date__tick::after {
  opacity: 1;
  transform: rotate(45deg) scale(1);
}
.date input:focus-visible + .date__face {
  outline: 2px solid var(--acid);
  outline-offset: 2px;
}
/* Below ~380px two cards side by side squeeze "BIRMINGHAM" to breaking
   point, so they stack rather than shrink the city name. */
@media (max-width: 380px) {
  /* "Pick one or both" - the legend has to say the picker is multi-select,
   because two square boxes still read as a choose-one to most people. */
.dates__hint {
  margin-left: 6px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--ash-dim);
}
.dates__grid { grid-template-columns: 1fr; }
}

/* ============================================================
   FORM
   ============================================================ */
.form { margin: 0; }
.form__row { margin: 0 0 16px; }
.form__label {
  display: block;
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--acid);
}
.form__input {
  display: block;
  width: 100%;
  padding: 13px 14px;
  background: var(--field-bg);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 0;
  color: var(--paper);
  font-family: var(--font);
  font-size: 16px;            /* >=16px stops iOS zoom-on-focus */
  line-height: 1.3;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.form__input::placeholder { color: rgba(255, 255, 255, 0.3); }
.form__input:focus {
  outline: none;
  border-color: var(--acid);
  background: rgba(255, 255, 255, 0.075);
}

/* Chrome paints autofilled inputs pale lavender and ignores `background`
   outright; a huge inset shadow is the only override that holds. The colour
   is --field-flat (the flattened stack), NOT the field's rgba, or an
   autofilled field would not match the empty one beside it. The long
   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(--paper) !important;
  caret-color: var(--paper);
  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(--ash);
  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; }

/* --- buttons --- */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  margin: 20px 0 0;
  padding: 16px 18px;
  border: 0;
  border-radius: 0;
  font-family: var(--font);
  font-variation-settings: "wdth" 112, "wght" 800;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  transition: background-color 0.15s ease, box-shadow 0.15s ease;
}
.btn--primary {
  background: var(--acid);
  color: var(--void);
  box-shadow: var(--bloom-sm);
  /* shrink type before it can wrap - never let a CTA break to two lines */
  white-space: nowrap;
  font-size: clamp(0.85rem, 3.4vw, 1.05rem);
  letter-spacing: clamp(0.06em, 0.5vw, 0.14em);
  text-transform: uppercase;
}
.btn--primary:hover:not(:disabled) { background: var(--acid-hi); box-shadow: var(--bloom); }
.btn--primary:disabled { opacity: 0.6; cursor: wait; box-shadow: none; }

/* ============================================================
   intl-tel-input - black/acid theme, styled searchable dropdown
   ============================================================ */
.iti { width: 100%; }
.iti input.form__input { padding-left: calc(52px + 0.7rem); } /* repadPhone() re-measures */

.iti__selected-country { background: transparent; color: var(--paper); }
.iti__selected-dial-code { color: var(--ash); font-size: 15px; }
.iti__arrow { border-top-color: var(--acid); }
.iti__arrow--up { border-bottom-color: var(--acid); }

.iti__dropdown-content {
  background: #070707;
  border: 1px solid var(--acid-line);
  border-radius: 0;
  color: var(--paper);
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.8);
}
/* Vertical padding only: a `padding` shorthand wipes the vendor's reserved
   padding-left:30px and the magnifying glass then sits on the word "Search". */
.iti__search-input {
  padding: 12px 30px 12px 32px;
  background: rgba(255, 255, 255, 0.05);
  border: none;
  border-bottom: 1px solid var(--acid-line);
  color: var(--paper);
  font-family: var(--font);
  font-size: 15px;
}
.iti__search-input::placeholder { color: rgba(255, 255, 255, 0.34); }
.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(14, 255, 0, 0.16); }
.iti__country:hover { background: rgba(14, 255, 0, 0.1); }
.iti__dial-code { color: var(--ash); }
.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 */
.iti__dropdown-content.iti__hide { display: none !important; }

/* ============================================================
   FOOTER
   ============================================================ */
.foot {
  flex-shrink: 0;
  width: 100%;
  margin: 0;
  padding: 16px clamp(16px, 4vw, 40px) 20px;
  border-top: 1px solid rgba(14, 255, 0, 0.2);
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  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: var(--ash); letter-spacing: 0.02em; }
.foot__legal a { color: var(--ash); text-decoration: none; }
.foot__legal a:hover { color: var(--acid); }
.site-built { margin: 0; }
.site-built a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ash);
  text-decoration: none;
  padding: 5px 11px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
}
.site-built a:hover { border-color: var(--acid); color: var(--paper); }
.site-built img { display: block; opacity: 0.9; }
@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.
   ============================================================ */
@media (min-width: 768px) and (min-aspect-ratio: 7/10) {
  .stage__inner {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    align-items: center;
    gap: clamp(30px, 5vw, 68px);
    padding-right: clamp(14px, 2vw, 28px);
  }
  .brand { text-align: left; }
  /* Column here is ~576px at the 1280 cap; "4AM KRU" in Archivo Expanded
     Black runs ~6.7em, so 96px overflowed and wrapped. 78px keeps it on one
     line from 768px up. */
  .brand__mark { font-size: clamp(40px, 5.6vw, 78px); }
  /* width:fit-content + auto margins would re-centre this in a left-aligned
     column, so it gets explicit margins here */
  .brand__season { margin-left: 0; margin-right: 0; justify-content: flex-start; }
  .brand__season .brand__hair:first-child { display: none; }
  .brand__dates li { justify-content: flex-start; font-size: clamp(15px, 1.75vw, 24px); }
  .brand__line { margin-left: 0; margin-right: 0; }
  /* margin-left stays auto - never margin:0, which is what left-shifts the
     panel at a single breakpoint */
  .panel { margin-left: auto; margin-right: 0; }
}

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

/* PORTRAIT: the mobile crop puts the singer's face at the TOP (Adam,
   25 Aug), so content has to start below it. Measured, not guessed: his face
   ends ~19.6% down the crop and .bg is 118svh tall, so the face clears at
   ~23svh - 27svh leaves margin without pushing the form further than it has
   to go. If the crop is ever regenerated, re-derive this number. */
@media (max-aspect-ratio: 7/10), (max-width: 767px) {
  .stage__inner {
    padding-top: 27svh;
    gap: clamp(18px, 3.5vw, 28px);
  }
}

/* Phones: panel runs the full frame width */
@media (max-width: 767px) {
  .stage__inner { padding-left: 14px; padding-right: 14px; }
  .panel { max-width: none; }
  /* the brand lede repeats what the panel lede says; dropping it on phones
     lifts the form ~80px closer to the fold */
  .brand__line { display: none; }
}

/* Landscape phones are a first-class layout, not an afterthought: 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.92fr) minmax(0, 1fr);
    align-items: start;
    gap: clamp(18px, 3vw, 32px);
    padding: 14px clamp(14px, 3vw, 28px);
    min-height: 0;
  }
  .brand { text-align: left; align-self: center; }
  .brand__mark { font-size: clamp(30px, 5.2vw, 52px); }
  .brand__presents { font-size: 9.5px; letter-spacing: 0.24em; margin-bottom: 6px; }
  .brand__season { font-size: 9.5px; letter-spacing: 0.2em; margin: 7px 0 0; gap: 9px; justify-content: flex-start; }
  .brand__season .brand__hair:first-child { display: none; }
  .brand__hair { flex-basis: 18px; }
  .brand__dates { margin-top: 8px; }
  .brand__dates li { justify-content: flex-start; font-size: clamp(12px, 1.9vw, 16px); line-height: 1.3; }
  /* the lede is the first thing to go: on a 390px-tall viewport every line it
     costs is a form field pushed under the fold */
  .brand__line { display: none; }
  .panel__inner { padding: 13px 15px 15px; }
  .panel__title { font-size: clamp(17px, 2.4vw, 22px); margin-bottom: 6px; }
  .panel__lede { margin-bottom: 10px; font-size: 12.5px; }
  .panel__eyebrow { margin-bottom: 7px; font-size: 10px; letter-spacing: 0.2em; }
  .dates { margin-bottom: 10px; }
  .dates__legend { font-size: 10px; margin-bottom: 6px; }
  /* "Pick one or both" - the legend has to say the picker is multi-select,
   because two square boxes still read as a choose-one to most people. */
.dates__hint {
  margin-left: 6px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--ash-dim);
}
.dates__grid { gap: 7px; }
  .date__face { padding: 8px 10px 9px; }
  .date__city { font-size: 14px; }
  .date__venue { font-size: 11px; }
  .date__when { font-size: 10px; margin-top: 1px; }
  .date__tick { width: 13px; height: 13px; }
  .form__row { margin-bottom: 8px; }
  .form__label { font-size: 10px; margin-bottom: 3px; }
  .form__input { padding: 9px 12px; }
  .form__check { font-size: 11.5px; line-height: 1.35; }
  .form__row--check { margin-top: 9px; }
  .btn { margin-top: 10px; padding: 10px 14px; }
  .panel__foot-note { font-size: 11px; margin-top: 10px; }
  .foot { padding: 8px 20px 10px; }
}

/* ============================================================
   TICKETS (gensale.html) - deliberately the same object as the
   show picker on the sign-up page, so a returning visitor
   recognises the choice they already made. Anchors, not radios:
   these leave the page, so they must not look selectable.
   ============================================================ */
.tickets {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin: 0 0 4px;
}
.ticket {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 14px 15px;
  background: var(--field-bg);
  box-shadow: inset 0 0 0 1px var(--acid-line);
  color: var(--paper);
  text-decoration: none;
  transition: background-color 0.15s ease, box-shadow 0.15s ease;
}
.ticket:hover,
.ticket:focus-visible {
  background: var(--acid-dim);
  box-shadow: inset 0 0 0 1px var(--acid), var(--bloom-sm);
}
.ticket__city {
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: clamp(16px, 3.6vw, 19px);
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--acid);
}
.ticket__venue {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ash);
}
.ticket__when {
  margin-top: 2px;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
/* The CTA is a label inside the card, not a nested button: the whole card is
   already the link, and a button inside an anchor is invalid. nowrap + a
   clamped size because "Buy tickets" at wide tracking wraps in a half-width
   card on a 320px viewport. */
.ticket__cta {
  margin-top: 11px;
  padding-top: 10px;
  border-top: 1px solid rgba(14, 255, 0, 0.22);
  white-space: nowrap;
  font-size: clamp(11px, 3vw, 12.5px);
  font-weight: 600;
  letter-spacing: clamp(0.06em, 0.5vw, 0.14em);
  text-transform: uppercase;
  color: var(--acid);
}
.ticket__cta::after { content: " \2192"; }
@media (max-width: 380px) {
  .tickets { grid-template-columns: 1fr; }
}
@media (min-width: 640px) and (min-aspect-ratio: 7/10) and (max-height: 520px) {
  .tickets { gap: 7px; }
  .ticket { padding: 9px 11px 10px; }
  .ticket__city { font-size: 15px; }
  .ticket__venue { font-size: 11px; }
  .ticket__when { font-size: 10px; }
  .ticket__cta { margin-top: 7px; padding-top: 6px; font-size: 10.5px; }
}

/* ============================================================
   MOTION - one orchestrated page-load reveal, nothing else
   ============================================================ */
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.brand  { 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;
}

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