/* GreenInBetween landing. The page is the dark hall; the render is the lamp.
   Tokens and rules are written up in DESIGN.md. */

/* Both variable, cut down to the weights the page sets (fontTools varLib.instancer): Besley
   500 to 600, Archivo 400 to 600. A font that changes gets a new file name: fonts/ is
   cached for a year as immutable (_headers). */
@font-face {
  font-family: "Besley";
  src: url("fonts/besley-latin-wght500-600.woff2") format("woff2");
  font-weight: 500 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-latin-wght400-600.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

:root {
  /* the room */
  --room: #0a0a09;
  --room-1: #121210;
  --slate: #0d1511;            /* the chalkboard: cloth green gone nearly black */
  --hair: rgba(236, 229, 214, 0.13);
  --hair-strong: rgba(236, 229, 214, 0.26);

  /* the light on things */
  --ivory: #ece5d6;            /* cue-ball ivory: primary text */
  --ivory-2: #b3ac9f;          /* secondary text */
  --ivory-3: #8f897d;          /* tertiary text, captions */
  --sight: #d8ccb2;            /* rail sights */

  /* the one accent: cloth */
  --cloth: #1f5c3d;
  --cloth-hi: #276f4b;
  --cloth-ink: #86c29e;        /* cloth green that can sit on the dark as text */

  /* state only, never decoration */
  --warn: #efa47f;

  --font-display: "Besley", "Clarendon", "Rockwell", Georgia, serif;
  --font-body: "Archivo", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --gutter: clamp(20px, 5.5vw, 80px);
  --wrap: 1360px;
  --space-section: clamp(104px, 13vw, 196px);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --radius-pill: 999px;
}

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

html {
  background: var(--room);
  color-scheme: dark;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--room);
  color: var(--ivory);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.55;
  font-variation-settings: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, p, dl, dd, figure { margin: 0; }
/* lamp-light pseudo-elements reach past their boxes; never let them widen the page */
main, .foot { overflow-x: clip; }
img, video, svg { display: block; max-width: 100%; }
button, input { font: inherit; color: inherit; }
a { color: inherit; }

::selection { background: var(--cloth-hi); color: var(--ivory); }

:focus-visible {
  outline: 2px solid var(--ivory);
  outline-offset: 3px;
}

/* read by screen readers, copied with the text, never seen */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.125rem, 1.45rem + 2.9vw, 3.875rem);
  line-height: 1.02;
  letter-spacing: -0.024em;
  text-wrap: balance;
}

.lead {
  margin-top: 1.1rem;
  max-width: 38ch;
  color: var(--ivory-2);
  font-size: clamp(1.125rem, 1.04rem + 0.4vw, 1.375rem);
  line-height: 1.5;
  text-wrap: pretty;
}

/* ---------------------------------------------------------------- skip + top */

