/* One Nation Under Gina
 * Tokens live at the top and are shared with the share card (templates/card.css),
 * so the Facebook preview and the page it links to can never drift apart.
 * Palette is sampled from Vape Slag's background.png: flat fills, bold black ink.
 */

:root {
  --ink:         #0F0A0A;
  --sky:         #9DCFEE;
  --stone:       #F1CB93;
  --stone-shade: #DBAB74;
  --dirt:        #9B443E;
  --dirt-deep:   #6B413F;
  --gold:        #FFC800;
  --gold-hot:    #FFE14D;
  --paper:       #F5EEE1;

  /* Anton is only used by the 404 page now; the poster lettering is SVG. */
  --font-title: "Anton", "Liberation Sans Narrow", Impact, sans-serif;
  --font-body:  "Archivo", "Lato", system-ui, -apple-system, sans-serif;

  /* Fluid type. The teaser must hold a single screen from 320px to 4K. */
  /* Logline. Grows with width but is also held by height, so a short wide
     window cannot trade the cast's space for it. */
  --step-lede:  clamp(1.12rem, min(3vw, 3.6vh), 2rem);
  --step-small: clamp(0.72rem, 1.35vw, 0.9rem);
}

@font-face {
  font-family: "Anton";
  src: url("/fonts/anton-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-display: block; /* block, not swap: a fallback flash would wreck the 404 lockup */
}

@font-face {
  font-family: "Archivo";
  src: url("/fonts/archivo-400-800-latin.woff2") format("woff2");
  font-weight: 400 800;
  font-display: swap;
}

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

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  background: var(--stone);
  color: var(--paper);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; }

/* ------------------------------------------------------------------ stage */

.stage {
  position: relative;
  isolation: isolate;
  /* Exactly one screen, not at least one. The cast row takes whatever the
     masthead and footplate leave, so nothing can push the release date below
     the fold on a short landscape window. */
  height: 100svh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  /* minmax(0, 1fr), not the default `auto`. A grid column sized `auto` grows to
     its widest item, so an over-wide cast row would stretch the whole grid past
     the viewport and push the centred title off-screen. */
  grid-template-columns: minmax(0, 1fr);
  overflow: clip;

  /* Vape Slag's scene is portrait art, drawn in two layers behind everything:
     ::after is the scene itself and ::before a blurred copy that fills whatever
     the scene leaves uncovered at the sides of a wide screen, so zooming out
     never shows bare bars. A percentage y position pins that point of the image
     to the same percentage of the stage, so --scene-y keeps the steps under
     the characters' feet. */
  --scene-y: 78%;
  --scene-size: cover;
  background: var(--sky);
}

.stage::before,
.stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: url("/assets/background.webp") 50% var(--scene-y) / cover no-repeat;
}

/* Ambient fill: blurred only. It used to be dimmed as well, which read as a
   dark patch wherever the fill showed (Pete): the band above the picture on a
   tall phone and the sides on a laptop. The blur alone separates it. */
.stage::before {
  inset: -48px;
  filter: blur(26px);
}

.stage::after { background-size: var(--scene-size); }

/* Wide screens zoom out to show more of the scene (Pete, 2026-09-14). The
   picture is then narrower than the screen, so:
   - its left and right edges fade into the blurred fill rather than stopping
     at a hard line. --scene-w is the picture's rendered width: 135% of the
     stage height at the art's 1288:1920 aspect.
   - the cast and the tagline stay inside the sharp part, so nobody stands half
     in the blur.
   - --scene-y drops the jester hat on the steps behind the footplate, which
     also puts the title over sky. */
@media (min-aspect-ratio: 5/4) {
  .stage {
    --scene-size: auto 135%;
    --scene-y: 20%;
    --scene-w: calc(135svh * 1288 / 1920);
    --fade: 7svh;
  }
  .stage::after {
    mask-image: linear-gradient(90deg,
      transparent calc(50% - var(--scene-w) / 2),
      #000 calc(50% - var(--scene-w) / 2 + var(--fade)),
      #000 calc(50% + var(--scene-w) / 2 - var(--fade)),
      transparent calc(50% + var(--scene-w) / 2));
  }
  .cast {
    width: min(100%, calc(var(--scene-w) - 2 * var(--fade)));
    justify-self: center;
  }
  .kicker img { width: min(92vw, 44rem, calc(var(--scene-w) - 2 * var(--fade))); }
}

