/* The FIRM, marketing site
   ---------------------------------------------------------------
   Every chapter borrows a role colour from the game's own palette,
   and the whole page, header included, shifts with it as you
   scroll. Then the agents arrive in round nine and everything from
   there on is the same cold cyan. The variety stopping is the point:
   the site performs the twist rather than describing it.

   It is all driven by --accent on <html>, keyed off data-accent.
   The other three accent values derive from it, so a chapter only
   ever needs to set one colour.
   --------------------------------------------------------------- */

/* Registered so --accent interpolates instead of snapping. Unsupported
   browsers still get the colour, just without the cross-fade. */
@property --accent {
  syntax: "<color>";
  inherits: true;
  initial-value: #e9b64a;
}

@property --accent-lit {
  syntax: "<color>";
  inherits: true;
  initial-value: #f7d68c;
}

:root {
  /* Surfaces, darkest first. */
  --ink-900: #06080b;
  --ink-850: #090d12;
  --ink-800: #0d1219;
  --ink-750: #121924;
  --ink-700: #18202c;

  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.16);

  --text: #e9edf3;
  --text-dim: #9aa6b6;
  /* The lightest this may go and still clear 4.5:1 on every surface it is
     used on, including the --ink-750 ledger header. */
  --text-faint: #788492;

  --gold: #e9b64a;
  --gold-lit: #f7d68c;
  --cyan: #4fd1e8;
  --cyan-lit: #a4ecf8;
  --danger: #e2564a;

  /* A chapter sets --accent and nothing else; these follow it. */
  --accent: var(--gold);
  --accent-lit: color-mix(in srgb, var(--accent) 60%, #ffffff);
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
  --accent-line: color-mix(in srgb, var(--accent) 34%, transparent);
  --accent-fade: 620ms;

  /* The game's own role palette, from scripts/role_style.gd. */
  --role-dev: #4fd1bd;
  --role-qa: #98aaff;
  --role-sa: #e7a06e;
  --role-ds: #73c4ec;
  --role-ux: #f497bd;
  --role-ga: #badf73;
  --role-ba: #d1a0f3;
  --role-pm: #ffd477;
  --role-a: #a6d4c0;
  --role-t: #72cbd0;
  --role-any: #e3e7dc;

  /* The fixed header's height, and therefore the exact height of the
     black band the hero leaves for it. Driving both from one value is
     the only way they cannot disagree: they used to, and a sliver of
     background showed under the header on taller viewports. */
  --nav-h: 70px;
  /* Every chapter breathes the same amount. These used to be five
     different clamps between 64px and 112px, which read as the page
     changing its mind. Tightened while unifying. */
  --chapter-space: clamp(3rem, 6.5vw, 5.5rem);

  --shell: 1220px;
  --gutter: clamp(1rem, 4vw, 3rem);
  --radius: 14px;

  --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --ease: cubic-bezier(0.22, 0.75, 0.3, 1);
}

/* One role colour per chapter, chosen to sit with what that chapter is
   about rather than cycled through the palette in order. */
html {
  transition: --accent var(--accent-fade) var(--ease),
    --accent-lit var(--accent-fade) var(--ease);
}

/* Growth analyst, for the section whose poster has a man pointing at a
   chart that goes up and means nothing. Also the only accent far enough
   from the hero's gold to register as a change that early in the page. */
html[data-accent="welcome"] { --accent: var(--role-ga); }

/* The talent-market key art is lit blue end to end. */
/* The turn order, in project-manager gold. */
html[data-accent="week"] { --accent: var(--role-pm); }

/* The talent-market key art is lit blue end to end. */
html[data-accent="market"] { --accent: var(--role-ds); }

/* The chairs chapter takes the developer teal, the role it seats most. */
html[data-accent="team"] { --accent: var(--role-dev); }

/* Keeping people, in quality-assurance periwinkle: the chapter is about a
   promise held to, which is QA's whole disposition. */
html[data-accent="retention"] { --accent: var(--role-qa); }

/* Office politics, in business-analyst lilac. */
html[data-accent="politics"] { --accent: var(--role-ba); }

/* The only red on the site, and the only chapter that can end a contract. */
html[data-accent="backlog"] { --accent: var(--danger); }

html[data-accent="contracts"] { --accent: var(--role-sa); }

/* Once the agents arrive, nothing changes colour again. */
html[data-accent="change"] { --accent: var(--cyan); }

/* ---------------------------------------------------------------- base */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

/* Every nav link and in-page button jumps to one of these. Without the
   margin the section's first line lands underneath the fixed header. */
:target,
section[id],
figure[data-accent] {
  scroll-margin-top: var(--nav-h);
}

body {
  margin: 0;
  background: var(--ink-900);
  color: var(--text);
  font-family: var(--display);
  font-size: 17px;
  line-height: 1.62;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  transition: background 900ms var(--ease);
}

img {
  display: block;
  max-width: 100%;
}

a {
  color: var(--accent-lit);
  text-decoration-color: var(--accent-line);
  text-underline-offset: 3px;
  transition: color 180ms var(--ease);
}

a:hover {
  color: var(--text);
}

:focus-visible {
  outline: 2px solid var(--accent-lit);
  outline-offset: 3px;
  border-radius: 3px;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 800;
  font-stretch: 92%;
  line-height: 1.02;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% -140%;
  z-index: 200;
  padding: 0.7rem 1.3rem;
  background: var(--accent);
  color: var(--ink-900);
  font-weight: 700;
  border-radius: 0 0 10px 10px;
  text-decoration: none;
}

.skip-link:focus {
  translate: -50% 0;
}

/* ------------------------------------------------------- type helpers */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1.15rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
}

.eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--accent-line), transparent);
}

.eyebrow .count {
  color: var(--text-faint);
  letter-spacing: 0.14em;
}

/* Centred variant needs a rule on both sides or the label sits off-axis. */
.eyebrow.is-centered {
  justify-content: center;
}

.eyebrow.is-centered::before {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(270deg, var(--accent-line), transparent);
}

.lede {
  font-size: clamp(1.06rem, 1.5vw, 1.28rem);
  line-height: 1.55;
  color: var(--text-dim);
  font-weight: 400;
}

.lede strong {
  color: var(--text);
  font-weight: 600;
}

.section-title {
  font-size: clamp(2.1rem, 5.4vw, 3.5rem);
}

.prose p + p {
  margin-top: 1.05rem;
}

.prose {
  color: var(--text-dim);
}

.prose strong {
  color: var(--text);
  font-weight: 600;
}

.note {
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-faint);
}

.note-after {
  margin-top: 1.5rem;
}

/* Three sections are rendered by site.js. Without it they would be empty
   boxes, so each carries a prose equivalent instead. */
.noscript-note {
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  padding: 1.2rem 1.4rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--ink-850);
  font-size: 0.93rem;
  line-height: 1.6;
  color: var(--text-dim);
}

/* ------------------------------------------------------------ buttons */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.6rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  transition: background 200ms var(--ease), border-color 200ms var(--ease),
    color 200ms var(--ease), translate 200ms var(--ease);
}

.btn-primary {
  background: var(--accent);
  color: var(--ink-900);
}

