/* ============================================================
   East End Dubs · Document, Bristol · Sat 14 November 2026
   General sale. Client: Document / Louder Entertainment.

   DIRECTION
   The layout is the one this page has always had - the poster
   whole in the left column, the ticket box on the right - so the
   change here is the artwork and the palette, not the structure.

   What is new is the ground. The client supplied the artwork as
   layers as well as flats, so the plain beam plate (no type, no
   figure) becomes the page's own full-bleed background and the
   poster sits on it as a printed sheet on the light it was shot
   under, rather than on a made-up texture.

   Square corners everywhere, because the poster has none. One
   element is allowed to be loud: the ticket button, a solid block
   of the beams' own orange and the only place on the page where
   the light/dark relationship inverts. On a page whose whole job
   is one click, that is where the boldness goes.

   COLOUR - every value is a literal pixel out of the supplied
   layers, not an interpretation:
     #150D1C  darkest point of the plate
     #2E2635  plate mid-dark, bottom left
     #5206B3  the ultraviolet beam
     #AC4E7E  the magenta where violet crosses orange
     #ED563B  the hot orange beam            -> the button
     #F8F3DC  the poster cream               (median of the type layer)
   Cream on the ground is 16.3:1. Cream on the orange is only
   3.14:1, so the button runs the other way round: near-black on
   orange, 5.42:1, which passes AA at any size and is the reason
   the button reads as a switched-on light rather than a panel.

   TYPE - the PSD names the poster's own faces: Helvetica Neue
   Black and Heavy for the billing, Medium for "DOCUMENT PRESENTS",
   Helvetica Bold for the date. So there is nothing to guess at and
   no second family to introduce - the page runs the poster's own
   family through the system stack, which needs no webfont request
   at all. That matters here: every visitor arrives from a paid
   social ad on mobile data. Tension comes from weight, case and
   tracking, not from a competing face. (This replaces Anton, which
   the previous acid-green artwork was matched to.)

   GRAIN - the supplied artwork carries a heavy film grain baked
   into every layer. Grain is incompressible and it was costing
   ~660KB on the desktop plate alone, so it is filtered out of
   the rasters in build-assets.py and re-applied once here as a
   single fixed noise layer over the whole page, which is what
   the artwork does conceptually anyway.
   ============================================================ */

:root {
  --pitch:    #120A18;   /* page ground, one step under the plate's darkest */
  --shadow:   #150D1C;   /* plate darkest */
  --slate:    #2E2635;   /* plate mid-dark */
  --violet:   #5206B3;   /* the ultraviolet beam */
  --magenta:  #AC4E7E;   /* violet crossing orange */
  --flare:    #ED563B;   /* the hot orange beam - the button */
  --flare-lo: #C43F27;   /* pressed state, same hue darkened */
  --cream:    #F8F3DC;   /* the poster type colour */
  --cream-dim: rgba(248, 243, 220, .72);

  --sans: "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, "Liberation Sans", sans-serif;

  --panel-bg:   rgba(19, 12, 26, .80);
  --panel-line: rgba(237, 86, 59, .40);
  --hairline:   rgba(248, 243, 220, .16);

  --maxw: 1180px;
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

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

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

img { display: block; max-width: 100%; }
a { color: inherit; }

/* ---------- the plate, rebuilt as the page ground ----------
   Chosen by aspect ratio rather than width alone: width-only breakpoints
   leave a gap at squarish window shapes where neither plate applies. The
   <link rel=preload> conditions in the head mirror these three rules. */
.bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background: var(--pitch) url("/assets/images/plate-portrait-1080.webp?v=20260910-1") center / cover no-repeat;
}
@media (min-aspect-ratio: 7/10) {
  .bg { background-image: url("/assets/images/plate-land-1600.webp?v=20260910-1"); }
}
@media (min-aspect-ratio: 7/10) and (min-width: 1501px) {
  .bg { background-image: url("/assets/images/plate-land-2560.webp?v=20260910-1"); }
}

/* Scrim. One gradient, weighted to the bottom where the ticket block sits -
   the beams are meant to stay bright at the top, this only has to sink the
   lower third far enough for cream type and a dark button caption to read. */
.bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(18,10,24,.10) 0%,
    rgba(18,10,24,.02) 34%,
    rgba(18,10,24,.46) 82%,
    rgba(18,10,24,.72) 100%);
}

/* Grain, re-applied here rather than baked into the rasters. Also functional:
   the plate is a field of smooth gradients and WebP bands across it visibly
   without a little tooth on top. */
.grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .13;
  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='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================
   STAGE
   ============================================================ */
