/* ==========================================================================
   Scrap Paper Party — homemade board game aesthetic
   Cardboard table, paper scraps, masking tape, marker handwriting.
   ========================================================================== */

:root {
  --cardboard: #b98d5f;
  --paper: #fdf8e8;
  --paper-shadow: rgba(60, 40, 10, 0.35);
  --ink: #2b2b2b;
  --marker-red: #d9483b;
  --marker-red-dark: #9c2f24;
  --marker-orange: #d4701f;
  --marker-blue: #3b6bd9;
  --marker-green: #3f9e4d;
  --marker-gold: #e8b830;
  --marker-purple: #8b4fc9;
  --pencil: #6b6b6b;
  --tape: rgba(255, 250, 220, 0.55);

  --hand-font: "Patrick Hand", "Comic Sans MS", "Comic Sans", cursive;
  --marker-font: "Permanent Marker", "Comic Sans MS", cursive;

  /* the classic "hand-drawn" wobbly border radius trick */
  --wobble: 255px 15px 225px 15px / 15px 225px 15px 255px;
  --wobble-2: 15px 225px 15px 255px / 255px 15px 225px 15px;

  --ease-out-back: cubic-bezier(0.34, 1.4, 0.64, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; }

body {
  font-family: var(--hand-font);
  color: var(--ink);
  font-size: 20px;
  -webkit-tap-highlight-color: transparent;
}

/* ---- cardboard table surface: layered gradients fake corrugation ---- */
.cardboard {
  min-height: 100vh;
  min-height: 100dvh;
  padding: 24px 16px 48px;
  background-color: var(--cardboard);
  background-image:
    repeating-linear-gradient(90deg,
      rgba(0, 0, 0, 0.04) 0px, rgba(0, 0, 0, 0.04) 2px,
      transparent 2px, transparent 9px),
    repeating-linear-gradient(0deg,
      rgba(255, 255, 255, 0.03) 0px, rgba(255, 255, 255, 0.03) 1px,
      transparent 1px, transparent 7px),
    radial-gradient(ellipse at 30% 20%, rgba(255, 235, 200, 0.25), transparent 60%),
    radial-gradient(ellipse at 80% 90%, rgba(80, 50, 20, 0.25), transparent 55%);
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow-x: hidden;
}

.screen {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}

/*
 * Join and lobby are short screens, and pinned to the top of a desktop monitor
 * they leave a lake of empty cardboard underneath. `margin-block: auto` centres
 * them in the leftover space — and unlike `justify-content: center` on the
 * parent, it still scrolls correctly when the content is taller than the
 * viewport instead of clipping the top off.
 */
#screen-join:not(.hidden),
#screen-lobby:not(.hidden) { margin-block: auto; }

.hidden { display: none !important; }

/* ==========================================================================
   ANIMATION LIBRARY
   Screens re-run their entrance animation because display:none -> flex
   restarts CSS animations.
   ========================================================================== */
@keyframes screen-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes drop-in {
  0%   { opacity: 0; transform: translateY(-18px) rotate(-6deg) scale(0.94); }
  100% { opacity: 1; }
}

@keyframes pop-in {
  0%   { opacity: 0; transform: scale(0.5) rotate(-12deg); }
  70%  { transform: scale(1.12) rotate(4deg); }
  100% { opacity: 1; transform: scale(1) rotate(5deg); }
}

/* Same bounce, but it lands square. `pop-in` deliberately settles at a jaunty
   5deg, which is right for a sticker slapped on the page and wrong for
   anything you have to read or aim at. */
@keyframes pop-in-flat {
  0%   { opacity: 0; transform: scale(0.6); }
  70%  { transform: scale(1.08); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes stamp-in {
  0%   { opacity: 0; transform: scale(2.6) rotate(-14deg); filter: blur(4px); }
  60%  { opacity: 1; transform: scale(0.92) rotate(-3deg); filter: blur(0); }
  80%  { transform: scale(1.06) rotate(-5deg); }
  100% { opacity: 1; transform: scale(1) rotate(-4deg); }
}

@keyframes flash-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

@keyframes tile-flip {
  0%   { transform: rotateX(-90deg) scale(1.2); background: var(--marker-gold); }
  100% { transform: rotateX(0) scale(1); }
}

@keyframes shake-x {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-8px); }
  40%      { transform: translateX(8px); }
  60%      { transform: translateX(-5px); }
  80%      { transform: translateX(5px); }
}

@keyframes shake {
  0%, 100% { transform: rotate(3deg); }
  25%      { transform: rotate(6deg) scale(1.06); }
  75%      { transform: rotate(0deg) scale(1.02); }
}

@keyframes slide-up {
  from { opacity: 0; transform: translate(-50%, 16px) rotate(-1deg); }
  to   { opacity: 1; transform: translate(-50%, 0) rotate(-1deg); }
}

@keyframes score-bump {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.18); color: var(--marker-green); }
  100% { transform: scale(1); }
}

/* every screen eases in when it becomes visible */
.screen:not(.hidden) { animation: screen-in 0.34s ease-out both; }

/* ==========================================================================
   Paper scraps
   ========================================================================== */
.paper {
  background: var(--paper);
  background-image:
    repeating-linear-gradient(0deg,
      transparent 0px, transparent 27px,
      rgba(100, 140, 200, 0.18) 27px, rgba(100, 140, 200, 0.18) 28px);
  border: 2px solid var(--ink);
  border-radius: var(--wobble);
  box-shadow: 3px 4px 0 var(--paper-shadow);
  padding: 22px 20px;
  width: 100%;
  position: relative;
}

.title-paper { text-align: center; transform: rotate(-1.2deg); }
.form-paper  { transform: rotate(0.8deg); text-align: center; }
.prompt-paper { text-align: center; transform: rotate(-0.6deg); }
.scoreboard-paper { transform: rotate(0.5deg); }
.winner-paper { transform: rotate(-1.5deg); }

.urgent-paper {
  border-color: var(--marker-red);
  box-shadow: 3px 4px 0 rgba(217, 72, 59, 0.45);
}

/* ---- masking tape strips ---- */
.tape-top::before,
.tape-corner::before,
.tape-corner::after {
  content: "";
  position: absolute;
  background: var(--tape);
  border-left: 1px dashed rgba(120, 100, 60, 0.4);
  border-right: 1px dashed rgba(120, 100, 60, 0.4);
  box-shadow: 0 1px 2px rgba(60, 40, 10, 0.2);
  pointer-events: none;
}

.tape-top::before {
  width: 110px; height: 30px;
  top: -15px; left: 50%;
  transform: translateX(-50%) rotate(-2deg);
}

.tape-corner::before {
  width: 80px; height: 26px;
  top: -12px; left: -18px;
  transform: rotate(-38deg);
}
.tape-corner::after {
  width: 80px; height: 26px;
  top: -12px; right: -18px;
  transform: rotate(38deg);
}

/* ==========================================================================
   Typography
   ========================================================================== */
.game-title {
  font-family: var(--marker-font);
  font-size: 2.4rem;
  line-height: 1.1;
  color: var(--marker-red);
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.12);
  transform: rotate(-1deg);
}

/*
 * The logo on the way in. White with a hard outline, so it reads as a name
 * painted on the box rather than another line of marker on another scrap.
 *
 * `paint-order` is the part that matters: without it a text stroke is centred
 * on the glyph edge and eats half the letter, which at this weight closes up
 * the counters in the P and the R. Drawing the fill last keeps the outline
 * outside the letterform.
 */
#screen-join .game-title {
  color: #fff;
  -webkit-text-stroke: 3px var(--ink);
  paint-order: stroke fill;
  text-shadow: 3px 4px 0 var(--paper-shadow);
}

.section-title { font-family: var(--marker-font); font-size: 1.8rem; color: var(--marker-blue); }

.subtitle { color: var(--pencil); font-size: 1rem; margin-top: 6px; }

.headline {
  font-family: var(--marker-font);
  font-size: 1.25rem;
  color: var(--marker-green);
  margin-top: 10px;
  animation: pop-in 0.5s var(--ease-out-back) both;
  transform-origin: center;
}
.headline.sad { color: var(--pencil); }

.scribble-label {
  display: block;
  font-size: 1.15rem;
  margin-bottom: 12px;
  text-decoration: underline wavy var(--marker-blue) 2px;
  text-underline-offset: 5px;
}

.prompt-text {
  font-family: var(--marker-font);
  font-size: 2rem;
  color: var(--ink);
  letter-spacing: 1px;
  word-break: break-word;
}
.prompt-text .blank { color: var(--marker-red); }

/* the nudge that appears for the last stretch of a riddle */
.riddle-hint {
  margin-top: 14px;
  font-size: 1rem;
  color: var(--pencil);
  font-style: italic;
  animation: drop-in 0.4s var(--ease-out-back) both;
}
.riddle-hint::before { content: "Hint: "; font-style: normal; font-weight: bold; }

/* riddles are a sentence, not a phrase — smaller and easier to read */
.riddle-text {
  font-family: var(--hand-font);
  font-size: 1.35rem;
  line-height: 1.4;
  letter-spacing: 0;
}

.pencil-note { color: rgba(45, 45, 45, 0.75); font-size: 1rem; text-align: center; }
.big-note { font-size: 1.3rem; line-height: 1.5; }
.small-note { font-size: 0.85rem; color: var(--pencil); text-decoration: none; }
.error-note { margin-top: 12px; color: var(--marker-red); font-size: 1rem; transform: rotate(-1deg); }
.error-note.shake { animation: shake-x 0.4s ease-in-out; }

/* ==========================================================================
   Inputs & buttons
   ========================================================================== */
