/* hearts-game.css — table page layout for hearts.gameshack.org */

/* Optional "Hide top header" setting — hides the SHARED site header/nav
   (from header.php, used by all five GameShack games) via a rule that
   only exists in this stylesheet, which only loads on Hearts' own
   pages. Never touches header.php itself, so this has zero effect on
   any other game. */
body.hearts-hide-header .site-header,
body.hearts-hide-header .site-nav {
  display: none !important;
}

/* Match the shared paper background on <html> itself, so any sliver below
   a short page (viewport taller than content) doesn't show browser-default
   white instead of the site's cream. */
html {
  background: var(--paper);
}

.table-page {
  max-width: 900px;
  margin: 0 auto;
  padding: 0;
}

.is-hidden {
  display: none !important;
}

/* Name entry */
.name-entry {
  max-width: 320px;
  margin: 2rem auto;
  text-align: center;
}
.name-entry input {
  display: block;
  width: 100%;
  margin: 0.5rem 0 1rem;
  padding: 0.7rem 0.85rem;
  font-size: 1rem;
  border: 1px solid rgba(24, 43, 58, 0.25);
  border-radius: 4px;
}

.name-entry button,
.passing-bar button,
.modal__inner button {
  background: var(--gold);
  color: var(--navy);
  border: none;
  border-radius: 4px;
  padding: 0.65rem 1.4rem;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.15s ease;
}
.name-entry button:hover,
.passing-bar button:hover,
.modal__inner button:hover {
  filter: brightness(0.92);
}
.passing-bar button:disabled {
  background: rgba(232, 169, 59, 0.4);
  cursor: not-allowed;
}

/* Full-bleed green table — spans the entire viewport edge-to-edge and
   fills the space between header and footer, same technique as the
   lobby's green band. Seats, trick area, AND the player's own hand all
   live inside this one continuous zone. */
.table-wrap {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-top: -2.5rem;
  margin-bottom: -4rem;
  background: #1B4332;
  padding: 1rem 1.5rem 1.5rem;
  min-height: calc(100vh - 160px); /* tightened from 200px to reclaim some vertical room */
  display: flex;
  flex-direction: column;
}

/* Table top bar — join code (so a returning player can note it down
   and rejoin later via the lobby's "Join Game" form) and a way to
   actually leave. Leaving doesn't end or delete the game — state just
   persists in PocketBase and resumes automatically when this same code
   is opened again, so this doubles as the "suspend" mechanism. */
