/* ============================================================
   Play — Pong
   Geometry is a 1:1 copy of Figma frames 1328:402 / 1359:24
   (1280×832): fixed px, desktop only, same conventions as
   styles.css. Wide elements centre on the 640px axis; vertical
   positions are exact at 832px tall.
   ============================================================ */

.play-stage {
  position: relative;
  height: 100vh;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.5s ease;
}
.play-stage.revealed { opacity: 1; }

/* ---- entrance: title, court, and record row rise in turn when the
   stage reveals — the case-study chapters' manner ---- */
.play-title { transition: opacity 0.55s ease, translate 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
.record-row {
  transition: opacity 0.55s ease 0.16s,
              translate 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.16s;
}
.play-stage:not(.revealed) :is(.play-title, .board, .record-row) {
  opacity: 0;
  translate: 0 16px;
}

/* ---- the snap scroller: one game per gesture, sliding in HORIZONTALLY —
   the same mechanics as work.css's carousel (vertical wheel is translated
   to pages by js/play-pager.js; horizontal swipes scroll natively). Nav +
   pager stay outside and hold still. Scrollbar hidden per site
   convention. ---- */
.play-scroll {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.play-scroll::-webkit-scrollbar { display: none; }
.play-slide {
  position: relative;
  flex: none;
  width: 100%;
  height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* ---- title (Figma 1395:202 rev 2: plain 24px text again — the capsule
   was removed from the frame; pair centres on the frame axis at top 40) ---- */
.play-title {
  position: absolute;
  top: 40px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: baseline;
  gap: 10px;
  white-space: nowrap;
}
.play-title h1 {
  font-size: 28px;                    /* user's 28px header unification */
  font-weight: 400;
  color: #5e5e5e;
}
.play-title p {
  font-size: 28px;
  color: rgba(0, 0, 0, 0.3);
}

/* ---- the court (Figma 1395:162: 1135×426 @ 72,203 — vertically centred
   in the frame now that the controls card is gone) ---- */
.board {
  position: absolute;
  top: 203px;
  left: 50%;
  margin-left: -567.5px;
  width: 1135px;
  height: 426px;
  background: rgba(233, 233, 233, 0.23);
  border: 2px solid #eeeded;
  border-radius: 31px;
  box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25);
  overflow: hidden;
  transition: opacity 0.55s ease 0.08s,
              translate 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.08s,
              border-color 0.18s ease, box-shadow 0.18s ease;
}
/* the court wakes a touch under the cursor — the site card hover */
.board:hover {
  border-color: rgba(0, 0, 0, 0.1);
  box-shadow: 0 8px 14px rgba(0, 0, 0, 0.08),
              0 1px 2px rgba(0, 0, 0, 0.06);
}

/* inner rail (Figma 1363:140: 1094×378 @ 92,197) — the playfield boundary;
   js/pong.js reads its box, so geometry lives here only */
.board-wall {
  position: absolute;
  top: 22px;
  left: 19px;
  width: 1094px;
  height: 378px;
  border: 1px solid #d9d9d9;
  border-radius: 20px;
  pointer-events: none;
}

/* Paddles and ball (Figma 1395:164: solid #5e5e5e); both are placed with
   transforms from js/pong.js (base at the board's content-box origin). */
.paddle,
.ball {
  position: absolute;
  top: 0;
  left: 0;
  background: #5e5e5e;
  border-radius: 5px;
  will-change: transform;
}
.paddle { width: 21px; height: 81px; }
.ball   {
  width: 21px;
  height: 21px;
  background: var(--orange);          /* the site accent — pops off the court */
}

/* Snake pieces speak the same language: 21px cells (the pong unit), r5,
   segments in the paddle grey, food in the site's orange accent.
   js/snake.js appends and moves them like pong's movers. */
.snake-seg,
.snake-food {
  position: absolute;
  top: 0;
  left: 0;
  width: 21px;
  height: 21px;
  border-radius: 5px;
  will-change: transform;
}
.snake-seg  { background: #5e5e5e; }
.snake-food { background: var(--orange); }

/* ---- Snake's SQUARE court (Figma 1417:116/115: 492×492 @ top 165, rail
   436.56² — the pong recipe scaled ×1.155). snake.js derives the grid from
   the rail's content box: 20×20 cells of 21px, leftover centred. ---- */
#snake-board {
  top: 165px;
  margin-left: -246px;
  width: 492px;
  height: 492px;
  border-width: 2.31px;
  border-radius: 35.803px;
  box-shadow: 0 4.62px 4.62px rgba(0, 0, 0, 0.25);
}
#snake-wall {
  left: 24.25px;
  top: 27.72px;
  width: 436.56px;
  height: 436.56px;
  border-width: 1.155px;
  border-radius: 23.099px;
}
/* game-over tallies: Score and Best flank the replay glyph, the whole
   trio vertically centred in the square card */
#snake-board .score-computer { left: 71px;  width: 103px; }
#snake-board .score-player   { left: 337px; width: 64px; }
#snake-board .score-col {
  top: 50%;
  transform: translateY(-50%);
}