input[type="text"] {
  width: 100%;
  font-family: var(--hand-font);
  font-size: 1.4rem;
  text-align: center;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 3px dashed var(--ink);
  padding: 8px 4px;
  margin-bottom: 18px;
  outline: none;
  transition: border-color 0.2s ease;
}
input[type="text"]::placeholder { color: rgba(43, 43, 43, 0.35); }
input[type="text"]:focus { border-bottom-color: var(--marker-blue); }
input.wrong { animation: shake-x 0.4s ease-in-out; border-bottom-color: var(--marker-red); }

.marker-btn {
  font-family: var(--marker-font);
  font-size: 1.25rem;
  color: var(--paper);
  background: var(--marker-red);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 3px 3px 0 var(--ink);
  padding: 12px 28px;
  cursor: pointer;
  transform: rotate(-1deg);
  transition: transform 0.1s ease, box-shadow 0.1s ease, background 0.2s ease;
  touch-action: manipulation;
}
.marker-btn:active {
  transform: rotate(-1deg) translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--ink);
}
.marker-btn.big { font-size: 1.5rem; padding: 14px 36px; background: var(--marker-green); }

/* Armed: one more press and the answer is locked in. */
.marker-btn.armed {
  background: var(--marker-red-dark);
  transform: rotate(-1deg) scale(1.04);
}
.marker-btn:disabled { background: var(--pencil); opacity: 0.6; cursor: not-allowed; transform: rotate(-1deg); }

/* ==========================================================================
   Lobby player scraps
   ========================================================================== */
.player-scraps { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; width: 100%; }

.scrap {
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble);
  box-shadow: 2px 3px 0 var(--paper-shadow);
  padding: 8px 16px;
  font-size: 1.15rem;
  position: relative;
  animation: drop-in 0.32s var(--ease-out-back) both;
}
.scrap:nth-child(odd)  { transform: rotate(-2deg); }
.scrap:nth-child(even) { transform: rotate(2deg); background: #fdf0d5; }
.scrap:nth-child(3n)   { background: #eef5e0; }

.scrap .host-badge {
  font-family: var(--marker-font);
  font-size: 0.7rem;
  color: var(--paper);
  background: var(--marker-blue);
  border-radius: 6px;
  padding: 1px 6px;
  margin-left: 6px;
  display: inline-block;
  transform: rotate(3deg);
}
.scrap.me { outline: 3px dashed var(--marker-blue); outline-offset: 2px; }

/* ==========================================================================
   Game themes — a game module picks one by name, and it colours that game's
   intro stamp and its in-play sticker. Adding a colour here makes it
   available to every future game.

   A theme sets two custom properties rather than a background directly, so it
   never has to out-specify the component it lands on — the component reads
   --theme-bg and --theme-ink, and the cascade stays out of it.
   Gold is the only colour light enough to keep dark ink on top.
   ========================================================================== */
.theme-red    { --theme-bg: var(--marker-red);    --theme-ink: var(--paper); }
.theme-gold   { --theme-bg: var(--marker-gold);   --theme-ink: var(--ink); }
.theme-purple { --theme-bg: var(--marker-purple); --theme-ink: var(--paper); }
.theme-blue   { --theme-bg: var(--marker-blue);   --theme-ink: var(--paper); }
.theme-green  { --theme-bg: var(--marker-green);  --theme-ink: var(--paper); }

/* ==========================================================================
   Round intro splash
   ========================================================================== */
.event-flash {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  width: 100%;
  padding-top: 24px;
}

.event-kicker {
  font-family: var(--marker-font);
  font-size: 1.1rem;
  color: var(--paper);
  letter-spacing: 2px;
  animation: flash-pulse 0.8s ease-in-out infinite;
}

.event-stamp {
  background: var(--theme-bg, var(--marker-gold));
  color: var(--theme-ink, var(--ink));
  border: 4px solid var(--ink);
  border-radius: var(--wobble);
  box-shadow: 5px 6px 0 rgba(60, 40, 10, 0.45);
  padding: 20px 26px;
  animation: stamp-in 0.6s var(--ease-out-back) both;
}

.event-name {
  font-family: var(--marker-font);
  font-size: 2.1rem;
  line-height: 1.15;
  text-align: center;
  color: inherit; /* the theme class on the stamp decides ink or paper */
}

.event-rules {
  text-align: center;
  transform: rotate(0.8deg);
  animation: drop-in 0.4s var(--ease-out-back) 0.45s both;
}

/* ==========================================================================
   Answer phase shared bits
   ========================================================================== */
.round-row { width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 10px; }

.sticker {
  font-family: var(--marker-font);
  font-size: 1.05rem;
  background: var(--marker-blue);
  color: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 50% 45% 55% 48% / 55% 50% 48% 45%;
  padding: 10px 16px;
  transform: rotate(-4deg);
  box-shadow: 2px 2px 0 var(--paper-shadow);
}
.sticker.event-sticker {
  background: var(--theme-bg, var(--marker-purple));
  color: var(--theme-ink, var(--paper));
  animation: pop-in 0.45s var(--ease-out-back) both;
}

.timer-tag {
  font-family: var(--marker-font);
  font-size: 1.6rem;
  min-width: 64px;
  text-align: center;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble);
  box-shadow: 2px 2px 0 var(--paper-shadow);
  padding: 6px 14px;
  transform: rotate(3deg);
}
.timer-tag.hurry { color: var(--marker-red); animation: shake 0.4s infinite; }

.status-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }

.status-chip {
  font-size: 0.95rem;
  background: rgba(253, 248, 232, 0.7);
  border: 1.5px dashed var(--ink);
  border-radius: 12px;
  padding: 4px 12px;
  color: var(--pencil);
  transition: color 0.25s ease, background 0.25s ease;
}
.status-chip.done { color: var(--marker-green); border-style: solid; background: var(--paper); }

/* ==========================================================================
   Guess the Word
   ========================================================================== */
.letter-tiles {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 18px 0 10px;
}
/* Games without tiles shouldn't leave a gap where the tiles would have been. */
.letter-tiles:empty { display: none; }

.tile {
  width: 38px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--marker-font);
  font-size: 1.5rem;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 6px 10px 7px 9px;
  box-shadow: 2px 2px 0 var(--paper-shadow);
}
.tile.blank { color: transparent; background: rgba(43, 43, 43, 0.07); }
.tile.flip { animation: tile-flip 0.45s var(--ease-out-back) both; }

.miss-list { display: flex; flex-direction: column; gap: 6px; width: 100%; align-items: center; }

.miss {
  font-size: 0.95rem;
  color: var(--paper);
  background: rgba(43, 43, 43, 0.55);
  border-radius: 10px;
  padding: 3px 12px;
  animation: drop-in 0.3s ease-out both;
}
.miss s { opacity: 0.8; }

/* ==========================================================================
   Reveal
   ========================================================================== */
.results-list { width: 100%; display: flex; flex-direction: column; gap: 14px; }

.result-card {
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble);
  box-shadow: 2px 3px 0 var(--paper-shadow);
  padding: 12px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  animation: drop-in 0.36s var(--ease-out-back) both;
}
.result-card:nth-child(odd)  { transform: rotate(-0.8deg); }
.result-card:nth-child(even) { transform: rotate(0.8deg); background: #fdf0d5; }
.result-card.winner { border-color: var(--marker-green); border-width: 3px; background: #eef5e0; }

.result-name { font-size: 1rem; color: var(--pencil); }
.result-word { font-family: var(--marker-font); font-size: 1.3rem; word-break: break-word; }
.result-word.no-answer { color: var(--pencil); font-size: 1rem; font-style: italic; }
.result-match { font-size: 0.85rem; color: var(--marker-blue); }

.points-badge {
  font-family: var(--marker-font);
  font-size: 1.15rem;
  flex-shrink: 0;
  border: 2px solid var(--ink);
  border-radius: 50% 45% 55% 48% / 55% 50% 48% 45%;
  padding: 8px 12px;
  animation: pop-in 0.4s var(--ease-out-back) both;
}
.points-badge.p4 { background: var(--marker-purple); color: var(--paper); }
.points-badge.p3 { background: var(--marker-green); color: var(--paper); }
.points-badge.p2 { background: var(--marker-gold); color: var(--ink); }
.points-badge.p1 { background: var(--marker-gold); color: var(--ink); }
.points-badge.p0 { background: transparent; color: var(--pencil); border-style: dashed; }

.score-lines { display: flex; flex-direction: column; gap: 6px; }

.score-line {
  display: flex;
  justify-content: space-between;
  font-size: 1.15rem;
  border-bottom: 1px dashed rgba(43, 43, 43, 0.3);
  padding: 2px 4px;
  animation: drop-in 0.3s ease-out both;
}
.score-line .pts { font-family: var(--marker-font); display: inline-block; }
.score-line .pts.bumped { animation: score-bump 0.6s var(--ease-out-back) both; }
.score-line.leader .pts { color: var(--marker-red); }
/* Your own row, so you can find yourself in a list of ten without reading it. */
.score-line.mine { color: var(--marker-gold); font-weight: 700; }
.score-line.mine .pts { color: var(--marker-gold); }

/* ==========================================================================
   "player left" banner
   ========================================================================== */
.away-banner {
  position: sticky;
  top: 6px;
  z-index: 40;
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.away-banner:not(:empty) { margin-bottom: 16px; }

.away-bubble {
  background: var(--marker-red);
  color: var(--paper);
  font-size: 0.95rem;
  text-align: center;
  padding: 8px 18px;
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 2px 3px 0 var(--paper-shadow);
  transform: rotate(-0.8deg);
  animation: drop-in 0.3s var(--ease-out-back) both;
}
.away-bubble b { font-family: var(--marker-font); }

.score-line.away-line { opacity: 0.55; }
.score-line .away-tag { font-size: 0.8rem; color: var(--marker-red); }

/* ==========================================================================
   Toast
   ========================================================================== */
.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) rotate(-1deg);
  background: var(--ink);
  color: var(--paper);
  font-size: 1.05rem;
  padding: 12px 22px;
  border-radius: var(--wobble-2);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.3);
  z-index: 50;
  max-width: 90vw;
  text-align: center;
  animation: slide-up 0.3s var(--ease-out-back) both;
}

