/* ============================================================
   Basslayerz London - teaser sign-up, v4 (12 Oct: v3 layout with the
   client's Rock City photo and the updated 2026 logo PNG in place of the
   vectorised wordmark + rails). Client: Sell Out Events Ltd.

   DIRECTION
   The client asked for the design to be built around one photo: a DJ
   at the decks, seen from behind, facing a packed room under a mirror
   ball and white beams. v3 lets that photo be the whole art side, in
   full colour, edge to edge. v4 swaps in the client's Rock City photo
   and their updated logo (white with a black outline), centred on the
   dark ceiling above the mirror ball, with London beneath it.

   COLOUR - the photo brings all the colour. Everything we draw stays
   black and white (the approved v1/v2 rule): black sheet, white fields.

   TYPE - unchanged: Michroma display, Archivo reading copy.

   MOTION - one moment: the logo settles, the room
   fades up from black. Reduced motion gets the final state.
   ============================================================ */

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

:root {
  --black:  #000000;
  --white:  #FFFFFF;
  --studio: #CDCDCD;   /* MUST equal the photo backdrop value (205) */
  --hint:   #6E6E6E;   /* placeholder text in white fields (5.1:1) */
  --muted:  #BDBDBD;   /* secondary copy on the black sheet (11:1) */

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

  --sheet-w: clamp(400px, 34vw, 540px);
  --gutter:  clamp(18px, 5vw, 96px);
}

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

/* `hidden` is display:none only in the UA sheet, the weakest layer. Keep this
   ABOVE every rule that sets display. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--black);
}
body {
  margin: 0;
  font-family: var(--body);
  color: var(--white);
  background: transparent;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ============================================================
   PAGE: stacked by default (art on top), split when wide
   ============================================================ */
.page {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr;
}

/* ---------- ART ---------- */
/* Phones: a portrait window on the room, ball to decks, that melts into
   the black sheet below it. */
.art {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: min(118vw, 74svh);
  color: var(--white);            /* the SVG paints in currentColor */
  background: var(--black);
  padding: clamp(22px, 6vw, 40px) var(--gutter) 0;
}
.art__h1 {
  position: relative;
  z-index: 2;
  margin: 0;
  align-self: center;             /* centred over the mirror ball */
  width: min(74%, 340px);
  font-size: inherit;
  line-height: 0;
  filter: drop-shadow(0 2px 14px rgba(0,0,0,.55));
}
.art__logo {
  display: block;
  width: 100%;
  height: auto;
}
.art__city {
  display: block;
  margin-top: .55em;
  font-family: var(--display);
  font-size: clamp(14px, 3.6vw, 22px);
  line-height: 1;
  letter-spacing: .2em;
  text-align: center;
  text-transform: uppercase;
  color: var(--white);
}

.art__photo {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.art__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}
/* Two scrims, nothing more: dark ceiling under the wordmark, and a fade
   to the sheet's black at the foot so the photo has no hard bottom edge. */
.art__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(0,0,0,.62) 0%, rgba(0,0,0,0) 30%),
    linear-gradient(to top, var(--black) 0%, rgba(0,0,0,0) 22%);
}

/* The one orchestrated moment. Rails are SVG rects; CSS px on an SVG
   element are user units, so -2600px is a slide of 2600 logo units. */
.art__h1    { animation: fadeIn .7s .2s ease-out both; }
.art__photo { animation: fadeIn 1.1s .55s ease-out both; }
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ---------- SHEET ---------- */
.sheet {
  position: relative;
  isolation: isolate;             /* country dropdown stacks above the slanted edge */
  display: flex;
  flex-direction: column;
  background: var(--black);
  color: var(--white);
}
.sheet__body {
  flex: 1 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(28px, 6vw, 72px) clamp(18px, 5vw, 64px);
}

.panel { width: 100%; max-width: 430px; }

/* 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; }

/* ============================================================
   PANEL COPY
   ============================================================ */
.panel__title {
  margin: 0 0 16px;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.45rem, 2.3vw, 1.95rem);
  line-height: 1.18;
  letter-spacing: .01em;
  color: var(--white);
  text-wrap: balance;
}
/* Line two is set black in a white block: v1's device, inverted for the
   black sheet. Reset from italic, Michroma has none. */