.table-topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  color: #fff;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
  opacity: 0.85;
}
.table-topbar__code strong {
  color: #ffe9b3;
  letter-spacing: 0.05em;
}
.table-topbar__actions {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.table-topbar__leave {
  color: #fff;
  text-decoration: underline;
}
.table-topbar__leave:hover {
  color: #ffe9b3;
}
.table-topbar__cancel {
  background: none;
  border: none;
  color: #ffb3b3;
  text-decoration: underline;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0;
}
.table-topbar__cancel:hover {
  color: #ff8a8a;
}

/* Scoreboard */
.scoreboard {
  /* Now nested inside .table-topbar, which sets a smaller font-size and
     reduced opacity for its own code/actions text — reset both
     explicitly here so scores stay clearly legible rather than
     inheriting that dimmer styling. */
  display: flex;
  justify-content: center;
  gap: 1.2rem;
  flex-wrap: wrap;
  font-size: 0.95rem;
  font-weight: 600;
  color: #fff;
  opacity: 1;
}

/* Table felt + seats — now includes the hand row as its bottom grid row */
.table-felt {
  position: relative;
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto auto auto;
  align-content: center;
  gap: 0.5rem;
  /* Widened from 900px — that cap was confining the left/right seats to
     a narrow strip regardless of how wide the actual window was,
     leaving a lot of unused green on both sides on wider screens. The
     trick area stays centered either way (it's absolutely positioned
     within .table-middle-zone, which spans the full felt width), so
     widening this just gives the side seats genuine room to spread out
     at full card size instead of needing to shrink to fit. */
  max-width: 1300px;
  margin: 0 auto;
  width: 100%;
}

.seat {
  color: #fff;
  text-align: center;
  padding: 0.5rem;
}
.seat--top    { grid-column: 2; grid-row: 1; }

/* Small hero graphic in row 1's otherwise-empty first column — the top
   seat only occupies the center column, leaving the columns beside it
   in that same row unused. Placed here rather than in the topbar (too
   short to fit the artwork legibly) or anywhere that would need to grow
   a row's height (which would push hands down) — this space was already
   reserved by the top seat's own height, doing double duty at no cost. */
.table-felt__hero {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  justify-self: start;
  /* Matched to roughly how wide the same logo renders on gameshack.org's
     own landing-page card — that version is fluid (100% of its card's
     width, which itself resizes with the grid), so there's no exact
     fixed match, but ~210px is close to its typical size on a normal
     desktop window with 5 games in the grid.
     Set as a direct width, not width:100%/max-width — percentage-width
     sizing on a grid item with justify-self other than stretch can
     resolve inconsistently, which is likely why bumping max-width alone
     didn't visibly change anything. */
  width: 210px;
  height: auto;
  /* No border-radius/opacity dimming needed now that the artwork has a
     real transparent background — the cards + lettering sit directly
     on the green felt the same way every other card-shaped element on
     the table does, rather than looking like a box laid on top of it. */
}

/* Middle zone: left seat, trick area, right seat. Given its own
   min-height matching the trick area's own size, guaranteeing enough
   room regardless of how tall the side seats' own content (piles,
   hand-stacks) happens to be at any given moment — previously the trick
   area centered within the WHOLE table-felt box, whose height was only
   as tall as its actual content needed, so when that was short the
   trick area's centered position pushed its bottom edge down into
   where the hand row renders, covering played cards. */
.table-middle-zone {
  grid-column: 1 / span 3;
  grid-row: 2;
  position: relative;
  min-height: 330px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  align-items: center;
}
.seat--left   { grid-column: 1; }
.seat--right  { grid-column: 3; }

.seat__name.is-turn,
.my-seat-name.is-turn {
  color: #ffd54f;
  font-weight: 700;
}

.seat__points {
  font-size: 0.85rem;
  color: #ffe9b3;
  opacity: 0.9;
}

/* Belt-and-suspenders: pin the color on the player's own points line
   directly by ID, in case something else in the cascade (shared site
   styles, a more specific ancestor rule) was winning over the shared
   .seat__points class for this particular instance. */
#mySeatPoints {
  color: #ffe9b3 !important;
}

/* Row (top seat: hand-left, info-middle, tricks-right) vs column
   (left/right seats: hand-above, info-middle, tricks-below) layouts. */
.seat__row {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.seat__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}
.seat__info {
  text-align: center;
}

.stack-group {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.stack-label {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #ffe9b3;
  opacity: 0.85;
  margin-bottom: 0.2rem;
}

.my-seat-name-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-bottom: 0.4rem;
}

/* Only ever shown when a sweep is genuinely, mathematically guaranteed
   — see HL.canSweepRemainingTricks — so it's styled to stand out rather
   than blend in like an ordinary secondary action. */
.sweep-btn {
  background: var(--gold);
  color: var(--navy);
  border: none;
  border-radius: 4px;
  padding: 0.4rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.15s ease;
}
.sweep-btn:hover {
  filter: brightness(0.92);
}

/* Hand + tricks-won pile side by side, rather than stacked — the pile
   can grow to a full card's height once tricks are won, and stacking
   it above the fan was costing significant vertical space that's in
   short supply on shorter screens. */
.my-hand-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}
.my-hand-row__center {
  flex: 1;
  min-width: 0; /* lets the fan's own overflow-x:auto scroll correctly inside a flex child */
}

/* Hand-stack — small card-back stack representing a seat's remaining
   hand (opponents only; the player's own real cards are shown in full
   below, so no stack is rendered for their own seat). */
.hand-stack-wrap {
  min-height: 162px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Same footprint as the main .card so opponents' hand-stacks read at
   the same size as the player's own cards, not a shrunken-down version. */
.hand-stack {
  position: relative;
  width: 108px;
  height: 157px;
}
.hand-stack__back {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: drop-shadow(1px 1px 0 rgba(0,0,0,0.3)) drop-shadow(2px 2px 0 rgba(0,0,0,0.15));
}
.hand-stack__count {
  position: absolute;
  bottom: -8px;
  right: -8px;
  background: var(--gold);
  color: var(--navy);
  font-size: 0.75rem;
  font-weight: 700;
  border-radius: 50%;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4);
}