.btn-primary:hover {
  background: var(--accent-lit);
  color: var(--ink-900);
  translate: 0 -2px;
}

.btn-ghost {
  border-color: var(--line-strong);
  color: var(--text);
  background: rgba(255, 255, 255, 0.03);
}

.btn-ghost:hover {
  border-color: var(--accent-line);
  color: var(--accent-lit);
  translate: 0 -2px;
}

/* ---------------------------------------------------------------- nav */

.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: var(--nav-h);
  padding: 0 var(--gutter);
  background: linear-gradient(180deg, rgba(6, 8, 11, 0.82), rgba(6, 8, 11, 0));
  transition: background 320ms var(--ease), border-color 320ms var(--ease),
    backdrop-filter 320ms var(--ease);
  border-bottom: 1px solid transparent;
}

.nav.is-stuck {
  background: rgba(6, 8, 11, 0.88);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--line);
}

.nav-mark {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-weight: 900;
  font-stretch: 88%;
  font-size: 1.02rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}

.nav-mark span {
  color: var(--accent);
}

.nav-links {
  display: flex;
  gap: 1.55rem;
  margin-left: auto;
  list-style: none;
  padding: 0;
  margin-block: 0;
}

.nav-links a {
  font-size: 0.84rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  text-decoration: none;
}

.nav-links a:hover,
.nav-links a.is-current {
  color: var(--accent-lit);
}

.nav .btn {
  padding: 0.6rem 1.15rem;
  font-size: 0.82rem;
}

@media (max-width: 900px) {
  .nav-links {
    display: none;
  }

  .nav .btn {
    margin-left: auto;
  }
}

/* --------------------------------------------------------------- hero */

/* A black band the height of the nav, so the masthead's own logo is never
   read through the navigation sitting on top of it. */
.hero {
  position: relative;
  padding-top: var(--nav-h);
}

.hero-art {
  position: relative;
  width: 100%;
  aspect-ratio: 1919 / 820;
  overflow: hidden;
}

.hero-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
}

/* On a tall screen the hero swaps to the portrait key art, so the frame has
   to become portrait too or object-fit crops the composition to a sliver. */
@media (max-aspect-ratio: 3/4) {
  .hero-art {
    aspect-ratio: 1024 / 1380;
    max-height: 92svh;
  }

  .hero-art img {
    object-position: center top;
  }
}

/* The art carries its own logo and tagline, so the page adds only a
   fade that lets the masthead dissolve into the copy beneath it. */
.hero-art::after {
  content: "";
  position: absolute;
  inset: 0;
  /* The fade starts below the board labels, PROJECTS, TALENT, CONTRACTS,
     CASH, VICTORY POINTS, because those are the game in one line. */
  background: linear-gradient(
      180deg,
      rgba(6, 8, 11, 0) 0%,
      rgba(6, 8, 11, 0) 68%,
      rgba(6, 8, 11, 0.78) 90%,
      var(--ink-900) 100%
    ),
    radial-gradient(130% 85% at 50% 45%, transparent 52%, rgba(6, 8, 11, 0.45) 100%);
  pointer-events: none;
}

.hero-body {
  position: relative;
  z-index: 2;
  margin-top: clamp(-7rem, -8vw, -3rem);
  padding-bottom: clamp(3.5rem, 7vw, 6rem);
  text-align: center;
}

.hero-lede {
  max-width: 44ch;
  margin-inline: auto;
  font-size: clamp(1.1rem, 2.1vw, 1.5rem);
  line-height: 1.45;
  font-weight: 500;
  color: var(--text);
}

.hero-sub {
  max-width: 56ch;
  margin: 1.1rem auto 0;
  color: var(--text-dim);
}

/* The tone line: half specification, half warning. */
.hero-meta {
  margin: 1.4rem auto 0;
  font-family: var(--mono);
  font-size: clamp(0.7rem, 1.3vw, 0.8rem);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  justify-content: center;
  margin-top: 2.1rem;
}

/* ------------------------------------------------------------- facts */

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 1px;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.fact {
  padding: 1.35rem 1rem;
  background: var(--ink-850);
  text-align: center;
}

.fact dt {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 0.5rem;
}

.fact dd {
  margin: 0;
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 800;
  font-stretch: 88%;
  line-height: 1;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ plates */

/* Each key art is composed as a finished poster: a headline along the top
   edge, a line of copy at the bottom right, firm banners at both sides.
   So the plate crops nothing and overlays nothing, the image sets its
   own height and the caption sits underneath it. */
.plate {
  position: relative;
  width: 100%;
  margin: 0;
  background: var(--ink-850);
  /* The entrance scales the image past 100% for a moment; without this it
     widens the document and puts a scrollbar under the whole page. */
  overflow: hidden;
}

/* Every key art carries its own headline near the top edge and a line of
   copy near the bottom right, so the frame matches the source aspect
   exactly and nothing may scale it at rest. The entrance settles at 1. */
.plate img {
  width: 100%;
  height: auto;
  scale: 1;
  transition: scale 1400ms var(--ease);
}

.plate[data-reveal] {
  translate: none;
}

.plate[data-reveal] img {
  scale: 1.045;
}

.plate[data-reveal].is-in img {
  scale: 1;
}

.plate-caption {
  padding: 0.85rem var(--gutter);
  text-align: right;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  background: var(--ink-900);
}

/* ------------------------------------------------------------ chapter */

.chapter {
  position: relative;
  padding-block: var(--chapter-space);
}

.chapter-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 5vw, 4.5rem);
  align-items: start;
}

.chapter-head .prose {
  padding-top: 0.5rem;
}

@media (max-width: 820px) {
  .chapter-head {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
}

/* --------------------------------------------------------- pull quote */

.pull {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding: 1.6rem 1.9rem;
  border-left: 3px solid var(--accent);
  background: linear-gradient(90deg, var(--accent-soft), transparent 70%);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: clamp(1.1rem, 2vw, 1.4rem);
  font-weight: 600;
  line-height: 1.38;
  color: var(--text);
}

.pull small {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.82rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--text-faint);
}

/* -------------------------------------------------------------- cards */

.grid {
  display: grid;
  gap: 1px;
  margin-top: clamp(2rem, 4vw, 3rem);
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.grid-3 {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.tile {
  padding: 1.6rem 1.5rem;
  background: var(--ink-850);
  transition: background 220ms var(--ease);
}

.tile:hover {
  background: var(--ink-800);
}

.tile h3 {
  font-size: 1.06rem;
  font-weight: 700;
  margin-bottom: 0.55rem;
}

.tile p {
  font-size: 0.93rem;
  color: var(--text-dim);
  line-height: 1.55;
}

.tile .figure {
  display: block;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.9rem;
}

/* ================================================ welcome to consulting
   A deliberate tonal break: the one bright screen on a dark site, done
   as a 1990s recruitment advert that immediately undercuts itself. */

.advert {
  position: relative;
  padding-block: var(--chapter-space);
  background: var(--ink-900);
  color: var(--text);
  text-align: center;
  overflow: hidden;
  isolation: isolate;
}

/* Just enough daylight behind the poster to feel like a different world,
   without handing a whole screen of the site to an advertisement. */
.advert::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(90% 60% at 50% 42%, rgba(142, 198, 240, 0.16), transparent 70%);
  z-index: -1;
}

.advert-kicker {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1.4rem;
}

/* The poster carries the headline, the strapline and the disclaimer, so
   the section frames it rather than restating any of it. */
.advert-art {
  margin: 0 0 clamp(1.75rem, 3.5vw, 2.5rem);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.9), 0 0 0 1px var(--line);
}