.skip {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 20;
  padding: 10px 16px;
  border-radius: var(--radius-pill);
  background: var(--ivory);
  color: var(--room);
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { top: 12px; }

.top {
  position: absolute;
  inset: 0 0 auto;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  max-width: var(--wrap);
  margin-inline: auto;
  padding: max(18px, env(safe-area-inset-top)) var(--gutter) 0;
}

/* Green(in)Between: the rendered ball (assets/scripts/render_wordmark_ball.py) sits in
   the word like a letter. Its box is 1.2em square with the ball filling 96.5 % of it,
   dropped 0.26em so its centre lands 0.34em above the baseline, on the middle of the
   capitals, where a parenthesis sits. It stands a little proud of the caps, as an O
   overshoots, so the printed "in" stays readable. */
.wordmark,
.foot__mark {
  font-family: var(--font-display);
  color: var(--ivory);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark {
  font-weight: 600;
  font-size: 1.25rem;            /* 20 px: the ball is the 24 px small cut, pixel for pixel */
  line-height: 1.2;
  letter-spacing: -0.012em;
}
/* desktops, where a 1x screen is likely: 25 px type and the 30 px cut, pixel for pixel, so
   the printed "in" is big enough to read (at 24 px it is a smudge on a 1x screen) */
@media (min-width: 1000px) {
  .wordmark { font-size: 1.5625rem; }
}
.wordmark__ball,
.foot__ball {
  display: inline-block;
  width: 1.2em;
  height: 1.2em;
  margin-inline: 0.02em 0.045em;
  vertical-align: -0.26em;
}
.wordmark__ball img,
.foot__ball img { width: 100%; height: 100%; }

.top__link {
  padding: 10px 0;
  color: var(--ivory-2);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.2s ease;
}
.top__link:hover { color: var(--ivory); }

/* ---------------------------------------------------------------- buttons */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 54px;
  padding: 0 28px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--cloth);
  color: var(--ivory);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: 0.005em;
  text-decoration: none;
  cursor: pointer;
  box-shadow:
    inset 0 1px 0 rgba(236, 229, 214, 0.16),
    0 14px 30px -14px rgba(0, 0, 0, 0.9);
  transition: background-color 0.2s ease, transform 0.2s var(--ease-out);
}
.btn:hover { background: var(--cloth-hi); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { cursor: progress; background: var(--cloth); opacity: 0.8; }

.btn__spin { display: none; }
.btn[aria-busy="true"] .btn__spin {
  display: block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(236, 229, 214, 0.3);
  border-top-color: var(--ivory);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.textlink {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  color: var(--ivory);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: rgba(236, 229, 214, 0.35);
  text-underline-offset: 6px;
  text-decoration-thickness: 1px;
  transition: text-decoration-color 0.2s ease;
}
.textlink:hover { text-decoration-color: var(--ivory); }
.textlink__icon { width: 14px; height: 14px; }

/* ---------------------------------------------------------------- 1. hero */

.hero {
  --media-h: 50%;            /* the render's share of the hero's height */
  position: relative;
  isolation: isolate;
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
}

.hero__media {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 0;
  width: 100%;
  height: var(--media-h);
  /* the render falls off into the room: fade its upper-left edge into the page. The
     solid core is wide enough that the cue ball keeps ~94 % of its brightness (at 52 %
     it sat at ~0.57 alpha and read as a grey stone); the box's top-left corner still
     fades to nothing, and the render's own black is the room's (#0a0a09), so the edge
     never shows. tools/landing-check.mjs measures the cue ball on screen. */
  -webkit-mask-image: radial-gradient(ellipse 140% 115% at 100% 100%, #000 62%, transparent 100%);
  mask-image: radial-gradient(ellipse 140% 115% at 100% 100%, #000 62%, transparent 100%);
}
/* what the lamp does before (or without) the render: a pool of light on cloth */
.hero__media::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(38% 30% at 76% 74%, rgba(232, 196, 138, 0.16), transparent 72%),
    radial-gradient(62% 56% at 80% 86%, rgba(39, 103, 68, 0.4), transparent 74%);
}
.hero__still,
.hero__loop {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* where the crop sits on the render. A phone shows about 62% of its width
     (27% to 89% at 390x844), which holds the pocket, the 3 on its lip and the
     whole cue ball (its left edge sits at about 29%). */
  object-position: var(--hero-x, 71%) var(--hero-y, 80%);
}
.hero__media.no-still .hero__still { visibility: hidden; }
.hero.no-still .disclose { display: none; }

/* the lamp comes up once the render has decoded; visible after 4s regardless */
.js .hero__still:not(.is-lit) {
  filter: brightness(0.28);
  animation: failsafe 0s 4s forwards;
}
.hero__still { transition: filter 2.2s var(--ease-out); }
@keyframes failsafe { to { filter: none; } }

/* the loop cuts in on the still's own frame as the 3 drops: a cut, not a fade,
   so the 3's frozen numeral turns into motion blur only once it moves */
.hero__loop { opacity: 0; }
.hero__media.is-playing .hero__loop { opacity: 1; }

.hero__copy {
  position: relative;
  z-index: 2;
  max-width: var(--wrap);
  margin-inline: auto;
  padding: clamp(104px, 17svh, 200px) var(--gutter) 0;
}
/* room under the buttons for the render line when a short screen (a phone on its
   side) makes the hero grow to its content */
.hero__copy { padding-bottom: 72px; }
@media (min-width: 1000px) {
  .hero__copy { padding-bottom: 84px; }
}

.hero__title {
  max-width: 12ch;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.875rem, 1.75rem + 4.7vw, 5.75rem);
  line-height: 0.97;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.hero__hook {
  margin-top: clamp(18px, 2.4vw, 28px);
  max-width: 33ch;
  color: var(--ivory-2);
  font-size: clamp(1.0625rem, 0.98rem + 0.42vw, 1.3125rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px clamp(20px, 3vw, 30px);   /* both on one line from a 360 px phone */
  margin-top: clamp(26px, 3.4vw, 40px);
}

.hero__foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: max(18px, env(safe-area-inset-bottom));
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  pointer-events: none;
}
.hero__foot > * { pointer-events: auto; }

.disclose,
.motion-toggle {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 13px;
  border-radius: var(--radius-pill);
  background: rgba(10, 10, 9, 0.72);
  color: var(--ivory-2);
  font-size: 0.8125rem;
  line-height: 1.3;
  letter-spacing: 0.01em;
}
.motion-toggle {
  gap: 7px;
  min-height: 40px;
  border: 1px solid var(--hair);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.motion-toggle[hidden] { display: none; }
.motion-toggle:hover { color: var(--ivory); border-color: var(--hair-strong); }
.motion-toggle svg { width: 13px; height: 13px; }
.motion-toggle__play { display: none; }
.motion-toggle[data-state="paused"] .motion-toggle__play { display: block; }
.motion-toggle[data-state="paused"] .motion-toggle__pause { display: none; }
@media (max-width: 999px) {
  /* icon only on phones and tablets; the label stays for screen readers */
  .motion-toggle { flex: none; width: 40px; padding: 0; justify-content: center; }
  .motion-toggle__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* On a phone or a tablet the bottom of the frame is the cue ball and the cloth,
     and the 3 rolls in from the bottom. The render line and the pause sit at the
     top right of the frame instead, in the dark above the pocket, a caption over
     the picture. */
  .hero__foot {
    /* the frame's top, or just under the buttons when a short screen pushes them
       past it (main.js keeps --copy-end, the copy's bottom edge, current) */
    top: max(calc(100% - var(--media-h) + 10px), calc(var(--copy-end, 0px) + 18px));
    bottom: auto;
    left: auto;
    right: 0;
    width: min(62%, 260px);
    flex-direction: row-reverse;
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: 12px;
    padding-inline: 0 var(--gutter);
  }
  .disclose {
    display: block;
    flex: 1 1 auto;
    min-height: 0;
    padding: 3px 0 0;
    background: none;
    border-radius: 0;
    font-size: 0.8125rem;
    line-height: 1.35;
    text-align: right;
    text-wrap: balance;
  }
}

@media (min-width: 700px) {
  .hero { --media-h: 72%; }
  .hero__media {
    width: 92%;
    /* the box no longer bleeds off the left edge: fade that edge to nothing over its
       first 15 %, and fade the upper left toward the headline with the radial, the two
       intersected. The cue ball (its left edge at ~17 % of the box at 1440x900) stays at
       ~0.92 alpha; the box's top edge needs no fade, the render's black being the room's. */
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 15%),
      radial-gradient(ellipse 120% 130% at 100% 100%, #000 62%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(to right, transparent 0, #000 15%),
      radial-gradient(ellipse 120% 130% at 100% 100%, #000 62%, transparent 100%);
    mask-composite: intersect;
  }
}
@media (min-width: 1000px) {
  .hero { --media-h: 100%; }
  .hero__media { width: 76%; --hero-x: 84%; }
  .hero__copy { padding-top: clamp(150px, 24vh, 260px); }
}
@media (min-width: 1000px) and (max-height: 760px) {
  .hero__copy { padding-top: 120px; }
}

/* ---------------------------------------------------------------- 2. the stroke */

.stroke { padding-block: var(--space-section); }

.stroke__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(48px, 8vw, 72px);
}

/* The facts are read against a line at 55 % of the viewport: the one whose heading has
   crossed it plays its demo on the cue ball (main.js), and the rest step back to the
   secondary and caption inks (8.8:1 and 5.7:1, never below body contrast). Each fact
   has the room to be the only one on the line while its demo runs. */
.points { border-bottom: 1px solid var(--hair); }
.point {
  padding: 34px 0 40px;
  border-top: 1px solid var(--hair);
}
.point dt,
.point dd { transition: color 0.45s var(--ease-out); }
.points[data-on] .point:not(.is-on) dt { color: var(--ivory-2); }
.points[data-on] .point:not(.is-on) dd { color: var(--ivory-3); }
.point dt,
.doc__item h2 {
  display: flex;
  align-items: baseline;
  gap: 14px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.3125rem, 1.16rem + 0.6vw, 1.6875rem);
  line-height: 1.2;
  letter-spacing: -0.012em;
}
/* a rail sight: the diamond that marks distance along a real rail */
.point dt::before,
.doc__item h2::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  background: var(--sight);
  transform: translateY(-0.2em) rotate(45deg);
  transition: background-color 0.45s var(--ease-out), transform 0.45s var(--ease-out);
}
.points[data-on] .point:not(.is-on) dt::before { background: var(--ivory-3); }
.point.is-on dt::before { transform: translateY(-0.2em) rotate(45deg) scale(1.35); }
.point dd {
  margin-top: 10px;
  padding-left: 21px;
  max-width: 62ch;
  color: var(--ivory-2);
  text-wrap: pretty;
}

/* the cue-ball face */
.ballface {
  display: grid;
  justify-items: center;
  gap: 18px;
  padding-block: 8px;
}
.ballface__stage {
  position: relative;
  width: min(74vw, 330px);
  aspect-ratio: 1;
  border-radius: 50%;
  touch-action: none;
  cursor: crosshair;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
/* the lamp above the ball */
.ballface__stage::before {
  content: "";
  position: absolute;
  inset: -34% -40% -10%;
  z-index: -1;
  background: radial-gradient(50% 46% at 50% 38%, rgba(232, 204, 158, 0.11), transparent 70%);
  pointer-events: none;
}
.ballface__stage:focus-visible { outline-offset: 8px; border-radius: 50%; }
.ballface__svg { width: 100%; height: 100%; overflow: visible; }

.ballface__grid line {
  stroke: rgba(46, 36, 22, 0.2);
  stroke-width: 1;
  stroke-dasharray: 2 4;
}
.ballface__limit {
  fill: none;
  stroke: rgba(46, 36, 22, 0.55);
  stroke-width: 1.3;
  stroke-dasharray: 4 5;
}
.ballface__trace {
  fill: none;
  stroke: var(--cloth);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.55;
}
.ballface__tipring {
  fill: rgba(31, 92, 61, 0.14);
  stroke: rgba(31, 92, 61, 0.5);
  stroke-width: 1;
}
.ballface__tipdot { fill: var(--cloth); }
.ballface.is-miscue .ballface__tipdot,
.lost__ball .ballface__tipdot {
  fill: none;
  stroke: #3a2f22;
  stroke-width: 2;
  stroke-dasharray: 3 3;
}
.ballface.is-miscue .ballface__tipring,
.lost__ball .ballface__tipring { fill: none; stroke: rgba(58, 47, 34, 0.5); }
.ballface.is-miscue .ballface__limit,
.lost__ball .ballface__limit { stroke: rgba(46, 36, 22, 0.85); stroke-dasharray: none; }

.ballface__read {
  display: grid;
  justify-items: center;
  gap: 2px;
  min-height: 6.6em;
  text-align: center;
}
.ballface__call {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.5rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.ballface.is-miscue .ballface__call { color: var(--warn); }
.ballface__mm {
  color: var(--ivory-3);
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}
.ballface__note {
  margin-top: 4px;
  max-width: 30ch;
  color: var(--ivory-2);
  font-size: 0.9375rem;
  text-wrap: balance;
}
.ballface__cap {
  max-width: 34ch;
  color: var(--ivory-3);
  font-size: 0.875rem;
  line-height: 1.5;
  text-align: center;
  text-wrap: pretty;
}

@media (min-width: 960px) {
  .stroke__grid {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    grid-template-rows: auto 1fr;
    column-gap: clamp(56px, 7vw, 128px);
    row-gap: 56px;
  }
  .stroke__head { grid-column: 1; grid-row: 1; }
  .points { grid-column: 1; grid-row: 2; }
  .ballface {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: start;
    position: sticky;
    top: 10vh;
    padding-top: 12px;
  }
  /* the whole figure stays on a laptop screen while it is pinned */
  .ballface__stage { width: min(100%, 380px, calc(100svh - 330px)); min-width: 220px; }
  .point { padding-block: clamp(36px, 8.5vh, 92px) clamp(40px, 9vh, 96px); }
  /* room under the list, inside the figure's grid area, so the figure stays pinned
     while the last fact's demo plays; the section gives the same room back */
  .points { margin-bottom: 20vh; }
  .stroke { padding-bottom: max(48px, calc(var(--space-section) - 20vh)); }
}

/* Phones and tablets: the figure pins to the top of the screen for the length of the
   list, compact (the ball beside its readout), so each fact's demo plays in view.
   Its caption sits above the ball and scrolls away as it pins: main.js keeps
   --bf-lift, the stage's offset in the figure, current. */
@media (max-width: 959px) {
  .stroke__grid { gap: 40px; }
  .ballface {
    --bf-ball: clamp(120px, min(42vw, 25svh), 196px);
    grid-template-columns: var(--bf-ball) minmax(0, 1fr);
    grid-template-areas: "cap cap" "stage read";
    justify-items: start;
    align-items: center;
    column-gap: clamp(18px, 5.5vw, 32px);
    row-gap: 22px;
    padding-block: 0 12px;
  }
  /* it pins only when the script is there to play the demos */
  .js .ballface {
    --bf-pad: max(12px, env(safe-area-inset-top));
    position: sticky;
    top: calc(var(--bf-pad) - var(--bf-lift, 0px));
    z-index: 3;
  }
  /* the room behind the pinned bar, edge to edge, and a short fall-off under it so the
     facts go into the dark instead of under a hard edge */
  .js .ballface::before {
    content: "";
    position: absolute;
    inset: 0 -100vmax -30px;
    z-index: -1;
    background: linear-gradient(to bottom, var(--room) calc(100% - 30px), rgba(10, 10, 9, 0));
    pointer-events: none;
  }
  .ballface__cap { grid-area: cap; max-width: 46ch; text-align: left; }
  .ballface__stage { grid-area: stage; width: var(--bf-ball); }
  .ballface__stage::before { inset: -22% -30% -8%; }
  .ballface__read {
    grid-area: read;
    justify-items: start;
    align-content: center;
    min-height: 0;
    text-align: left;
  }
  .ballface__call { font-size: 1.25rem; }
  .ballface__mm,
  .ballface__note { font-size: 0.875rem; }
  .ballface__note { max-width: 26ch; }
  .point { padding-block: 34px 44px; }
}

/* ---------------------------------------------------------------- 3. the shot */

.shot { padding-bottom: clamp(88px, 10vw, 150px); }
.shot__head { margin-bottom: clamp(32px, 5vw, 56px); }

.film {
  max-width: var(--wrap);
  margin-inline: auto;
}
.film__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background:
    radial-gradient(46% 60% at 62% 68%, rgba(39, 103, 68, 0.34), transparent 72%),
    #070707;
}
.film__poster,
.film__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.film__video { background: #000; }
.film__frame.no-poster .film__poster { visibility: hidden; }
.film__frame.is-playing .film__poster { visibility: hidden; }

/* the play control sits in the dark of the hall, upper left, so it never
   covers the table, the cue ball or the shot line */
.film__play {
  --playball: clamp(48px, 5vw, 64px);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 14px;
  width: 100%;
  padding: clamp(14px, 3vw, 36px);
  border: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0) 40%);
  color: var(--ivory);
  text-align: left;
  cursor: pointer;
}
.film__play[hidden] { display: none; }
.film__play:focus-visible { outline-offset: -6px; }
/* the play button is a cue ball */
.film__playball {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--playball);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 36% 30%, #fffbf2 0%, #eee6d4 40%, #b8aa8e 88%, #8a7c63 100%);
  color: var(--room);
  box-shadow: 0 12px 26px -10px rgba(0, 0, 0, 0.9);
  transition: transform 0.35s var(--ease-out);
}
.film__playball svg { width: 42%; height: 42%; transform: translateX(6%); }
.film__play:hover .film__playball { transform: scale(1.06); }
.film__playtext {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 8px;
  min-height: var(--playball);
  font-weight: 600;
  font-size: clamp(0.9375rem, 0.9rem + 0.25vw, 1.0625rem);
}
.film__playmeta {
  color: var(--ivory-2);
  font-weight: 400;
}
.film__missing {
  position: absolute;
  inset: 0 0 auto;              /* where the play control was: in the dark, off the cloth */
  padding: clamp(14px, 3vw, 36px);
  color: var(--ivory-2);
}
.film__missing[hidden] { display: none; }
.film__cap {
  margin-top: 14px;
  padding-inline: var(--gutter);
  color: var(--ivory-3);
  font-size: 0.875rem;
}
@media (min-width: 760px) {
  .film { padding-inline: var(--gutter); }
  .film__frame { border-radius: 3px; }
  .film__cap { padding-inline: 0; }
}

/* ---------------------------------------------------------------- 4. friends */

.friends {
  padding-block: var(--space-section);
  border-top: 1px solid var(--hair);
}
.friends__title { max-width: 16ch; }
.friends__lead { max-width: 40ch; }
@media (min-width: 980px) {
  .friends__intro {
    display: grid;
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    column-gap: clamp(56px, 7vw, 128px);
    align-items: end;
  }
  .friends__lead { margin-top: 0; padding-bottom: 0.35em; }
}

.tiers {
  display: grid;
  gap: 36px;
  margin-top: clamp(48px, 7vw, 88px);
}
.tier {
  padding-top: 22px;
  border-top: 1px solid var(--hair-strong);
}
.tier h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.4375rem, 1.3rem + 0.55vw, 1.8125rem);
  line-height: 1.15;
  letter-spacing: -0.014em;
}
.tier p {
  margin-top: 12px;
  max-width: 50ch;
  color: var(--ivory-2);
  text-wrap: pretty;
}
@media (min-width: 820px) {
  .tiers { grid-template-columns: 1fr 1fr; gap: clamp(40px, 6vw, 96px); }
}
@media (min-width: 980px) {
  /* same columns as the intro above, so "Ranked" lines up under the lead */
  .tiers {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    column-gap: clamp(56px, 7vw, 128px);
  }
}