/* Taken-trick pile — an actual card-back image (same size as the main
   .card / hand-stack) with a gold count badge, rather than a plain
   colored box, so it reads as "a stack of cards this seat has won"
   instead of an abstract counter. */
.seat__pile {
  min-height: 24px; /* just enough for the label — was reserving a full
  card's-worth of empty space even before any trick had been won */
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 0.25rem;
}
.taken-pile {
  position: relative;
  width: 108px;
  height: 157px;
}
.taken-pile__back {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: drop-shadow(1px 1px 0 rgba(0,0,0,0.3)) drop-shadow(2px 2px 0 rgba(0,0,0,0.15));
}
.taken-pile__count {
  position: absolute;
  bottom: -12px;
  right: -12px;
  background: var(--gold) !important;
  color: var(--navy) !important;
  font-size: 1rem;
  font-weight: 700;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4);
}

/* Trick-flyer: a transient, absolutely-positioned clone of a completed
   trick's cards that animates toward the winning seat's pile before
   being removed. Purely cosmetic — the real game state has already
   moved on by the time this plays. */
.trick-flyer {
  position: fixed;
  display: flex;
  gap: 2px;
  pointer-events: none;
  z-index: 200;
  transition: transform 0.6s ease, opacity 0.6s ease;
}
.trick-flyer .card-svg {
  width: 72px;
  height: auto;
}

/* Card-flyer: a single card animating from a player's hand toward the
   trick area the moment it's played. */
.card-flyer {
  position: fixed;
  width: 108px;
  height: 157px;
  pointer-events: none;
  z-index: 200;
  transition: transform 0.5s ease, opacity 0.5s ease;
}
.card-flyer .card-svg {
  width: 100%;
  height: 100%;
}

.trick-area {
  /* Absolutely positioned relative to .table-middle-zone (not a grid
     participant itself), dead-centered within that zone rather than
     sitting in the outer grid's row 2 alongside the left/right seat
     columns. Two problems this solves together: (1) when a seat's
     taken pile first appears (jumping from nothing to a full
     card-height image), that grows its column's height, which used to
     shift the whole trick-area box on the page; (2) .table-middle-zone
     has its own guaranteed min-height matching this box's own size, so
     centering here can never push the trick area's bottom edge down
     into the hand row below when the side columns are short. */
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* Fixed 2x2 box (2 cards + a gap, each direction) so each corner has
     a stable place to land, rather than flex-centering cards in
     chronological play order. */
  width: 232px;
  height: 330px;
}

.trick-area .card--played {
  position: absolute;
}
.trick-card--top-left    { top: 0; left: 0; }
.trick-card--top-right   { top: 0; right: 0; }
.trick-card--bottom-left { bottom: 0; left: 0; }
.trick-card--bottom-right { bottom: 0; right: 0; }

.waiting-message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  text-align: center;
  color: #fff;
}
.waiting-message__title {
  font-size: 1.1rem;
  font-weight: 600;
  margin: 0 0 0.3rem;
}
.waiting-message__count {
  color: #ffe9b3;
  margin: 0 0 0.3rem;
}
.waiting-message__names {
  font-size: 0.85rem;
  opacity: 0.8;
  margin: 0;
}

.my-hand-wrap {
  grid-column: 1 / span 3;
  grid-row: 3;
  text-align: center;
  padding-top: 0.25rem;
}

.my-seat-name {
  color: #fff;
  font-size: 1.05rem;
  margin-bottom: 0.25rem;
}