/* ==========================================================================
   Party browser — a pinboard of tables you could sit at.
   ========================================================================== */
.you-tag {
  align-self: flex-start;
  font-size: 0.95rem;
  color: var(--paper);
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.35);
}
.you-tag b { font-family: var(--marker-font); letter-spacing: 0.3px; }

.link-btn {
  background: none;
  border: none;
  font-family: var(--hand-font);
  font-size: 0.9rem;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  padding: 2px 4px;
  opacity: 0.8;
}
.link-btn:hover { opacity: 1; }

.board-paper {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 14px 14px;
}

.board-head { text-align: center; }
.board-head .section-title { margin-bottom: 2px; }

/* The list scrolls; the header and the footer stay put. */
.party-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: min(46vh, 380px);
  overflow-y: auto;
  padding: 4px 2px;
  border-top: 2px dashed rgba(43, 43, 43, 0.25);
  border-bottom: 2px dashed rgba(43, 43, 43, 0.25);
}

.party-card {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  text-align: left;
  font-family: var(--hand-font);
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 14px 9px 15px 8px / 9px 15px 8px 14px;
  box-shadow: 2px 2px 0 var(--paper-shadow);
  cursor: pointer;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.party-card:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--paper-shadow); }
.party-card:active:not(:disabled) { transform: translate(1px, 1px); box-shadow: 1px 1px 0 var(--paper-shadow); }
.party-card:disabled { opacity: 0.55; cursor: not-allowed; }

.party-face { flex-shrink: 0; width: 42px; height: 42px; }
.party-face svg { width: 100%; height: 100%; display: block; }

.party-lines { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.party-name {
  font-family: var(--marker-font);
  font-size: 1.05rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.party-sub { font-size: 0.85rem; color: var(--pencil); }

.party-status {
  flex-shrink: 0;
  font-size: 0.78rem;
  padding: 3px 9px;
  border: 2px solid var(--ink);
  border-radius: 10px;
  background: var(--marker-green);
  color: var(--paper);
}
.party-status.busy { background: var(--marker-gold); color: var(--ink); }
.party-status.full { background: var(--pencil); }

.party-empty {
  text-align: center;
  color: var(--pencil);
  padding: 26px 10px;
  line-height: 1.5;
}

.board-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.board-legend { font-size: 0.85rem; color: var(--pencil); }

.marker-btn.small { font-size: 0.85rem; padding: 6px 12px; }

/* A private party is listed like any other; the padlock is the only tell. */
.party-lock { margin-right: 5px; }

/* The code prompt, shared with the new-party form's field styling. */
#join-code {
  width: 100%;
  padding: 8px 10px;
  margin-bottom: 4px;
  font-family: var(--marker-font);
  font-size: 1.4rem;
  letter-spacing: 6px;
  text-align: center;
  text-transform: uppercase;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 2px dashed var(--ink);
}
#join-code::placeholder { opacity: 0.35; }
#join-code:focus { outline: none; border-bottom-style: solid; }

/* The one blue thing on the page, because it's the one thing to press. */
.create-btn {
  margin-left: auto;
  background: var(--marker-blue);
  color: var(--paper);
  border-color: var(--ink);
  letter-spacing: 0.5px;
}

/* ---- new party ---- */
.choice-row { display: flex; gap: 10px; margin: 6px 0 4px; }
.choice-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px;
  text-align: left;
  font-family: var(--hand-font);
  color: var(--ink);
  background: var(--paper);
  border: 2px dashed var(--ink);
  border-radius: 12px 8px 13px 7px / 8px 13px 7px 12px;
  cursor: pointer;
}
.choice-btn.picked {
  border-style: solid;
  background: rgba(59, 107, 217, 0.14);
  box-shadow: 2px 2px 0 var(--paper-shadow);
}
.choice-title { font-family: var(--marker-font); font-size: 0.98rem; }
.choice-note { font-size: 0.8rem; color: var(--pencil); line-height: 1.3; }

.code-choice { display: flex; flex-direction: column; gap: 4px; margin-bottom: 6px; }
.code-choice input {
  padding: 7px 9px;
  font-family: var(--marker-font);
  font-size: 1rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 2px dashed var(--ink);
}
.code-choice input::placeholder {
  font-family: var(--hand-font);
  letter-spacing: 0;
  text-transform: none;
  font-size: 0.85rem;
}
.code-choice input:focus { outline: none; border-bottom-style: solid; }

/* ---- invite strip in the lobby ---- */
.invite-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  color: var(--paper);
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.35);
}
.invite-code {
  font-family: var(--marker-font);
  font-size: 1.25rem;
  letter-spacing: 4px;
  padding: 4px 12px;
  color: var(--ink);
  background: var(--marker-gold);
  border: 2px solid var(--ink);
  border-radius: 10px 7px 11px 6px / 7px 11px 6px 10px;
  text-shadow: none;
}

@media (max-width: 480px) {
  .board-foot { flex-direction: column; align-items: stretch; }
  .create-btn { margin-left: 0; width: 100%; }
  .party-list { max-height: 42vh; }
}

/* ==========================================================================
   What next? — three cards, ten seconds, and a slot machine for a tie.
   ========================================================================== */
.choice-games {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.choice-game {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  text-align: left;
  font-family: var(--hand-font);
  color: var(--ink);
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 16px 9px 17px 8px / 9px 17px 8px 16px;
  box-shadow: 3px 3px 0 var(--paper-shadow);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.choice-game:hover { transform: translate(-1px, -1px); box-shadow: 5px 5px 0 var(--paper-shadow); }
.choice-game.picked { background: rgba(232, 184, 48, 0.28); }
.choice-game.picked::after {
  content: "your pick";
  position: absolute;
  right: 10px;
  bottom: 4px;
  font-size: 0.7rem;
  color: var(--pencil);
}

.choice-lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.choice-name { font-family: var(--marker-font); font-size: 1.1rem; line-height: 1.1; }
.choice-blurb {
  font-size: 0.82rem;
  color: var(--pencil);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.choice-tally {
  flex-shrink: 0;
  min-width: 46px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--marker-font);
  font-size: 1.5rem;
  color: var(--paper);
  background: var(--pencil);
  border: 2px solid var(--ink);
  border-radius: 50% 45% 55% 48% / 55% 50% 48% 45%;
}
.choice-tally.has-votes { background: var(--marker-green); }

/* ---- the slot machine ---- */
.choice-games.spinning .choice-game { opacity: 0.4; transform: none; box-shadow: 2px 2px 0 var(--paper-shadow); }
.choice-games.spinning .choice-game.out { opacity: 0.12; }
.choice-games.spinning .choice-game.lit {
  opacity: 1;
  transform: scale(1.03);
  background: var(--marker-gold);
  box-shadow: 5px 5px 0 var(--ink);
}
.choice-games.settled .choice-game.lit {
  animation: stamp-in 0.45s var(--ease-out-back) both;
  background: var(--marker-green);
  color: var(--paper);
}
.choice-games.settled .choice-game.lit .choice-blurb { color: rgba(253, 248, 232, 0.85); }

/* ==========================================================================
   The colour palette — a big sheet of squares, not a gradient to hunt in.
   ========================================================================== */
/*
 * Never over the drawing.
 *
 * Narrow screens get it directly beneath the paper, which is empty space on a
 * drawing round; wide ones get it parked alongside, clear of everything. It
 * lands square either way — `pop-in` settles at a jaunty 5deg, which is right
 * for a sticker and wrong for a grid you have to hit.
 */
.color-panel {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  right: 0;
  z-index: 30;
  padding: 10px 12px 12px;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 14px 10px 15px 9px / 10px 15px 9px 14px;
  box-shadow: 4px 4px 0 var(--paper-shadow);
  animation: pop-in-flat 0.16s var(--ease-out-back) both;
}

/* Room either side of the 480px column — put it there and leave the page be. */
@media (min-width: 1150px) {
  .color-panel {
    top: 0;
    left: calc(100% + 16px);
    right: auto;
    width: 290px;
  }
}

.color-heading {
  font-family: var(--marker-font);
  font-size: 0.72rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--pencil);
  margin-bottom: 5px;
}
.color-heading + .color-grid { margin-bottom: 8px; }

.color-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 5px;
}

.color-chip {
  aspect-ratio: 1;
  min-height: 0;
  padding: 0;
  border: 2px solid var(--ink);
  border-radius: 6px 4px 7px 3px / 4px 7px 3px 6px;
  cursor: pointer;
  transition: transform 0.08s ease;
}
.color-chip:hover { transform: scale(1.15); }
.color-chip.picked { box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--ink); }

.color-empty { grid-column: 1 / -1; font-size: 0.78rem; color: var(--pencil); }

@media (max-width: 480px) {
  .color-grid { grid-template-columns: repeat(8, 1fr); gap: 4px; }
  .color-panel { padding: 8px 9px 10px; }
}

/* ==========================================================================
   Reveal thumbnails — whose drawing was whose.
   ========================================================================== */
.result-art {
  flex-shrink: 0;
  width: 58px;
  height: 58px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 8px 5px 9px 4px / 5px 9px 4px 8px;
  box-shadow: 2px 2px 0 var(--paper-shadow);
}
.result-with-art { display: flex; align-items: center; gap: 10px; }

/* ==========================================================================
   Mute — a scrap of tape in the far corner, opposite the chat button.
   ========================================================================== */
