/* ==================================================================
   Color Wars
   ------------------------------------------------------------------
   Palette is lifted straight off the board: warm paper, a coral red,
   a swimming-pool blue. During a game the whole page takes on the
   colour of whoever is to move, which is the one bit of chrome the
   game really needs.
   ================================================================== */

:root {
  --ink:        #241f1c;
  --ink-2:      #5d5248;
  --ink-3:      #8d8175;

  --paper:      #f7efe1;
  --paper-2:    #efe4d1;
  --card:       #fdf8ee;

  --p1:         #f9564f;
  --p1-deep:    #cf3a33;
  --p1-soft:    #f8cabf;
  --p1-stage:   #ee9377;
  --p1-tile:    #fbe6cf;

  --p2:         #17bee0;
  --p2-deep:    #0d8fae;
  --p2-soft:    #bde6f1;
  --p2-stage:   #63b2d0;
  --p2-tile:    #edeedc;

  --line:       #2b2622;
  --radius:     18px;

  /* Chain-reaction pacing. Raise these to let long chains breathe,
     lower them for a snappier board. `--settle` lives in ui.js. */
  --burst:      260ms;
  --flight:     260ms;
  --land:       220ms;
  --hold:       2400ms;
  --shadow:     0 2px 0 rgba(43,38,34,.18);

  --display: "Bricolage Grotesque", "Trebuchet MS", system-ui, sans-serif;
  --body:    "DM Sans", -apple-system, "Segoe UI", Roboto, sans-serif;
}

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

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

button, input { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }

::selection { background: var(--p1); color: #fff; }

/* A little tooth on the paper so it doesn't read as flat vector output. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: .055;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

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

.site-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px clamp(18px, 5vw, 56px);
  max-width: 1240px;
  margin: 0 auto;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -.02em;
  text-decoration: none;
  color: var(--ink);
}

.wordmark__dots { display: inline-flex; }
.wordmark__dots i {
  width: 15px; height: 15px;
  border-radius: 50%;
  display: block;
  background: var(--p1);
}
.wordmark__dots i:last-child {
  background: var(--p2);
  margin-left: -6px;
  mix-blend-mode: multiply;
}

.site-nav { display: flex; align-items: center; gap: 6px; }

.site-nav > button {
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink-2);
  transition: background .18s, color .18s;
}
.site-nav > button:hover { background: rgba(43,38,34,.07); color: var(--ink); }

.sound-toggle { display: inline-flex; align-items: center; gap: 8px; }
.sound-toggle__wave { display: inline-flex; align-items: flex-end; gap: 2px; height: 13px; }
.sound-toggle__wave i {
  width: 3px; border-radius: 2px;
  background: var(--ink-2);
  transition: height .2s;
}
.sound-toggle__wave i:nth-child(1) { height: 5px; }
.sound-toggle__wave i:nth-child(2) { height: 12px; }
.sound-toggle__wave i:nth-child(3) { height: 8px; }
.sound-toggle[aria-pressed="false"] .sound-toggle__wave i { height: 3px; opacity: .45; }

.site-foot {
  max-width: 1240px;
  margin: 0 auto;
  padding: 56px clamp(18px, 5vw, 56px) 48px;
  border-top: 2px solid rgba(43,38,34,.12);
  font-size: 14px;
  color: var(--ink-3);
}
.site-foot p { margin: 0 0 4px; }
.site-foot__meta { font-size: 13px; }

/* ------------------------------------------------------------------ */
/*  Screens                                                            */
/* ------------------------------------------------------------------ */

.screen { display: none; }
.screen.is-active { display: block; }

body[data-screen="game"] .site-head,
body[data-screen="game"] .site-foot { display: none; }

body[data-screen="game"] { overflow: hidden; }

/* ------------------------------------------------------------------ */
/*  Home - hero                                                        */
/* ------------------------------------------------------------------ */

.screen--home { max-width: 1240px; margin: 0 auto; padding: 0 clamp(18px, 5vw, 56px); }

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(24px, 5vw, 72px);
  align-items: center;
  padding: clamp(20px, 5vw, 60px) 0 clamp(48px, 8vw, 96px);
}