/* Cards — rendered from the shared svg-cards.svg sprite via <use> */
.card {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 108px;
  height: 157px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  user-select: none;
  transition: transform 0.1s ease;
}
.card-svg {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.35));
}
.card--played {
  cursor: default;
}
.card--selected {
  transform: translateY(-10px);
  z-index: 10;
}
.card--disabled {
  /* No opacity reduction — in a fan layout, transparent cards let
     whatever's behind them (an adjacent overlapping disabled card, e.g.
     two hearts sitting next to each other) bleed through and blend into
     a muddy double-exposure. Fully opaque + grayscale/darkened conveys
     "disabled" without that artifact, since opaque elements properly
     occlude what's behind them regardless of overlap. */
  filter: grayscale(100%) brightness(0.75);
  cursor: not-allowed;
}
.card--playable:hover {
  transform: translateY(-6px);
  z-index: 10;
}

/* Overlapping "fan" layout for the player's own hand, so 13 cards don't
   need 13 full card-widths of horizontal space. flex-wrap: wrap was a
   bug here — if the row ran out of horizontal room, cards would break
   to a second line with broken overlap math (:first-child only zeroes
   the margin on the true first card, not each wrapped row's first
   card), producing a jumbled stair-step instead of a clean fan. nowrap
   + horizontal scroll keeps it a single clean row on any screen width. */
.my-hand--fan {
  display: flex;
  justify-content: center;
  flex-wrap: nowrap;
  overflow-x: auto;
  /* Top padding matters here, not just cosmetic spacing: setting
     overflow-x to anything but visible forces overflow-y to become
     'auto' too (a CSS behavior, not a bug) — with zero top padding, a
     selected card's translateY(-10px) pop-up had nowhere to go and got
     clipped clean off at the container's own top edge. */
  padding: 16px 1rem 0;
}
.my-hand--fan .card {
  margin-left: -50px;
  flex-shrink: 0;
}
.my-hand--fan .card:first-child {
  margin-left: 0;
}

.passing-bar {
  margin-bottom: 0.5rem;
  color: #fff;
}
.passing-bar button {
  margin-left: 0.5rem;
}

/* Modals */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.modal__inner {
  background: #fff;
  border-radius: 8px;
  padding: 1.5rem;
  max-width: 480px;
  text-align: center;
}
.modal__inner button,
.modal__inner .btn {
  margin-top: 1rem;
  display: inline-block;
}

/* Per-hand score table shown in the hand-over modal — hand deltas per
   round plus a cumulative Total row, pulled from the actual persisted
   hand records rather than tracked only in memory. */
.score-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.75rem;
  font-size: 0.9rem;
}
.score-table th,
.score-table td {
  padding: 0.4rem 0.5rem;
  text-align: center;
  border-bottom: 1px solid rgba(24, 43, 58, 0.12);
}
.score-table th {
  color: var(--navy);
  font-weight: 700;
}
.score-table td:first-child,
.score-table th:first-child {
  text-align: left;
  color: var(--brick);
}
.score-table__total td {
  font-weight: 700;
  color: var(--navy);
  border-top: 2px solid var(--navy);
  border-bottom: none;
}

/* Lobby (index.php) — uses the shared site's --navy/--paper/--gold/--ink/--brick tokens */

/* Full-bleed green: breaks out of the shared <main> max-width container
   so it spans the entire viewport edge-to-edge, not just the content column. */
.game-lobby {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-top: -2.5rem;
  margin-bottom: -4rem;
  background: #1B4332;
  padding: 2.5rem 1.5rem;
}

.lobby-card {
  position: relative;
  max-width: 760px;
  margin: 0 auto;
  text-align: center;
  /* Sampled directly from hearts-hero.png's background (~253,248,230)
     rather than the site's --paper token, so the card and the image
     blend seamlessly instead of showing a visible seam. */
  background: #FDF8E6;
  border: 1px solid rgba(24, 43, 58, 0.12);
  border-radius: 8px;
  padding: 2rem 1.75rem;
}

.rules-btn {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--gold);
  color: var(--navy);
  border: none;
  font-size: 1.1rem;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.15s ease;
}
.rules-btn:hover {
  filter: brightness(0.92);
}

.rules-modal__inner {
  max-width: 560px;
  max-height: 85vh;
  overflow-y: auto;
  text-align: left;
  position: relative;
  padding-top: 2.5rem;
}
.rules-modal__inner h2 {
  text-align: center;
  margin-top: 0;
}
.rules-modal__inner h3 {
  color: var(--navy);
  margin-bottom: 0.3rem;
}
.rules-modal__inner p {
  margin-top: 0;
  margin-bottom: 1rem;
  line-height: 1.5;
}
.modal__close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid rgba(24, 43, 58, 0.25);
  color: var(--navy);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}