.stage {
  position: relative;
  z-index: 1;
  flex: 1 0 auto;
  display: grid;
  align-items: center;
  padding: clamp(16px, 3vw, 34px) clamp(16px, 4vw, 40px) clamp(18px, 3vw, 34px);
}

/* ---------- HERO: poster left, ticket box right ---------- */
.hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(20px, 4vw, 48px);
  align-items: center;
  align-content: center;
  justify-items: center;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;                  /* auto at EVERY breakpoint, never 0 */
}
.hero__col { width: 100%; display: flex; justify-content: center; }

/* The supplied composite, shown whole. The artwork already carries its own
   edge, so there is no frame, no radius and no glow around it - just a shadow
   deep enough to lift it off the plate it is standing on. */
.poster {
  margin: 0;
  width: min(100%, 30rem);
}
.poster img {
  width: 100%;
  height: auto;
  box-shadow: 0 30px 64px -28px rgba(0, 0, 0, .85);
}

/* ---------- TICKET BOX ---------- */
.signup { width: 100%; display: flex; justify-content: center; }
.panel {
  width: min(100%, 27rem);
  padding: clamp(22px, 4vw, 34px) clamp(20px, 3.6vw, 32px) clamp(24px, 4vw, 34px);
  background: var(--panel-bg);
  border: 1px solid var(--panel-line);
  box-shadow: 0 30px 64px -30px rgba(0, 0, 0, .9);
  text-align: center;
}

.panel__eyebrow {
  margin: 0 0 clamp(12px, 2vw, 18px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-size: clamp(.6rem, 2.4vw, .7rem);
  font-weight: 500;
  letter-spacing: .3em;
  text-indent: .3em;
  text-transform: uppercase;
  color: var(--flare);
}
.panel__eyebrow-hair { flex: 1 1 auto; height: 1px; background: var(--hairline); }

.panel__title {
  margin: 0 0 clamp(12px, 2vw, 16px);
  font-size: clamp(1.9rem, 6.4vw, 2.6rem);
  font-weight: 800;
  line-height: .98;
  letter-spacing: -.015em;
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--cream);
}
.panel__title em { font-style: normal; color: var(--flare); }

.panel__lede {
  margin: 0;
  font-size: clamp(.82rem, 3.2vw, .93rem);
  line-height: 1.55;
  color: var(--cream-dim);
}

/* The one loud element on the page: square, unshadowed, near-black on the
   beams' own orange. Cream on this orange is 3.14:1 and would fail; the
   near-black is 5.42:1, and inverting the page's light/dark is exactly what
   makes the button read as the thing to press. */