.eyebrow {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--p1-deep);
}

.hero__title {
  margin: 0 0 22px;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(40px, 7.2vw, 82px);
  line-height: 1.02;
  letter-spacing: -.035em;
}
.hero__title em {
  font-style: normal;
  color: var(--p1);
  position: relative;
  white-space: nowrap;
}
/* Hand-drawn underline rather than a border - it wobbles, on purpose.
   Sat behind the glyphs so a tight leading can't make it collide. */
.hero__title em::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: -2%; right: -2%; bottom: .16em;
  height: .12em;
  background: var(--p2);
  opacity: .34;
  border-radius: 50%;
  transform: rotate(-.8deg);
}

.lede {
  margin: 0 0 34px;
  max-width: 46ch;
  font-size: clamp(16px, 1.7vw, 19px);
  color: var(--ink-2);
}

.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; }

.mode-card {
  position: relative;
  display: grid;
  gap: 2px;
  min-width: 232px;
  padding: 18px 22px 20px;
  text-align: left;
  border-radius: var(--radius);
  border: 2.5px solid var(--line);
  background: var(--card);
  box-shadow: 5px 5px 0 var(--line);
  transition: transform .16s cubic-bezier(.2,.8,.3,1), box-shadow .16s, background .2s;
}
.mode-card:hover { transform: translate(-2px, -2px) rotate(-.7deg); box-shadow: 8px 8px 0 var(--line); }
.mode-card:active { transform: translate(3px, 3px); box-shadow: 1px 1px 0 var(--line); }
.mode-card--duel:hover { background: var(--p1-soft); }
.mode-card--solo:hover { background: var(--p2-soft); }

