/* ==========================================================================
   Cribbage — Design tokens (inherited from Rummy)
   Felt-table aesthetic: deep green felt, ivory chrome, brass accents.
   ========================================================================== */
:root {
  --felt-deep: #1B4332;
  --felt-shadow: #0D2818;
  --ivory: #F5F0E6;
  --brass: #C9A227;
  --danger-red: #8B1E1E;
  --card-back: #B0202E;
  --ink: #2A2A2A;
  --ink-soft: #5A5A52;

  --font-display: Georgia, 'Iowan Old Style', 'Palatino Linotype', serif;
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'SF Mono', 'Cascadia Code', Consolas, monospace;

  /* Matches the deck art's own rounded corners at any card size: the
     card outline's corner radius is 8.12 units on a 169.075 x 244.64
     card (6.87 path radius + half the 2.5 stroke), i.e. 4.8% of the
     width and 3.32% of the height. A fixed px value (was 6px) was
     roughly double the art's corner at 80px wide and triple at 55px,
     so shadows didn't follow the card and the border got clipped. */
  --radius-card: 4.8% / 3.32%;
  --radius-panel: 12px;
  --shadow-card: 0 2px 6px rgba(0, 0, 0, 0.35);
  --shadow-card-lifted: 0 6px 16px rgba(0, 0, 0, 0.45);

  /* Playing-card shadows (the two tokens above stay for panels/modals).
     Two layers, like a real card on cloth: a tight, dark contact shadow
     right under the edge, plus a soft ambient one. As a card rises, the
     contact layer softens and the ambient layer drifts further down and
     spreads. Every level has exactly two layers so the browser can
     animate smoothly between them (game.js reads these same values for
     the drop glide — see cardShadow()). Light comes from straight above,
     so offsets are vertical only. Strengths are tuned for the dark felt —
     black on deep green needs far more opacity than on a light page. */
  --card-shadow-rest: 0 1px 2px rgba(0, 0, 0, 0.55), 0 4px 10px rgba(0, 0, 0, 0.45);
  --card-shadow-lift: 0 4px 6px rgba(0, 0, 0, 0.45), 0 14px 26px rgba(0, 0, 0, 0.55);
  --card-shadow-held: 0 6px 8px rgba(0, 0, 0, 0.4), 0 22px 38px rgba(0, 0, 0, 0.6);

  color-scheme: light;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--felt-deep);
}

.hidden {
  display: none !important;
}

button {
  font-family: inherit;
  cursor: pointer;
}

button:focus-visible,
input:focus-visible {
  outline: 3px solid var(--brass);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }

}

/* ==========================================================================
   Shared: screens, buttons, panels
   ========================================================================== */
.screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

#lobby-screen {
  justify-content: flex-start;
  padding-top: 40px;
  padding-bottom: 40px;
  min-height: auto;
}

.game-title {
  font-family: var(--font-display);
  font-size: 2.6rem;
  font-weight: 700;
  color: var(--ivory);
  text-align: center;
  margin: 0 0 24px;
  letter-spacing: 0.02em;
}

.game-title-image {
  display: block;
  max-width: 420px;
  width: 100%;
  height: auto;
  margin: 0 auto 24px;
}

.lobby-card {
  background: var(--ivory);
  border-radius: var(--radius-panel);
  padding: 32px;
  max-width: 960px;
  width: 100%;
  box-shadow: var(--shadow-card-lifted);
  position: relative;
}

.lobby-card .game-title {
  color: var(--felt-deep);
}

.account-status {
  display: block;
  margin: -14px auto 20px;
  background: none;
  border: none;
  color: var(--ink-soft);
  font-size: 0.85rem;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  text-align: center;
}

.account-status:hover {
  color: var(--felt-deep);
}

.account-status.signed-in {
  color: var(--felt-deep);
  font-weight: 600;
  text-decoration: none;
}

.lobby-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: stretch;
  justify-content: center;
}

.lobby-panel {
  flex: 1 1 220px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lobby-panel h2 {
  font-family: var(--font-display);
  font-size: 1.2rem;
  margin: 0 0 8px;
  color: var(--felt-deep);
}

.lobby-panel label {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin-top: 8px;
}

.lobby-panel input {
  padding: 10px 12px;
  border: 1px solid #ccc4b0;
  border-radius: 6px;
  font-size: 1rem;
  background: #fff;
}

.lobby-panel select {
  padding: 10px 12px;
  border: 1px solid #ccc4b0;
  border-radius: 6px;
  font-size: 1rem;
  background: #fff;
  height: 42px;
}

.lobby-divider {
  align-self: center;
  color: var(--ink-soft);
  font-family: var(--font-display);
  font-style: italic;
}

.lobby-error {
  color: var(--danger-red);
  text-align: center;
  margin-top: 16px;
  font-weight: 600;
}

.btn {
  border: none;
  border-radius: 8px;
  padding: 12px 20px;
  font-size: 1rem;
  font-weight: 600;
  margin-top: 12px;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}

.btn:active {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--brass);
  color: var(--felt-shadow);
}

.btn-primary:hover:not(:disabled) {
  box-shadow: 0 2px 8px rgba(201, 162, 39, 0.5);
}

.btn-secondary {
  background: transparent;
  border: 1.5px solid var(--ink-soft);
  color: var(--ink-soft);
}

.code-display {
  margin-top: 16px;
  text-align: center;
}

.game-code {
  font-family: var(--font-mono);
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  color: var(--felt-deep);
  background: rgba(201, 162, 39, 0.15);
  border: 2px dashed var(--brass);
  border-radius: 8px;
  padding: 12px 20px;
  display: inline-block;
  margin-top: 8px;
}

.copy-link-btn {
  display: block;
  margin: 10px auto 0;
}

.invite-form {
  margin-top: 24px;
  text-align: left;
}

.invite-form label {
  font-size: 0.85rem;
  color: var(--ink-soft);
  display: block;
  margin-bottom: 6px;
}

.invite-form-row {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}

.invite-form-row input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid #ccc4b0;
  border-radius: 6px;
  font-size: 1rem;
  background: #fff;
}

.invite-form-row .btn {
  margin-top: 0;
  white-space: nowrap;
}

.invite-status {
  margin-top: 8px;
  font-size: 0.85rem;
  color: var(--felt-deep);
}