.friends__open {
  margin-top: clamp(64px, 9vw, 120px);
  max-width: 26ch;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.75rem, 1.3rem + 1.9vw, 2.875rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.friends__open-sub {
  margin-top: 14px;
  max-width: 44ch;
  color: var(--ivory-2);
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
}
.friends__status {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: clamp(40px, 5vw, 56px);
  max-width: 60ch;
  color: var(--ivory-3);
  font-size: 0.9375rem;
}
.friends__status .dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1.5px solid var(--cloth-ink);
  transform: translateY(-1px);
}

/* ---------------------------------------------------------------- 5. beta */

.beta {
  padding-block: var(--space-section);
  background:
    radial-gradient(70% 50% at 50% 0%, rgba(232, 204, 158, 0.05), transparent 70%),
    var(--slate);
  border-top: 1px solid rgba(134, 194, 158, 0.12);
}
.beta__grid {
  display: grid;
  gap: clamp(40px, 6vw, 64px);
}
@media (min-width: 980px) {
  .beta__grid {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    column-gap: clamp(56px, 7vw, 128px);
    align-items: start;
  }
  .beta__head { position: sticky; top: 12vh; }
}

.signup { max-width: 38rem; }
.signup__preview {
  margin-bottom: 28px;
  padding: 12px 18px;
  border: 1px dashed rgba(236, 229, 214, 0.45);
  border-radius: 18px;
  color: var(--ivory-2);
  font-size: 0.9375rem;
  line-height: 1.45;
}
.signup__preview[hidden] { display: none; }