.advert-art img {
  width: 100%;
  height: auto;
}

.advert-terms {
  max-width: 82ch;
  margin: clamp(1.5rem, 3vw, 2.25rem) auto 0;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
  /* It is a joke about small print, so it stays smaller than the body
     copy, but 12.5px in the faintest grey on the palette was asking too
     much of anybody reading a screen at arm's length. The joke survives at
     15px; being unreadable was never the joke. */
  font-size: 0.94rem;
  line-height: 1.65;
  text-align: left;
  color: var(--text-dim);
  columns: 2;
  column-gap: 2.5rem;
}

.advert-terms b {
  font-weight: 700;
  color: var(--text-dim);
}

@media (max-width: 720px) {
  .advert-terms {
    columns: 1;
  }
}

/* ===================================================== the roster
   Ten cards, one per role, that lean toward the pointer and turn over
   to be read. The portrait is the game's own staff art; the type sits
   on a scrim heavy enough that the role code is read first. */

/* Five across, declared rather than left to wrapping, so each card takes
   its full share of the width. The old flex layout pinned cards at 172px
   and left the remainder empty, which is why the copy on them had to be
   10.6px to fit. */
.roster {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(0.6rem, 1.3vw, 1.1rem);
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  perspective: 1200px;
}

.rcard {
  position: relative;
  width: auto;
  height: 392px;
  padding: 0;
  border: 0;
  border-radius: 13px;
  background: linear-gradient(168deg, #222b37, #141a23);
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
  transform-style: preserve-3d;
  /* The pointer handler writes --ry and --rx and nothing else. */
  transform: rotateY(var(--ry, 0deg)) rotateX(var(--rx, 0deg));
  transition: transform 400ms var(--ease), box-shadow 400ms var(--ease);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.07) inset,
    0 16px 28px -16px rgba(0, 0, 0, 0.9);
}

.rcard.is-live {
  transition: transform 90ms linear, box-shadow 400ms var(--ease);
}

.rcard:hover,
.rcard:focus-visible {
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset,
    0 36px 54px -22px rgba(0, 0, 0, 0.95), 0 0 0 1px var(--role-color);
}

.rcard .r-front,
.rcard .r-back {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border-top: 4px solid var(--role-color);
  overflow: hidden;
  backface-visibility: hidden;
}

.rcard .r-front {
  display: grid;
  grid-template-rows: auto 1fr auto;
  text-align: center;
}

.rcard .r-art {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.rcard .r-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 18%;
  filter: saturate(0.85) contrast(1.04);
}

.rcard .r-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(8, 11, 16, 0.92) 0%, rgba(8, 11, 16, 0.5) 22%,
      rgba(8, 11, 16, 0.16) 42%, rgba(8, 11, 16, 0.74) 74%, rgba(8, 11, 16, 0.96) 100%),
    linear-gradient(180deg, color-mix(in srgb, var(--role-color) 20%, transparent), transparent 45%);
}

.rcard .r-code,
.rcard .r-who,
.rcard .r-turn { position: relative; z-index: 1; }

.rcard .r-code {
  padding: 0.7rem 0.7rem 0;
  font-family: var(--mono);
  font-size: 1.12rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--role-color);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.95), 0 0 3px rgba(0, 0, 0, 0.9);
}

.rcard .r-who {
  align-self: end;
  padding-inline: 0.7rem;
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.2;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.9);
}

.rcard .r-turn {
  padding: 0.35rem 0.7rem 0.75rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.95);
}

/* The foil, tracking the pointer across the face. */
.rcard .r-foil {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background:
    radial-gradient(38% 60% at var(--mx, 50%) var(--my, 50%),
      color-mix(in srgb, var(--role-color) 40%, transparent), transparent 70%),
    linear-gradient(calc(var(--ry, 0deg) * 6 + 100deg),
      transparent 34%, rgba(255, 255, 255, 0.15) 48%, transparent 60%);
  opacity: 0;
  transition: opacity 260ms var(--ease);
  pointer-events: none;
  mix-blend-mode: screen;
}

.rcard:hover .r-foil,
.rcard:focus-visible .r-foil { opacity: 1; }

.rcard .r-back {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: 0.5rem;
  padding: 0.8rem 0.8rem 0.85rem;
  background: linear-gradient(168deg, #1b2530, #0d131a);
  transform: rotateY(180deg);
  text-align: left;
}

.rcard .r-back .r-code { padding: 0; font-size: 0.8rem; }

.rcard .r-goal {
  font-size: clamp(0.84rem, 1.02vw, 0.94rem);
  line-height: 1.45;
  color: var(--text-dim);
  font-style: italic;
}

.rcard .r-fact {
  align-self: end;
  padding-top: 0.5rem;
  border-top: 1px solid var(--line);
  font-size: clamp(0.84rem, 1.02vw, 0.94rem);
  line-height: 1.45;
  color: var(--text);
}

.rcard .r-fact b,
.rcard .r-status b {
  display: block;
  font-family: var(--mono);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--role-color);
  margin-bottom: 0.25rem;
}

/* The third beat. It arrives after the flip has landed rather than with
   it, so the card has two punchlines instead of one crowded one. No
   second click: making it work for the joke would cost more than it
   returns. */
.rcard .r-status {
  padding-top: 0.5rem;
  border-top: 1px solid var(--line);
  font-size: clamp(0.78rem, 0.94vw, 0.87rem);
  line-height: 1.4;
  font-style: italic;
  color: var(--text-dim);
  opacity: 0;
  translate: 0 5px;
  transition: opacity 360ms var(--ease), translate 360ms var(--ease);
}

.rcard.is-flipped .r-status {
  opacity: 1;
  translate: 0 0;
  transition-delay: 620ms;
}

.rcard .r-status b { font-style: normal; color: var(--text-faint); }

.rcard.is-flipped {
  transform: rotateY(180deg) translateZ(24px) !important;
}

.roster-hint {
  margin-top: 1.25rem;
  text-align: center;
}

/* Two across on a phone leaves the card too short for the back copy, so
   it gets taller rather than smaller. The scroll is a safety net for the
   longest backs at the very narrowest sizes. */