.sfx-toggle {
  position: fixed;
  left: 14px;
  bottom: 14px;
  z-index: 60;
  width: 44px;
  height: 44px;
  font-size: 1.15rem;
  line-height: 1;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 48% 55% 45% 52% / 52% 45% 55% 48%;
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  opacity: 0.75;
  transition: transform 0.1s ease, box-shadow 0.1s ease, opacity 0.15s ease;
}
.sfx-toggle:hover { opacity: 1; }
.sfx-toggle:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }

/* Struck through with a pencil line, the way you'd cross something out. */
.sfx-toggle.muted { opacity: 0.55; }
.sfx-toggle.muted::after {
  content: "";
  position: absolute;
  left: 4px;
  right: 4px;
  top: 50%;
  border-top: 2px solid var(--marker-red);
  transform: rotate(-24deg);
}

@media (max-width: 480px) {
  .sfx-toggle { width: 38px; height: 38px; font-size: 1rem; left: 8px; bottom: 8px; }
}

/* ==========================================================================
   Feedback
   ========================================================================== */
.feedback-toggle {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 60;
  font-family: var(--marker-font);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  padding: 8px 14px;
  background: var(--paper);
  color: var(--ink);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  transform: rotate(1.5deg);
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.feedback-toggle:hover { transform: rotate(0deg) translateY(-1px); }
.feedback-toggle:active { transform: translate(2px, 2px) rotate(0deg); box-shadow: 1px 1px 0 var(--ink); }

.feedback-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(20, 14, 6, 0.55);
}

.feedback-paper {
  position: relative;
  max-width: 420px;
  width: 100%;
  transform: rotate(-0.6deg);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.feedback-close {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 32px;
  height: 32px;
  font-size: 1.2rem;
  line-height: 1;
  color: var(--paper);
  background: var(--ink);
  border: 2px solid var(--paper);
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 2px 2px 0 var(--paper-shadow);
}

.feedback-prompt {
  font-size: 1.05rem;
  line-height: 1.4;
  padding-right: 18px;
}

.feedback-textarea {
  width: 100%;
  min-height: 140px;
  resize: vertical;
  font-family: var(--hand-font);
  font-size: 1.05rem;
  padding: 10px 12px;
  background: #fffdf5;
  border: 2px solid var(--ink);
  border-radius: 6px;
  color: var(--ink);
}
.feedback-textarea:focus { outline: 2px dashed var(--marker-blue); outline-offset: 2px; }

.feedback-submit {
  align-self: center;
  background: var(--marker-green);
}
.feedback-submit:disabled { opacity: 0.6; cursor: not-allowed; }

@media (max-width: 480px) {
  .feedback-toggle { font-size: 0.75rem; padding: 7px 11px; top: 8px; right: 8px; }
}

/* ==========================================================================
   Version stamp — pencilled in beside the mute button.
   ========================================================================== */
.version-tag {
  position: fixed;
  left: 66px;
  bottom: 14px;
  /* Matching the mute button's height sits the text level with it without any
     magic numbers, and keeps them level if either one is ever resized. */
  height: 44px;
  display: flex;
  align-items: center;
  z-index: 60;
  font-size: 0.75rem;
  color: var(--pencil);
  pointer-events: none; /* never in the way of a tap */
  user-select: none;
}

@media (max-width: 480px) {
  .version-tag { left: 52px; bottom: 8px; height: 38px; font-size: 0.7rem; }
}

/* ==========================================================================
   Chat — a taped-up notepad. Slides in on phones, docked open on desktops.
   ========================================================================== */
.chat-toggle {
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 60;
  width: 58px;
  height: 58px;
  font-size: 1.6rem;
  line-height: 1;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 50% 45% 55% 48% / 55% 50% 48% 45%;
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.chat-toggle:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }

.chat-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 24px;
  padding: 2px 5px;
  font-family: var(--marker-font);
  font-size: 0.8rem;
  color: var(--paper);
  background: var(--marker-red);
  border: 2px solid var(--ink);
  border-radius: 12px;
  animation: pop-in 0.35s var(--ease-out-back) both;
}

.chat-panel {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 70;
  width: min(330px, 88vw);
  height: 100%;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  background-image:
    repeating-linear-gradient(0deg,
      transparent 0px, transparent 27px,
      rgba(100, 140, 200, 0.18) 27px, rgba(100, 140, 200, 0.18) 28px);
  border-left: 3px solid var(--ink);
  box-shadow: -4px 0 0 var(--paper-shadow);
  transform: translateX(0);
  transition: transform 0.28s var(--ease-out-back);
}
/* `.hidden` is display:none everywhere else; chat slides instead. */
.chat-panel.hidden { display: flex !important; transform: translateX(105%); }

.chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 14px 10px;
  border-bottom: 2px dashed var(--ink);
  background: var(--marker-blue);
}
.chat-title { font-family: var(--marker-font); font-size: 1.3rem; color: var(--paper); }
.chat-close {
  font-size: 1.8rem;
  line-height: 1;
  color: var(--paper);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0 4px;
}

/* who's here, with the kick controls */
.chat-players {
  padding: 10px 12px;
  border-bottom: 2px dashed var(--ink);
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 34vh;
  overflow-y: auto;
}
.chat-players:empty { display: none; }

.chat-player {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 1rem;
}
.chat-player .pname { flex: 1; }
.chat-player.is-away .pname { opacity: 0.55; }
.chat-player .crown { font-size: 0.75rem; }

.kick-btn {
  font-family: var(--hand-font);
  font-size: 0.85rem;
  color: var(--ink);
  background: transparent;
  border: 1.5px dashed var(--marker-red);
  border-radius: 10px;
  padding: 2px 9px;
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
}
.kick-btn:hover { background: rgba(217, 72, 59, 0.12); }
.kick-btn.voted {
  background: var(--marker-red);
  border-style: solid;
  color: var(--paper);
}

.chat-log {
  flex: 1;
  overflow-y: auto;
  padding: 12px 12px 4px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.chat-msg { animation: drop-in 0.25s ease-out both; word-break: break-word; }
.chat-msg .who { font-family: var(--marker-font); font-size: 0.95rem; }
.chat-msg .said { font-size: 1.05rem; }
.chat-msg.mine .said { color: var(--ink); }
.chat-msg.system {
  font-size: 0.9rem;
  color: var(--pencil);
  font-style: italic;
  text-align: center;
}
.chat-empty { color: var(--pencil); font-size: 0.95rem; text-align: center; margin-top: 12px; }

.chat-form {
  display: flex;
  gap: 8px;
  padding: 10px 12px 14px;
  border-top: 2px dashed var(--ink);
  align-items: center;
}
.chat-form input[type="text"] {
  flex: 1;
  font-size: 1.05rem;
  text-align: left;
  margin-bottom: 0;
  border-bottom-width: 2px;
}
.chat-send {
  font-family: var(--marker-font);
  font-size: 1rem;
  color: var(--paper);
  background: var(--marker-green);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 2px 2px 0 var(--ink);
  padding: 8px 14px;
  cursor: pointer;
  flex-shrink: 0;
}
.chat-send:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--ink); }

/*
 * Roomy screens: the chat starts docked open beside the board. Hitting the
 * hide button collapses it away and brings the floating button back, exactly
 * like on a phone.
 */
@media (min-width: 1024px) {
  .cardboard.chat-docked { padding-right: 350px; }
  .chat-panel.docked { transform: translateX(0); }
  .chat-panel.docked.hidden { transform: translateX(105%); }
  .chat-toggle.docked.chat-open { display: none; }
}

/* ==========================================================================
   Leaderboard — a scrap of paper taped to the corner of the table
   ========================================================================== */
.leaderboard {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 45;
  width: 168px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 8px 12px 9px 11px;
  box-shadow: 3px 3px 0 var(--paper-shadow);
  transform: rotate(-1.2deg);
  overflow: hidden;
}

.leaderboard-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 6px 10px;
  background: var(--marker-gold);
  border: none;
  border-bottom: 2px dashed var(--ink);
  cursor: pointer;
  font-family: var(--marker-font);
  font-size: 0.9rem;
  color: var(--ink);
}
.leaderboard-toggle:active { transform: translateY(1px); }
.lb-caret { font-size: 0.7rem; }

.leaderboard-body { padding: 4px 0; max-height: 45vh; overflow-y: auto; }

.lb-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: 3px 10px;
  font-size: 0.9rem;
  line-height: 1.3;
}
.lb-row + .lb-row { border-top: 1px dashed rgba(43, 43, 43, 0.18); }
.lb-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-pts { font-family: var(--marker-font); flex-shrink: 0; }
.lb-row.me .lb-name { font-weight: bold; color: var(--marker-blue); }
.lb-row.lead .lb-pts { color: var(--marker-green); }
.lb-row.away { opacity: 0.5; }

/* Out of the way of the drawing tools on a small screen. */
@media (max-width: 480px) {
  .leaderboard { width: 132px; top: 6px; left: 6px; }
  .leaderboard-toggle { font-size: 0.8rem; padding: 5px 8px; }
  .lb-row { font-size: 0.8rem; }
}

/* ==========================================================================
   Evolving prompt

   Every box for the round exists from the first second — the unrevealed ones
   just sit there as dots. That's deliberate: if boxes appeared one at a time
   the row would re-centre on each twist and shove the canvas down the page,
   which is exactly the thing that made this feel janky.
   ========================================================================== */
.prompt-lines {
  width: 100%;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
  /* Reserve the tallest state so the "current" box growing can't nudge
     anything below it. */
  min-height: 58px;
}