.player-roster {
  list-style: none;
  margin: 16px 0;
  padding: 0;
  text-align: left;
}

.player-roster li {
  padding: 8px 12px;
  background: rgba(201, 162, 39, 0.1);
  border-radius: 6px;
  margin-bottom: 6px;
  color: var(--felt-deep);
  font-weight: 600;
}

.player-roster li.roster-open {
  background: transparent;
  border: 1.5px dashed #ccc4b0;
  color: var(--ink-soft);
  font-weight: 400;
  font-style: italic;
}

/* ==========================================================================
   Draw-off ("who goes first") screen — once per match only
   ========================================================================== */
.draw-off-card {
  text-align: center;
}

.draw-off-card #draw-off-subtitle {
  color: var(--ink-soft);
  margin: -12px 0 20px;
}

.draw-off-deck-row {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

.draw-off-deck {
  display: inline-flex;
}

.draw-off-slots {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 24px;
  margin: 16px 0;
}

.draw-off-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.draw-off-slot-name {
  color: var(--felt-deep);
  font-weight: 600;
  font-size: 0.9rem;
}

.draw-off-slot-card {
  display: flex;
}

/* An empty outline where a seat's card will land — replaced by the real
   (revealed) card the instant its flight animation lands, see
   runDrawOffFlights. Sized to match a real card in JS so nothing shifts. */
.draw-off-placeholder {
  border: 1.5px dashed #ccc4b0;
  border-radius: var(--radius-card);
  background: rgba(0, 0, 0, 0.03);
}

/* Tappable state applies to the shared deck only, and only while your own
   seat hasn't drawn yet — see canDraw in renderDrawOffScreen. */
/* Reuses the same gold-flash cue as a discard landing, timed to the
   moment a slot's card actually flips face-up. */
.draw-off-revealed .draw-off-slot-card .card {
  animation: draw-off-reveal-anim 1.4s ease-out;
}

.draw-off-announcement {
  margin-top: 8px;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--felt-deep);
}

.resume-session-list {
  list-style: none;
  margin: 16px auto;
  padding: 0;
  text-align: left;
  max-width: 500px;
}

.resume-session-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  background: rgba(201, 162, 39, 0.1);
  border-radius: 6px;
  margin-bottom: 8px;
}

.resume-session-info {
  color: var(--felt-deep);
  font-weight: 600;
}

.resume-session-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.resume-session-list .btn {
  margin-top: 0;
  white-space: nowrap;
}

.invite-status-error {
  color: var(--danger-red);
}

/* ==========================================================================
   Game table
   ========================================================================== */
#table-screen {
  /* Nothing on the table is text anyone needs to copy (buttons, labels,
     hints, scores) — and a stray selection there used to hijack card
     drags (see suppressNativeGesture in game.js). This is the backstop,
     mainly for an iPad long-press, which can select text on its own. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  justify-content: flex-start;
  padding: 12px;
  gap: 12px;
  min-height: auto;
  /* The playing surface as cloth rather than flat paint — table only;
     the lobby, site header and footer keep the plain green. Layers,
     top to bottom:
       1. Fine grain: an SVG noise tile generated by the browser from the
          inline markup below (no image file). Dark speckles at roughly
          2-10% opacity, tiled seamlessly (stitchTiles), rasterized once,
          so it costs nothing while cards animate.
       2. Lamp falloff: slightly lighter just above centre, darkening
          toward the edges.
       3. The existing felt green. */
  background-color: var(--felt-deep);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0.18 0 0 0 -0.03'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(ellipse at 50% 40%, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0) 45%, rgba(0, 0, 0, 0.28) 100%);
  background-repeat: repeat, no-repeat;
  background-size: 180px 180px, 100% 100%;
}

/* Anything typeable on the table stays selectable — on iOS Safari,
   user-select: none on a text field can stop it accepting input. */
#table-screen input,
#table-screen textarea,
#table-screen [contenteditable] {
  user-select: text;
  -webkit-user-select: text;
}

/* Board-focus mode: hides the GameShack site header/nav and the in-game
   table header (scores, turn indicator, leave-game link), leaving just
   the meld quadrants, piles, and hand. Toggled via #board-focus-btn.
   Only applies at the table (body.at-table, set by showScreen in game.js):
   the toggle button lives on the table, so hiding the header in the lobby
   or waiting room left no way to bring it back — and those screens have
   room to spare anyway. The preference itself is remembered, so it takes
   effect again the moment you're back at a table. */
body.board-focus-mode.at-table .site-header,
body.board-focus-mode.at-table .site-nav,
body.board-focus-mode.at-table .table-header {
  display: none;
}

.table-header {
  width: 100%;
  max-width: min(1100px, 96vw);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  background: rgba(13, 40, 24, 0.5);
  border-radius: var(--radius-panel);
  border: 1px solid rgba(245, 240, 230, 0.1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  position: relative;
}

.icon-btn {
  position: relative;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1.5px solid var(--brass);
  background: rgba(13, 40, 24, 0.9);
  color: var(--brass);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.icon-btn:hover {
  background: var(--brass);
  color: var(--felt-shadow);
}

.lobby-icon-row {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  gap: 6px;
}

.bottom-right-controls {
  width: 100%;
  max-width: min(1100px, 96vw);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
}

.corner-btn {
  position: relative;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 2px solid var(--brass);
  background: var(--felt-shadow);
  color: var(--ivory);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.3rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  box-shadow: var(--shadow-card-lifted);
}

.corner-btn:hover {
  background: var(--brass);
  color: var(--felt-shadow);
}

.corner-btn.active {
  background: var(--brass);
  color: var(--felt-shadow);
}

/* Undo only appears for a short window and otherwise looks like any
   other icon in this row — a bright gold fill plus a slow pulsing ring
   calls it out while it's there. Uses #ffd700, the game's existing
   "this needs your attention now" gold (hint highlight, the old
   discard-undo state) rather than --brass: --brass is also what every
   corner-btn turns on hover/active (e.g. board-focus-btn once the
   header's hidden), so sharing it here made Undo hard to tell apart
   from that. Both the fill and the pulse stop the instant it's hidden
   (via the existing .hidden class), so nothing pulses off-screen. */
.switcher-panel {
  position: fixed;
  bottom: 84px;
  right: 20px;
  width: 300px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 120px);
  background: var(--ivory);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-card-lifted);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 95;
}