@media (max-width: 1000px) {
  .roster { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rcard { height: 376px; }
}

@media (max-width: 660px) {
  .roster { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rcard { height: 404px; }
}

/* At 320px three of the ten backs run about nine pixels past the card.
   That turns each one into a scrolling region, which a keyboard cannot
   reach and a hidden scrollbar cannot advertise, so axe flags it and it
   is right to. Sixteen pixels of height is the honest fix; the overflow
   below stays as a safety net for text scaling. */
@media (max-width: 360px) {
  .rcard { height: 420px; }
}

.rcard .r-back { overflow-y: auto; scrollbar-width: none; }
.rcard .r-back::-webkit-scrollbar { display: none; }

@media (prefers-reduced-motion: reduce) {
  .rcard, .rcard.is-live { transition: none; }
  .rcard:not(.is-flipped) { transform: none !important; }
  .rcard .r-foil { display: none; }
}

/* ===================================================== build the team
   The chair mechanic is easier to show than to describe, so this
   section is the mechanic rather than a picture of it. */

.table-demo {
  margin-top: clamp(2.25rem, 5vw, 3.25rem);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--ink-800), var(--ink-850));
  overflow: hidden;
}

.table-projects {
  display: flex;
  gap: 0.5rem;
  padding: 0.9rem 1rem;
  overflow-x: auto;
  border-bottom: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.25);
  scrollbar-width: thin;
  /* Fades the last tab out so it reads as a scrollable row. */
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 3rem), transparent 100%);
}

.proj-tab {
  flex: 0 0 auto;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 0.83rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: all 180ms var(--ease);
}

.proj-tab:hover {
  border-color: var(--line-strong);
  color: var(--text);
}

.proj-tab[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink-900);
}

.proj-tab .chairs {
  font-family: var(--mono);
  font-size: 0.72rem;
  opacity: 0.7;
  margin-left: 0.4rem;
}

.table-body {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  padding: clamp(1.25rem, 3vw, 2rem);
}

@media (max-width: 860px) {
  .table-body {
    grid-template-columns: 1fr;
  }
}

.table-brief h3 {
  font-size: 1.35rem;
  margin-bottom: 0.4rem;
}

.table-brief .req {
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 1.35rem;
}

/* The chairs themselves. */
.chairs-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}

.chair {
  position: relative;
  width: clamp(76px, 12vw, 104px);
  aspect-ratio: 3 / 4;
  padding: 0;
  border: 1px dashed var(--chair-color, var(--line-strong));
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.02);
  color: var(--chair-color, var(--text-dim));
  font-family: inherit;
  cursor: pointer;
  overflow: hidden;
  transition: all 220ms var(--ease);
}

.chair:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.06);
  translate: 0 -3px;
}

.chair:disabled {
  cursor: default;
}

.chair-code {
  position: absolute;
  inset: auto 0 0;
  z-index: 2;
  padding: 0.3rem 0.2rem;
  background: var(--chair-color, var(--ink-700));
  color: #101d28;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
}

.chair-empty {
  display: grid;
  place-items: center;
  height: 100%;
  font-size: 1.5rem;
  line-height: 1;
  opacity: 0.45;
  padding-bottom: 1.2rem;
}

.chair img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
}

.chair.is-filled {
  border-style: solid;
  border-color: var(--chair-color, var(--accent));
  box-shadow: 0 0 0 1px var(--chair-color, var(--accent)),
    0 10px 30px -12px var(--chair-color, var(--accent));
}

.chair.is-filled .chair-empty {
  display: none;
}

.table-status {
  margin-top: 1.5rem;
  padding: 0.95rem 1.2rem;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.3);
  font-size: 0.92rem;
  color: var(--text-dim);
  transition: all 300ms var(--ease);
}

.table-status.is-ready {
  border-color: var(--accent-line);
  background: var(--accent-soft);
  color: var(--text);
}

.table-status b {
  color: var(--accent-lit);
  font-weight: 700;
}

.table-status .delivery {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.83rem;
  color: var(--text-faint);
}

/* The bench you seat people from. */
.bench h4 {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 0.9rem;
}

.bench-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

/* Role chips mirror the game's own: a colour swatch and the role code.
   A portrait at this size is unreadable mud, so it does not get one. */
.staff-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: all 180ms var(--ease);
}

.staff-chip .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--role-color, var(--text-faint));
  flex: none;
}

.staff-chip:hover:not(:disabled) {
  border-color: var(--role-color, var(--line-strong));
  background: rgba(255, 255, 255, 0.07);
}

.staff-chip.is-wanted {
  border-color: var(--role-color);
  box-shadow: 0 0 0 1px var(--role-color);
}

.staff-chip:disabled {
  opacity: 0.3;
  cursor: default;
}

.bench-hint {
  margin-top: 1rem;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--text-faint);
}

/* -------------------------------------------------------- class table */

.classes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(214px, 1fr));
  gap: 1px;
  margin-top: clamp(2rem, 4vw, 3rem);
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.class-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.35rem 1.3rem 1.4rem;
  background: var(--ink-850);
  border-top: 2px solid var(--role-color, var(--accent));
  transition: background 220ms var(--ease);
}

.class-cell:hover {
  background: var(--ink-800);
}

.class-cell .code {
  display: inline-block;
  padding: 0.12rem 0.5rem;
  border-radius: 4px;
  background: var(--role-color, var(--accent));
  color: #101d28;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  margin-bottom: 0.75rem;
}

.class-cell h3 {
  font-size: 1rem;
  line-height: 1.24;
  margin-bottom: 0.6rem;
}

.class-cell p {
  font-size: 0.855rem;
  line-height: 1.5;
  color: var(--text-dim);
}

/* margin-top:auto lines every cell's figures up along one baseline,
   however long the power description above them runs. */
/* Two by two, not one row of four. The figures became ranges, and four
   unbreakable ones will not fit across a fifth of the page. */
.class-cell dl {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem 0.9rem;
  margin: auto 0 0;
  padding-top: 1.1rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}

.class-cell dl div {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.class-cell dl dt {
  text-transform: uppercase;
  font-size: 0.6rem;
}

/* These are ranges now, and an en-dash is a break opportunity, so "12-16"
   split across two lines in a column this narrow. */
.class-cell dl dd {
  white-space: nowrap;
  margin: 0;
  color: var(--text);
  font-size: 0.86rem;
  font-weight: 600;
}

/* ------------------------------------------------------- card library */

/* The strip scrolls sideways. The native scrollbar under it is the only
   affordance there was, and on a desktop that is a 5px sliver nobody
   notices, so the strip is draggable and gets a pair of arrows. */
.cardstrip-wrap {
  position: relative;
}

.strip-btn {
  position: absolute;
  top: 27%;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: rgba(6, 8, 11, 0.86);
  backdrop-filter: blur(8px);
  color: var(--text);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  transition: opacity 200ms var(--ease), border-color 200ms var(--ease),
    color 200ms var(--ease);
}

.strip-btn:hover,
.strip-btn:focus-visible {
  border-color: var(--accent-line);
  color: var(--accent-lit);
}

/* Kept in the layout when it cannot go further, rather than vanishing and
   shifting the other one about. */
.strip-btn[disabled] {
  opacity: 0.25;
  cursor: default;
}

.strip-prev { left: calc(var(--gutter) * -1 + 0.25rem); }
.strip-next { right: calc(var(--gutter) * -1 + 0.25rem); }

@media (max-width: 1100px) {
  .strip-prev { left: 0.4rem; }
  .strip-next { right: 0.4rem; }
}

/* The strip takes focus so it can be scrolled by keyboard, so it has to
   show that it has it. :focus-visible keeps the ring off a mouse drag. */
.cardstrip:focus-visible {
  outline: 2px solid var(--accent, #d9a441);
  outline-offset: 4px;
  border-radius: 6px;
}

.cardstrip.is-draggable { cursor: grab; }
.cardstrip.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}

.cardstrip.is-dragging img { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .strip-btn { transition: none; }
}

.cardstrip {
  display: flex;
  gap: 1rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding: 0.5rem var(--gutter) 1.5rem;
  margin-inline: calc(var(--gutter) * -1);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Without this the first card snaps flush to the border edge, 48px left
     of every other left margin on the page. */
  scroll-padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}

.action-card {
  flex: 0 0 clamp(250px, 30vw, 310px);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--ink-850);
  overflow: hidden;
  transition: border-color 220ms var(--ease), translate 220ms var(--ease);
}