.prompt-line {
  font-family: var(--marker-font);
  font-size: 0.95rem;
  line-height: 1.15;
  text-align: center;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 12px 16px 13px 15px;
  padding: 8px 10px;
  min-width: 0;
  flex: 0 1 auto;
  /* Transitioned rather than re-animated: these boxes are updated in place,
     so a twist eases into the highlight instead of the whole row flashing. */
  transition: color 0.25s ease, border-color 0.25s ease, transform 0.25s var(--ease-out-back);
}

/* Not revealed yet — present, but obviously empty. The min-width stops an
   empty box collapsing to nothing and keeps the row roughly the shape it will
   end up as. */
.prompt-line.pending {
  color: var(--pencil);
  border-color: rgba(43, 43, 43, 0.35);
  border-style: dashed;
  background: rgba(253, 248, 232, 0.6);
  letter-spacing: 3px;
  min-width: 5em;
}

/* The twist that's live right now. */
.prompt-line.current {
  color: var(--marker-green);
  border-color: var(--marker-green);
  border-width: 3px;
  transform: scale(1.1);
  box-shadow: 2px 2px 0 var(--paper-shadow);
}

@media (max-width: 520px) {
  .prompt-lines { gap: 5px; min-height: 52px; }
  .prompt-line { font-size: 0.72rem; padding: 6px 6px; border-radius: 9px 12px 10px 11px; }
}

/* ==========================================================================
   Stage clock — how long until the prompt twists again. Hangs off the top
   corner of the drawing paper, deliberately outside the canvas.
   ========================================================================== */
.draw-wrap { position: relative; width: 100%; }

.stage-clock {
  position: absolute;
  top: -18px;
  right: -8px;
  z-index: 3;
  min-width: 46px;
  padding: 4px 10px;
  font-family: var(--marker-font);
  font-size: 1.3rem;
  text-align: center;
  color: var(--paper);
  background: var(--ink);
  border: 2px solid var(--paper);
  border-radius: 50%;
  box-shadow: 2px 2px 0 var(--paper-shadow);
  transform: rotate(4deg);
}
.stage-clock.hurry {
  background: var(--marker-red);
  animation: shake 0.4s infinite;
}

/* ==========================================================================
   Drawing
   ========================================================================== */
.draw-paper { padding: 12px; transform: rotate(-0.4deg); }

/* Canvas and the brush slider side by side; the slider column stretches to
   match the canvas. */
.draw-stage { display: flex; align-items: stretch; gap: 8px; }

/*
 * `width: 100%` is load-bearing and must stay on the shared class. The replay
 * canvas uses .doodle-canvas too but sits outside .draw-stage, so if its width
 * comes from anywhere other than CSS it falls back to its own width attribute
 * — which fitCanvas() then writes to, on every animation frame, and the thing
 * grows 25% a frame until the tab dies. Flex sizing is scoped below.
 */
.doodle-canvas {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  background: #fffdf5;
  border: 2px solid var(--ink);
  border-radius: 4px;
  /* the browser must not steal the drag for scrolling or pinch-zoom */
  touch-action: none;
  cursor: crosshair;
}
.doodle-canvas.replay { cursor: default; }
.doodle-canvas.filling { cursor: cell; }

/* Only the drawing canvas shares its row with the slider. */
.draw-stage > .doodle-canvas { flex: 1 1 auto; min-width: 0; width: auto; }

.draw-tools { position: relative; display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }

.draw-palette { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }

.swatch {
  width: 30px;
  height: 30px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
  box-shadow: 1px 1px 0 var(--paper-shadow);
  transition: transform 0.12s ease;
}
.swatch.picked { transform: scale(1.25); box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--ink); }

/* The one on the end opens the big sheet. It wears whatever colour was last
   taken from there, so it doubles as "the colour I'm mixing with". */
.swatch-wheel { position: relative; }
.swatch-wheel::after {
  content: "";
  position: absolute;
  right: -1px;
  bottom: -1px;
  border: 5px solid transparent;
  border-right-color: var(--ink);
  border-bottom-color: var(--ink);
}

.draw-row { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }

.draw-brush-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  flex: 0 0 auto;
  transition: opacity 0.15s ease;
}
/* Width means nothing to a bucket — fade it rather than removing it, so the
   toolbar doesn't jump about every time the tool changes. */
.draw-brush-row.dimmed { opacity: 0.35; pointer-events: none; }

.tool-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  padding: 6px 9px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  cursor: pointer;
  box-shadow: 2px 2px 0 var(--paper-shadow);
  transition: transform 0.12s ease;
}
.tool-btn.picked {
  background: var(--marker-gold);
  transform: scale(1.1);
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--ink);
}
.tool-btn:active { transform: translate(2px, 2px); box-shadow: none; }

.tool-btn svg {
  width: 22px;
  height: 22px;
  display: block;
  fill: none;
  stroke: var(--ink);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* The drop coming off the bucket reads better solid. */
.tool-btn svg .drip { fill: var(--ink); stroke: none; }

/* Upright, running the height of the canvas. `writing-mode` is the modern way
   to turn a range vertical; the -webkit rule keeps older iOS Safari working. */
.draw-slider {
  flex: 1 1 auto;
  width: 26px;
  min-height: 90px;
  writing-mode: vertical-lr;
  direction: rtl;
  -webkit-appearance: slider-vertical;
  accent-color: var(--marker-red);
}

.draw-width-dot {
  display: inline-block;
  border-radius: 50%;
  background: var(--ink);
  flex-shrink: 0;
  transition: width 0.1s ease, height 0.1s ease;
}

.draw-undo {
  font-family: var(--hand-font);
  font-size: 0.95rem;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  padding: 4px 12px;
  cursor: pointer;
  box-shadow: 2px 2px 0 var(--paper-shadow);
}
.draw-undo:active { transform: translate(2px, 2px); box-shadow: none; }

/* ==========================================================================
   Showcase voting
   ========================================================================== */
.vote-row {
  display: flex;
  justify-content: center;
  gap: 12px;
  width: 100%;
  animation: pop-in-flat 0.35s var(--ease-out-back) both;
}

.vote-btn {
  flex: 1;
  max-width: 130px;
  font-family: var(--marker-font);
  font-size: 1.2rem;
  padding: 12px 8px;
  color: var(--theme-ink, var(--paper));
  background: var(--theme-bg, var(--marker-blue));
  border: 3px solid var(--ink);
  border-radius: var(--wobble);
  box-shadow: 3px 3px 0 var(--paper-shadow);
  cursor: pointer;
  transition: transform 0.12s ease;
}
.vote-btn:active { transform: translate(2px, 2px); box-shadow: none; }
.vote-btn.picked { transform: scale(1.06); outline: 3px dashed var(--ink); outline-offset: 3px; }

/* ==========================================================================
   Sketchy Business — the line-up, the ring, the accusation
   ========================================================================== */
.gallery-spotlight { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 8px; }

.gallery-spotlight-name {
  font-family: var(--marker-font);
  font-size: 1.4rem;
  color: var(--ink);
}

/*
 * Players sit evenly around a ring — a triangle at three, a square at four,
 * and so on. Positions come from the client as percentages, so the shape falls
 * out of however many people are playing. The middle is empty by design: the
 * big canvas has done its job by now.
 */
.gallery-ring {
  position: relative;
  width: 100%;
  max-width: 460px;
  aspect-ratio: 1 / 1;
  margin: 0 auto;
}

.gallery-seats { position: absolute; inset: 0; }

/* The vote clock, in the hole the drawings left behind. */
.ring-timer {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  min-width: 82px;
  padding: 10px 6px;
  font-family: var(--marker-font);
  font-size: 2.6rem;
  line-height: 1;
  text-align: center;
  color: var(--ink);
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 50%;
  box-shadow: 3px 3px 0 var(--paper-shadow);
  pointer-events: none;
}
.ring-timer.hurry {
  color: var(--paper);
  background: var(--marker-red);
  animation: shake 0.4s infinite;
}

.gallery-warning {
  font-family: var(--marker-font);
  font-size: 0.95rem;
  color: var(--marker-red);
  margin-top: 4px;
}

@media (max-width: 480px) {
  .ring-timer { min-width: 62px; font-size: 2rem; padding: 8px 5px; }
}

.seat {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 27%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 5px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 2px 2px 0 var(--paper-shadow);
  cursor: pointer;
  font-family: var(--hand-font);
  transition: transform 0.15s var(--ease-out-back), box-shadow 0.15s ease,
              border-color 0.15s ease, opacity 0.2s ease;
}

.seat-canvas {
  width: 100%;
  aspect-ratio: 1 / 1;
  background: #fffdf5;
  border: 1px solid rgba(43, 43, 43, 0.4);
  border-radius: 3px;
}

.seat-name {
  font-size: 0.8rem;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Vote count, floating above the head. */
.seat-count {
  position: absolute;
  top: -12px;
  right: -10px;
  min-width: 24px;
  padding: 1px 6px;
  font-family: var(--marker-font);
  font-size: 1rem;
  color: var(--pencil);
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 50%;
  transition: transform 0.15s var(--ease-out-back), color 0.15s ease;
}
.seat-count.has-votes { color: var(--paper); background: var(--marker-red); transform: scale(1.15); }

/* "Sketchy?" / "You sure?" */
.seat-bubble {
  position: absolute;
  top: -34px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--marker-font);
  font-size: 0.85rem;
  color: var(--ink);
  background: var(--marker-gold);
  padding: 2px 8px;
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  pointer-events: none;
  z-index: 2;
}
.seat-bubble:empty { display: none; }

/* Mouse-over on desktop: a nudge, nothing committal. */
.seat.hovering { transform: translate(-50%, -50%) rotate(-2deg) scale(1.04); box-shadow: 4px 5px 0 rgba(0,0,0,0.25); }

/* Pressed once — about to accuse. */
.seat.armed {
  border-color: var(--marker-red);
  animation: seat-jitter 0.28s infinite;
}

/* Locked in. */
.seat.locked {
  border: 3px dashed var(--marker-red);
  transform: translate(-50%, -50%) scale(1.06);
  cursor: default;
}

/* Knocked out of a runoff. */
.seat.out { opacity: 0.35; filter: grayscale(1); cursor: default; }

@keyframes seat-jitter {
  0%, 100% { transform: translate(-50%, -50%) rotate(-2deg); }
  50%      { transform: translate(-50%, -50%) rotate(2deg); }
}

/* ---- the reveal ---- */
.gallery-payoff { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 14px; }

.payoff-tease {
  font-family: var(--marker-font);
  font-size: 2rem;
  text-align: center;
  color: var(--paper);
  animation: pop-in-flat 0.4s var(--ease-out-back) both;
}

.payoff-card {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  animation: stamp-in 0.55s var(--ease-out-back) both;
}
.payoff-paper { width: 100%; max-width: 300px; }

.payoff-prompts {
  font-size: 1rem;
  text-align: center;
  color: var(--paper);
  line-height: 1.5;
}

@media (max-width: 480px) {
  .seat { width: 30%; padding: 3px; }
  .seat-name { font-size: 0.7rem; }
  .seat-count { font-size: 0.85rem; min-width: 20px; top: -10px; right: -8px; }
  .seat-bubble { font-size: 0.72rem; top: -28px; }
  .payoff-tease { font-size: 1.5rem; }
}

/* ==========================================================================
   SCRAP FIGHT
   Naming, the bracket, the tale of the tape, and the arena.
   ========================================================================== */

/* ---- name your fighter ---- */
.naming-mine {
  display: flex;
  justify-content: center;
  margin: 4px 0 10px;
}

.naming-canvas {
  width: 46vw;
  max-width: 200px;
  height: 130px;
  /* The doodle is a cut-out with nothing behind it, so it sits on the
     cardboard rather than on a sheet of paper — it IS the sprite. */
  filter: drop-shadow(2px 3px 0 var(--paper-shadow));
}

#fighter-name { margin-bottom: 10px; }

.style-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.style-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 4px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 2px 3px 0 var(--paper-shadow);
  font-family: var(--hand-font);
  color: var(--ink);
  cursor: pointer;
  transition: transform 0.12s var(--ease-out-back), box-shadow 0.12s;
}