.switcher-game-list {
  list-style: none;
  margin: 0;
  padding: 10px 12px;
  overflow-y: auto;
  flex: 1;
}

.switcher-game-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: rgba(201, 162, 39, 0.1);
  border-radius: 6px;
  margin-bottom: 8px;
}

.switcher-game-info {
  flex: 1;
  color: var(--felt-deep);
  font-size: 0.85rem;
  line-height: 1.3;
}

.switcher-game-list .btn {
  margin-top: 0;
  padding: 6px 12px;
  font-size: 0.85rem;
}

.switcher-empty {
  color: var(--ink-soft);
  font-style: italic;
  font-size: 0.85rem;
  text-align: center;
  padding: 12px 0;
}

.switcher-add-btn {
  margin: 0;
  border-radius: 0;
  width: 100%;
}

.score-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: var(--ivory);
  min-width: 90px;
}

.score-name-row {
  display: flex;
  align-items: center;
  gap: 4px;
}

.presence-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.presence-online {
  background: #4caf50;
  box-shadow: 0 0 4px rgba(76, 175, 80, 0.7);
}

.presence-offline {
  background: rgba(245, 240, 230, 0.3);
}

.score-name {
  font-size: 0.8rem;
  opacity: 0.8;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.score-presence-label {
  font-size: 0.65rem;
  color: rgba(245, 240, 230, 0.55);
  margin-top: 1px;
}

.score-value {
  font-family: var(--font-display);
  font-size: 1.8rem;
  font-weight: 700;
  color: var(--brass);
}

.table-header-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.turn-indicator {
  color: var(--ivory);
  font-weight: 600;
  font-family: var(--font-display);
  font-size: 1.1rem;
}

/* Consistent emoji size everywhere a player's emoji appears — score row,
   hand labels, turn indicator, meld boxes, chat, game-over modal, waiting
   room, game lists — independent of whatever font-size the surrounding
   label happens to use. Matches the turn indicator's size, since that's
   the reference point for "how big it should look." */
.player-emoji {
  font-size: 1.1rem;
  line-height: 1;
  vertical-align: -1px;
}

.table-game-code {
  color: var(--ivory);
  opacity: 0.6;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
}

.leave-game-link {
  background: transparent;
  border: none;
  color: var(--ivory);
  opacity: 0.5;
  font-size: 0.7rem;
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
  margin-top: 2px;
}

.leave-game-link:hover {
  opacity: 0.85;
}

.scores-row {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

.header-logo {
  align-self: stretch;
  width: auto;
  max-height: 64px;
  flex-shrink: 0;
}

.hand-toolbar {
  width: 100%;
  max-width: min(1100px, 96vw);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 4px;
}

.hand-toolbar-actions {
  display: flex;
  gap: 8px;
}

.btn-small {
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(245, 240, 230, 0.3);
  color: var(--ivory);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 0.8rem;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease;
}

.btn-small:hover {
  background: rgba(201, 162, 39, 0.25);
}

.btn-small:disabled {
  opacity: 0.4;
  cursor: default;
}

.hint-banner {
  width: 100%;
  max-width: min(1100px, 96vw);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  background: rgba(201, 162, 39, 0.15);
  border: 1px solid rgba(201, 162, 39, 0.5);
  border-radius: var(--radius-panel);
  padding: 8px 14px;
  color: var(--ivory);
  font-size: 0.85rem;
  margin: 0;
}

#hint-banner-text {
  flex: 1;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.hint-banner-close {
  flex: 0 0 auto;
  background: none;
  border: none;
  color: var(--ivory);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
  opacity: 0.7;
}

.hint-banner-close:hover {
  opacity: 1;
}

/* Applied to the shared #undo-meld-btn specifically while it represents
   an undoable discard rather than a meld — bright and impossible to miss
   for the few seconds it's actually actionable. */
.card.hint-highlight {
  box-shadow: 0 0 0 3px #ffd700, var(--card-shadow-lift);
}

.hand-label {
  width: 100%;
  max-width: min(1100px, 96vw);
  text-align: center;
  color: var(--ivory);
  font-family: var(--font-display);
  font-size: 0.9rem;
  opacity: 0.75;
  margin: 4px 0 0;
}

.your-hand-row-wrap {
  width: 100%;
  max-width: min(1100px, 96vw);
  position: relative;
}

.your-hand-row-wrap .hand-label {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: auto;
  max-width: none;
  text-align: left;
  margin: 0;
  z-index: 1;
  pointer-events: none;
}

.your-hand-row {
  max-width: min(1100px, 96vw);
  min-height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  padding: 8px 8px 8px 90px; /* left space reserved for the overlaid "My hand" label */
  border-radius: var(--radius-panel);
  position: relative;
  /* Same shrink-wrap fix as .opponent-hand-block — was width: 100%,
     which made the .slot-active highlight span the full row width
     instead of hugging just the cards. max-width above still caps it
     so a full hand wraps to a second line exactly as before. */
  width: -webkit-fit-content;
  width: fit-content;
  margin: 0 auto;
}

/* The generic .slot-active background/box-shadow below would otherwise
   paint across the row's own padding box — including the 90px gutter
   reserved for the "My hand" label on the left, which has no cards in
   it. Paint the highlight on a pseudo-element instead, inset past that
   gutter, so it hugs just the actual cards. Always rendered (opacity
   toggled) rather than added/removed with the class, so it still fades
   in/out the same way the row's own background used to. */
.your-hand-row.slot-active {
  background: none;
  box-shadow: none;
}

.your-hand-row::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  /* 90px minus 8px so this leaves the same ~8px gap before the first
     card that top/right/bottom already get from the row's own padding
     — left: 90px landed exactly on the card edge with no gap at all. */
  left: 82px;
  background: rgba(201, 162, 39, 0.14);
  box-shadow: 0 0 0 2px var(--brass);
  border-radius: var(--radius-panel);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.your-hand-row.slot-active::before {
  opacity: 1;
}

/* Fills your hand row once it's emptied by going out (see
   renderYourHand) — sized like a row of cards, so the turn outline keeps
   a proper rectangle instead of collapsing into a thin oval. */
/* Highlights whichever quadrant/opponent-block belongs to the currently
   active player — since nobody's position on screen moves with whose
   turn it is, this (plus the "X's turn" banner above the table) is the
   tell-tale for who's up. */
.slot-active {
  background: rgba(201, 162, 39, 0.14);
  box-shadow: 0 0 0 2px var(--brass);
}

/* Meld quadrants + piles, together in one grid. Your own melds live in
   the standalone #quadrant-me block near your hand, not here.
   Turn order flows clockwise starting from you: next (your left), then
   third (across from you), then fourth (your right) — but visually they
   all sit in a single row across the top now, in that order left-to-right,
   each with equal width and room for their hand + melds stacked vertically.
   The piles get their own full-width row below that opponent row.
     2 players -> next, stacked directly above the piles
     3 players -> next, third across the top; piles span full width below
     4 players -> next, third, fourth across the top; piles span full
                  width below */
.meld-quadrant {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0; /* lets this grid/flex item actually shrink to its
                   column's width instead of overflowing past it */
  background: rgba(0, 0, 0, 0.15);
  border-radius: var(--radius-panel);
  border: 1px solid rgba(245, 240, 230, 0.1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  padding: 26px 10px 10px;
  min-height: 72px;
  transition: box-shadow 0.2s ease, background 0.2s ease;
}

/* Your own melds: a standalone block (not part of the .meld-quadrants
/* Your own melds AND your own hand, together — sitting between the
   piles and the rest of the page, needing its own width/centering the
   way .piles-row gets theirs. Your hand used to be a separate element
   entirely (a plain .your-hand-row-wrap sibling below); now it's nested
   inside here too, same as an opponent's hand sits inside their own
   .meld-quadrant box. */
#quadrant-me {
  width: 100%;
  max-width: min(1100px, 96vw);
}

/* The player's name sits superimposed in the top-left corner of their
   quadrant, rather than taking up a full row of its own, so a quadrant
   with few/no melds yet doesn't look mostly empty. */
.quadrant-header {
  position: absolute;
  top: 6px;
  left: 10px;
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 700;
}

/* A small tell-tale for which difficulty a bot is playing at, since once
   the game starts there's nowhere else that shows it. Color-coded so it
   reads at a glance without needing to parse the word every time. */
/* Each meld-segment is one player's contribution to one meld, shown in
   their own quadrant — a label clarifies whose meld it's part of when
   it's not their own (a lay-off onto someone else's run/set). */
/* Each opponent's hand-count block, now built inside their own quadrant
   (see .quadrant-hand in index.php) rather than a separate shared row. */
.other-hand-row {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  min-height: 80px; /* a 55px-wide card's height — so an emptied hand (going out) keeps its size instead of shrinking and shifting the layout */
}

.pile {
  width: 90px;
  height: 130px;
  border-radius: var(--radius-card);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  cursor: pointer;
  /* Without this, iOS Safari treats a finger-drag on the pile as a page
     pan/scroll gesture and takes the touch over before pointermove ever
     sees enough movement to cross the drag threshold — so tap-to-draw
     still works but drag never starts. Same reasoning as
     .your-hand-row .card below. */
  touch-action: none;
}

/* The deck's thickness: thin card edges peeking out below and to the
   right of the top card, like a real deck seen from above. game.js sets
   --pile-depth on .draw-pile (0-6: roughly one edge per 8 cards beneath
   the top one), so the deck visibly thins as the game goes on.

   Each edge is a same-size box-shadow layer (no blur) offset one step
   further out; min() parks the edges beyond the current depth exactly
   under the last visible one, so a single variable controls how many
   show. Edges alternate ivory and a darker line so they read as
   separate cards. The last two layers are the resting card shadow
   (same values as --card-shadow-rest), pushed out by the depth so it
   falls under the bottom of the stack rather than the top card. */
.pile-label {
  color: rgba(245, 240, 230, 0.5);
  font-family: var(--font-display);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Brief reminder toast for tapping a pile when it's not actually
   actionable (not your turn, or already drawn and time to discard
   instead). Non-blocking — fades on its own, never demands a click. */
/* Individual cards */
.card {
  border-radius: var(--radius-card);
  /* Leading transparent ring layer: .selected and .hint-highlight add a
     ring in that same first slot, so selecting/deselecting animates the
     ring and the lift as matching layers instead of cross-fading
     unrelated ones. */
  box-shadow: 0 0 0 0 rgba(201, 162, 39, 0), var(--card-shadow-rest);
  transition: transform 0.15s ease, box-shadow 0.15s ease, margin 0.15s ease;
  cursor: pointer;
  flex-shrink: 0;
  /* The card art includes SVG <text> elements for the rank/suit corner
     labels — without this, a mouse drag across the hand highlights them
     like ordinary page text instead of just moving/selecting cards. */
  user-select: none;
  -webkit-user-select: none;
}

.card svg {
  display: block;
  border-radius: var(--radius-card);
}

/* The SVG deck's back designs set their own fill to `inherit` specifically
   so it can be recolored via CSS without editing the SVG file — this pulls
   the card back into the felt/brass theme instead of the deck's default
   blue. */
.card-back svg use {
  fill: var(--card-back);
}

.your-hand-row .card {
  margin-left: -28px;
  cursor: grab;
  touch-action: none;
}

.your-hand-row .card:first-child {
  margin-left: 0;
}

/* The original of a card being dragged out of your hand: invisible, and
   its width/margin animate so the gap it leaves can close up or reopen —
   see startDragVisual / collapseDragOrigins in game.js. */
/* Empty landing slot that opens in your hand while you drag a card from
   the draw or discard pile over it — see updateHandDropSlot in game.js.
   Width and margin-left are set inline and animate open/closed so the
   neighbouring cards slide apart. Keep the duration in sync with
   HAND_DROP_SLOT_MS. */
/* Only apply the hover-lift on devices with a real hover-capable pointer
   (mouse/trackpad). On touch devices, iOS/iPadOS Safari simulates :hover
   after a tap and doesn't clear it until the next tap lands somewhere
   else — so a card re-rendered at the same screen position (e.g. right
   after being deselected) would otherwise pick up this hover transform
   and look like it only lifted "halfway" instead of dropping fully back
   down. Touch has no real hover concept anyway, so scoping this out
   entirely is correct, not just a workaround. */
@media (hover: hover) and (pointer: fine) {
  .your-hand-row .card:not(.selected):hover {
    transform: translateY(-10px);
    box-shadow: 0 0 0 0 rgba(201, 162, 39, 0), var(--card-shadow-lift);
    z-index: 5;
  }

}

.card.selected {
  transform: translateY(-20px);
  box-shadow: 0 0 0 3px var(--brass), var(--card-shadow-lift);
  z-index: 6;
}

.card.dragging {
  cursor: grabbing;
  transform: scale(1.08) rotate(-3deg);
  box-shadow: var(--card-shadow-held);
  transition: none;
}

@keyframes card-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}

.card.shake {
  animation: card-shake 0.35s ease;
}

/* Briefly draws the eye to a card the instant it lands on top of the
   discard pile — added in JS only on the render right after the top
   card actually changes, so a fast bot's discard is noticeable even if
   it happens between one glance and the next. */
/* Softened: a thinner ring, no scale-up — a card landing on a pile
   doesn't grow, and the landing motion itself will come from the card
   flights. */
/* Draw-for-first-turn reveal: a deliberate "ta-da" moment, so it keeps
   the bigger ring and the pop. Its own keyframes so it can be tuned
   separately from the discard cue. */
@keyframes draw-off-reveal-anim {
  0% {
    box-shadow: 0 0 0 5px rgba(201, 162, 39, 0.9), var(--card-shadow-rest);
    transform: scale(1.1);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(201, 162, 39, 0), var(--card-shadow-rest);
    transform: scale(1);
  }
}

/* Positioning/stacking for the synthetic card clone used to animate an
   opponent's action (e.g. a discard) traveling across the table — the
   clone is created and animated entirely in JS via the Web Animations
   API (see flyCard() in game.js), so no CSS transition is defined here;
   that sidesteps any interaction with .card's own transition rule. */
.card.flying-card {
  position: fixed;
  top: 0;
  left: 0;
  margin: 0;
  z-index: 9999;
  pointer-events: none;
  transform-origin: 50% 50%; /* flyCard rotates/scales about the card's centre */
}

/* A card that turns over mid-flight (flyCard's flipToFaceUp): a container
   holding both faces back to back. The container carries the shadow and
   does the turning; each face hides itself while facing away, so the
   back shows for the first half of the turn and the front (pre-turned
   180°) for the second. */
.other-hand-row .card {
  margin-left: -35px;
  cursor: default;
}

.other-hand-row .card:first-child {
  margin-left: 0;
}

.other-hand-row .card:hover {
  transform: none;
}

/* Action bar */
.action-bar {
  width: 100%;
  max-width: 640px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: nowrap;
  gap: 10px;
  background: rgba(13, 40, 24, 0.7);
  padding: 8px 14px;
  border-radius: var(--radius-panel);
}

.action-bar .btn {
  margin-top: 0;
  white-space: nowrap;
  flex-shrink: 0;
}

.action-hint {
  color: var(--ivory);
  font-size: 0.85rem;
  flex: 1;
  text-align: center;
  min-width: 0;
}

/* Game over */
.modal {
  position: fixed;
  top: 80px;
  left: 50%;
  transform: translateX(-50%);
  width: 320px;
  max-width: calc(100vw - 32px);
  background: var(--ivory);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-card-lifted);
  z-index: 100;
  overflow: hidden;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--felt-deep);
  color: var(--ivory);
  padding: 10px 14px;
  font-family: var(--font-display);
  font-weight: 700;
  cursor: grab;
  user-select: none;
}