/* ---- Flappy Bird's court — the pong recipe at 640×588: a bit longer
   than snake's 492 card, well short of pong's 1135, same borders/radius/
   shadow and rail insets. ---- */
#flappy-board {
  top: 122px;
  margin-left: -320px;
  width: 640px;
  height: 588px;
}
#flappy-wall {
  width: 599px;                        /* pong's 19/22 side insets */
  height: 540px;                       /* and 22/26 top/bottom */
}
/* ended card: same centred Score · replay · Best trio as snake's */
#flappy-board .score-computer { left: 108px; width: 103px; }
#flappy-board .score-player   { left: 448px; width: 64px; }
#flappy-board .score-col {
  top: 50%;
  transform: translateY(-50%);
}

/* pipes render inside this clip layer — the rail's content box exactly —
   so they emerge through the inner border instead of appearing in the
   gutter between rail and card edge */
.flappy-clip {
  position: absolute;
  left: 20px;                          /* wall left 19 + its 1px border */
  top: 23px;
  width: 597px;
  height: 538px;
  border-radius: 19px;
  overflow: hidden;
  pointer-events: none;                /* board clicks (= flaps) fall through */
}

/* the bird is the pong ball given wings; pipes are long paddles (2 units
   wide). js/flappy.js sizes each pipe's height inline and places both
   with the shared translate3d trick. */
.bird {
  position: absolute;
  top: 0;
  left: 0;
  width: 21px;
  height: 21px;
  border-radius: 5px;
  background: var(--orange);
  will-change: transform;
}
.pipe {
  position: absolute;
  top: 0;
  left: 0;
  width: 42px;
  border-radius: 5px;
  background: #5e5e5e;
  will-change: transform;
}