.panel__title em {
  font-style: normal;
  color: var(--black);
  background: var(--white);
  padding: .02em .22em .06em;
  margin-left: -.22em;
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
}
.panel__lede {
  margin: 0 0 12px;
  font-size: 16px;
  line-height: 1.55;
  color: var(--white);
  max-width: 44ch;
}
.panel__lede--last { margin-bottom: 24px; }
.panel__hint { margin: 14px 0 0; font-size: 13.5px; color: var(--muted); }
.panel__success-note { margin: 0 0 12px; color: var(--white); font-weight: 600; font-size: 14.5px; }

/* ============================================================
   FORM
   ============================================================ */
.form__row { margin: 0 0 12px; }
/* 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: 14px 15px;
  font-family: var(--body);
  font-size: 16px;                /* 16px minimum or iOS zooms on focus */
  color: var(--black);
  background: var(--white);       /* OPAQUE - see the autofill rule below */
  border: 1px solid var(--white);
  border-radius: 2px;
  transition: box-shadow .18s ease;
}
.form__input::placeholder { color: var(--hint); }
.form__input:focus {
  outline: none;
  box-shadow: 0 0 0 3px var(--black), 0 0 0 5px var(--white);
}
.form__input--otp {
  font-family: var(--display);
  font-size: 20px;
  letter-spacing: .4em;
  text-align: center;
  text-indent: .4em;
}

/* Chrome paints autofilled inputs pale lavender and IGNORES background on
   :-webkit-autofill; a huge inset shadow is the only override. It cannot be
   translucent, so it must be the flattened opaque field colour (white). */
.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(--white) inset !important;
          box-shadow: 0 0 0 1000px var(--white) inset !important;
  -webkit-text-fill-color: var(--black) !important;
  caret-color: var(--black);
  transition: background-color 9999s ease-in-out 0s;
}

/* No red in a black-and-white build: errors are bold white with a rail
   marker, so they still read as different from help text. */
.form__error {
  margin: 7px 0 0;
  padding-left: 10px;
  border-left: 3px solid var(--white);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--white);
}
.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. */
.hp-row { display: none !important; }

.form__row--check { margin: 18px 0 22px; }
.form__check {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
  cursor: pointer;
}
.form__check input {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  margin: 1px 0 0;
  accent-color: var(--white);
  cursor: pointer;
}
.form__check a { color: var(--white); text-decoration: underline; text-underline-offset: 2px; }
.form__check a:hover { text-decoration-thickness: 2px; }

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

/* ---------- button ---------- */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 16px 18px;
  font-family: var(--display);
  font-size: clamp(.82rem, 2.8vw, .95rem);
  letter-spacing: .06em;
  white-space: nowrap;            /* shrink before it can ever wrap */
  text-decoration: none;
  border: 1px solid var(--white);
  border-radius: 2px;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, transform .12s ease;
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .65; cursor: default; }
.btn--primary { color: var(--black); background: var(--white); }
.btn--primary:hover:not(:disabled) { color: var(--white); background: var(--black); }

/* ============================================================
   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 flashes open on first paint. */
.iti__dropdown-content.iti__hide { display: none !important; }
.iti__dropdown-content {
  background: var(--white);
  border: 1px solid var(--black);
  border-radius: 2px;
  box-shadow: 0 22px 48px -18px rgba(0,0,0,.45);
  overflow: hidden;
}
.iti__search-input {
  /* Keep the vendor's horizontal reservation (30px left for the magnifier,
     28px right for the clear button); a padding shorthand that drops them
     puts the icon on top of the placeholder. */
  padding: 10px 30px 10px 32px;
  width: 100%;
  font-family: var(--body);
  font-size: 14px;
  color: var(--black);
  background: var(--white);
  border: 0;
  border-bottom: 1px solid var(--black);
}
.iti__search-input::placeholder { color: var(--hint); }
.iti__search-input:focus { outline: none; box-shadow: inset 0 -1px 0 var(--black); }
.iti__country-list { background: var(--white); max-height: 240px; }
.iti__country { padding: 9px 12px; font-family: var(--body); font-size: 14px; color: var(--black); }
.iti__country:hover,
.iti__country.iti__highlight { background: var(--black); }
.iti__country:hover .iti__country-name,
.iti__country:hover .iti__dial-code,
.iti__country.iti__highlight .iti__country-name,
.iti__country.iti__highlight .iti__dial-code { color: var(--white); }
.iti__dial-code { color: var(--black); }
.iti__country-name { color: var(--black); }
.iti__selected-country { border-radius: 2px 0 0 2px; }
.iti__selected-country:hover,
.iti__selected-country-primary:hover { background: rgba(0,0,0,.06); }
.iti__selected-dial-code { color: var(--black); font-family: var(--body); font-size: 15px; }
.iti__arrow { border-top-color: var(--black); }
.iti__arrow--up { border-bottom-color: var(--black); }