.modal-header:active {
  cursor: grabbing;
}

.modal-close-btn {
  background: transparent;
  border: none;
  color: var(--ivory);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.modal-body {
  padding: 20px;
  text-align: center;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 99;
}

/* Chat */
.chat-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--danger-red);
  color: var(--ivory);
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chat-panel {
  position: fixed;
  bottom: 84px;
  right: 20px;
  width: 300px;
  max-width: calc(100vw - 32px);
  height: 380px;
  max-height: calc(100vh - 120px);
  background: var(--ivory);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-card-lifted);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 95;
}

.chat-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--felt-deep);
  color: var(--ivory);
  padding: 10px 14px;
  font-family: var(--font-display);
  font-weight: 700;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.chat-message {
  max-width: 85%;
  padding: 6px 10px;
  border-radius: 10px;
  font-size: 0.85rem;
  line-height: 1.3;
  word-wrap: break-word;
}

.chat-message-mine {
  align-self: flex-end;
  background: rgba(201, 162, 39, 0.25);
  color: var(--ink);
}

.chat-message-theirs {
  align-self: flex-start;
  background: rgba(27, 67, 50, 0.12);
  color: var(--ink);
}

.chat-message-sender {
  font-size: 0.7rem;
  font-weight: 700;
  opacity: 0.65;
  display: block;
  margin-bottom: 2px;
}