.style-btn:active { transform: translate(2px, 3px); box-shadow: none; }

.style-btn.picked {
  background: var(--theme-bg, var(--marker-red));
  color: var(--theme-ink, var(--paper));
  transform: rotate(-1.5deg) scale(1.04);
}

.style-icon { font-size: 1.5rem; line-height: 1.1; }
.style-name { font-family: var(--marker-font); font-size: 0.85rem; }
.style-blurb { font-size: 0.7rem; opacity: 0.75; text-align: center; line-height: 1.15; }
.style-btn.picked .style-blurb { opacity: 0.95; }

/* ==========================================================================
   Scrap Fight's wide screens
   The rest of the game is a 480px column of paper scraps, which is right for a
   phone held upright. A bracket and a fighting arena are landscape by nature —
   squeezed into that column they end up postage stamps. These two get the whole
   table.
   ========================================================================== */
#screen-bracket,
#screen-fight { max-width: 760px; }

/* ---- the bracket: a tournament tree, drawn on the table ---- */
.bracket-viewport {
  width: 100%;
  margin: 0 auto;
  /* No padding: the height is set in JS and box-sizing is border-box, so any
     padding here comes straight out of the visible area and clips the bottom
     row of the tree. The breathing room is built into the layout instead.

     No scrolling either. The tree is always fitted to this box, so there is
     never anything outside it — and a bracket you have to drag sideways to
     read has stopped doing the one job a bracket has. */
  overflow: hidden;
}

.bracket-tree {
  position: relative;
  transform-origin: top left;
}

/* The connecting lines, under the scraps so a box always sits on top of the
   line that reaches it. */
.bracket-wires {
  position: absolute;
  inset: 0;
  overflow: visible;
  pointer-events: none;
}

/* The marker layer. Last in the DOM and positioned, so it paints over the
   cards — which is where a line crossing somebody out belongs. */
.bracket-marks { z-index: 2; }

.bracket-wires .wire {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
}

/* The red marker through a loser's name: drawn on rather than simply there. */
.bracket-wires .strike {
  fill: none;
  stroke: var(--marker-red);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: sharpie 0.45s var(--ease-out-back) forwards;
}

@keyframes sharpie {
  to { stroke-dashoffset: 0; }
}

/* Crossings-out from earlier rounds: already there, not drawn on again. */
.bracket-wires .strike.done {
  stroke-dasharray: none;
  stroke-dashoffset: 0;
  animation: none;
  opacity: 0.7;
}

/* ---- a fighter's card: a polaroid of their doodle, name written under it ---- */
.tree-seat {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 5px 5px 3px;
  background: var(--paper);
  border: 2.5px solid var(--ink);
  box-shadow: 2px 3px 0 var(--paper-shadow);
  overflow: hidden;
  /* --tilt is set per card, so every polaroid sits a degree or so off square. */
  transform: rotate(var(--tilt, 0deg));
  transition: opacity 0.25s, filter 0.25s;
}

/* The photo: square, and given every pixel the caption doesn't need. */
.tree-chip {
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
}

.tree-name {
  font-family: var(--marker-font);
  font-size: 0.7rem;
  line-height: 1.1;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tree-player {
  font-family: var(--hand-font);
  font-size: 0.62rem;
  line-height: 1.05;
  color: var(--pencil);
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tree-style { font-size: 0.62rem; }

/* ---- a slot nobody has earned yet ---- */
.tree-seat.pending {
  justify-content: center;
  gap: 2px;
  background: transparent;
  border-style: dashed;
  border-width: 2px;
  border-color: rgba(107, 107, 107, 0.7);
  box-shadow: none;
}

.tree-seat.pending .tree-frame {
  width: 54%;
  aspect-ratio: 1;
  margin-bottom: 4px;
  border: 2px dashed rgba(107, 107, 107, 0.5);
  border-radius: 8px 3px 7px 4px / 4px 7px 3px 8px;
}

.tree-seat.pending .tree-waiting {
  font-family: var(--hand-font);
  font-size: 0.58rem;
  font-style: italic;
  color: var(--pencil);
  line-height: 1;
}

.tree-seat.pending .tree-name {
  font-family: var(--marker-font);
  font-size: 0.68rem;
  color: var(--pencil);
}

/* ---- the play-in cards, smaller and off to the side ---- */
.tree-seat.is-playin { padding: 4px 4px 2px; }
.tree-seat.is-playin .tree-name { font-size: 0.6rem; }
.tree-seat.is-playin .tree-player { display: none; }

/* ---- won, lost ---- */
.tree-seat.through {
  border-color: var(--marker-green);
  box-shadow: 2px 3px 0 rgba(63, 158, 77, 0.35);
}
.tree-seat.through .tree-name { color: var(--marker-green); }

.tree-seat.beaten { opacity: 0.45; filter: saturate(0.35); }

/* Being knocked out beats having been promoted. Somebody who won a round and
   then lost the next one is out, and leaving them green would say otherwise. */
.tree-seat.beaten.through {
  border-color: var(--ink);
  box-shadow: 2px 3px 0 var(--paper-shadow);
}
.tree-seat.beaten.through .tree-name { color: var(--ink); }

/* Hidden while its winner is still walking the line towards it. */
.tree-seat.incoming { opacity: 0; }
.tree-seat.departed { opacity: 0; }

.tree-seat.landed {
  animation: seat-land 0.45s var(--ease-out-back) both;
}

/* Through to a round that has no card of its own — the final. Nothing to move
   to, so it takes its bow where it stands. */
.tree-seat.promoted {
  animation: seat-promote 0.5s var(--ease-out-back) both;
}

@keyframes seat-promote {
  0%   { transform: rotate(var(--tilt, 0deg)) scale(1); }
  45%  { transform: rotate(var(--tilt, 0deg)) scale(1.16); }
  100% { transform: rotate(var(--tilt, 0deg)) scale(1); }
}

@keyframes seat-land {
  0%   { transform: rotate(var(--tilt, 0deg)) scale(1.3); }
  60%  { transform: rotate(var(--tilt, 0deg)) scale(0.94); }
  100% { transform: rotate(var(--tilt, 0deg)) scale(1); }
}

/* ---- the champion's polaroid: the biggest thing on the table ---- */
.tree-champ {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 12px 8px 8px;
  background: var(--paper);
  border: 3.5px solid var(--ink);
  border-radius: 20px 8px 18px 9px / 9px 18px 8px 20px;
  box-shadow: 4px 5px 0 var(--paper-shadow);
  transform: rotate(-1deg);
}

/* A strip of masking tape holding it to the table, like every other card. */
.champ-tape {
  position: absolute;
  top: -12px;
  left: 50%;
  width: 66px;
  height: 22px;
  transform: translateX(-50%) rotate(-3deg);
  background: var(--tape);
  border-left: 1px dashed rgba(160, 140, 90, 0.4);
  border-right: 1px dashed rgba(160, 140, 90, 0.4);
}

.champ-title {
  font-family: var(--marker-font);
  font-size: 1.05rem;
  letter-spacing: 0.07em;
  color: var(--marker-red);
  line-height: 1;
}

.champ-chip {
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
}

.champ-name {
  font-family: var(--marker-font);
  font-size: 0.92rem;
  line-height: 1.05;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* An empty frame, before anybody has won it. */
.champ-empty {
  display: grid;
  place-items: center;
  width: 78%;
  flex: 1 1 auto;
  min-height: 0;
  border: 3px dashed rgba(107, 107, 107, 0.6);
  border-radius: 14px 5px 12px 6px / 6px 12px 5px 14px;
  font-family: var(--marker-font);
  font-size: 2rem;
  color: rgba(107, 107, 107, 0.7);
}

.tree-champ.crowned {
  background: #fdf0c8;
  border-color: var(--marker-gold);
  box-shadow: 4px 5px 0 rgba(200, 150, 20, 0.4), 0 0 26px 5px rgba(232, 184, 48, 0.45);
}

.tree-champ.arriving { animation: champ-pop 0.55s var(--ease-out-back) both; }

@keyframes champ-pop {
  0%   { transform: rotate(-1deg) scale(0.65); }
  55%  { transform: rotate(2deg) scale(1.12); }
  100% { transform: rotate(-1deg) scale(1); }
}

/* The winner's polaroid, mid-journey up the bracket. */
.bracket-fly {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 5px 5px 3px;
  pointer-events: none;
  background: var(--paper);
  border: 2.5px solid var(--marker-green);
  border-radius: 14px 5px 12px 6px / 6px 12px 5px 14px;
  box-shadow: 3px 4px 0 rgba(63, 158, 77, 0.4);
  overflow: hidden;
}

.bracket-fly .tree-name { color: var(--marker-green); }

/* ---- tale of the tape ---- */
.faceoff-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 6px;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
}

.faceoff-side { opacity: 0; }
.faceoff-side.enter.from-left  { animation: slide-in-left 0.55s var(--ease-out-back) both; }
.faceoff-side.enter.from-right { animation: slide-in-right 0.55s var(--ease-out-back) both; }

@keyframes slide-in-left {
  from { opacity: 0; transform: translateX(-60px) rotate(-6deg); }
  to   { opacity: 1; transform: translateX(0) rotate(-2deg); }
}
@keyframes slide-in-right {
  from { opacity: 0; transform: translateX(60px) rotate(6deg); }
  to   { opacity: 1; transform: translateX(0) rotate(2deg); }
}

.fighter-card {
  padding: 10px 8px 12px;
  text-align: center;
  border-top: 6px solid var(--theme-bg, var(--marker-red));
}

.fighter-art { width: 100%; height: 110px; }
.fighter-name { font-family: var(--marker-font); font-size: 1rem; line-height: 1.1; margin-top: 2px; }
.fighter-player { font-size: 0.72rem; color: var(--pencil); }
.fighter-style { font-size: 0.8rem; margin: 3px 0; }

.fighter-stats {
  display: flex;
  justify-content: center;
  gap: 7px;
  font-size: 0.68rem;
  color: var(--pencil);
}
.fighter-stats b { font-family: var(--marker-font); font-size: 0.85rem; color: var(--ink); }
.fighter-hp { font-family: var(--marker-font); font-size: 0.9rem; margin-top: 3px; }

.faceoff-vs {
  font-family: var(--marker-font);
  font-size: 1.6rem;
  color: var(--marker-red);
  text-shadow: 2px 2px 0 var(--paper);
  animation: vs-pop 0.5s 0.35s var(--ease-out-back) both;
}

@keyframes vs-pop {
  from { transform: scale(0) rotate(-30deg); }
  to   { transform: scale(1) rotate(-8deg); }
}

/* ---- the hype meter ---- */
.hype-wrap {
  width: 100%;
  max-width: 700px;
  margin: 0 auto 8px;
}

.hype-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--marker-font);
  font-size: 0.8rem;
  margin-bottom: 2px;
}