.action-card:hover {
  border-color: var(--accent-line);
  translate: 0 -4px;
}

/* height:auto is required: the img's height attribute is a presentational
   hint that otherwise wins over the intrinsic ratio and squares the art. */
.action-card img {
  width: 100%;
  height: auto;
  border-bottom: 1px solid var(--line);
}

.action-card .body {
  padding: 1rem 1.1rem 1.2rem;
}

.action-card h3 {
  font-size: 0.98rem;
  margin-bottom: 0.45rem;
}

.action-card p {
  font-size: 0.83rem;
  line-height: 1.5;
  color: var(--text-dim);
}

.action-card .tag {
  display: inline-block;
  margin-bottom: 0.6rem;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

/* --------------------------------------------------------- the backlog
   Backlog is the one mechanic that punishes on three axes at once, so it
   gets the only red on the site. */

#backlog {
  --accent: var(--danger);
  --accent-lit: #f58b80;
  --accent-soft: rgba(226, 86, 74, 0.13);
  --accent-line: rgba(226, 86, 74, 0.38);
  background: radial-gradient(90% 60% at 50% 0%, rgba(226, 86, 74, 0.09), transparent 70%);
}

.penalties {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
  gap: 1rem;
  margin-top: clamp(2rem, 4vw, 3rem);
}

.penalty {
  padding: 1.45rem 1.4rem;
  border: 1px solid rgba(226, 86, 74, 0.28);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(226, 86, 74, 0.08), rgba(226, 86, 74, 0.02));
}

.penalty .amount {
  display: block;
  font-size: clamp(1.7rem, 3.4vw, 2.3rem);
  font-weight: 900;
  font-stretch: 88%;
  line-height: 1;
  color: #f58b80;
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.6rem;
}

.penalty p {
  font-size: 0.89rem;
  line-height: 1.5;
  color: var(--text-dim);
}

/* ====================================================== the transition
   A full-bleed hinge between the two halves of the page. */

/* The artwork's subject is a face in the middle of the frame, so the copy
   sits to the left of it rather than over it. */
.hinge {
  position: relative;
  display: grid;
  align-items: center;
  justify-items: start;
  min-height: 78svh;
  overflow: hidden;
  isolation: isolate;
}

.hinge img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hinge::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
      180deg,
      var(--ink-900) 0%,
      rgba(6, 8, 11, 0.35) 18%,
      rgba(6, 8, 11, 0.35) 62%,
      var(--ink-900) 100%
    ),
    linear-gradient(90deg, rgba(6, 8, 11, 0.82) 0%, rgba(6, 8, 11, 0.62) 34%, transparent 62%);
}

.hinge-body {
  width: min(100%, var(--shell));
  margin-inline: auto;
  padding: clamp(2rem, 6vw, 4rem) var(--gutter);
}

.hinge-body > * {
  max-width: 34ch;
}

.hinge h2 {
  font-size: clamp(1.9rem, 5vw, 3.1rem);
  margin-bottom: 1rem;
}

.hinge p {
  color: rgba(233, 237, 243, 0.78);
  font-size: clamp(1rem, 1.8vw, 1.15rem);
}

.hinge p + p {
  margin-top: 1.05rem;
}

/* Three cells whose labels are different lengths: "Arrives" sits on one
   line where "Your juniors" and "Assisted work" wrap to two, so as flex
   items each value started at its own height. Subgrid puts every label in
   one shared row and every value in another, so the values line up
   whatever the labels do. */
.hinge .odds {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  grid-template-rows: auto auto;
  gap: 1px;
  margin-top: 2rem;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 10px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(8px);
}

.hinge .odds div {
  display: grid;
  grid-row: span 2;
  grid-template-rows: subgrid;
  align-content: start;
  padding: 0.8rem 0.9rem;
  background: rgba(6, 8, 11, 0.72);
}

/* Without subgrid the cells get independent tracks and drift apart again.
   Reserving two lines on the label costs an empty line where they would
   have fitted on one, which is the lesser of the two. */
@supports not (grid-template-rows: subgrid) {
  .hinge .odds dt { min-height: 2.1em; }
}

.hinge .odds dt {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(233, 237, 243, 0.55);
  margin-bottom: 0.3rem;
}

.hinge .odds dd {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--cyan-lit);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- after */

.after {
  background: linear-gradient(180deg, var(--ink-900), #070c12 40%, var(--ink-900));
}

.ledger {
  display: grid;
  gap: 1px;
  margin-top: clamp(2rem, 4vw, 3rem);
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.ledger-row {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr) minmax(0, 1fr);
  gap: 1px;
  background: var(--line);
}

.ledger-row > * {
  padding: 1.05rem 1.25rem;
  background: var(--ink-850);
}

.ledger-head > * {
  background: var(--ink-750);
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.ledger-row .what {
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--text);
}

.ledger-row .before {
  color: var(--text-faint);
  font-size: 0.88rem;
}

.ledger-row .after-col {
  color: var(--cyan-lit);
  font-size: 0.88rem;
  font-weight: 500;
}

@media (max-width: 760px) {
  .ledger-row {
    grid-template-columns: 1fr;
  }

  .ledger-head {
    display: none;
  }

  .ledger-row .before::before {
    content: "Before · ";
    font-family: var(--mono);
    font-size: 0.64rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
  }

  .ledger-row .after-col::before {
    content: "After · ";
    font-family: var(--mono);
    font-size: 0.64rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
}

/* === the bargain: the decision the AI mode actually asks of you ======= */

.bargain {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin-top: clamp(2rem, 4vw, 3rem);
  background: var(--line);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius);
  overflow: hidden;
}

.bargain-side {
  padding: clamp(1.6rem, 3vw, 2.2rem);
  background: var(--ink-850);
}

.bargain-side.is-cost {
  background: linear-gradient(160deg, var(--accent-soft), var(--ink-850) 70%);
}

.bargain-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1.1rem;
}

.bargain-side ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.75rem;
}

.bargain-side li {
  position: relative;
  padding-left: 1.4rem;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--text-dim);
}

.bargain-side li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.55rem;
  height: 1px;
  background: var(--accent);
}

.bargain-figure {
  font-size: clamp(2.6rem, 6vw, 4rem);
  font-weight: 900;
  font-stretch: 88%;
  line-height: 0.95;
  letter-spacing: -0.03em;
  color: var(--accent-lit);
  margin-bottom: 0.7rem;
}