.mode-card__num {
  font-family: var(--display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--ink-3);
}
.mode-card__name {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.mode-card__note { font-size: 14px; color: var(--ink-2); }

/* Demo board sitting in a tilted frame. The frame needs a resolved
   width of its own - the board inside is sized as a % of it - so no
   `auto` margins here: on a grid item they force shrink-to-fit. */
.hero__demo { display: grid; justify-items: center; align-content: center; gap: 12px; }

.demo-frame {
  width: min(100%, 380px);
  padding: clamp(16px, 3vw, 30px);
  border-radius: 26px;
  background: var(--p2-stage);
  border: 2.5px solid var(--line);
  box-shadow: 8px 8px 0 var(--line);
  transform: rotate(2.2deg);
  transition: background .8s ease;
}
.demo-frame[data-turn="1"] { background: var(--p1-stage); }

.demo-caption {
  margin: 0;
  font-size: 14px;
  text-align: center;
  color: var(--ink-3);
  transform: rotate(-1.5deg);
}

/* ------------------------------------------------------------------ */
/*  Home - rules strip                                                 */
/* ------------------------------------------------------------------ */

.strip { padding: clamp(36px, 6vw, 72px) 0; border-top: 2px solid rgba(43,38,34,.12); }

.strip__title {
  margin: 0 0 34px;
  font-family: var(--display);
  font-size: clamp(24px, 3.4vw, 36px);
  font-weight: 700;
  letter-spacing: -.03em;
}

.rules-grid {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: clamp(18px, 3vw, 34px);
  counter-reset: rule;
}

.rule { counter-increment: rule; }
.rule__art {
  border-radius: var(--radius);
  background: var(--paper-2);
  border: 2.5px solid var(--line);
  padding: 14px;
  margin-bottom: 16px;
}
.rule__art svg { display: block; width: 100%; height: auto; }
.rule h3 {
  margin: 0 0 6px;
  font-family: var(--display);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.rule h3::before {
  content: counter(rule, decimal-leading-zero) " ";
  color: var(--ink-3);
  font-size: 13px;
  letter-spacing: .1em;
}
.rule p { margin: 0; font-size: 15px; color: var(--ink-2); }

.s-tile      { fill: #e6dcc8; }
.s-red       { fill: var(--p1); }
.s-blue      { fill: var(--p2); }
.s-mid       { fill: #90a4a0; }
.s-pip       { fill: #fff; }
.s-ghost     { opacity: .38; }
.s-arrow     { fill: none; stroke: var(--ink-3); stroke-width: 2.2; stroke-dasharray: 5 5; }
.s-arrowhead { fill: var(--ink-3); }

/* ------------------------------------------------------------------ */
/*  Home - stats                                                       */
/* ------------------------------------------------------------------ */

.stats-strip {
  padding: clamp(30px, 5vw, 56px) 0 8px;
  border-top: 2px solid rgba(43,38,34,.12);
}
.stats-strip h2 {
  margin: 0 0 20px;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.stats {
  margin: 0 0 14px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.stats > div {
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--paper-2);
  border: 2px solid rgba(43,38,34,.14);
}
.stats dt { font-size: 13px; color: var(--ink-3); }
.stats dd {
  margin: 2px 0 0;
  font-family: var(--display);
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1;
}

.link-btn {
  font-size: 13px;
  color: var(--ink-3);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.link-btn:hover { color: var(--p1-deep); }

/* ------------------------------------------------------------------ */
/*  Setup + rules pages                                                */
/* ------------------------------------------------------------------ */

.setup, .prose {
  max-width: 660px;
  margin: 0 auto;
  padding: clamp(16px, 4vw, 40px) clamp(18px, 5vw, 40px) 90px;
}

.back-btn {
  display: inline-block;
  margin-bottom: 26px;
  font-size: 14px;
  color: var(--ink-3);
}
.back-btn:hover { color: var(--ink); }

.setup__title, .prose h2 {
  margin: 0 0 34px;
  font-family: var(--display);
  font-size: clamp(30px, 5vw, 46px);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1;
}

.field { margin-bottom: 30px; }
.field__label {
  display: block;
  margin-bottom: 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.field__hint { margin: 10px 0 0; font-size: 14px; color: var(--ink-2); }

.names { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.versus {
  font-family: var(--display);
  font-size: 15px;
  color: var(--ink-3);
  transform: rotate(-6deg);
}
.name {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1 1 180px;
  padding: 10px 16px;
  border-radius: 999px;
  border: 2.5px solid var(--line);
  background: var(--card);
}
.name__dot { width: 16px; height: 16px; border-radius: 50%; flex: none; }
.name--p1 .name__dot { background: var(--p1); }
.name--p2 .name__dot { background: var(--p2); }
.name input {
  width: 100%;
  min-width: 0;
  border: 0;
  background: none;
  outline: none;
  font-family: var(--display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -.01em;
}

.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  border: 2.5px solid var(--line);
  background: var(--card);
}
.segmented button {
  padding: 9px 18px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink-2);
  transition: background .16s, color .16s;
}
.segmented button:hover { background: rgba(43,38,34,.07); }
.segmented button[aria-checked="true"] {
  background: var(--line);
  color: var(--paper);
  font-weight: 700;
}

.big-btn {
  display: inline-block;
  padding: 15px 34px;
  border-radius: 999px;
  border: 2.5px solid var(--line);
  background: var(--p1);
  color: #fff;
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -.01em;
  box-shadow: 5px 5px 0 var(--line);
  transition: transform .14s, box-shadow .14s;
}
.big-btn:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 var(--line); }
.big-btn:active { transform: translate(3px, 3px); box-shadow: 1px 1px 0 var(--line); }

.prose h3 {
  margin: 32px 0 8px;
  font-family: var(--display);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.prose p, .prose li { color: var(--ink-2); }
.prose ul { padding-left: 20px; }
.prose li { margin-bottom: 8px; }
.prose strong { color: var(--ink); }
.prose .big-btn { margin-top: 40px; }

/* ------------------------------------------------------------------ */
/*  The board                                                          */
/* ------------------------------------------------------------------ */

.board {
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  grid-template-rows: repeat(var(--rows), 1fr);
  gap: var(--gap, 8px);
  aspect-ratio: var(--cols) / var(--rows);
  width: 100%;
}

.tile {
  position: relative;
  border-radius: 22%;
  background: var(--tile, #edeedc);
  transition: background .25s ease, transform .12s ease;
}
.board--demo { --gap: clamp(4px, 1.7vmin, 9px); }
.board--demo .tile { pointer-events: none; }

.tile:disabled { cursor: default; }
.tile.is-playable:hover { transform: scale(1.05); }
.tile.is-last { box-shadow: inset 0 0 0 3px rgba(255,255,255,.75); }

/* The current player's cells glow slightly, as on the real board. */
body[data-turn="1"] .tile.own-1,
.board--demo[data-turn="1"] .tile.own-1 { background: var(--p1-soft); }
body[data-turn="2"] .tile.own-2,
.board--demo[data-turn="2"] .tile.own-2 { background: var(--p2-soft); }

.disc {
  position: absolute;
  inset: 16%;
  border-radius: 50%;
  background: var(--p1);
  transform: scale(0);
  opacity: 0;
  transition: transform var(--land) cubic-bezier(.34,1.56,.64,1),
              opacity calc(var(--land) * .8),
              background .2s;
}
.disc[data-p="1"] { background: var(--p1); }
.disc[data-p="2"] { background: var(--p2); }
.disc[data-n="1"], .disc[data-n="2"], .disc[data-n="3"], .disc[data-n="4"], .disc[data-n="5"] {
  transform: scale(1);
  opacity: 1;
}

/* Pips, arranged like a die face. */
.disc i {
  position: absolute;
  left: 39%; top: 39%;
  width: 22%; height: 22%;
  border-radius: 50%;
  background: #fff;
  opacity: 0;
  transform: scale(.2);
  transition: transform var(--land) cubic-bezier(.34,1.56,.64,1),
              opacity calc(var(--land) * .75);
}

.disc[data-n="1"] i:nth-child(1) { opacity: 1; transform: translate(0, 0); }

.disc[data-n="2"] i:nth-child(1) { opacity: 1; transform: translate(-68%, 0); }
.disc[data-n="2"] i:nth-child(2) { opacity: 1; transform: translate(68%, 0); }

.disc[data-n="3"] i:nth-child(1) { opacity: 1; transform: translate(-72%, -44%); }
.disc[data-n="3"] i:nth-child(2) { opacity: 1; transform: translate(72%, -44%); }
.disc[data-n="3"] i:nth-child(3) { opacity: 1; transform: translate(0, 74%); }

.disc[data-n="4"] i:nth-child(1) { opacity: 1; transform: translate(-70%, -70%); }
.disc[data-n="4"] i:nth-child(2) { opacity: 1; transform: translate(70%, -70%); }
.disc[data-n="4"] i:nth-child(3) { opacity: 1; transform: translate(-70%, 70%); }
.disc[data-n="4"] i:nth-child(4) { opacity: 1; transform: translate(70%, 70%); }

.disc[data-n="5"] i:nth-child(1) { opacity: 1; transform: translate(-72%, -72%); }
.disc[data-n="5"] i:nth-child(2) { opacity: 1; transform: translate(72%, -72%); }
.disc[data-n="5"] i:nth-child(3) { opacity: 1; transform: translate(-72%, 72%); }
.disc[data-n="5"] i:nth-child(4) { opacity: 1; transform: translate(72%, 72%); }
.disc[data-n="5"] i:nth-child(5) { opacity: 1; transform: translate(0, 0); }

/* One orb short of bursting - the cell gets visibly nervous. */
.tile.is-loaded .disc { animation: fidget 1.9s ease-in-out infinite; }
@keyframes fidget {
  0%, 100% { rotate: 0deg; }
  25%      { rotate: 7deg; }
  50%      { rotate: 0deg; }
  75%      { rotate: -7deg; }
}

/* Where the machine is about to play - shown for a beat before the
   orb actually lands, so you can see it coming. */
.tile.is-target::after {
  content: "";
  position: absolute;
  inset: -7%;
  border-radius: 26%;
  border: 3px solid rgba(255, 255, 255, .95);
  box-shadow: 0 0 0 2px rgba(36, 31, 28, .16);
  animation: target 620ms ease-in-out infinite alternate;
}
@keyframes target {
  from { transform: scale(.9);  opacity: .55; }
  to   { transform: scale(1.04); opacity: 1; }
}

.tile.is-bursting .disc {
  transform: scale(1.5);
  opacity: 0;
  transition: transform var(--burst) cubic-bezier(.3, 0, .5, 1),
              opacity var(--burst) ease-out;
}

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

.stage {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  align-items: center;
  justify-items: center;
  padding: 20px 16px 24px;
  background: var(--p1-stage);
  transition: background .55s ease;
  --tile: var(--p1-tile);
}
body[data-turn="2"] .stage { background: var(--p2-stage); --tile: var(--p2-tile); }

.stage__top { text-align: center; padding-top: 6px; width: 100%; }

/* Both players, always on screen, with the live cell count. */
.scoreboard {
  display: flex;
  justify-content: center;
  align-items: stretch;
  gap: clamp(8px, 2vw, 14px);
  margin: 0 auto 10px;
  max-width: min(92vw, 520px);
}

.pchip {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px clamp(10px, 2.4vw, 16px);
  border-radius: 999px;
  background: rgba(255, 255, 255, .34);
  border: 2px solid transparent;
  transition: background .25s, border-color .25s, transform .25s;
}
.pchip.is-active {
  background: #fdf9f1;
  border-color: rgba(36, 31, 28, .16);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(36, 31, 28, .14);
}

.pchip__dot {
  width: 13px; height: 13px;
  border-radius: 50%;
  flex: none;
}
.pchip--1 .pchip__dot { background: var(--p1); }
.pchip--2 .pchip__dot { background: var(--p2); }

.pchip__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  font-size: clamp(13px, 1.8vw, 15px);
  font-weight: 500;
  color: rgba(36, 31, 28, .8);
}
.pchip__score {
  flex: none;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(19px, 2.8vw, 24px);
  letter-spacing: -.03em;
  line-height: 1;
}
.pchip--1 .pchip__score { color: var(--p1-deep); }
.pchip--2 .pchip__score { color: var(--p2-deep); }
.turn-line {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(17px, 2.4vw, 22px);
  letter-spacing: -.02em;
  color: rgba(36,31,28,.78);
}
.turn-line span { color: #fff; }
.turn-line.is-off { visibility: hidden; }

/* The board must never move. Both status lines keep their space at all
   times and are toggled with visibility, because switching `hidden` on
   and off resized this block and nudged the grid down 13px every time
   the machine started thinking. */
.turn-line, .think-line { min-height: 1.35em; }
.think-line {
  margin: 4px 0 0;
  font-size: 14px;
  color: rgba(36,31,28,.55);
  visibility: hidden;
}
.think-line.is-on { visibility: visible; }
.dots i { animation: blink 1.2s infinite; }
.dots i:nth-child(2) { animation-delay: .2s; }
.dots i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 60%, 100% { opacity: .2; } 30% { opacity: 1; } }

/* Sized by width, but never so tall that a 7×9 board runs off the
   bottom of a phone - hence the height term. --cols/--rows are set
   from ui.js and inherit down into .board. */
.board-wrap {
  position: relative;
  width: min(86vw, 560px);
  width: min(86vw, 560px, calc((100dvh - var(--chrome, 250px)) * var(--cols, 5) / var(--rows, 5)));
  align-self: center;
  justify-self: center;
}
.board-wrap .board { --gap: clamp(5px, 1.4vmin, 11px); }

.fx { position: absolute; inset: 0; pointer-events: none; }

.flyer {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
  transition: transform var(--flight) cubic-bezier(.25, .6, .35, 1),
              opacity var(--flight) ease-in;
}

.stage__bottom {
  display: grid;
  justify-items: center;
  gap: 6px;
  padding-bottom: 4px;
  width: 100%;
}

/* ---- hold-to-confirm ------------------------------------------------
   Ending a game is one press away from losing your position, so it
   takes a deliberate press-and-hold. The fill is the timer. */

.hold-btn { position: relative; overflow: hidden; isolation: isolate; }

.hold-btn__fill {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--p1);
  opacity: .85;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .18s ease-out;
}
.hold-btn.is-holding .hold-btn__fill {
  transform: scaleX(1);
  transition: transform var(--hold, 2400ms) linear;
}
.hold-btn.is-holding .hold-btn__label { color: #fff; }

.hold-btn--bar {
  display: none;                     /* phone-only; desktop uses the rail */
  padding: 11px 26px;
  border-radius: 999px;
  border: 2px solid rgba(36, 31, 28, .35);
  font-size: 15px;
  font-weight: 500;
  color: rgba(36, 31, 28, .78);
}

/* The rail is a circle, so its timer fills bottom-up instead. */
.rail--right .hold-btn__fill {
  transform: scaleY(0);
  transform-origin: center bottom;
}
.rail--right .hold-btn.is-holding .hold-btn__fill { transform: scaleY(1); }

.hold-hint {
  margin: 0;
  min-height: 18px;
  font-size: 13px;
  color: rgba(36, 31, 28, .6);
  opacity: 0;
  transition: opacity .2s;
}
.hold-hint.is-on { opacity: 1; }

.ghost-btn {
  padding: 9px 20px;
  border-radius: 999px;
  border: 2px solid rgba(36,31,28,.35);
  font-size: 15px;
  font-weight: 500;
  color: rgba(36,31,28,.75);
  transition: background .16s, border-color .16s, color .16s;
}
.ghost-btn:hover { background: rgba(255,255,255,.35); border-color: rgba(36,31,28,.6); color: var(--ink); }
.ghost-btn:disabled { opacity: .35; cursor: default; }
.ghost-btn:disabled:hover { background: none; }

/* Side rails - circles half off the edge of the screen. */
.rail {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
}
.rail--left  { left: 0; }
.rail--right { right: 0; }

.rail__pill {
  /* How much of the circle hangs off the edge of the screen. The
     padding that keeps the label on screen is derived from it, so the
     two can never drift apart. */
  --overhang: clamp(38px, 5.5vw, 50px);

  display: grid;
  place-items: center;
  /* Without this the auto rows stretch to fill the circle and the two
     scores drift to opposite ends of it. */
  place-content: center;
  gap: 3px;
  width: clamp(96px, 13vw, 124px);
  height: clamp(96px, 13vw, 124px);
  border-radius: 50%;
  background: #fdf9f1;
  box-shadow: 0 6px 18px rgba(36,31,28,.16);
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: -.02em;
}

/* Both rails read upright. Rotated text in a half-hidden circle was
   almost impossible to make legible - a "0" on its side is just an
   oval - so the content sits in the visible half instead, pushed there
   by padding on whichever edge is clipped. */
.rail--left .rail__pill {
  margin-left: calc(-1 * var(--overhang));
  padding-left: var(--overhang);
  gap: clamp(4px, .8vh, 9px);
}
.rail--right .rail__pill {
  margin-right: calc(-1 * var(--overhang));
  padding-right: var(--overhang);
  transition: background .16s;
}
.rail--right .rail__pill:hover { background: #fff; }

.rail-score {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: clamp(16px, 1.5vw, 20px);
  line-height: 1;
}
.rail-score i {
  width: 9px; height: 9px;
  border-radius: 50%;
  flex: none;
}
.rail-score b { font-weight: 800; letter-spacing: -.03em; }
.rail-score--1 i { background: var(--p1); }
.rail-score--2 i { background: var(--p2); }
.rail-score--1 b { color: var(--p1-deep); }
.rail-score--2 b { color: var(--p2-deep); }

.hold-btn__label { display: grid; gap: 1px; justify-items: center; }
.hold-btn__word {
  font-size: clamp(14px, 1.5vw, 17px);
  letter-spacing: -.02em;
  line-height: 1;
}
.hold-btn__sub {
  font-family: var(--body);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1;
}
.hold-btn.is-holding .hold-btn__sub { color: rgba(255,255,255,.85); }

/* ------------------------------------------------------------------ */
/*  Result overlay                                                     */
/* ------------------------------------------------------------------ */

.result {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(36,31,28,.42);
  backdrop-filter: blur(3px);
  animation: fade .35s ease both;
}
.result[hidden] { display: none; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.result__card {
  width: min(440px, 92vw);
  padding: 34px 30px 30px;
  text-align: center;
  border-radius: 26px;
  border: 2.5px solid var(--line);
  background: var(--card);
  box-shadow: 8px 8px 0 var(--line);
  animation: pop-in .4s cubic-bezier(.2,1.3,.4,1) both;
}
@keyframes pop-in {
  from { transform: translateY(16px) scale(.94); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

.result__kicker {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.result__title {
  margin: 0 0 8px;
  font-family: var(--display);
  font-size: clamp(28px, 6vw, 38px);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1;
}
.result__sub { margin: 0 0 26px; font-size: 15px; color: var(--ink-2); }
.result__actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.result__actions .ghost-btn { border-color: rgba(36,31,28,.3); }

/* ------------------------------------------------------------------ */
/*  Responsive                                                         */
/* ------------------------------------------------------------------ */

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; }
  .hero__demo { order: -1; }
  .demo-frame { width: min(100%, 300px); transform: rotate(1.4deg); }
}

/* Below this the side rails would sit on top of the board, so the
   furniture moves inline: score above, hold-to-exit below. */
@media (max-width: 760px) {
  .rail { display: none; }
  .hold-btn--bar { display: block; }
  .board-wrap {
    width: min(94vw, 460px);
    width: min(94vw, 460px, calc((100dvh - var(--chrome, 250px)) * var(--cols, 5) / var(--rows, 5)));
  }
  .stage { --chrome: 235px; padding: 12px 10px 16px; }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  .site-head { padding: 14px 16px; gap: 10px; }
  .wordmark { font-size: 17px; gap: 7px; white-space: nowrap; }
  .wordmark__dots i { width: 13px; height: 13px; }
  .site-nav { gap: 2px; }
  .site-nav > button { padding: 8px 9px; font-size: 14px; white-space: nowrap; }
  .site-nav .sound-toggle__label { display: none; }

  .hero { padding-bottom: 34px; gap: 26px; }
  .hero__title { font-size: clamp(31px, 8.6vw, 46px); }
  .lede { margin-bottom: 26px; }
  .hero__actions { gap: 10px; }
  .mode-card { min-width: 100%; padding: 15px 18px 17px; box-shadow: 4px 4px 0 var(--line); }
  .mode-card:hover { transform: none; box-shadow: 4px 4px 0 var(--line); }

  .rules-grid { grid-template-columns: 1fr; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stats dd { font-size: 25px; }

  .setup, .prose { padding-bottom: 64px; }
  .setup__title, .prose h2 { margin-bottom: 26px; }
  .field { margin-bottom: 24px; }
  .names { gap: 8px; }
  .name { flex-basis: 100%; }
  .versus { display: none; }
  .segmented { display: flex; width: 100%; }
  .segmented button { flex: 1 1 0; padding: 10px 8px; text-align: center; font-size: 14px; }
  .big-btn { width: 100%; text-align: center; }

  .stage { --chrome: 218px; padding: 10px 8px 14px; }
  .scoreboard { max-width: 100%; margin-bottom: 8px; }
  .turn-line { font-size: 15px; }
  .result__card { padding: 26px 20px 22px; }
  .result__actions .big-btn,
  .result__actions .ghost-btn { width: 100%; }
}

/* Small phones: every millimetre of height counts. */
@media (max-width: 400px) {
  .stage { --chrome: 205px; }
  .pchip { padding: 7px 10px; gap: 6px; }
  .pchip__name { font-size: 12px; }
  .board-wrap { width: min(96vw, 460px); }
  .board-wrap { width: min(96vw, 460px, calc((100dvh - var(--chrome, 205px)) * var(--cols, 5) / var(--rows, 5))); }
  .hold-btn--bar { padding: 10px 18px; font-size: 14px; }
}

/* Landscape phones are short, not narrow - shrink the chrome, not
   the board's width. */
@media (max-height: 560px) and (orientation: landscape) {
  .stage { --chrome: 124px; padding: 6px 8px 8px; }
  .scoreboard { margin-bottom: 3px; max-width: min(92vw, 420px); }
  .pchip { padding: 5px 12px; }
  .turn-line { font-size: 13px; }
  .think-line { display: none; }
  .hold-btn--bar { padding: 7px 20px; font-size: 13px; }
  .hold-hint { display: none; }
}

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