/* ------------------------------------------------------------------ title */

.masthead {
  padding: clamp(0.9rem, 3vh, 2.2rem) 1rem 0;
  text-align: center;
}

.kicker { margin: 0 0 clamp(0.4rem, 1.4vh, 0.9rem); }

.kicker img {
  width: min(92vw, 44rem);
  height: auto;
  margin: 0 auto;
}

.title { margin: 0; }

/* Capped by height as well as width, so a short landscape window cannot let the
   title eat the space the cast needs. */
.title img {
  width: min(94vw, 52rem, 62vh);
  height: auto;
  margin: 0 auto;
}

.lede {
  font-size: var(--step-lede);
  font-weight: 600;
  line-height: 1.3;
  max-width: 30ch;
  margin: clamp(0.5rem, 1.6vh, 1.1rem) auto 0;
  text-wrap: balance;
  color: var(--paper);
  /* The line crosses sky, throne and red dirt depending on the screen, so it
     carries its own ink edge rather than relying on what is behind it. */
  text-shadow: 0 2px 0 var(--ink), 0 0 12px rgba(15, 10, 10, 0.8);
}

/* ------------------------------------------------------------------- cast */

.cast {
  position: relative;
  height: 100%;
  min-height: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  width: 100%;
  padding: clamp(0.4rem, 2vh, 1.4rem) clamp(0.5rem, 2vw, 2rem) 0;
}

/* Sized by max-height AND max-width, with both dimensions left auto. The browser
   then honours whichever limit binds first and preserves the aspect ratio either
   way. Fixing `height` alone (the obvious approach) makes the character's width
   uncontrollable, and on a narrow screen they overflow the viewport. */
.cast img {
  width: auto;
  height: auto;
  max-height: var(--h);
  max-width: var(--w);
  filter: drop-shadow(0 0.4rem 0.7rem rgba(15, 10, 10, 0.35));
}

/* Heights are shares of the cast row, which is whatever space is left over, so
   the court grows on a tall screen and shrinks on a short one. */
.cast img[data-role="ben"]     { --h: 100%; --w: 30%; }
/* The Queen is 15% bigger than she was (Pete, 2026-09-14): both limits raised
   by 15%, so she grows whichever one binds. */
.cast img[data-role="gina"]    { --h: 103.5%; --w: 19.55%; }
.cast img[data-role="barnaby"] { --h: 88%;  --w: 25%; }

/* Kneeling in front of the Queen, overlapping the guard's boots and her own. */
.cast img[data-role="pauline"] {
  --h: 58%;
  --w: 34%;
  position: relative;
  z-index: 1;
  margin: 0 -8% 0 -6%;
}

/* --------------------------------------------------------------- footplate */

.footplate {
  position: relative;
  z-index: 2;
  background: var(--ink);
  border-top: 4px solid var(--gold);
  padding: clamp(0.7rem, 1.8vh, 1.1rem) 1rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(0.6rem, 2.5vw, 1.8rem);
  text-align: center;
}

.release {
  height: clamp(34px, 6.5vh, 56px);
  width: auto;
}

.cta {
  display: inline-block;
  font-family: var(--font-body);
  font-size: clamp(0.85rem, 1.7vw, 1.05rem);
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.72em 1.7em;
  border-radius: 999px;
  background: var(--gold);
  color: var(--ink);
  border: 0;
  transition: transform 0.14s ease, background-color 0.14s ease;
}

a.cta:hover, a.cta:focus-visible {
  background: var(--gold-hot);
  transform: translateY(-2px);
}

.rating {
  font-size: var(--step-small);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--paper);
  opacity: 0.72;
  margin: 0;
}

.credit {
  font-size: var(--step-small);
  color: var(--paper);
  opacity: 0.5;
  margin: 0;
}

.credit a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.credit a:hover, .credit a:focus-visible { color: var(--gold); opacity: 1; }