.bargain-cost {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--text-dim);
}

.bargain-cost b {
  color: var(--text);
}

.bargain-question {
  grid-column: 1 / -1;
  padding: clamp(1.25rem, 2.5vw, 1.75rem) clamp(1.6rem, 3vw, 2.2rem);
  background: var(--ink-750);
  font-size: clamp(1.1rem, 2.2vw, 1.55rem);
  font-weight: 800;
  font-stretch: 92%;
  letter-spacing: -0.018em;
  line-height: 1.3;
  color: var(--text);
  text-wrap: balance;
}

@media (max-width: 720px) {
  .bargain {
    grid-template-columns: 1fr;
  }
}

.price {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
  margin-top: clamp(2rem, 4vw, 3rem);
}

.price-card {
  padding: 1.7rem 1.6rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-850);
}

.price-card.is-cost {
  border-color: rgba(79, 209, 232, 0.35);
  background: linear-gradient(180deg, rgba(79, 209, 232, 0.08), transparent);
}

.price-card h3 {
  font-size: 1.05rem;
  margin-bottom: 0.7rem;
}

.price-card p {
  font-size: 0.9rem;
  color: var(--text-dim);
  line-height: 1.55;
}

.price-card .headline {
  display: block;
  font-size: clamp(1.8rem, 3.6vw, 2.5rem);
  font-weight: 900;
  font-stretch: 88%;
  line-height: 1;
  color: var(--cyan-lit);
  margin-bottom: 0.7rem;
  font-variant-numeric: tabular-nums;
}

/* ===================================================== the staff wall
   Ten posters, one per role. Everything they say is printed on the art,
   so the card underneath carries only a name and the status line, and the
   picture is given the room instead. */

.staffgrid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.2vw, 1.75rem);
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  padding: 0;
  list-style: none;
}

.staffcard-item {
  display: flex;
}

.staffcard {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-850);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  transition: border-color 240ms var(--ease), translate 240ms var(--ease),
    box-shadow 240ms var(--ease);
}

.staffcard:hover,
.staffcard:focus-visible {
  border-color: var(--accent-line);
  translate: 0 -4px;
  box-shadow: 0 24px 50px -28px rgba(0, 0, 0, 0.9);
}

.staffcard picture {
  display: block;
  flex: none;
}

/* The posters are 16:9 and stay that way: everything on them is composed
   to the edges, so cropping costs words. */
.staffcard img {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  object-fit: cover;
  display: block;
  border-bottom: 1px solid var(--line);
}

.staffcard-body {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.3rem 1rem;
  padding: 0.95rem 1.15rem 1.05rem;
}

.staffcard-name {
  font-size: 1rem;
  font-weight: 700;
  font-stretch: 92%;
  letter-spacing: -0.015em;
}

.staffcard-status {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}

@media (max-width: 720px) {
  .staffgrid { grid-template-columns: 1fr; }
}

/* ================================================== the poster archive
   A campaign wall. The posters are dense with small print, so the grid
   is a contact sheet and the reading happens in the viewer. */

.archive {
  background: radial-gradient(90% 60% at 50% 0%, var(--accent-soft), transparent 68%);
}

.posters {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.2vw, 1.75rem);
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

/* Cards fill their row, so a row is as tall as its tallest card and every
   card in it matches. Combined with the fixed image box and the clamped
   body below, that makes all of them the same height. */
.poster-item {
  display: flex;
}

/* Act headings. Full-width rows inside the same list, so the campaign stays
   one ordered list and the poster numbering runs straight through it. */
.poster-act {
  grid-column: 1 / -1;
  display: grid;
  gap: 0.3rem;
  margin-top: clamp(1.75rem, 4vw, 3.25rem);
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--accent-line);
}

.poster-act:first-child {
  margin-top: 0;
}

.poster-act-no {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent-lit);
}

.poster-act-name {
  margin: 0;
  font-size: clamp(1.4rem, 3vw, 2rem);
  font-weight: 800;
  font-stretch: 90%;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.poster-act-line {
  margin: 0;
  max-width: 54ch;
  color: var(--text-dim);
  font-size: 0.95rem;
  line-height: 1.5;
}

.poster-card {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-850);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  position: relative;
  transition: border-color 240ms var(--ease), translate 240ms var(--ease),
    box-shadow 240ms var(--ease);
}

.poster-card:hover,
.poster-card:focus-visible {
  border-color: var(--accent-line);
  translate: 0 -4px;
  box-shadow: 0 24px 50px -28px rgba(0, 0, 0, 0.9);
}

.poster-card {
  display: flex;
  flex-direction: column;
  width: 100%;
}

/* One box for every poster whatever its own shape. The set is a mix of
   3:2 and 16:9, and 16:10 sits between them, so the most any poster loses
   is about 5% off two edges. The full thing is one click away. */
.poster-card picture {
  display: block;
  flex: none;
}

/* The ratio goes on the image, not on the picture around it. On the
   wrapper it silently loses: the image's height:100% has no definite
   parent height to resolve against, so it falls back to its intrinsic
   size and stretches the box it was supposed to be constrained by. The
   3:2 posters were coming out 237px tall against the 16:9 set's 221. */
.poster-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  height: auto;
  object-fit: cover;
  display: block;
  border-bottom: 1px solid var(--line);
}

.poster-no {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 2rem;
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  background: rgba(6, 8, 11, 0.82);
  backdrop-filter: blur(6px);
  color: var(--accent-lit);
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
}

/* Two lines for each of the title and the strapline. Without a ceiling a
   long title pushes its card taller than the rest of the row. */
/* Fixed, not just capped. Clamping the lines stops a long title making a
   card taller, but a short one still made it shorter, so the heights
   still disagreed. This is two lines of each plus the padding. */
.poster-body {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  flex: 1;
  min-height: 7.9rem;
  padding: 1.1rem 1.25rem 1.3rem;
}

.poster-title,
.poster-strap {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.poster-title {
  display: block;
  font-size: 1.02rem;
  font-weight: 700;
  font-stretch: 92%;
  letter-spacing: -0.015em;
  line-height: 1.2;
}

.poster-strap {
  display: block;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--text-dim);
}