.modal__close:hover {
  background: rgba(24, 43, 58, 0.08);
}

.lobby-card__logo {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  margin: 0 auto 1.5rem;
  border-radius: 6px;
}

.lobby-card__tagline {
  color: var(--brick);
  font-size: 1.05rem;
  max-width: 34rem;
  margin: 0.5rem auto 1.5rem;
}

.lobby-columns {
  display: flex;
  align-items: flex-start;
  gap: 2rem;
}

.lobby-section {
  flex: 1 1 0;
}

.lobby-section--join {
  border-left: 1px solid rgba(24, 43, 58, 0.15);
  padding-left: 2rem;
}

@media (max-width: 640px) {
  .lobby-columns {
    flex-direction: column;
  }
  .lobby-section--join {
    border-left: none;
    border-top: 1px solid rgba(24, 43, 58, 0.15);
    padding-left: 0;
    padding-top: 1.5rem;
    width: 100%;
  }
}

.lobby-section h2 {
  margin-top: 0;
}

.lobby-form label,
.lobby-form__label,
.lobby-section label {
  display: block;
  font-weight: 600;
  color: var(--navy);
  margin: 1.25rem 0 0.4rem;
  text-align: left;
}

.lobby-section input[type="text"],
.invite-email-field input {
  width: 100%;
  padding: 0.7rem 0.85rem;
  font-size: 1rem;
  border: 1px solid rgba(24, 43, 58, 0.25);
  border-radius: 4px;
  background: #fff;
  color: var(--ink);
}

.player-count-select {
  width: 100%;
  padding: 0.7rem 0.85rem;
  font-size: 1rem;
  border: 1px solid rgba(24, 43, 58, 0.25);
  border-radius: 4px;
  background: #fff;
  color: var(--ink);
  appearance: auto;
}

.lobby-form__hint {
  font-size: 0.85rem;
  color: var(--brick);
  margin: 0.4rem 0 0;
  text-align: left;
}

.invite-emails {
  margin: 1.25rem 0 0.5rem;
  text-align: left;
}
.invite-email-field {
  margin-bottom: 0.9rem;
}
.invite-email-field label {
  margin: 0 0 0.35rem;
}

/* Buttons — gold accent, matching the site's hover/active convention */
.lobby-section button,
.btn {
  background: var(--gold);
  color: var(--navy);
  border: none;
  border-radius: 4px;
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  margin-top: 1.5rem;
  width: 100%;
  transition: filter 0.15s ease;
}
.lobby-section button:hover,
.btn:hover {
  filter: brightness(0.92);
}
.lobby-section button:disabled {
  background: rgba(232, 169, 59, 0.4);
  cursor: not-allowed;
}

.btn {
  display: inline-block;
  text-decoration: none;
  width: auto;
}

.game-over-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
}
.game-over-actions .btn {
  margin-top: 0;
}
.btn--secondary {
  background: transparent;
  color: var(--navy);
  border: 1px solid rgba(24, 43, 58, 0.3);
}
.btn--secondary:hover {
  background: rgba(24, 43, 58, 0.06);
}
.game-over-actions .btn:disabled {
  background: rgba(232, 169, 59, 0.4);
  cursor: not-allowed;
}

.lobby-section form {
  display: flex;
  flex-direction: column;
}

.game-created-result {
  max-width: 460px;
  margin: 1.5rem auto 0;
  text-align: center;
  background: var(--paper);
  border: 1px solid rgba(24, 43, 58, 0.12);
  border-radius: 8px;
  padding: 2rem 1.75rem;
}

/* "Your Games" — locally-remembered games this browser can rejoin. */
/* "Rejoin Games" — now a sub-section within the Join Game column rather
   than its own standalone card, so it just needs spacing/heading style,
   not a full card background/border of its own. */