.chat-input-row {
  display: flex;
  gap: 6px;
  padding: 10px;
  border-top: 1px solid #ddd4c0;
}

.chat-input-row input {
  flex: 1;
  padding: 8px 10px;
  border: 1px solid #ccc4b0;
  border-radius: 6px;
  font-size: 0.9rem;
}

.chat-input-row .btn {
  margin-top: 0;
  padding: 8px 14px;
}

.rules-modal {
  width: 1400px;
  top: 40px;
}

.rules-modal .modal-header {
  cursor: default;
}

.rules-body {
  text-align: left;
  max-height: 78vh;
  overflow-y: auto;
  overflow-anchor: none;
  scroll-behavior: smooth;
  color: var(--ink);
}

.rules-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  background: rgba(27, 67, 50, 0.06);
  border: 1px solid rgba(27, 67, 50, 0.15);
  border-radius: var(--radius-panel);
  padding: 14px 18px;
  margin-bottom: 18px;
}

.rules-toc-group {
  flex: 1 1 180px;
  min-width: 160px;
}

.rules-toc-group h4 {
  font-family: var(--font-display);
  color: var(--felt-deep);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 8px;
}

.rules-toc-group ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rules-toc-group li {
  margin-bottom: 5px;
  font-size: 0.85rem;
  line-height: 1.3;
}