@media (max-width: 1000px) {
  .posters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 680px) {
  .posters {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------- the poster index
   Real links to each poster's own page. The grid above is built by script
   and this is not, which is the point: it is what a crawler, and anyone
   without JavaScript, actually gets. */

.poster-index {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid var(--line);
}

.poster-index > h3 {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 1.4rem;
}

.poster-index-act {
  display: grid;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
  gap: 0.4rem clamp(1rem, 3vw, 2rem);
  padding-block: 0.9rem;
  border-top: 1px solid var(--line);
}

.poster-index-act:first-of-type { border-top: 0; }

.poster-index-no {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-lit);
}

.poster-index ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: 0.15rem 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.poster-index a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.2rem 0;
  color: var(--text-dim);
  font-size: 0.92rem;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.poster-index a span {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.poster-index a:hover,
.poster-index a:focus-visible {
  color: var(--accent-lit);
}

@media (max-width: 700px) {
  .poster-index-act { grid-template-columns: 1fr; gap: 0.5rem; }
}

/* ------------------------------------------------------------- viewer */

.viewer {
  /* pan-y hands vertical scrolling to the browser and keeps horizontal
     for us; without it a right-swipe is taken as the back gesture and the
     visitor leaves the page instead of seeing the previous poster.
     overscroll-behavior stops the same thing happening at the edges. */
  touch-action: pan-y;
  overscroll-behavior: contain;
  width: min(1180px, 94vw);
  max-width: none;
  max-height: 92svh;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--ink-850);
  color: var(--text);
  overflow: visible;
}

.viewer::backdrop {
  background: rgba(3, 5, 8, 0.86);
  backdrop-filter: blur(6px);
}

.viewer-figure {
  display: grid;
  grid-template-columns: minmax(0, 1.65fr) minmax(260px, 1fr);
  margin: 0;
  max-height: 92svh;
}

.viewer-figure img {
  width: 100%;
  height: 100%;
  max-height: 92svh;
  object-fit: contain;
  background: #05070a;
  border-radius: var(--radius) 0 0 var(--radius);
}

.viewer-caption {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(1.4rem, 2.5vw, 2rem);
  overflow-y: auto;
  border-left: 1px solid var(--line);
}

.viewer-step {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.9rem;
}

.viewer-caption h3 {
  font-size: clamp(1.2rem, 2vw, 1.55rem);
  margin-bottom: 0.6rem;
}

.viewer-strap {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--accent-lit);
  margin-bottom: 1.1rem;
}

.viewer-note {
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--text-dim);
}

/* The house line under the joke. Always gold, never the chapter accent:
   this is the firm talking, and the firm does not change colour. */
.viewer-flavour {
  margin-top: 0.95rem;
  padding-left: 0.85rem;
  border-left: 2px solid var(--gold);
  color: var(--gold);
  font-size: 0.95rem;
  font-style: italic;
  line-height: 1.5;
  text-wrap: pretty;
}

/* ============================================================ waitlist
   The last thing on the page and the only thing on it that asks for
   anything, so it is quiet and centred rather than loud. */

.signup {
  padding-block: var(--chapter-space);
  border-top: 1px solid var(--line);
  background:
    radial-gradient(70% 60% at 50% 0%, var(--accent-soft), transparent 70%),
    var(--ink-900);
  text-align: center;
}

/* Same reason as the poster pages' chip: an inline-level box drops its
   vertical margin. Centred with auto margins since it is no longer inline
   and the parent's text-align cannot reach it. */
.badge-soon {
  display: flex;
  width: fit-content;
  margin-inline: auto;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.4rem;
  padding: 0.45rem 1.1rem;
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-lit);
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* Same trailing letter-space problem as the poster pages' chip. */
.badge-soon span { margin-right: -0.22em; }

.badge-soon::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}

.signup .lede {
  max-width: 54ch;
  margin: clamp(1rem, 2vw, 1.5rem) auto 0;
}

/* Any display declaration beats the hidden attribute's own display:none,
   so a flex container set to hidden stays on screen. This is the whole
   reason the form was still visible after a successful signup. */
[hidden] {
  display: none !important;
}

.signup-form {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
  max-width: 560px;
  margin: clamp(1.75rem, 4vw, 2.5rem) auto 0;
}

.signup-input {
  flex: 1 1 260px;
  min-width: 0;
  padding: 0.95rem 1.2rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--ink-850);
  color: var(--text);
  font: inherit;
  font-size: 1rem;
  text-align: center;
}

.signup-input::placeholder { color: var(--text-faint); }

.signup-input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* The honeypot. Hidden from sight and from assistive technology, but not
   with display:none, which some bots check for. */
.signup-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.signup-note {
  min-height: 1.6em;
  margin: 1.1rem 0 0;
  font-size: 0.95rem;
  font-weight: 600;
}

.signup-note[data-tone="good"] { color: var(--accent-lit); }
.signup-note[data-tone="bad"] { color: #f58b80; }


/* The page is roughly nineteen thousand pixels tall and this is the end of
   it. The footer has the same link, but by the time you have read this far
   the footer is another scroll away. */
.signup-back {
  margin-top: clamp(2.25rem, 5vw, 3.25rem);
}

.signup-back .btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}

.signup-arrow {
  font-size: 1.05em;
  line-height: 1;
  translate: 0 -1px;
  transition: translate 240ms var(--ease);
}

.signup-back .btn:hover .signup-arrow,
.signup-back .btn:focus-visible .signup-arrow {
  translate: 0 -4px;
}

@media (prefers-reduced-motion: reduce) {
  .signup-arrow { transition: none; }
  .signup-back .btn:hover .signup-arrow { translate: 0 -1px; }
}

@media (max-width: 520px) {
  .signup-form { flex-direction: column; }
  .signup-form .btn { width: 100%; }

  /* flex-basis follows the main axis. The 260px that set the input's
     width while the form was a row became its height the moment the
     form stacked, and the field rendered as a 260px oval. */
  .signup-input {
    flex: 0 0 auto;
    width: 100%;
  }
}

/* ------------------------------------------------------------- sharing */

.viewer-share {
  margin-top: clamp(1.4rem, 2.6vw, 2rem);
  padding-top: clamp(1rem, 2vw, 1.4rem);
  border-top: 1px solid var(--line);
}

.share-label {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 0.75rem;
}

.share-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.share-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: border-color 200ms var(--ease), color 200ms var(--ease),
    background-color 200ms var(--ease);
}

.share-btn svg {
  width: 1rem;
  height: 1rem;
  flex: none;
}

.share-btn:hover,
.share-btn:focus-visible {
  color: var(--text);
  border-color: var(--accent-line);
  background: var(--accent-soft);
}

/* Each network keeps its own colour on hover, which is the one moment the
   buttons need to be recognisable rather than quiet. */