/* ---- pager dots — the work.html navigator, two games ---- */
.play-pager {
  position: absolute;
  top: 778px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6.15px;
  padding: 6.15px 16.9px;
  background: rgba(0, 0, 0, 0.03);
  border: 0.562px solid #d9d9d9;
  border-radius: 5.623px;
}
.play-dot {
  width: 7.69px;
  height: 7.69px;
  border-radius: 50%;
  border: 1px solid #5e5e5e;
  background: transparent;
  transition: background-color 0.18s ease;
}
.play-dot:hover { background: rgba(94, 94, 94, 0.45); }
.play-dot[aria-current='page'] { background: #5e5e5e; }

/* ---- centre overlays: tallies or countdown ---- */
.board-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.board-overlay[hidden] { display: none; }

/* Tallies sit wide, near each paddle (Figma 1361:113: columns at 223 and
   768 in board-content coords). Replay screen only — idle and play stay
   clean, like the other games. */
.score-col {
  position: absolute;
  top: 177px;
  text-align: center;
}
.score-computer { left: 235px; width: 103px; }
.score-player   { left: 781px; width: 64px; }
.score-label {
  font-size: 24px;                    /* 1395:157 rev 3 — down from 36 */
  color: #5e5e5e;
  line-height: 29px;
}
.score-num {
  font-size: 24px;
  color: rgba(0, 0, 0, 0.25);
  line-height: 29px;
  margin-top: 5px;                    /* mock pitch: 34px label→num */
}

.countdown {
  font-size: 24px;                    /* follows the smaller board type */
  color: #5e5e5e;
}

/* ============================================================
   Site records — the arcade crown under each court, fed by
   js/records.js from the shared scoreboard API
   ============================================================ */
.record-row {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
#pong   .record-row { top: 663px; }
#snake  .record-row { top: 686px; }
#flappy .record-row { top: 733px; }

/* a little hand-drawn crown that draws itself once the stage settles,
   and redraws when you admire it */
.record-crown { color: var(--orange); }
.record-crown path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.1s cubic-bezier(0.4, 0, 0.2, 1) 0.7s;
}
.play-stage.revealed .record-crown path { stroke-dashoffset: 0; }
.record-row:hover .record-crown path {
  animation: crown-redraw 0.7s cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes crown-redraw {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}

/* the chip itself: the site's warm-wash pill, number in the accent */
.record-chip {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 14px;
  font-size: 14px;
  line-height: 1.35;
  color: #5e5e5e;
  background: rgba(253, 143, 59, 0.13);
  border: 1px solid rgba(253, 143, 59, 0.35);
  border-radius: 20px;
}
.record-val { color: var(--orange); }
.record-chip.is-offline {
  background: rgba(233, 233, 233, 0.48);
  border-color: #d9d9d9;
}
.record-chip.is-offline .record-val { color: rgba(0, 0, 0, 0.3); }
/* a fresh record pops the chip once */
.record-chip.is-pop { animation: record-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes record-pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* ---- the initials entry — appears on the ended card when a run beats
   the site record; js/records.js drives the letters ---- */
.record-entry {
  position: absolute;
  left: 50%;
  bottom: 30px;
  transform: translateX(-50%);
  text-align: center;
  z-index: 3;
}
.entry-head {
  font-size: 16px;
  color: #5e5e5e;
}
.entry-head strong {
  font-weight: 400;
  color: var(--orange);
}
.entry-slots {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
}
.entry-slot {
  width: 34px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  color: #404040;
  border-bottom: 2px solid #d9d9d9;
  transition: border-color 0.18s ease;
}
.entry-slot.is-cur { border-color: var(--orange); }
.entry-slot.is-cur:empty::after {
  content: '';
  display: block;
  width: 14px;
  height: 2px;
  background: var(--orange);
  animation: caret-blink 1.1s steps(1) infinite;
}
@keyframes caret-blink {
  50% { opacity: 0; }
}
.entry-hint {
  margin-top: 10px;
  font-size: 13.25px;
  color: rgba(0, 0, 0, 0.3);
}
/* the off-screen input that summons the OS keyboard on touch — present
   but invisible; the letter slots are the real display */
.entry-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  border: 0;
  padding: 0;
  font-size: 16px;              /* ≥16 so iOS doesn't zoom the page on focus */
}

/* ---- centre buttons: play (idle, Figma 1363:139) and replay (game over,
   Figma 1361:110) — bare SF-symbol glyphs centred in the board ---- */
.board-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 0;
  background: none;
  border: none;
  line-height: 0;
  cursor: pointer;
  color: #494949;
  transition: color 0.18s ease;
}
.board-btn:hover,
.board-btn:focus-visible { color: var(--orange); }
.board-btn[hidden] { display: none; }

/* glyphs are masks over currentColor (the SVGs' own fill is #494949) so the
   hover tint is plain CSS `color` */
.board-btn .glyph {
  display: block;
  background: currentColor;
}
.glyph-play {
  width: 59px;                          /* Figma 1395:163 rev 3 — down from 66 */
  height: 59px;
  -webkit-mask: url(../Media/pong-play.svg) center / contain no-repeat;
  mask: url(../Media/pong-play.svg) center / contain no-repeat;
}
.glyph-replay {
  width: 66px;                          /* keeps the old 96:86 ratio to play */
  height: 59px;
  -webkit-mask: url(../Media/pong-replay.svg) center / contain no-repeat;
  mask: url(../Media/pong-replay.svg) center / contain no-repeat;
}

@media (prefers-reduced-motion: reduce) {
  .play-title, .board, .record-row {
    transition: opacity 0.25s ease;
    translate: none;
  }
  .record-crown path { transition: none; stroke-dashoffset: 0; }
  .record-row:hover .record-crown path { animation: none; }
  .record-chip.is-pop { animation: none; }
  .entry-slot.is-cur:empty::after { animation: none; }
}

/* ============================================================
   MOBILE (≤700px) — swipe between the games; each slide stacks
   title · court · crown in a centred column. Courts resize to
   the phone (the games read the rail's box at init, so the
   geometry follows) and gestures replace the keyboard: drag
   steers the pong paddle, swipes steer the snake, taps flap.
   Desktop untouched above.
   ============================================================ */
/* the courtesy note is desktop-hidden; the mobile block reveals it */
.play-mobile { display: none; }

@media (max-width: 700px) {
  /* Play retires on phones (the boards want a keyboard + a wider court):
     hide the games and show a courtesy note instead */
  .play-scroll, .play-pager { display: none; }
  .play-mobile {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    max-width: 340px;
    margin: 0 auto;
    padding: 130px 24px 0;
  }
  .play-mobile-eyebrow {
    font-size: 12px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(0, 0, 0, 0.3);
  }
  .play-mobile-title {
    margin-top: 12px;
    font-size: 26px;
    font-weight: 400;
    line-height: 32px;
    color: #5e5e5e;
  }
  .play-mobile-copy {
    margin-top: 16px;
    font-size: 16px;
    line-height: 24px;
    color: rgba(0, 0, 0, 0.42);
  }
  .play-mobile-link {
    margin-top: 26px;
    font-size: 16px;
    color: #5e5e5e;
    text-decoration: none;
    transition: color 0.18s ease;
  }
  .play-mobile-link:hover,
  .play-mobile-link:focus-visible { color: var(--orange); }

  .play-slide {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 14px;
    padding: 84px 18px 20px;
  }
  .play-title {
    position: static;
    transform: none;
    flex-wrap: wrap;
    justify-content: center;
    white-space: normal;
    text-align: center;
  }
  .play-title h1 { font-size: 22px; }
  .play-title p { width: 100%; font-size: 14px; }

  .board, #board, #snake-board, #flappy-board {
    position: static;
    margin: 0;                       /* the ids beat the class — reset all */
    width: min(430px, 100%);
    height: 400px;
    border-radius: 22px;
    touch-action: none;              /* the court owns its gestures */
  }
  #snake-board {
    width: min(354px, 94vw);
    height: min(354px, 94vw);
  }
  #flappy-board {
    width: min(354px, 94vw);
    height: 480px;
  }
  #board-wall, #snake-wall, #flappy-wall {
    left: 12px;
    top: 12px;
    right: 12px;
    bottom: 12px;
    width: auto;
    height: auto;
    border-width: 1px;
    border-radius: 16px;
  }
  #flappy-board .flappy-clip {
    left: 13px;
    top: 13px;
    right: 13px;
    bottom: 13px;
    width: auto;
    height: auto;
    border-radius: 15px;
  }

  /* ended-card tallies hug the sides at mid-height on every court */
  #board .score-col, #snake-board .score-col, #flappy-board .score-col {
    top: 50%;
    transform: translateY(-50%);
  }
  #board .score-computer, #snake-board .score-computer,
  #flappy-board .score-computer { left: 5%; right: auto; width: 42%; }
  #board .score-player, #snake-board .score-player,
  #flappy-board .score-player { left: auto; right: 5%; width: 42%; }
  .score-label, .score-num { font-size: 17px; line-height: 22px; }
  .countdown { font-size: 20px; }
  .glyph-play { width: 46px; height: 46px; }
  .glyph-replay { width: 51px; height: 46px; }

  .record-row { position: static; transform: none; }
  .record-chip { white-space: normal; }
  .play-pager { top: auto; bottom: 18px; }

  .record-entry { bottom: 22px; width: 92%; }
  .entry-head { font-size: 15px; }
}