.socials {
  display: flex;
  gap: 0.9rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.socials a {
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  color: var(--ink);
  background: var(--paper);
  text-decoration: none;
  transition: background-color 0.14s ease;
}

.socials a:hover, .socials a:focus-visible { background: var(--gold); }
.socials svg { width: 1.15rem; height: 1.15rem; fill: currentColor; }

/* ------------------------------------------------------------------ small */

@media (max-width: 640px) {
  /* Four characters at phone width become four smudges. The fool goes; the
     guard, the courtier and the Queen carry the joke on their own. At a real
     phone width they are limited by width, not height, so they take almost the
     whole row and overlap deeply: the courtier kneels across both the guard's
     rifle and the Queen's feet. Widths plus margins come to 98.2% (63.2 + 50
     - 20 - 31 + 36), leaving room for rounding: at 100% or more a 412px phone
     overflows. */
  .cast img[data-role="barnaby"] { display: none; }

  /* The guard and the Queen stand the same height (Pete, 2026-09-14). Their
     width shares are in the ratio of the art's aspect ratios (0.774 : 0.441,
     so 1.755 : 1) and both may use the full row height, so whichever limit
     binds first, they come out equal. */
  .cast img[data-role="ben"]     { --h: 80%; --w: 63.2%; }
  .cast img[data-role="gina"]    { --h: 80%; --w: 36%; }
  .cast img[data-role="pauline"] { --h: 46%; --w: 50%; margin: 0 -20% 0 -31%; --lift: 10%; }

  /* Lifted off the footplate so they stand on the steps (Pete): the guard and
     the Queen by 14% of the row, the kneeling courtier by 10%. Relative offsets,
     so they move without resizing. The guard and the Queen are capped at 80% of
     the row, which keeps their heads below the logline on a short phone. */
  .cast img { position: relative; bottom: var(--lift, 14%); }
  .lede { max-width: 24ch; margin-top: 0.35rem; }

  /* On a phone the browser's own bars take 150-200px, and the court was left
     with barely a third of what remained (Pete: "characters too small"). Every
     pixel taken back from the lettering and footplate goes to the cast row. */
  /* The tagline sits exactly halfway between the top of the screen and the
     title (Pete): the same gap above it and below it. Layout space, not an
     offset, so the lettering can never slide over the characters. */
  .masthead    { --tag-gap: calc(0.25rem + 2svh); padding-top: var(--tag-gap); }

  /* Zoomed out as far as the art allows (Pete): the whole picture fits, the
     blurred copy fills whatever it leaves uncovered, and an edge only fades
     where there is a gap to fade into (the min() makes the fade 0 otherwise). */
  .stage {
    --scene-size: contain;
    --scene-y: 100%;
    --scene-w: min(100vw, 100svh * 1288 / 1920);
    --scene-h: min(100svh, 100vw * 1920 / 1288);
    --fade-x: min(5svh, (100vw - var(--scene-w)) * 100);
    --fade-y: min(5svh, (100svh - var(--scene-h)) * 100);
  }
  .stage::after {
    mask-image:
      linear-gradient(90deg,
        transparent calc(50% - var(--scene-w) / 2),
        #000 calc(50% - var(--scene-w) / 2 + var(--fade-x)),
        #000 calc(50% + var(--scene-w) / 2 - var(--fade-x)),
        transparent calc(50% + var(--scene-w) / 2)),
      linear-gradient(180deg,
        transparent calc(100% - var(--scene-h)),
        #000 calc(100% - var(--scene-h) + var(--fade-y)));
    mask-composite: intersect;
  }
  .kicker      { margin-bottom: var(--tag-gap); }
  .title img   { width: min(86vw, 62vh); }
  .cast        { padding: 0; }

  /* Footplate as a small grid rather than stacked rows: the release lockup on
     the left, the rating and the social icon beside it, and the credit under
     them. Named areas so adding an icon cannot push it into a third row and
     steal height from the cast. */
  .footplate {
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-areas:
      "release rating social"
      "release credit credit";
    justify-content: center;
    align-items: center;
    column-gap: 0.7rem;
    row-gap: 0.15rem;
    padding: 0.45rem 0.75rem;
    text-align: left;
  }
  .release       { grid-area: release; height: 32px; }
  .rating        { grid-area: rating; font-size: 0.68rem; letter-spacing: 0.12em; }
  .socials       { grid-area: social; }
  .credit        { grid-area: credit; font-size: 0.68rem; }
  .cta           { grid-area: rating; }
  .socials a     { width: 1.75rem; height: 1.75rem; }
  .socials svg   { width: 0.95rem; height: 0.95rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

:focus-visible {
  outline: 3px solid var(--gold-hot);
  outline-offset: 3px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