.field__label {
  display: block;
  margin-bottom: 10px;
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
}
.field__input {
  width: 100%;
  min-height: 56px;
  padding: 0 22px;
  border: 1px solid var(--hair-strong);
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, 0.32);
  color: var(--ivory);
  font-size: 1.0625rem;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.field__input::placeholder { color: var(--ivory-3); opacity: 1; }
.field__input:hover { border-color: rgba(236, 229, 214, 0.4); }
.field__input:focus { border-color: var(--ivory); background: rgba(0, 0, 0, 0.45); }
.field__input:focus-visible { outline: 2px solid var(--ivory); outline-offset: 3px; }
.field__input[aria-invalid="true"] { border-color: var(--warn); }
.field__err {
  margin-top: 10px;
  padding-left: 22px;
  color: var(--warn);
  font-size: 0.9375rem;
}
.field__err[hidden] { display: none; }

.choice {
  margin: 30px 0 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.choice__q {
  padding: 0;
  margin-bottom: 12px;
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
}
.choice__opt {
  margin-left: 6px;
  color: var(--ivory-3);
  font-weight: 400;
}
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 0 18px 0 14px;
  border: 1px solid var(--hair-strong);
  border-radius: var(--radius-pill);
  color: var(--ivory-2);
  font-size: 0.9875rem;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}