.my-games {
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(24, 43, 58, 0.15);
  text-align: left;
}
.my-games h3 {
  margin: 0 0 0.6rem;
  font-size: 0.95rem;
  color: var(--navy);
}
.my-games__item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.6rem 0.75rem;
  margin-bottom: 0.5rem;
  background: #fff;
  border: 1px solid rgba(24, 43, 58, 0.15);
  border-radius: 4px;
}
.my-games__item:hover {
  filter: brightness(0.96);
}
.my-games__item:last-child {
  margin-bottom: 0;
}
.my-games__link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
  flex: 1;
  cursor: pointer;
}
.my-games__code {
  font-weight: 700;
  letter-spacing: 0.1em;
  color: #fff;
  background: #1B4332;
  border: 1px solid #1B4332;
  border-radius: 4px;
  padding: 0.3rem 0.7rem;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.my-games__link:hover .my-games__code {
  background: #24573f;
  border-color: #24573f;
}
.my-games__date {
  font-size: 0.8rem;
  color: var(--brick);
}
.my-games__cancel {
  background: #fff;
  border: 1px solid rgba(24, 43, 58, 0.25);
  color: var(--brick);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0.4rem 0.8rem;
  margin-left: 0.5rem;
  border-radius: 4px;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.my-games__cancel:hover {
  background: #fdeceb;
  border-color: #c0392b;
  color: #c0392b;
}

.join-code {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  color: var(--navy);
  background: #fff;
  border-radius: 4px;
  padding: 0.5rem 1rem;
  display: inline-block;
  margin: 0.75rem 0;
}

.copy-link-btn {
  display: inline-block;
  background: #fff;
  color: var(--navy);
  border: 1px solid rgba(24, 43, 58, 0.3);
  border-radius: 4px;
  padding: 0.5rem 1.1rem;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  margin: 0 0 0.75rem;
  transition: filter 0.15s ease;
}
.copy-link-btn:hover {
  filter: brightness(0.96);
}
.copy-link-btn:disabled {
  color: var(--brick);
  cursor: default;
}

/* Tablet (iPad portrait/landscape and similar ~641–1024px widths): the
   640px-only mobile tier below doesn't catch these, so a full 13-card
   hand at desktop size (888px wide) doesn't fit an iPad's viewport
   without horizontal scrolling. Sized so 13 overlapping cards land
   around 660px wide — comfortably inside an iPad's content area. */
@media (min-width: 641px) and (max-width: 1024px) {
  .table-felt__hero {
    width: 145px;
  }
  .card {
    width: 90px;
    height: 131px;
  }
  .hand-stack {
    width: 90px;
    height: 131px;
  }
  .taken-pile {
    width: 90px;
    height: 131px;
  }
  .card-flyer {
    width: 90px;
    height: 131px;
  }
  .trick-flyer .card-svg {
    width: 60px;
  }
  .my-hand--fan .card {
    margin-left: -42px;
  }
  .taken-pile__count {
    width: 24px;
    height: 24px;
    font-size: 0.75rem;
    bottom: -9px;
    right: -9px;
  }
  .hand-stack-wrap {
    min-height: 150px;
  }
  .trick-area {
    width: 192px;
    height: 274px;
  }
  .table-middle-zone {
    min-height: 274px;
  }
}

/* Mobile: cards at 60% of desktop size (a 40% reduction), scaling every
   card-related dimension together — the base card, hand-stacks, taken
   piles, both flyer animations, the fan overlap, and the badge — so
   proportions stay consistent rather than just shrinking the card. */
@media (max-width: 640px) {
  .table-felt__hero {
    display: none; /* no real room for it at phone width */
  }
  .card {
    width: 72px;
    height: 104px;
  }
  .hand-stack {
    width: 72px;
    height: 104px;
  }
  .taken-pile {
    width: 72px;
    height: 104px;
  }
  .card-flyer {
    width: 72px;
    height: 104px;
  }
  .trick-flyer .card-svg {
    width: 48px;
  }
  .my-hand--fan .card {
    margin-left: -34px;
  }
  .taken-pile__count {
    width: 19px;
    height: 19px;
    font-size: 0.6rem;
    bottom: -7px;
    right: -7px;
  }
  .hand-stack-wrap {
    min-height: 108px;
  }
  .seat__pile {
    min-height: 24px; /* unchanged — still just enough for the empty-pile case */
  }
  .trick-area {
    width: 154px;
    height: 218px;
  }
  .table-middle-zone {
    min-height: 218px;
  }
}

/* Chat — adapted from Rummy's rummy_chat implementation. Now a normal
   inline item in the topbar (next to Leave Table) rather than a
   viewport-fixed floating bubble — the fixed version overlapped the
   shared site header above the green table surface. Only shown when
   there are 2+ human seats (chatting with just yourself + bots isn't
   useful). */
.chat-toggle-btn {
  position: relative;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  background: transparent;
  color: #fff;
  font-size: 0.9rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
}
.chat-toggle-btn:hover {
  background: var(--gold);
  color: var(--navy);
}

.chat-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 8px;
  background: #c0392b;
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Sweep banner — visible to every connected client for the duration of
   a sweep, positioned top-right (anchored to .table-wrap, same as the
   chat panel below it), regardless of whether anyone has chat open. */
.sweep-banner {
  position: absolute;
  top: 60px;
  right: 20px;
  background: var(--gold);
  color: var(--navy);
  font-weight: 700;
  font-size: 0.95rem;
  padding: 0.6rem 1.1rem;
  border-radius: 6px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
  z-index: 96; /* above the chat panel/toggle so it's never hidden behind them */
  animation: sweep-banner-pulse 1s ease-in-out infinite alternate;
}
@keyframes sweep-banner-pulse {
  from { opacity: 0.85; }
  to { opacity: 1; }
}

.chat-panel {
  /* Absolute relative to .table-wrap (position:relative), not fixed to
     the viewport — keeps it anchored inside the green table surface
     itself rather than floating over the page. */
  position: absolute;
  top: 60px;
  right: 20px;
  width: 300px;
  max-width: calc(100vw - 32px);
  height: 380px;
  max-height: calc(100% - 80px);
  background: var(--paper);
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 95;
}

.chat-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--navy);
  color: #fff;
  padding: 10px 14px;
  font-weight: 700;
  cursor: grab;
  user-select: none;
  touch-action: none; /* prevents the browser from treating a drag as a page scroll gesture on touch */
}
.chat-panel__header:active {
  cursor: grabbing;
}
.chat-panel__close {
  background: transparent;
  border: none;
  color: #fff;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.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(232, 169, 59, 0.3);
  color: var(--ink);
}
.chat-message--theirs {
  align-self: flex-start;
  background: rgba(24, 43, 58, 0.1);
  color: var(--ink);
}
.chat-message__sender {
  font-size: 0.7rem;
  font-weight: 700;
  opacity: 0.65;
  display: block;
  margin-bottom: 2px;
}