.share-x:hover,
.share-x:focus-visible { color: #fff; border-color: #fff; background: rgba(255, 255, 255, 0.1); }

.share-facebook:hover,
.share-facebook:focus-visible { color: #74a0f5; border-color: #3b5ba5; background: rgba(59, 91, 165, 0.16); }

.share-instagram:hover,
.share-instagram:focus-visible { color: #f08bb4; border-color: #b8397e; background: rgba(184, 57, 126, 0.16); }

.share-tiktok:hover,
.share-tiktok:focus-visible { color: #4fd1e8; border-color: #2ea3b8; background: rgba(46, 163, 184, 0.16); }

.share-reddit:hover,
.share-reddit:focus-visible { color: #ff8a5c; border-color: #d64a1e; background: rgba(214, 74, 30, 0.16); }

/* Reserved so the row does not jump when a message appears. */
.share-note {
  min-height: 2.6em;
  margin-top: 0.7rem;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--accent-lit);
}

/* A 34px pill is a fine mouse target and a poor thumb one. Sized by input
   device rather than viewport width, so a touchscreen laptop gets it too. */
@media (pointer: coarse) {
  .share-btn { padding: 0.8rem 0.95rem; }
}

@media (prefers-reduced-motion: reduce) {
  .share-btn { transition: none; }
}

.viewer-btn {
  position: absolute;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: rgba(6, 8, 11, 0.9);
  color: var(--text);
  font-family: var(--display);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: background 180ms var(--ease), border-color 180ms var(--ease);
}

.viewer-btn:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink-900);
}

.viewer-close {
  top: -1.1rem;
  right: -1.1rem;
  font-size: 1.3rem;
}

.viewer-prev {
  top: 50%;
  left: -1.35rem;
  translate: 0 -50%;
}

.viewer-next {
  top: 50%;
  right: -1.35rem;
  translate: 0 -50%;
}

@media (max-width: 860px) {
  .viewer {
    width: 96vw;
  }

  .viewer-figure {
    grid-template-columns: 1fr;
    overflow-y: auto;
  }

  .viewer-figure img {
    max-height: 48svh;
    border-radius: var(--radius) var(--radius) 0 0;
  }

  .viewer-caption {
    border-left: 0;
    border-top: 1px solid var(--line);
    overflow: visible;
  }

  /* These used to sit in a row pinned to the bottom of the dialog, which
     worked until the caption grew a share row and the controls started
     landing on top of it. They live on the poster now: close at the top
     corner where a close button belongs, and the arrows against the edges
     of the image, clear of anything readable. Swiping does the same job;
     the buttons stay for anyone not using a touchscreen. */
  .viewer-btn {
    top: auto;
    bottom: auto;
    translate: none;
  }

  .viewer-close {
    top: 0.6rem;
    right: 0.6rem;
    left: auto;
    translate: none;
  }

  .viewer-prev,
  .viewer-next {
    /* The image is capped at 48svh, so this is its middle. */
    top: 24svh;
    translate: 0 -50%;
  }

  .viewer-prev { left: 0.6rem; }
  .viewer-next { right: 0.6rem; }
}

/* ================================================ a week at the firm
   The turn order, which is the one thing a visitor cannot infer from the
   artwork. Eight stages, each with the deadpan version underneath. */

.week {
  padding-block: var(--chapter-space);
  background: radial-gradient(90% 60% at 50% 0%, var(--accent-soft), transparent 70%);
}

.objective {
  max-width: 62ch;
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
}

.objective-line {
  font-size: clamp(1.1rem, 2vw, 1.4rem);
  font-weight: 500;
  line-height: 1.45;
  color: var(--text);
}

.week-title {
  font-size: clamp(2.4rem, 6.4vw, 4.2rem);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.loop {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  counter-reset: none;
}

.loop li {
  position: relative;
  padding: 1.7rem 1.5rem 1.8rem;
  background: var(--ink-850);
  transition: background 220ms var(--ease);
}

/* A thread running through the stages, so the eight read as a sequence
   rather than eight unrelated tiles. */
.loop li::after {
  content: "";
  position: absolute;
  top: 2.35rem;
  right: -1px;
  width: 1px;
  height: 0;
  border-top: 1px dashed var(--accent-line);
  width: 1.5rem;
  translate: 50% 0;
}

.loop li:last-child::after {
  display: none;
}

.loop li:hover {
  background: var(--ink-800);
}

.loop-no {
  display: block;
  font-family: var(--mono);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  color: var(--accent);
  margin-bottom: 0.85rem;
}

.loop h3 {
  font-size: 1.22rem;
  font-weight: 700;
  margin-bottom: 0.45rem;
}

.loop p {
  font-size: 0.89rem;
  line-height: 1.55;
  color: var(--text-dim);
}

.loop-payoff {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  font-size: clamp(1.1rem, 2.1vw, 1.5rem);
  font-weight: 700;
  line-height: 1.35;
  color: var(--accent-lit);
  text-wrap: balance;
}

/* === the card count, set as the selling point it is =================== */

.shout {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding: clamp(1.5rem, 3vw, 2.25rem) clamp(1.5rem, 3vw, 2.5rem);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius);
  background: linear-gradient(120deg, var(--accent-soft), transparent 70%);
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1.6rem;
}

.shout b {
  font-size: clamp(1.3rem, 3vw, 2.1rem);
  font-weight: 900;
  font-stretch: 88%;
  letter-spacing: -0.02em;
  line-height: 1.12;
  color: var(--text);
}

.shout b:first-child {
  color: var(--accent-lit);
}

.hinge-choice {
  margin-top: 1.4rem;
  font-size: clamp(1.05rem, 1.9vw, 1.3rem);
  font-weight: 700;
  line-height: 1.35;
  color: var(--accent-lit);
}

/* The spec line in the close, including the one entry that is not a fact. */
.spec {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 1.6rem;
  max-width: 62ch;
  margin: clamp(2.25rem, 4vw, 3rem) auto 0;
  padding: 1.35rem 1.5rem;
  border-block: 1px solid var(--line);
  list-style: none;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.spec b {
  color: var(--accent-lit);
  font-size: 1.25rem;
  font-weight: 800;
  margin-right: 0.4rem;
}

/* --------------------------------------------------------------- close */

.close {
  position: relative;
  padding-block: var(--chapter-space);
  text-align: center;
  border-top: 1px solid var(--line);
  background: radial-gradient(80% 60% at 50% 0%, var(--accent-soft), transparent 70%);
}

.close h2 {
  font-size: clamp(2rem, 5vw, 3.2rem);
  margin-bottom: 1.1rem;
}

.close .lede {
  max-width: 52ch;
  margin-inline: auto;
}

.welcome-line {
  margin-top: 1.1rem;
  font-size: clamp(1.15rem, 2.4vw, 1.7rem);
  font-weight: 800;
  font-stretch: 92%;
  letter-spacing: -0.02em;
  color: var(--accent-lit);
}

.btn-big {
  padding: 1.15rem 2.4rem;
  font-size: 1.05rem;
}

.close-actions {
  margin-top: clamp(2.25rem, 4vw, 3rem);
}

.close /* The tone line: half specification, half warning. */
.hero-meta {
  margin: 1.4rem auto 0;
  font-family: var(--mono);
  font-size: clamp(0.7rem, 1.3vw, 0.8rem);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.hero-actions {
  margin-top: 2.2rem;
}


/* -------------------------------------------------------------- footer */

.footer {
  padding: 2.5rem var(--gutter) 3rem;
  border-top: 1px solid var(--line);
  background: var(--ink-900);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2.5rem;
  align-items: center;
  justify-content: space-between;
  max-width: var(--shell);
  margin-inline: auto;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.4rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.footer-links a {
  font-size: 0.85rem;
  color: var(--text-dim);
  text-decoration: none;
}

.footer-links a:hover {
  color: var(--accent-lit);
}

.footer small {
  font-size: 0.8rem;
  color: var(--text-faint);
}

/* ------------------------------------------------------------- motion */

/* Scoped to .js so that a script failure leaves the page readable rather
   than invisible: without the class nothing is ever hidden. */
.js [data-reveal] {
  opacity: 0;
  translate: 0 22px;
  transition: opacity 800ms var(--ease), translate 800ms var(--ease);
}

.js [data-reveal].is-in {
  opacity: 1;
  translate: 0 0;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .js [data-reveal] {
    opacity: 1;
    translate: none;
  }

  .plate img,
  .plate[data-reveal] img {
    scale: 1;
  }
}