.chip input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.chip:hover { border-color: rgba(236, 229, 214, 0.44); color: var(--ivory); }
.chip__ball {
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1.5px solid rgba(236, 229, 214, 0.42);
  transition: background 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease, transform 0.35s var(--ease-out);
}
/* the chosen answer lights up as a cue ball */
.chip input:checked + .chip__ball {
  border-color: transparent;
  background: radial-gradient(circle at 36% 30%, #fffbf2 0%, #ece3cf 42%, #a4957a 100%);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.7);
  transform: scale(1.12);
}
.chip:has(input:checked) {
  border-color: rgba(236, 229, 214, 0.7);
  background: rgba(236, 229, 214, 0.06);
  color: var(--ivory);
}
.chip:has(input:focus-visible) { outline: 2px solid var(--ivory); outline-offset: 3px; }

.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.signup__send { margin-top: 38px; }
.btn--wide { width: 100%; }
@media (min-width: 560px) {
  .btn--wide { width: auto; min-width: 240px; }
}
.signup__fine {
  margin-top: 14px;
  color: var(--ivory-3);
  font-size: 0.875rem;
}
.signup__fine a {
  color: var(--ivory-2);
  text-underline-offset: 3px;
  text-decoration-color: rgba(236, 229, 214, 0.35);
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}
.signup__fine a:hover { color: var(--ivory); text-decoration-color: var(--ivory); }

.status:not(.is-shown) { display: block; height: 0; overflow: hidden; }
.status.is-shown {
  margin-top: 26px;
  padding: 18px 22px 20px;
  border: 1px solid var(--hair-strong);
  border-radius: 18px;
  background: rgba(0, 0, 0, 0.28);
}
.status:focus { outline: none; }
.status:focus-visible { outline: 2px solid var(--ivory); outline-offset: 3px; }
.status__title { font-weight: 600; }
.status__body { margin-top: 4px; color: var(--ivory-2); font-size: 0.9875rem; }
.status--preview { border-style: dashed; border-color: rgba(236, 229, 214, 0.45); }
.status--ok { border-color: rgba(134, 194, 158, 0.55); background: rgba(31, 92, 61, 0.22); }
.status--ok .status__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.625rem;
  line-height: 1.2;
  letter-spacing: -0.012em;
}
.status--error { border-color: rgba(239, 164, 127, 0.6); }
.status--error .status__title { color: var(--warn); }
noscript .status { display: block; margin-top: 20px; color: var(--warn); }