.rules-toc-group a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px dotted rgba(27, 67, 50, 0.4);
}

.rules-toc-group a:hover,
.rules-toc-group a:focus {
  color: var(--felt-deep);
  border-bottom-style: solid;
}

.back-to-top {
  display: block;
  text-align: left;
  font-size: 0.78rem;
  color: var(--felt-deep);
  opacity: 0.7;
  text-decoration: none;
  margin: -2px 0 4px;
  scroll-margin-top: 8px;
}

.back-to-top:hover,
.back-to-top:focus {
  opacity: 1;
  text-decoration: underline;
}

.rules-body h3 {
  font-family: var(--font-display);
  color: var(--felt-deep);
  margin: 16px 0 6px;
  scroll-margin-top: 8px;
}

.rules-body h3:first-child {
  margin-top: 0;
}

.rules-body ul,
.rules-body ol {
  margin: 0 0 8px;
  padding-left: 20px;
}

.rules-body li {
  margin-bottom: 6px;
  font-size: 0.9rem;
  line-height: 1.4;
}

.rules-body p {
  font-size: 0.9rem;
  line-height: 1.4;
  margin: 0 0 8px;
}

.settings-modal {
  width: 640px;
  top: 40px;
}

.settings-body {
  text-align: left;
  color: var(--ink);
  max-height: 78vh;
  overflow-y: auto;
}

.settings-scope-note {
  margin: 0 0 16px;
  font-size: 0.8rem;
  color: var(--ink-soft);
  font-style: italic;
}

.settings-toggle-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  margin: 0 0 20px;
  font-size: 0.9rem;
  line-height: 1.4;
}

.settings-toggle-row input {
  margin-top: 2px;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  accent-color: var(--felt-deep);
}

.settings-row-label {
  display: block;
  font-weight: 700;
  margin-bottom: 10px;
  font-size: 0.9rem;
}

.settings-row {
  margin: 0 0 20px;
}

.settings-text-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 1px solid #ccc4b0;
  border-radius: 6px;
  font-size: 1rem;
  background: #fff;
  font-family: inherit;
}

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

.emoji-swatch {
  width: 100%;
  aspect-ratio: 1;
  font-size: 1.1rem;
  border-radius: 6px;
  border: 2px solid transparent;
  background: #f4efe4;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.emoji-swatch:hover {
  background: #e9e1cd;
}

.emoji-swatch.selected {
  border-color: var(--brass);
  background: #fff;
}

.card-back-swatch-row {
  display: flex;
  gap: 14px;
}

.card-back-swatch {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 3px solid transparent;
  cursor: pointer;
  box-shadow: var(--shadow-card);
}

.card-back-swatch[data-color="red"] {
  background: #B0202E;
}

.card-back-swatch[data-color="black"] {
  background: #1C1C1C;
}

.card-back-swatch[data-color="blue"] {
  background: #1B4B72;
}

.card-back-swatch.selected {
  border-color: var(--brass);
}

.gameover-scores {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px 24px;
  margin: 4px 0 20px;
}

.gameover-scores .score-box {
  color: var(--felt-deep);
}

.gameover-scores .score-value {
  color: var(--danger-red);
}

.match-over-banner {
  background: var(--felt-deep);
  color: var(--brass);
  font-family: var(--font-display);
  font-weight: 700;
  text-align: center;
  padding: 10px 14px;
  border-radius: var(--radius-panel);
  margin: 0 0 14px;
}

.gameover-scores .match-winner-box {
  border: 2px solid var(--brass);
  border-radius: var(--radius-panel);
  padding: 6px 10px;
  background: rgba(201, 162, 39, 0.12);
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 600px) {
  .lobby-actions {
    flex-direction: column;
  }

  .lobby-divider {
    padding: 4px 0;
  }

  .game-title {
    font-size: 2rem;
  }

  .game-title-image {
    max-width: 280px;
  }

  .header-logo {
    max-height: 44px;
  }

  .pile {
    width: 70px;
    height: 110px; /* was 100px: a 70px-wide card is ~101px tall, plus room for the deck edges */
  }

  .meld-quadrant {
    flex-direction: column !important;
  }

}

/* ---- Head-to-head line (gameover modal) ---- */
.head-to-head-line {
  text-align: center;
  color: var(--felt-deep);
  font-size: 0.85rem;
  opacity: 0.8;
  margin: 0 0 14px;
}

/* ---- Stats modal ---- */
.stats-note {
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin: 0 0 16px;
}

#stats-modal label {
  display: block;
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: left;
  margin: 0 0 6px;
}

#stats-modal input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #ccc4b0;
  border-radius: 6px;
  font-size: 1rem;
  background: #fff;
  margin-bottom: 12px;
  box-sizing: border-box;
}

.stats-status {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin-top: 12px;
}

.stats-overall {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--felt-deep);
  font-size: 1.05rem;
  margin: 16px 0 8px;
}

#stats-results h3 {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  margin: 16px 0 6px;
  text-align: left;
}

.stats-opponent-list {
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: left;
}

.stats-opponent-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 12px;
  background: rgba(201, 162, 39, 0.1);
  border-radius: 6px;
  margin-bottom: 6px;
  color: var(--felt-deep);
}

.stats-opponent-record {
  font-weight: 700;
  color: var(--brass);
}

/* ---- Sign-in modal (OTP) ---- */
#signin-modal label {
  display: block;
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: left;
  margin: 0 0 6px;
}

#signin-modal input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #ccc4b0;
  border-radius: 6px;
  font-size: 1rem;
  background: #fff;
  margin-bottom: 12px;
  box-sizing: border-box;
}

#signin-modal .btn {
  width: 100%;
}

.signin-status {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin-top: 10px;
  text-align: center;
}

.signin-status.error {
  color: var(--danger-red);
  font-weight: 600;
}

/* Animated deal (see beginDealAnimation in game.js; the element itself
   is #deal-overlay in index.php): a transparent layer over everything
   that blocks play until the deal finishes, and skips straight to the
   dealt table when tapped. Sits under the flying cards (z-index 9999). */
.deal-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  cursor: pointer;
  background: transparent;
  -webkit-tap-highlight-color: transparent;
}