.btn {
  display: block;
  margin: clamp(18px, 3vw, 24px) 0 0;
  padding: clamp(14px, 3vw, 18px) 16px;
  border: 0;
  background: var(--flare);
  color: var(--shadow);
  font-family: inherit;
  font-weight: 700;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  /* gotcha 26 - shrink the label before it can ever wrap */
  white-space: nowrap;
  font-size: clamp(.78rem, 3.6vw, 1rem);
  letter-spacing: clamp(.05em, .45vw, .15em);
  text-indent: clamp(.05em, .45vw, .15em);
  transition: background-color .16s ease, transform .16s ease;
}
.btn__arrow { display: inline-block; margin-left: .5em; text-indent: 0; }
.btn:hover { background: #FF6B4F; }
.btn:active { background: var(--flare-lo); transform: translateY(1px); }
.btn:focus-visible { outline: 3px solid var(--cream); outline-offset: 3px; }

/* Two deliberate lines rather than one string left to wrap where it likes -
   it was breaking mid-time and leaving "3am" stranded on its own row. The
   time itself never splits; if the second line runs out of room it breaks
   before it instead. */
.panel__meta {
  margin: clamp(12px, 2vw, 16px) 0 0;
  font-size: clamp(.7rem, 2.8vw, .78rem);
  line-height: 1.5;
  letter-spacing: .04em;
  color: rgba(248, 243, 220, .62);
}
.panel__meta > span { display: block; }
.panel__meta .nb { display: inline; white-space: nowrap; }

/* ---------- FOOTER (fleet standard, full-bleed band) ----------
   Sits outside .stage so it runs the full width of the viewport rather than
   stopping at the content column, with its own darkened band so the legal
   type keeps its contrast wherever the beams happen to be bright. */
.foot {
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  width: 100%;
  margin: 0;
  padding: clamp(12px, 1.8vw, 18px) clamp(16px, 4vw, 40px) clamp(14px, 2vw, 22px);
  background: rgba(14, 8, 20, .62);
  border-top: 1px solid var(--hairline);
  display: flex;
  align-items: center;
  /* Phones get everything centred on its own line; the split left/right row
     only starts once there is width for it to read as one row rather than as
     two ragged ones. Width alone is the right test here - the footer does not
     care which hero layout is showing. */
  justify-content: center;
  text-align: center;
  gap: 10px 14px;
  flex-wrap: wrap;
}
.foot__left {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px 18px;
  flex-wrap: wrap;
}
/* Phones stack it into a clean centred column - copyright, then the Furiosa
   pill, then the privacy link - because the split row goes ragged as soon as
   the copyright wraps. Same 600px threshold the previous build used. */
@media (max-width: 600px) {
  .foot { flex-direction: column; gap: 1rem; }
  .foot__left { flex-direction: column; gap: .85rem; width: 100%; }
  .foot__legal { letter-spacing: .12em; }
}
@media (min-width: 601px) {
  .foot { justify-content: space-between; text-align: left; }
  .foot__left { justify-content: flex-start; }
}
.foot__legal { margin: 0; font-size: 12px; letter-spacing: .02em; color: rgba(248, 243, 220, .58); }
.foot__legal a { color: rgba(248, 243, 220, .58); text-decoration: none; }
.foot__legal a:hover { color: var(--flare); }

/* The Furiosa credit is a pill, as on every other page in the fleet */
.site-built { margin: 0; line-height: 0; }
.site-built a {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .35rem .75rem;
  font-size: 11px;
  letter-spacing: .08em;
  color: var(--cream-dim);
  background: rgba(8, 5, 12, .6);
  border: 1px solid rgba(248, 243, 220, .3);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  text-decoration: none;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.site-built a:hover {
  color: #FF6B4F;
  border-color: var(--flare);
  background: rgba(237, 86, 59, .14);
}
.site-built img {
  display: inline-block;
  opacity: .95;
  filter: grayscale(1) brightness(2.4);
  vertical-align: middle;
}

/* ============================================================
   TWO COLUMN - aspect-ratio threshold, not width alone, so
   squarish windows do not fall between the two treatments
   ============================================================ */
@media (min-width: 768px) and (min-aspect-ratio: 7/10) {
  .hero {
    grid-template-columns: minmax(0, 1fr) minmax(0, 27rem);
    gap: clamp(28px, 5vw, 64px);
    align-items: center;
  }
  .hero__col--poster { justify-content: flex-end; }
  .hero__col--signup { justify-content: flex-start; }
  .poster { width: auto; }
  .poster img {
    /* width:auto art needs an explicit max-width or it scales off its own
       ratio and runs under the panel on tall windows - gotcha 38 */
    width: auto;
    max-width: 100%;
    max-height: calc(100svh - 190px);
  }
  .panel { text-align: left; }
  .panel__eyebrow { justify-content: flex-start; }
  .panel__eyebrow-hair:first-child { display: none; }
}

/* ============================================================
   LANDSCAPE PHONES - wide enough for the two-column conditions,
   almost no height. 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: 12px clamp(14px, 3vw, 26px) 8px; gap: 10px; }
  .hero {
    grid-template-columns: auto minmax(0, 22rem);
    gap: clamp(16px, 3vw, 30px);
    align-items: start;
    min-height: 0;
  }
  .poster img { max-height: calc(100svh - 84px); width: auto; max-width: 100%; }
  .panel { padding: 14px 16px 16px; }
  .panel__eyebrow { margin-bottom: 8px; font-size: .58rem; }
  .panel__title { font-size: 1.5rem; margin-bottom: 8px; }
  .panel__lede { font-size: .76rem; line-height: 1.45; }
  .btn { margin-top: 12px; padding: 10px 14px; font-size: .78rem; }
  .panel__meta { margin-top: 9px; font-size: .68rem; }
  .foot { padding: 8px clamp(14px, 3vw, 26px) 10px; }
  .foot__legal, .site-built a { font-size: 11px; }
}

/* ============================================================
   MOTION - one arrival, in reading order. Nothing on scroll.
   ============================================================ */
@keyframes rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
.poster { animation: rise .85s .06s cubic-bezier(.16,.84,.36,1) both; }
.panel  { animation: rise .85s .20s cubic-bezier(.16,.84,.36,1) both; }
.foot   { animation: rise .8s .38s cubic-bezier(.16,.84,.36,1) both; }

@media (prefers-reduced-motion: reduce) {
  .poster, .panel, .foot { animation: none; }
  .btn { transition: none; }
}