/* Settings gear + panel — sound and auto-open-chat toggles, consolidated
   here rather than scattered as standalone controls. Reuses the chat
   panel's visual language (same header/close-button styles) for
   consistency, positioned to its left so the two don't overlap when
   both happen to be open. */
.settings-toggle-btn {
  position: relative;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  background: transparent;
  color: #fff;
  font-size: 0.9rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
}
.settings-toggle-btn:hover {
  background: var(--gold);
  color: var(--navy);
}

.settings-panel {
  position: absolute;
  top: 60px;
  right: 90px;
  width: 260px;
  max-width: calc(100vw - 32px);
  background: var(--paper);
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  overflow: hidden;
  z-index: 95;
}
.settings-panel__body {
  padding: 12px 16px;
}
.settings-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 8px 0;
  font-size: 0.9rem;
  color: var(--ink);
  cursor: pointer;
}

.chat-input-row {
  display: flex;
  gap: 6px;
  padding: 10px;
  border-top: 1px solid rgba(24, 43, 58, 0.12);
}
.chat-input-row input {
  flex: 1;
  padding: 8px 10px;
  border: 1px solid rgba(24, 43, 58, 0.25);
  border-radius: 4px;
  font-size: 0.9rem;
}
.chat-input-row button {
  padding: 8px 14px;
  background: var(--gold);
  color: var(--navy);
  border: none;
  border-radius: 4px;
  font-weight: 600;
  cursor: pointer;
}
.chat-input-row button:hover {
  filter: brightness(0.92);
}