.deal-skip-hint {
  position: absolute;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.45);
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.85rem;
  pointer-events: none;
  animation: deal-hint-in 0.4s ease-out 0.6s both; /* only appears if you're actually watching */
}

@keyframes deal-hint-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ---- Per-hand score table (gameover modal) ---- */
/* Zebra on the row, so a winner cell's own background paints over it. */
/* Solid (brass 16% over ivory) so the sticky header cell stays opaque. */
/* ==========================================================================
   Cribbage — table additions
   Everything above is inherited from Rummy (shared lobby, modals, chat,
   settings, hand/card styling). Rummy-only rules (melds, discard pile,
   3-4 player quadrant grid) get pruned once game.js is finished and we
   know exactly what's unused.
   ========================================================================== */
:root {
  --wood-light: #C98B4E;
  --wood-mid: #9A5B2C;
  --wood-dark: #6B3A1A;
  --peg-red: #C62828;
  --peg-blue: #1E5BB8;
}

/* Lobby logo: the cribbage art is wider-feeling than Rummy's wordmark,
   so allow a little more width. */
#lobby-screen .game-title-image {
  max-width: 480px;
}

/* ---- Pegboard ---------------------------------------------------------- */
.pegboard-wrap {
  width: 100%;
  max-width: min(900px, 96vw);
  margin: 10px auto 0;
}

/* The racetrack is drawn entirely in SVG (see renderPegboard in game.js);
   the container just holds it. */
.pegboard {
  position: relative;
  width: 100%;
}

.pegboard svg {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.45));
}

.pegboard .pb-board-fill {
  fill: url(#pb-wood);
}

/* Border only — drawn over the optional wood texture. */
.pegboard .pb-board {
  fill: none;
  stroke: #A97C45;
  stroke-width: 2;
}

/* The track: a darker edge under the colored lanes. */
.pegboard .pb-ribbon-edge {
  fill: none;
  stroke: rgba(90, 55, 20, 0.55);
  stroke-linecap: butt;
}

/* One lane per player, tinted in their color (set inline). */
.pegboard .pb-lane {
  fill: none;
  stroke-opacity: 0.55;
  stroke-linecap: butt;
}

.pegboard .peg-hole {
  fill: rgba(40, 20, 6, 0.85);
}

.pegboard .pb-finish-hole {
  stroke: rgba(40, 20, 6, 0.6);
  stroke-width: 1;
}

/* White ring + shadow so a peg stands out even on its own colored lane. */
.pegboard .peg {
  stroke: #fff;
  stroke-width: 1.6;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.6));
  transition: cx 0.6s ease, cy 0.6s ease;
}

.pegboard .pb-finish-ring {
  fill: none;
  stroke: rgba(70, 38, 12, 0.7);
  stroke-width: 1.2;
}

.pegboard .pb-group-line {
  stroke: rgba(60, 30, 8, 0.45);
  stroke-width: 1;
}

.pegboard .peg-skunk-line {
  stroke: #8B1A1A;
  stroke-width: 1.6;
  stroke-dasharray: 3 2;
}

.pegboard .peg-label,
.pegboard .pb-number,
.pegboard .pb-word {
  fill: rgba(70, 38, 12, 0.85);
  font-family: var(--font-display);
}

.pegboard .peg-label {
  font-size: 8px;
}

.pegboard .pb-skunk-label {
  fill: #8B1A1A;
}

.pegboard .pb-word {
  letter-spacing: 0.08em;
  font-weight: 700;
}

/* Games won this match: a short lane per player, holes filled per win. */
.pegboard .pb-games-band {
  opacity: 0.45;
}

.pegboard .pb-games-won {
  stroke: rgba(0, 0, 0, 0.55);
  stroke-width: 1;
}

/* ---- Seats (opponent across, you nearest) ------------------------------- */
.crib-seat {
  width: 100%;
  max-width: min(1100px, 96vw);
  margin: 10px auto 0;
  align-items: center;
}

.crib-seat .other-hand-row {
  display: flex;
  justify-content: center;
  min-height: 70px;
}

/* ---- Middle of the table: deck/starter · the play · crib ---------------- */
.crib-table-row {
  width: 100%;
  max-width: min(1100px, 96vw);
  margin: 14px auto;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
}

.crib-zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* Deck with the starter card sitting on top, slightly offset, like a
   real cut card turned up on the pack. */
.deck-pile {
  cursor: default;
}

.deck-pile-card,
.starter-card {
  position: absolute;
  inset: 0;
}

.starter-card {
  transform: translate(10px, -8px) rotate(4deg);
}

.starter-card:empty {
  display: none;
}

.crib-pile {
  cursor: default;
  outline: 2px dashed rgba(245, 240, 230, 0.2);
  outline-offset: 4px;
}

/* Crib is yours this hand: brass outline instead of the dashed ivory. */
.crib-pile.crib-mine {
  outline: 2px solid var(--brass);
}

/* The play */
.pegging-zone {
  position: relative;
  min-height: 150px;
  justify-content: center;
  background: rgba(0, 0, 0, 0.15);
  border: 1px solid rgba(245, 240, 230, 0.1);
  border-radius: var(--radius-panel);
  padding: 10px 14px;
}

.peg-count {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--ivory);
  font-family: var(--font-display);
}

.peg-count-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.6;
}

.peg-count-value {
  font-size: 2rem;
  font-weight: 700;
  color: var(--brass);
  min-width: 2ch;
  text-align: center;
}

/* Cards played this hand, in order, one group per round of the count
   (see groupPlaysByRound in game.js). */
.peg-cards {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 10px 16px;
  min-height: 100px;
}

.peg-group {
  display: flex;
  align-items: flex-end;
}

/* A thin divider between rounds. */
.peg-group + .peg-group {
  border-left: 1px solid rgba(245, 240, 230, 0.2);
  padding-left: 16px;
}

/* Overlap leaves each card's corner (rank + suit) fully visible. */
.peg-group-current .peg-card + .peg-card {
  margin-left: -28px;
}

.peg-group-old .peg-card + .peg-card {
  margin-left: -28px;
}

/* Earlier rounds: darkened but solid — nothing shows through. */
.peg-group-old .peg-card {
  filter: brightness(0.62) saturate(0.75);
}