.hype-label { letter-spacing: 0.05em; }
.hype-pct { font-size: 0.75rem; color: var(--pencil); }

.hype-track {
  height: 18px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 2px 3px 0 var(--paper-shadow);
}

.hype-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--marker-gold), var(--marker-red));
  /* No transition: the bar is redrawn every frame from a simulation that
     already eases and decays, and a CSS transition on top of that would only
     make it lag behind the crowd it is supposed to be showing. */
}

/* 90% — the room starts to move */
.hype-wrap.hyped .hype-track,
.hype-wrap.maxed .hype-track {
  animation: hype-shake 0.28s infinite;
  box-shadow: 0 0 14px 3px rgba(232, 184, 48, 0.75);
}

.hype-wrap.hyped .hype-label { color: var(--marker-red); }

@keyframes hype-shake {
  0%, 100% { transform: translate(0, 0); }
  25%      { transform: translate(-1.5px, 1px); }
  75%      { transform: translate(1.5px, -1px); }
}

/* 100% — MAX HYPE */
.hype-wrap.maxed { transform: scale(1.04); }

.hype-wrap.maxed .hype-fill {
  background: linear-gradient(90deg, #ff004d, #ff8a00, #ffe600, #14e05a, #00c8ff, #8b4fc9, #ff004d);
  background-size: 300% 100%;
  animation: rainbow-roll 0.9s linear infinite;
}

.hype-wrap.maxed .hype-track {
  animation: hype-shake 0.16s infinite;
  box-shadow: 0 0 22px 6px rgba(255, 90, 40, 0.85);
}

.hype-wrap.maxed .hype-label {
  color: var(--marker-red);
  animation: max-throb 0.4s infinite alternate;
}

@keyframes rainbow-roll {
  from { background-position: 0% 50%; }
  to   { background-position: 300% 50%; }
}

@keyframes max-throb {
  from { transform: scale(1); }
  to   { transform: scale(1.12); }
}

/* ---- the arena ---- */
.arena-box {
  width: 100%;
  max-width: 700px;
  margin: 0 auto;
  /* Squarer than it was: the extra height is what the fighters' names and the
     damage numbers live in, and at 16/10 the names were riding the top edge. */
  aspect-ratio: 3 / 2;
  background: #ffffff;
  border: 3px solid var(--ink);
  border-radius: var(--wobble);
  box-shadow: 3px 4px 0 var(--paper-shadow);
  overflow: hidden;
  transition: box-shadow 0.3s, transform 0.3s;
}

.arena-canvas { display: block; width: 100%; height: 100%; }

.arena-box.hyped { box-shadow: 0 0 20px 5px rgba(232, 184, 48, 0.65); }

.arena-box.maxed {
  box-shadow: 0 0 30px 9px rgba(255, 90, 40, 0.8);
  animation: arena-quake 0.14s infinite;
}

@keyframes arena-quake {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  25%      { transform: translate(-2px, 1.5px) rotate(-0.25deg); }
  75%      { transform: translate(2px, -1.5px) rotate(0.25deg); }
}

/* ---- cheering ---- */
.cheer-row {
  display: flex;
  gap: 10px;
  width: 100%;
  max-width: 700px;
  margin: 12px auto 0;
}

.cheer-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  /* Deliberately big: this is a button people mash while looking at something
     else on the same screen. */
  padding: 14px 6px;
  min-height: 78px;
  background: var(--theme-bg, var(--marker-red));
  color: var(--theme-ink, var(--paper));
  border: 3px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 3px 4px 0 var(--ink);
  font-family: var(--marker-font);
  cursor: pointer;
  user-select: none;
  touch-action: manipulation;
}

.cheer-icon { font-size: 1.4rem; line-height: 1; }