/* ============================================================
   FOOTER - house pattern (basslayerz), credit in a pill
   ============================================================ */
.foot {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  flex-wrap: wrap;
  padding: 16px clamp(18px, 5vw, 64px) 22px;
  border-top: 1px solid rgba(255,255,255,.28);
}
.foot__legal { margin: 0; font-size: 12px; color: var(--muted); letter-spacing: .02em; }
.foot__legal a { color: var(--muted); text-decoration: none; }
.foot__legal a:hover { color: var(--white); text-decoration: underline; }
.site-built { margin: 0; }
.site-built a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  font-size: 11px;
  letter-spacing: .04em;
  color: var(--white);
  text-decoration: none;
  border: 1px solid var(--white);
  border-radius: 999px;
  transition: background-color .18s ease, color .18s ease;
}
.site-built a:hover { color: var(--black); background: var(--white); }
/* The credit logo is a white wordmark with a teal roundel. Flattened to pure
   white (no teal in a black-and-white build), black on the hover fill. */
.site-built img { display: block; filter: brightness(0) invert(1); }
.site-built a:hover img { filter: brightness(0); }

/* Phones: a centred column, never a wrapping row. */
@media (max-width: 480px) {
  .foot { flex-direction: column; justify-content: center; text-align: center; }
}

/* ============================================================
   SPLIT LAYOUT - aspect-ratio threshold, not width alone
   ============================================================ */
@media (min-width: 900px) and (min-aspect-ratio: 7/10) {
  .page {
    grid-template-columns: minmax(0, 1fr) var(--sheet-w);
    grid-template-rows: auto;
  }
  .art {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    height: 100svh;
    padding: clamp(36px, 7svh, 84px) clamp(40px, 5vw, 96px) 0;
  }
  .art { height: 100vh; height: 100svh; }
  .art__h1 { width: min(62%, 540px); }
  /* Ceiling and beams at the top, crowd and decks below; the sticky panel
     is roughly square, so this sits the logo over the ceiling and
     still shows more of the DJ and decks (12 Oct, 24% -> 50%). */
  .art__photo img { object-position: 50% 50%; }
  .art__photo::after {
    background: linear-gradient(to bottom, rgba(0,0,0,.6) 0%, rgba(0,0,0,0) 34%);
  }
  .sheet { min-height: 100vh; min-height: 100svh; }
  /* Slanted leading edge echoing the logo's lean. A skewed pseudo element
     BEHIND the content rather than clip-path on the sheet, which would also
     clip the country dropdown. */
  .sheet::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0;
    left: -46px;
    width: 92px;
    background: var(--black);
    transform: skewX(-9deg);
    z-index: -1;
  }
}

/* --- landscape phones: a first-class layout ---
   844x390 / 932x430 / 667x375 satisfy the split conditions with almost no
   height. Compact side by side, placed AFTER the split block so it wins. */
@media (min-width: 640px) and (min-aspect-ratio: 7/10) and (max-height: 520px) {
  .page {
    grid-template-columns: minmax(0, 1fr) minmax(0, 54%);
    grid-template-rows: auto;
  }
  .art {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    height: 100svh;
    padding: 18px 20px 0;
  }
  .art__h1 { width: min(70%, 260px); }
  .art__photo img { object-position: 50% 60%; }
  .sheet { min-height: 100vh; min-height: 100svh; }
  .sheet::before { display: none; }
  .sheet__body { padding: 16px 20px; align-items: flex-start; }
  .panel__title { font-size: 1.12rem; margin-bottom: 8px; }
  .panel__lede { font-size: 13.5px; }
  .panel__lede--last { margin-bottom: 12px; }
  .form__row { margin-bottom: 9px; }
  .form__input { padding: 10px 13px; }
  .form__row--check { margin: 11px 0 13px; }
  .form__check { font-size: 12px; }
  .btn { padding: 12px 16px; }
  .iti__country-list { max-height: 150px; }
  .foot { padding: 10px 20px 14px; }
}

/* --- portrait phones: tighter sheet padding --- */
@media (max-width: 480px) {
  .sheet__body { padding: 26px 18px 30px; align-items: flex-start; }
}

/* ============================================================
   ACCESSIBILITY
   ============================================================ */
:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
