/* ==========================================================================
   board.css — the Mancala board, stones, badges, HUD, chat, and animations.

   All color/gloss values come from css/themes.css custom properties so the
   theme picker can reskin without touching this file. Layout is defined here:
   classic horizontal board on desktop/landscape, vertical two-column board on
   portrait (≤700px). Touch targets ≥44px (base.css --touch-min).
   ========================================================================== */

/* ---- Game screen shell --------------------------------------------------- */

.screen--game {
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--panel-bg, #14151a);
  /* dvh so the board stage fills the true visible height on iOS Safari (the
     vh fallback is for browsers without dvh). See base.css note. */
  min-height: 100vh;
  min-height: 100dvh;
  overflow-x: hidden;
}

/* ---- HUD ------------------------------------------------------------------ */

.game-hud {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.5rem;
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
  padding: 0.4rem 0.6rem;
}

.hud-player {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.hud-player--2 {
  justify-content: flex-end;
  flex-direction: row-reverse;
}

.hud-name {
  font-family: var(--font-display, system-ui);
  font-size: clamp(0.95rem, 3.5vw, 1.4rem);
  color: #fff;
  text-shadow: 0 2px 0 rgba(10, 46, 92, 0.9), 0 0 6px rgba(0, 0, 0, 0.35);
  transform: skewX(-6deg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hud-player--2 .hud-name {
  color: #d6ecff;
}

.hud-score {
  font-weight: 800;
  font-size: clamp(1rem, 4vw, 1.5rem);
  color: #0a2e5c;
  background: #fff;
  border: 2px solid #0a2e5c;
  border-radius: 999px;
  min-width: 2ch;
  padding: 0.05em 0.5em;
  text-align: center;
  line-height: 1.2;
}

/* Dim whichever player is not to move. */
.game-hud[data-turn="0"] .hud-player--2,
.game-hud[data-turn="1"] .hud-player--1 {
  opacity: 0.5;
}

.hud-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
}

.turn-indicator {
  font-family: var(--font-display, system-ui);
  font-size: clamp(0.75rem, 2.6vw, 1rem);
  color: #fff;
  background: var(--hl-turn, #2a6de0);
  border: 2px solid rgba(255, 255, 255, 0.85);
  border-radius: 999px;
  padding: 0.15em 0.8em;
  white-space: nowrap;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
}

.spectate-badge {
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  color: #fff;
  background: #d02ad0;
  border: 2px solid #fff;
  border-radius: 999px;
  padding: 0.1em 0.7em;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
}

/* ---- Resign button (HUD) ------------------------------------------------- */
/* Small white-flag button; only shown to the two seated players while the
   game is active (ui.js toggles [hidden]). Arcade-consistent styling. */
.resign-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  font-family: var(--font-display, system-ui);
  font-size: 0.72rem;
  font-weight: 700;
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  border: 2px solid rgba(255, 255, 255, 0.75);
  border-radius: 999px;
  padding: 0.12em 0.7em;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
  white-space: nowrap;
}
.resign-btn:hover { background: rgba(255, 80, 80, 0.35); }
.resign-btn:active { transform: translateY(1px); }
.resign-btn[hidden] { display: none; }

/* ---- Resign confirmation overlay ---------------------------------------- */
.resign-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(6, 8, 14, 0.72);
  backdrop-filter: blur(2px);
}
.resign-overlay[hidden] { display: none; }
.resign-dialog {
  max-width: 380px;
  text-align: center;
  align-items: center;
  gap: 0.75rem;
}
.resign-dialog-title {
  font-family: "Lilita One", system-ui, sans-serif;
  font-size: 1.6rem;
  color: #ff6b6b;
  transform: skewX(-6deg);
  margin: 0;
}
.resign-dialog-text {
  color: var(--color-text);
  font-size: 0.95rem;
}
.resign-dialog-actions {
  display: flex;
  gap: 0.6rem;
  width: 100%;
}
.resign-dialog-actions .btn { flex: 1; }

/* ---- Board stage ---------------------------------------------------------
   The stage is the flex-centered container that RESERVES space; the board
   inside it has FIXED internal design pixel dimensions and is uniformly
   scaled to fit via transform: scale(var(--board-scale)). Because scaling is
   a transform, the board's internal geometry never reflows — every pit keeps
   its exact relative position and size at any viewport, and pointer targets
   scale with it (pointer events are unaffected by transforms). The scale
   factor is computed in ui.js (fitBoardToStage) on render + resize +
   orientationchange. */

.board-stage {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  overflow: hidden;
  padding: 0.25rem;
}

/* ---- Board: default HORIZONTAL layout (desktop / landscape) --------------
   Columns: [P2 store] [6 pit columns] [P1 store]
   Rows:    top = P2 pits (12..7), bottom = P1 pits (0..5).

   FIXED design geometry: 1000x380 CSS px (classic wide mancala aspect ratio).
   All internal metrics are absolute px (no vw/clamp) so nothing reflows — the
   whole board is scaled as a unit by transform. --board-scale defaults to 1
   (unscaled) until ui.js measures. Must match BOARD_DESIGN.horizontal in ui.js. */
.board {
  --board-scale: 1;
  --stone-size: 24px;
  position: relative;
  display: grid;
  /* Classic mancala proportions (Club Penguin reference): two TIGHT rows of 6
     circular pits with slim elongated end stores. The design box is WIDE and
     relatively SHORT so each pit cell is near-square — that keeps the pits
     round while eliminating the tall vertical dead-space that made the old
     900x500 box look stretched. Store columns are slim (0.82fr). */
  grid-template-columns: 0.82fr repeat(6, 1fr) 0.82fr;
  grid-template-rows: 1fr 1fr;
  gap: 16px 20px;
  width: 1000px;
  height: 380px;
  flex: 0 0 auto;
  padding: 24px;
  border-radius: 34px;
  background: var(--board-bg, #6b4a2f);
  border: 7px solid var(--board-edge, #4a3220);
  box-shadow:
    inset 0 3px 0 rgba(255, 255, 255, 0.35),
    inset 0 -6px 14px rgba(0, 0, 0, 0.25),
    0 10px 24px rgba(0, 0, 0, 0.35);
  transform: scale(var(--board-scale));
  transform-origin: center center;
}

/* Stores flank the pit grid, spanning both rows. */
.store {
  position: relative;
  grid-row: 1 / 3;
  border-radius: 999px;
  background: var(--store-bg, #33220f);
  box-shadow:
    inset 0 6px 14px var(--store-shadow, #1c1206),
    inset 0 -3px 0 rgba(255, 255, 255, 0.2);
}

.store--p1 { grid-column: 8; }   /* right */
.store--p2 { grid-column: 1; }   /* left  */

/* Pits placed explicitly so DOM order is irrelevant.
   The 12 playing pits are ALWAYS perfect circles (never ovals) in both
   layouts: the pit is a square (aspect-ratio 1) centered in its grid cell,
   sized by whichever cell axis is the constraint, so uniform board scaling
   keeps it circular at every viewport. Only the two stores are elongated. */
.pit {
  position: relative;
  place-self: center;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: var(--pit-bg, #3d2a1a);
  box-shadow:
    inset 0 5px 12px var(--pit-shadow, #241708),
    inset 0 -2px 0 rgba(255, 255, 255, 0.18);
  transition: box-shadow 0.15s ease, transform 0.1s ease;
}

/* Horizontal: pit columns are narrower than rows are tall, so the WIDTH is
   the limiting axis — fill the cell width and derive height from it. */
.pit {
  width: 100%;
  height: auto;
}

/* Vertical: rows are shorter than columns are wide, so HEIGHT is the limiting
   axis — fill the cell height and derive width from it. */
.board[data-orientation="vertical"] .pit,
.verticalize .board .pit {
  width: auto;
  height: 100%;
}

/* P1 pits (0-5) bottom row, left→right. */
.pit[data-pit="0"] { grid-area: 2 / 2; }
.pit[data-pit="1"] { grid-area: 2 / 3; }
.pit[data-pit="2"] { grid-area: 2 / 4; }
.pit[data-pit="3"] { grid-area: 2 / 5; }
.pit[data-pit="4"] { grid-area: 2 / 6; }
.pit[data-pit="5"] { grid-area: 2 / 7; }
/* P2 pits (7-12) top row, mirrored so 12 sits above 0. */
.pit[data-pit="12"] { grid-area: 1 / 2; }
.pit[data-pit="11"] { grid-area: 1 / 3; }
.pit[data-pit="10"] { grid-area: 1 / 4; }
.pit[data-pit="9"]  { grid-area: 1 / 5; }
.pit[data-pit="8"]  { grid-area: 1 / 6; }
.pit[data-pit="7"]  { grid-area: 1 / 7; }

/* ---- Legal-move affordance ---------------------------------------------- */
.pit--legal {
  cursor: pointer;
  box-shadow:
    inset 0 5px 12px var(--pit-shadow, #241708),
    0 0 0 3px var(--hl-legal, #2ad06a),
    0 0 14px 2px var(--hl-legal, #2ad06a);
  animation: pit-pulse 1.3s ease-in-out infinite;
}
.pit--legal:hover,
.pit--legal:active {
  transform: scale(1.04);
}

@keyframes pit-pulse {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.12); }
}

@media (prefers-reduced-motion: reduce) {
  .pit--legal { animation: none; }
}

/* Stone containers clip the scatter so stones never spill outside the pit. */
.pit-stones,
.store-stones {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
}

/* ---- Stones -------------------------------------------------------------- */
.stone {
  position: absolute;
  width: var(--stone-size);
  height: var(--stone-size);
  border-radius: 50%;
  /* Deterministic offset set inline by ui.js via --sx/--sy (percentages). */
  left: calc(50% + var(--sx, 0%));
  top: calc(50% + var(--sy, 0%));
  transform: translate(-50%, -50%);
  background:
    radial-gradient(circle at 32% 28%, var(--stone-spec, #fff) 0%, transparent 38%),
    radial-gradient(circle at 50% 55%, var(--stone-hue, var(--stone-fill)) 0%,
      color-mix(in srgb, var(--stone-hue, var(--stone-fill)) 70%, #000) 100%);
  border: 2px solid var(--stone-outline, #1a1a2e);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  pointer-events: none;
  will-change: transform;
}

/* Image-based stone skin (static OR animated GIF/WebP — see themes.css).
   [data-stone-theme="frog"]  -> single theme-wide --stone-image (themes.css).
   [data-stone-theme="gems"]  -> per-stone --stone-image set inline by
     ui.js's makeStone() (one of 5 gem URLs, deterministically chosen).
   background-size: contain (NOT cover) so every source image — regardless
   of its own aspect ratio — fits inside the identical fixed .stone box
   without cropping or stretching, keeping all gems the same on-screen size. */
[data-stone-theme="frog"] .stone,
[data-stone-theme="gems"] .stone {
  background: var(--stone-image) center / contain no-repeat;
  border: none;
  /* No circular box-shadow on image stones — the art is irregularly
     shaped, so a round shadow reads wrong. drop-shadow() follows the
     image's alpha silhouette instead. Applies to all image-list themes
     (future animated GIF/WebP skins inherit this). */
  border-radius: 0;
  box-shadow: none;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
}

/* A flying stone during sow animation: positioned by transform, on top. */
.stone--flying {
  z-index: 5;
  transition: transform var(--hop-ms, 200ms) cubic-bezier(0.4, 0.9, 0.4, 1.1);
}

/* ---- Sowing animation: the travelling pile + landing drops --------------- */

/* The pile is a small cluster that lifts from the source pit and hops from
   pit to pit, dropping one stone at each. It lives inside .board so it scales
   with the board's transform; positioned in the board's UNSCALED coordinate
   space via left/top, moved with a transform transition for smooth eased
   hops (transform/opacity only — no layout thrash). */
.sow-pile {
  position: absolute;
  /* Anchor the pile's own center on the target point: start at -half a stone,
     then translate by the pit center (px,py) measured in board space. */
  left: calc(var(--stone-size) / -2);
  top: calc(var(--stone-size) / -2);
  width: var(--stone-size);
  height: var(--stone-size);
  z-index: 30;
  pointer-events: none;
  transform: translate(var(--px, 0px), var(--py, 0px));
  transition: transform var(--hop-ms, 280ms) cubic-bezier(0.34, 0.8, 0.36, 1);
  will-change: transform;
}
/* Each stone in the pile is stacked with a tiny scatter so the cluster reads
   as a little heap. The pile shrinks as stones drop (last child removed). */
.sow-pile .stone {
  left: 50%;
  top: 50%;
}

/* A stone dropping into a pit: appears at the pile, settles with a small
   bounce. Uses transform+opacity only. */
@keyframes stone-drop {
  0%   { transform: translate(-50%, -140%) scale(0.9); opacity: 0.85; }
  60%  { transform: translate(-50%, -50%) scale(1.06); opacity: 1; }
  80%  { transform: translate(-50%, -44%) scale(0.98); }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
.stone--dropping {
  animation: stone-drop 220ms cubic-bezier(0.3, 0.9, 0.4, 1.2);
  z-index: 4;
}

/* The count badge pops slightly when it increments at a drop. */
@keyframes badge-bump {
  0%   { transform: translateX(-50%) scale(1); }
  40%  { transform: translateX(-50%) scale(1.35); }
  100% { transform: translateX(-50%) scale(1); }
}
.pit-count--bump,
.store-count--bump {
  animation: badge-bump 220ms ease;
}

/* A stone sweeping toward the store during a capture: a quick glide. */
.stone--sweeping {
  z-index: 5;
  transition: transform 300ms cubic-bezier(0.4, 0.2, 0.2, 1), opacity 300ms ease;
}

@media (prefers-reduced-motion: reduce) {
  .sow-pile,
  .stone--dropping,
  .pit-count--bump,
  .store-count--bump,
  .stone--sweeping { animation: none !important; transition: none !important; }
}

/* ---- Count badges (glossy navy-outlined white pills) --------------------- */
.pit-count,
.store-count {
  position: absolute;
  z-index: 6;
  font-weight: 800;
  font-size: 13px;
  line-height: 1;
  color: var(--pit-count-fg, #0a2e5c);
  background: var(--pit-count-bg, #fff);
  border: 2px solid var(--pit-count-outline, #0a2e5c);
  border-radius: 999px;
  min-width: 1.4em;
  padding: 0.15em 0.35em;
  text-align: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.pit-count {
  bottom: -6px;
  left: 50%;
  transform: translateX(-50%);
}

.store-count {
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
}

/* ---- Capture / sweep flashes -------------------------------------------- */
.pit--capture {
  animation: pit-flash 0.4s ease;
}
@keyframes pit-flash {
  0%   { box-shadow: inset 0 5px 12px var(--pit-shadow), 0 0 0 4px #fff, 0 0 20px 6px var(--hl-legal); }
  100% { box-shadow: inset 0 5px 12px var(--pit-shadow); }
}

/* ---- EXTRA TURN splash --------------------------------------------------- */
.splash {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  z-index: 20;
}
.splash-text {
  font-family: var(--font-display, system-ui);
  font-size: 56px;
  color: #fff;
  text-shadow: 0 3px 0 #0a2e5c, 0 0 18px rgba(255, 255, 255, 0.6);
  transform: skewX(-8deg) scale(0.6);
  opacity: 0;
  animation: splash-pop 1.1s ease forwards;
}
@keyframes splash-pop {
  0%   { opacity: 0; transform: skewX(-8deg) scale(0.6); }
  20%  { opacity: 1; transform: skewX(-8deg) scale(1.15); }
  75%  { opacity: 1; transform: skewX(-8deg) scale(1); }
  100% { opacity: 0; transform: skewX(-8deg) scale(1.05); }
}

/* ==========================================================================
   PORTRAIT / VERTICAL LAYOUT
   Two columns of 6 pits; P2 store top, P1 store bottom. Fixed design geometry
   460x820 CSS px (scaled as a unit by transform, same as horizontal).

   Engagement is driven TWO ways so it is robust:
     1. ui.js sets [data-orientation="vertical"] on #board whenever the stage
        is taller than wide (or narrower than the portrait breakpoint). This
        is the authoritative trigger and, unlike an orientation media query,
        fires for a NARROW-BUT-LANDSCAPE desktop window / Webflow iframe.
     2. A media-query fallback (portrait OR <=700px wide) applies the same
        rules for the brief moment before ui.js measures, and if JS is slow.
   Both select the identical rule set below via :is().
   ========================================================================== */
.board[data-orientation="vertical"],
.verticalize .board {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1.15fr repeat(6, 1fr) 1.15fr;
  width: 460px;
  height: 820px;
  --stone-size: 22px;
}

/* Stores span both columns, top and bottom. */
.board[data-orientation="vertical"] .store,
.verticalize .board .store {
  grid-row: auto;
  grid-column: 1 / 3;
  height: 100%;
}
.board[data-orientation="vertical"] .store--p2,
.verticalize .board .store--p2 { grid-area: 1 / 1 / 2 / 3; }   /* top */
.board[data-orientation="vertical"] .store--p1,
.verticalize .board .store--p1 { grid-area: 8 / 1 / 9 / 3; }   /* bottom */

/* Left column = P1 pits (0..5) top→bottom; right column = P2 pits mirrored. */
.board[data-orientation="vertical"] .pit[data-pit="0"],
.verticalize .board .pit[data-pit="0"] { grid-area: 2 / 1; }
.board[data-orientation="vertical"] .pit[data-pit="1"],
.verticalize .board .pit[data-pit="1"] { grid-area: 3 / 1; }
.board[data-orientation="vertical"] .pit[data-pit="2"],
.verticalize .board .pit[data-pit="2"] { grid-area: 4 / 1; }
.board[data-orientation="vertical"] .pit[data-pit="3"],
.verticalize .board .pit[data-pit="3"] { grid-area: 5 / 1; }
.board[data-orientation="vertical"] .pit[data-pit="4"],
.verticalize .board .pit[data-pit="4"] { grid-area: 6 / 1; }
.board[data-orientation="vertical"] .pit[data-pit="5"],
.verticalize .board .pit[data-pit="5"] { grid-area: 7 / 1; }

.board[data-orientation="vertical"] .pit[data-pit="12"],
.verticalize .board .pit[data-pit="12"] { grid-area: 2 / 2; }
.board[data-orientation="vertical"] .pit[data-pit="11"],
.verticalize .board .pit[data-pit="11"] { grid-area: 3 / 2; }
.board[data-orientation="vertical"] .pit[data-pit="10"],
.verticalize .board .pit[data-pit="10"] { grid-area: 4 / 2; }
.board[data-orientation="vertical"] .pit[data-pit="9"],
.verticalize .board .pit[data-pit="9"]  { grid-area: 5 / 2; }
.board[data-orientation="vertical"] .pit[data-pit="8"],
.verticalize .board .pit[data-pit="8"]  { grid-area: 6 / 2; }
.board[data-orientation="vertical"] .pit[data-pit="7"],
.verticalize .board .pit[data-pit="7"]  { grid-area: 7 / 2; }

/* ==========================================================================
   CHAT drawer
   ========================================================================== */
.chat {
  position: fixed;
  z-index: 40;
}

.chat-handle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-display, system-ui);
  color: #fff;
  background: var(--hl-turn, #2a6de0);
  border: 2px solid rgba(255, 255, 255, 0.85);
  border-radius: 999px;
  padding: 0.4em 1em;
  min-height: var(--touch-min);
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.3);
}

.chat-unread {
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: 0.75rem;
  color: #fff;
  background: #ff3b3b;
  border: 2px solid #fff;
  border-radius: 999px;
  min-width: 1.4em;
  padding: 0.05em 0.35em;
  text-align: center;
}

.chat-panel {
  display: none;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--color-bg-raised, #1d1f26);
  border: 1px solid var(--color-border, #34364280);
  padding: 0.6rem;
}

.chat[data-open="true"] .chat-panel {
  display: flex;
}

.chat-log {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding-right: 0.2rem;
}

.chat-msg {
  max-width: 85%;
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius-md, 12px);
  font-size: 0.85rem;
  word-break: break-word;
}
.chat-msg-who {
  display: block;
  font-size: 0.65rem;
  opacity: 0.75;
  margin-bottom: 0.1rem;
}
.chat-msg--self {
  align-self: flex-end;
  background: var(--color-accent, #5da9ff);
  color: #0b1220;
}
.chat-msg--opponent {
  align-self: flex-start;
  background: var(--color-bg-card, #24262f);
  color: var(--color-text, #e8e9ee);
}
.chat-msg--spectator {
  align-self: flex-start;
  background: transparent;
  border: 1px dashed var(--color-info, #c9a8ff);
  color: var(--color-info, #c9a8ff);
  font-style: italic;
}

.chat-form {
  display: flex;
  gap: 0.4rem;
}
.chat-input { flex: 1; min-width: 0; }
.chat-send { flex: 0 0 auto; }

/* Mobile: slide-up sheet anchored bottom. */
@media (max-width: 900px) {
  .chat {
    left: 0;
    right: 0;
    bottom: 0;
  }
  .chat-handle {
    position: absolute;
    right: 0.75rem;
    bottom: calc(100% + 0.4rem);
  }
  .chat-panel {
    border-radius: 16px 16px 0 0;
    max-height: 55dvh;
    transform: translateY(0);
  }
  .chat-log { max-height: 38dvh; }
}

/* Desktop: side panel docked right. */
@media (min-width: 901px) {
  .chat {
    top: 5.5rem;
    right: 1rem;
    width: 280px;
  }
  .chat-handle {
    width: 100%;
    justify-content: center;
    border-radius: 12px 12px 0 0;
  }
  .chat-panel {
    border-radius: 0 0 12px 12px;
    height: 340px;
  }
  .chat-log { flex: 1; }
}