.cheer-name {
  font-size: 0.8rem;
  line-height: 1.1;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cheer-count { font-size: 0.95rem; opacity: 0.9; }

.cheer-btn.thumped { animation: thump 0.16s var(--ease-out-back); }

@keyframes thump {
  0%   { transform: scale(1); }
  45%  { transform: scale(0.93) translate(2px, 3px); }
  100% { transform: scale(1); }
}

/* ---- narrow phones ---- */
@media (max-width: 380px) {
  .fighter-art { height: 82px; }
  .faceoff-vs { font-size: 1.2rem; }
  .cheer-btn { min-height: 66px; padding: 10px 4px; }
  /* The tree is scaled in JS, so it needs nothing here — but the style blurbs
     are the whole point of the picker now, so they stay whatever the width. */
}

/* ==========================================================================
   Memory Sketch
   ========================================================================== */

/*
 * The showcase, side by side.
 *
 * One paper on its own behaves exactly as it always did — the flex row has a
 * single child and it fills the width — so Doodle Evolution and Sketchy
 * Business are untouched by any of this. The second paper only appears for a
 * game that sends a reference to judge against.
 */
.showcase-pair { display: flex; gap: 12px; width: 100%; align-items: flex-start; }
.showcase-pair > .paper { flex: 1 1 0; min-width: 0; }
/* The papers tilt in opposite directions, so a pair reads as two scraps laid
   down rather than one wide panel. */
.showcase-pair > .paper:first-child  { transform: rotate(-0.9deg); }
.showcase-pair > .paper:last-child   { transform: rotate(0.7deg); }
.showcase-pair > .paper:only-child   { transform: rotate(-0.4deg); }

.pair-label {
  font-family: var(--marker-font);
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  text-align: center;
  color: var(--pencil);
  margin-bottom: 6px;
}

/*
 * Two canvases need more room than one. Widened only while a pair is actually
 * up — the class comes off the moment the screen goes back to a single doodle,
 * so nothing else that uses this screen changes size.
 */
#screen-showcase.paired { max-width: 760px; }

/* The drawing you're being asked to remember. Bigger than a thumbnail, because
   five seconds is not long and squinting isn't part of the game. */
#play-sketch { padding: 12px; max-width: min(100%, max(260px, calc(100dvh - 330px))); margin-inline: auto; }

@media (max-width: 560px) {
  /* On a phone, side by side would be two postage stamps. Stack them and let
     the screen scroll — the original above, the attempt below. */
  .showcase-pair { flex-direction: column; align-items: stretch; }
}

/* ==========================================================================
   Guess the Doodle
   ========================================================================== */

/*
 * The play screen is one screen for every game, and this one wants its pieces
 * in an order none of the others do: the word, then the paper, then the box
 * you type your guess into. Reordering with `order` rather than by moving the
 * markup means the drawing kit stays exactly where Doodle Evolution and
 * Sketchy Business expect to find it.
 */
.doodle-mode #doodle-spin,
.doodle-mode #doodle-banner { order: 1; }
.doodle-mode #doodle-watch,
.doodle-mode #play-draw     { order: 2; }
.doodle-mode #play-form     { order: 3; }
.doodle-mode #play-status   { order: 4; }

/* ---- the machine that picks who draws ---- */
.doodle-spin {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 100%;
}

.doodle-names {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

.doodle-name {
  padding: 8px 16px;
  font-family: var(--marker-font);
  font-size: 1.25rem;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--wobble-2);
  box-shadow: 2px 2px 0 var(--paper-shadow);
  transform: rotate(-1deg);
  transition: transform 0.1s ease, background 0.1s ease;
}
.doodle-name:nth-child(even) { transform: rotate(1.4deg); }

.doodle-name.lit {
  background: var(--marker-gold);
  transform: scale(1.14) rotate(0deg);
  box-shadow: 3px 3px 0 var(--paper-shadow);
}
/* Once it has landed, the winner stops flickering and everyone else fades. */
.doodle-names.settled .doodle-name { opacity: 0.35; }
.doodle-names.settled .doodle-name.lit {
  opacity: 1;
  background: var(--marker-green);
  color: var(--paper);
  animation: stamp-in 0.4s var(--ease-out-back) both;
}

/* ---- the read-only paper everybody else watches ---- */
/*
 * Unlike every other canvas in the game, this one has to share the screen with
 * something you use at the same time: the box you type guesses into. A square
 * canvas at the full column width plus the blanks above it and the box below
 * comes to about 900px, so on anything shorter than that you end up scrolling
 * away from the drawing in order to guess at it.
 *
 * So the paper is capped by what's left of the viewport rather than by the
 * column. On a phone held upright there is room and nothing changes; on a
 * short window it gives way, because a slightly smaller drawing you can see
 * while typing beats a big one you can't.
 */
#doodle-watch { padding: 12px; margin-inline: auto; }

/*
 * ...and only while there is a guess box under it. `#play-form` sits earlier
 * in the markup, so this reads as "the box is showing" — which is exactly the
 * drawing step. While the drawer is still choosing there is nothing below the
 * paper to make room for, and squeezing it then just cramps the word cards.
 */
#play-form:not(.hidden) ~ #doodle-watch {
  max-width: min(100%, max(260px, calc(100dvh - 420px)));
}

/* Grey, over the blank page, while the drawer makes their mind up. */
.doodle-veil {
  position: absolute;
  inset: 12px;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 20px;
  font-size: 1.15rem;
  color: var(--pencil);
  text-align: center;
}

/* ---- the three cards ---- */
.doodle-picks {
  position: absolute;
  inset: 12px;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2.5%;
  padding: 4px;
}

.doodle-pick {
  flex: 1 1 0;
  min-width: 0;
  /* Sized to the word, not to the paper behind it: stretching these to fill
     the page left three tall columns with a word floating in the middle of
     each. They're scraps, so they should look torn to fit. */
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  filter: drop-shadow(3px 4px 0 var(--paper-shadow));
  transform: rotate(var(--tilt, 0deg));
  transition: transform 0.14s ease;
}
.doodle-pick:nth-child(1) { --tilt: -3deg; }
.doodle-pick:nth-child(2) { --tilt: 1.2deg; }
.doodle-pick:nth-child(3) { --tilt: 2.6deg; }

.doodle-pick:hover  { transform: rotate(0deg) translateY(-4px) scale(1.03); }
.doodle-pick:active { transform: rotate(0deg) translateY(1px) scale(0.99); }

/* The difficulty straddles the top edge, in its own colour. */
.pick-tag {
  align-self: center;
  position: relative;
  z-index: 2;
  margin-bottom: -7px;
  padding: 3px 12px 4px;
  font-family: var(--marker-font);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--paper);
  background: var(--pick-ink, var(--ink));
  border: 2px solid var(--ink);
  border-radius: 6px 9px 7px 8px;
  transform: rotate(-2deg);
}
.doodle-pick.d1 { --pick-ink: var(--marker-green); }
.doodle-pick.d2 { --pick-ink: var(--marker-orange); }
.doodle-pick.d3 { --pick-ink: var(--marker-red); }

/*
 * A strip torn off a bigger sheet.
 *
 * This was a jagged clip-path once, on the theory that a torn edge should look
 * torn. At this size the teeth came out as a row of neat little spikes — a
 * comb, not a tear — so the whole idea is gone. Slightly uneven corners do the
 * job on their own, and the ruled lines are what actually say "paper".
 */
.pick-sheet {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 128px;
  padding: 26px 12px;
  background: var(--paper);
  background-image: repeating-linear-gradient(
    0deg,
    transparent 0px, transparent 21px,
    rgba(100, 140, 200, 0.16) 21px, rgba(100, 140, 200, 0.16) 22px
  );
  border: 2px solid var(--ink);
  border-radius: 3px 6px 4px 7px;
}

.pick-word {
  font-family: var(--marker-font);
  font-size: 1.15rem;
  line-height: 1.15;
  text-align: center;
  overflow-wrap: anywhere;
  color: var(--ink);
}

.pick-meta {
  font-size: 0.8rem;
  line-height: 1.25;
  text-align: center;
  color: var(--pencil);
}

/* Chosen: it swells and squares up while the other two pop out of existence. */
.doodle-picks.decided .doodle-pick { pointer-events: none; }
.doodle-picks.decided .doodle-pick:not(.chosen) {
  animation: pick-pop 0.3s ease-in both;
}
.doodle-picks.decided .doodle-pick.chosen {
  animation: pick-chosen 0.5s var(--ease-out-back) both;
}

@keyframes pick-pop {
  0%   { transform: scale(1) rotate(var(--tilt, 0deg)); opacity: 1; }
  30%  { transform: scale(1.1) rotate(var(--tilt, 0deg)); opacity: 1; }
  100% { transform: scale(0) rotate(calc(var(--tilt, 0deg) + 26deg)); opacity: 0; }
}

@keyframes pick-chosen {
  0%   { transform: scale(1) rotate(var(--tilt, 0deg)); }
  45%  { transform: scale(1.22) rotate(0deg); }
  100% { transform: scale(1.1) rotate(0deg); }
}

/* ---- "YOU ARE DRAWING: ..." ---- */
.doodle-banner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  animation: drop-in 0.4s var(--ease-out-back) both;
}

.doodle-banner-label {
  font-family: var(--marker-font);
  font-size: 0.9rem;
  letter-spacing: 0.08em;
  color: var(--ink);
  transform: rotate(-1deg);
}

/* The card it landed on, laid on its side and pinned above the paper. */
#doodle-banner-card .doodle-pick {
  flex: 0 0 auto;
  max-height: none;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  cursor: default;
  transform: rotate(-0.8deg);
}
#doodle-banner-card .doodle-pick:hover { transform: rotate(-0.8deg); }
#doodle-banner-card .pick-tag { align-self: center; margin: 0 -14px 0 0; }
#doodle-banner-card .pick-sheet {
  flex-direction: row;
  align-items: baseline;
  gap: 10px;
  min-height: 0;
  /* Kept tight: this sits between the blanks and the paper, and every pixel
     it takes is a pixel of drawing the artist has to scroll to reach. */
  padding: 8px 16px 10px 22px;
}
#doodle-banner-card .pick-word { font-size: 1.35rem; }
#doodle-banner-card .pick-meta { font-size: 0.75rem; }

/*
 * The guess box, on one line.
 *
 * Everywhere else the box is the only thing on screen and can afford to stack
 * its input above its button. Here it lives directly under the drawing and the
 * two are used together — you watch and type at the same time — so the 80-odd
 * pixels a stacked layout costs are 80 pixels of drawing pushed off the top of
 * a short screen.
 */
.doodle-mode #play-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 16px;
}
.doodle-mode #play-input {
  flex: 1 1 160px;
  width: auto;
  min-width: 0;
  margin-bottom: 0;
}
.doodle-mode #play-btn { flex: 0 0 auto; }
/* Its own row, so a "so close!" doesn't shove the button off the end. */
.doodle-mode #play-feedback { flex: 1 0 100%; margin: 0; }

/* ---- word gaps in the letter tiles ----
   A space between words is not a letter waiting to be uncovered, so it gets
   no box — otherwise "hot air balloon" reads as one fourteen-letter word. */
.tile.gap {
  background: none;
  border: none;
  box-shadow: none;
  width: 14px;
}

/* ---- chat, once part of it is behind a door ---- */
.chat-msg.tone-win {
  font-family: var(--marker-font);
  font-size: 1.05rem;
  color: var(--marker-green);
  text-align: center;
  font-style: normal;
}
.chat-msg.tone-team .who { color: var(--marker-green) !important; }
.chat-msg.tone-team .said { color: var(--marker-green); }
.chat-msg.tone-team::before {
  content: "\1F510 ";
  font-size: 0.85rem;
}

.chat-form input:disabled {
  background: rgba(43, 43, 43, 0.06);
  cursor: not-allowed;
}

/* ---- bigger everything on wider screens ---- */
@media (min-width: 600px) {
  body { font-size: 22px; }
  .game-title { font-size: 3rem; }
  .prompt-text { font-size: 2.5rem; }
  .event-name { font-size: 2.6rem; }
  .tile { width: 44px; height: 54px; font-size: 1.7rem; }
}

/* ---- respect reduced-motion preferences ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