/* sent: the form folds away and the answer stays */
.signup.is-done > :not(.status) { display: none; }
.signup.is-done .status { margin-top: 0; }

/* ---------------------------------------------------------------- the small pages */

/* Privacy and the 404 share the page's header, footer and type; neither runs a script. */
.doc {
  padding-block: clamp(128px, 19svh, 210px) var(--space-section);
}
.doc__title,
.lost__title {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.028em;
  text-wrap: balance;
}
.doc__title {
  max-width: 12ch;
  font-size: clamp(2.625rem, 1.7rem + 3.9vw, 4.75rem);
  line-height: 0.98;
}
.doc__head .lead { max-width: 36ch; }
.doc__date {
  margin-top: 22px;
  color: var(--ivory-3);
  font-size: 0.875rem;
}
.doc__list {
  margin-top: clamp(48px, 7vw, 72px);
  border-bottom: 1px solid var(--hair);
}
.doc__item {
  padding: 30px 0 34px;
  border-top: 1px solid var(--hair);
}
.doc__item p {
  margin-top: 10px;
  padding-left: 21px;
  max-width: 60ch;
  color: var(--ivory-2);
  text-wrap: pretty;
}
.doc__item p + p { margin-top: 0.75em; }
.doc a:not(.btn) {
  color: var(--ivory);
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(236, 229, 214, 0.4);
  transition: text-decoration-color 0.2s ease;
}
.doc a:not(.btn):hover { text-decoration-color: var(--ivory); }
.doc__back { margin-top: clamp(40px, 6vw, 64px); }
@media (min-width: 980px) {
  /* the signup's split: the heading left and pinned, the reading right */
  .doc__grid {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    column-gap: clamp(56px, 7vw, 128px);
    align-items: start;
  }
  .doc__head { position: sticky; top: 12vh; }
  .doc__body .doc__list { margin-top: 0; }
}