/* Short-lived callout: "Fifteen for 2", "Go", "31 for 2"... */
.peg-toast {
  position: absolute;
  left: 50%;
  bottom: -14px;
  transform: translateX(-50%);
  white-space: nowrap;
  background: var(--brass);
  color: var(--felt-shadow);
  font-family: var(--font-display);
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 999px;
  box-shadow: var(--shadow-card);
  z-index: 5;
}

/* ---- Show (counting) modal --------------------------------------------- */
/* Wider than the 320px default modal: five cards plus a points column. */
.modal.show-modal {
  width: 440px;
}

.show-modal .modal-body {
  padding: 16px;
}

.show-cards {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}

/* The starter, shown last and set slightly apart. */
.show-cards .show-starter {
  margin-left: 12px;
}

.show-breakdown {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  max-height: 40vh;
  overflow-y: auto;
}

.show-breakdown li {
  text-align: left;
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 12px;
  align-items: baseline;
  padding: 4px 2px;
  border-bottom: 1px solid rgba(27, 67, 50, 0.12);
  color: var(--ink);
}

.show-breakdown .show-item-cards {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.show-breakdown .show-item-points {
  font-weight: 700;
  color: var(--felt-deep);
}

.show-breakdown .show-item-running {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-soft);
  min-width: 3ch;
  text-align: right;
}

/* Red suits read as red in the text breakdown. */
.suit-red {
  color: var(--danger-red);
}

.show-total {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--felt-deep);
  text-align: center;
  margin: 8px 0 14px;
}

/* ---- 5b: deck, crib, guidance line ------------------------------------ */
/* The deck when it's your turn to cut the starter. */
.deck-pile.deck-tappable {
  cursor: pointer;
}

.deck-pile.deck-tappable .deck-pile-card .card {
  box-shadow: 0 0 0 3px var(--brass), var(--card-shadow-lift);
  animation: deck-nudge 1.6s ease-in-out infinite;
}

@keyframes deck-nudge {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

/* Face-down crib cards, stacked slightly offset like a squared-up pile. */
.crib-pile .crib-stack-card {
  position: absolute;
  inset: 0;
  cursor: default;
}

/* One line of guidance in the middle panel ("Choose 2 cards…"). */
.table-message {
  margin: 0;
  align-self: center;
  color: rgba(245, 240, 230, 0.75);
  font-family: var(--font-display);
  font-size: 0.95rem;
  text-align: center;
}

/* The opponent's row lights up on their turn, like yours does. */
.other-hand-row.slot-active {
  border-radius: var(--radius-panel);
  box-shadow: 0 0 0 2px var(--brass);
  padding: 4px 8px;
}

/* Cards in your hand that can't be picked right now. */
.your-hand-row .card[style*="cursor: default"] {
  cursor: default;
}

/* ---- 5c: the play ------------------------------------------------------ */
/* Cards you can play right now lift a little on hover (from Rummy's hand
   rules); cards that would pass 31 fade back. */
.your-hand-row .card.card-unplayable {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Played cards: a small tab along the top edge in the color of whoever
   played them. */
.peg-cards .peg-card {
  position: relative;
  cursor: default;
}

/* Who played it: a small dot in the card's lower-left corner — the one
   corner that stays visible when cards overlap. */
.peg-cards .peg-seat-dot {
  position: absolute;
  left: 5px;
  bottom: 5px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}

.pegging-zone .table-message {
  margin-top: 8px;
}

/* ---- Cutting from a spread deck ---------------------------------------- */
/* The cut for deal: the whole deck fanned across the card. */
#draw-off-screen .draw-off-deck-row {
  width: 100%;
}

#draw-off-deck.cut-spread,
#draw-off-deck {
  position: relative;
  width: 100%;
  min-height: 120px;
  cursor: default;
}

/* The starter cut: the 40 undealt cards fanned over the middle of the
   table. */
.crib-table-row {
  position: relative;
}

.starter-spread {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 20;
  pointer-events: none;
}

.spread-card {
  position: absolute;
  margin: 0;
  cursor: default;
  transform-origin: 50% 100%;
  transition: translate 0.15s ease;
  pointer-events: none;
}

.spread-interactive .spread-card-pickable {
  pointer-events: auto;
  cursor: pointer;
}

/* Hovering lifts a card out of the spread (translate is separate from the
   rotate the arc sets inline, so the two combine). */
.spread-interactive .spread-card-pickable:hover {
  translate: 0 -12px;
}

/* A picked card on its way: drawn above everything. */
.flying-card {
  position: fixed;
  margin: 0;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.45);
}

/* ---- Game over: next steps on the table -------------------------------- */
.gameover-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
}

.gameover-bar .btn {
  width: auto;
  margin: 0;
  padding: 8px 16px;
}

/* The Hint button while its hint is showing (click again to hide it). */
#hint-btn.hint-on {
  background: #ffd700;
  border-color: #ffd700;
  color: #1a1a1a;
}

/* ---- Drag-to-play ------------------------------------------------------ */
/* Playable cards can be dragged (and still tapped). touch-action: none
   lets a finger drag the card instead of scrolling the page. */
.your-hand-row .card.card-playable {
  cursor: grab;
  touch-action: none;
}

.drag-ghost {
  cursor: grabbing;
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.5);
}

/* The middle of the table lights up while a card is dragged over it. */
.pegging-zone.drop-target {
  border-color: var(--brass);
  box-shadow: inset 0 0 0 2px var(--brass);
}

/* ---- Phones ------------------------------------------------------------ */
@media (max-width: 640px) {
  .crib-table-row {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "deck crib"
      "play play";
    gap: 12px;
  }

  #deck-zone { grid-area: deck;
  }

  #crib-zone { grid-area: crib;
  }

  #pegging-zone { grid-area: play;
  }

  .peg-count-value {
    font-size: 1.6rem;
  }

  /* Six cards fit on one line: tighter overlap, and the "My hand" label
     (which reserves 90px on the left) steps aside. */
  #quadrant-me .hand-label {
    display: none;
  }

  #quadrant-me .your-hand-row {
    padding-left: 8px;
  }

  #quadrant-me .your-hand-row .card {
    margin-left: -44px;
  }

  #quadrant-me .your-hand-row .card:first-child {
    margin-left: 0;
  }

}