/* 404: a miscue. The tip sits past the ring, the way the cue-ball face shows one. */
.lost {
  display: grid;
  align-content: center;
  gap: clamp(44px, 7vw, 64px);
  min-height: 100vh;
  min-height: 100svh;
  max-width: var(--wrap);
  margin-inline: auto;
  padding: clamp(112px, 17svh, 200px) var(--gutter) clamp(64px, 10svh, 120px);
}
.lost__title {
  max-width: 11ch;
  font-size: clamp(3rem, 1.9rem + 4.9vw, 6rem);
  line-height: 0.96;
}
.lost__text {
  margin-top: clamp(18px, 2.4vw, 28px);
  max-width: 34ch;
  color: var(--ivory-2);
  font-size: clamp(1.0625rem, 0.98rem + 0.42vw, 1.3125rem);
  line-height: 1.5;
  text-wrap: pretty;
}
.lost__figure {
  display: grid;
  justify-items: center;
  gap: 18px;
}
.lost__ball {
  position: relative;
  width: min(58vw, 300px);
  aspect-ratio: 1;
}
.lost__ball::before {
  content: "";
  position: absolute;
  inset: -34% -40% -10%;
  z-index: -1;
  background: radial-gradient(50% 46% at 50% 38%, rgba(232, 204, 158, 0.11), transparent 70%);
  pointer-events: none;
}
.lost__ball svg { width: 100%; height: 100%; overflow: visible; }
.lost__cap {
  max-width: 30ch;
  color: var(--ivory-3);
  font-size: 0.875rem;
  line-height: 1.5;
  text-align: center;
  text-wrap: balance;
}
@media (min-width: 860px) {
  .lost {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: center;
    column-gap: clamp(56px, 7vw, 128px);
  }
  .lost__ball { width: min(100%, 340px); }
}

/* ---------------------------------------------------------------- footer */

.foot {
  padding: clamp(56px, 8vw, 112px) 0 max(40px, env(safe-area-inset-bottom));
  background: var(--room);
  border-top: 1px solid var(--hair);
}
/* the sign-off: the wordmark at display size, the ball the large cut */
.foot__mark {
  font-weight: 500;
  font-size: clamp(2rem, 9.1vw, 8.25rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}
.foot__row {
  display: grid;
  gap: 14px;
  align-items: baseline;
  margin-top: clamp(28px, 4.5vw, 64px);
  padding-top: 22px;
  border-top: 1px solid var(--hair);
}
.foot__line {
  max-width: 62ch;
  color: var(--ivory-3);
  font-size: 0.875rem;
}
.foot__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0 28px;
  justify-self: start;
}
.foot__nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--ivory-2);
  font-size: 0.875rem;
  text-underline-offset: 4px;
  text-decoration-color: rgba(236, 229, 214, 0.35);
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}
.foot__nav a:hover { color: var(--ivory); text-decoration-color: var(--ivory); }
.foot__nav a[aria-current="page"] { color: var(--ivory); text-decoration: none; }
@media (min-width: 900px) {
  .foot__row { grid-template-columns: 1fr auto; column-gap: 48px; }
}

/* ---------------------------------------------------------------- motion off */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
  .js .hero__still:not(.is-lit) { filter: none; }
  .btn[aria-busy="true"] .btn__spin { display: none; }
}
