/* ==========================================================================
   big2.css — the Big Two table. Four seats (you at the bottom, opponents
   left/top/right), a played-card zone per seat, and a hand that must stay
   entirely on screen (no edge-clipping — see .b2-hand below). A separate
   implementation from table.css's three-seat Dou Di Zhu felt: nothing here
   is shared with .table/.felt/.seat/.play, only the tokens both read and the
   bare .card box table.css defines (width/aspect-ratio/colour), which every
   table in the app reuses. Sizes below are tuned and measured at 844x390,
   844x330 and 1280x720 — anything expressed in vh rather than px is there so
   a phone's browser-bar height (844x330) shrinks the whole table together
   instead of clipping it.
   ========================================================================== */

.b2-table {
  position: fixed; inset: 0; display: grid; overflow: hidden;
  grid-template-rows: auto 1fr auto;
  --card-w: clamp(36px, 6vw, 70px);
  background:
    radial-gradient(60% 50% at 50% 38%, rgba(255, 255, 255, 0.08), transparent 70%),
    radial-gradient(120% 100% at 50% 120%, rgba(0, 0, 0, 0.55), transparent 60%),
    linear-gradient(170deg, var(--felt-table), #0c3326 55%, #071c15);
}

/* --- head-up display ------------------------------------------------------- */

.b2-hud {
  display: flex; align-items: center; gap: clamp(8px, 1.6vw, 18px);
  padding: 6px clamp(10px, 2vw, 22px);
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0.08));
  border-bottom: 1px solid var(--hairline);
  font-size: clamp(11px, 1.5vw, 14px);
}
.b2-hud__spacer { flex: 1; }
.b2-hud__pill {
  display: flex; align-items: baseline; gap: 6px; white-space: nowrap;
  padding: 4px 10px; border-radius: var(--r-pill);
  border: 1px solid var(--hairline-strong); background: rgba(0, 0, 0, 0.3);
}
.b2-hud__pill b { font-size: 1.2em; font-weight: 600; color: var(--gold-bright); font-variant-numeric: lining-nums tabular-nums; }
.b2-hud__pill--table b { color: var(--text); font-weight: 400; }
.b2-hud__pill--table small { margin-left: 4px; }
.b2-hud__pill small { font-size: 0.78em; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-tertiary); }
.b2-hud .back-link { font-size: 1.25em; padding: 2px 8px; line-height: 1; }

/* --- felt -------------------------------------------------------------------
   seatTop, playTop, a flexible spacer, playSelf and controls are real flow
   children of this column now, not four independent top:NN% guesses: a
   fixed percentage for playTop and playSelf, tuned only against their own
   card row, is exactly what let each zone's caption (positioned outside
   that row, see .b2-play__name below) reach into the other's space without
   either box's height accounting for it. Flow makes the caption part of its
   own zone's height, so the spacer — not arithmetic — is what keeps them
   apart, at every viewport this table supports. Left/right seats and plays
   float beside this column and stay position:absolute, unchanged. */

.b2-felt { position: relative; min-height: 0; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.b2-spacer { flex: 1 1 0; }

.b2-seat {
  display: flex; flex-direction: column; gap: 4px; align-items: center;
  width: clamp(100px, 17vw, 176px);
}
/* flex-shrink:0 — a flex column's default shrink would rather compress this
   box below its content size than let the spacer do it, and a compressed
   box's overflowing content is what re-creates the exact sibling-overlap
   this whole restructure exists to remove. Only .b2-spacer may give. */
.b2-seat--top { margin-top: clamp(2px, 1vh, 8px); flex-shrink: 0; }
.b2-seat--left, .b2-seat--right { position: absolute; top: 50%; transform: translateY(-50%); }
.b2-seat--left { left: clamp(4px, 1.4vw, 16px); align-items: flex-start; }
.b2-seat--right { right: clamp(4px, 1.4vw, 16px); align-items: flex-end; }

.b2-seat__plate {
  display: flex; align-items: center; gap: 6px; padding: 4px 10px 4px 6px;
  border-radius: var(--r-pill); border: 1px solid var(--hairline-strong);
  background: rgba(0, 0, 0, 0.42); font-size: clamp(11px, 1.4vw, 13.5px); max-width: 100%;
}
.b2-seat__plate.is-turn { border-color: var(--gold-bright); box-shadow: 0 0 0 2px rgba(239, 219, 166, 0.22); }
.b2-seat__avatar {
  width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; flex: none;
  font-size: 12px; font-weight: 600; color: #201a08;
  background: linear-gradient(160deg, var(--gold-bright), #a98a48);
}
.b2-seat__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 12ch; }
.b2-seat__count { color: var(--gold); white-space: nowrap; font-variant-numeric: lining-nums tabular-nums; }
/* Rose-gold, tokens only (F4): the one hand a follower most needs to notice. */
.b2-seat__count.is-last-card { color: var(--rose-ink-1); font-weight: 600; }

.b2-seat__backs { display: flex; justify-content: center; max-width: 100%; }
.b2-seat__backs .card {
  --card-w: clamp(20px, 4.6vh, 32px);
  margin-left: calc(var(--card-w) * -0.62);
  box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.4);
}
.b2-seat__backs .card:first-child { margin-left: 0; }
/* Hand end: the stack becomes the real, face-up hand, revealed in place — a
   touch bigger than the backs it replaces, since it is now meant to be read. */
.b2-seat__backs.is-revealed .card { --card-w: clamp(24px, 5.4vh, 40px); margin-left: calc(var(--card-w) * -0.42); box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.35); }

/* --- the trick, one landing zone per seat ---------------------------------- */

.b2-play {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-height: clamp(38px, 9vh, 84px);
  flex-shrink: 0; /* see .b2-seat--top's comment above */
  transition: opacity 300ms var(--ease-std);
}
.b2-play--left, .b2-play--right { position: absolute; top: 50%; transform: translate(-50%, -50%); }
.b2-play--left { left: 27%; }
.b2-play--right { left: 73%; }

.b2-play__cards { display: flex; justify-content: center; }
.b2-play__cards .card {
  /* 24px floor, down from the 28px every other clamp on this table uses,
     because this is the one box that has to share its corridor with a
     second copy of itself (playTop's cards+caption stacked against
     playSelf's) inside the same north/south flow — see .b2-felt above. */
  --card-w: clamp(24px, 8vh, 58px);
  margin-left: calc(var(--card-w) * -0.5);
}
.b2-play__cards .card:first-child { margin-left: 0; }

.b2-play.is-empty { opacity: 0; }
.b2-play.is-fading { opacity: 0; }

.b2-play__name {
  white-space: nowrap; font-size: var(--t-caption); letter-spacing: 0.04em; line-height: 1.1;
  color: var(--gold); opacity: 0; transition: opacity 200ms var(--ease-std);
}
.b2-play:not(.is-empty):not(.is-fading) .b2-play__name { opacity: 0.9; }

.b2-play.is-entering .b2-play__cards > * {
  animation: b2-play-in 220ms var(--ease) backwards;
  animation-delay: calc(var(--i, 0) * 40ms);
}
@keyframes b2-play-in {
  from { opacity: 0; transform: translateY(-8%) scale(0.88); }
  to { opacity: 1; transform: none; }
}

/* --- controls: last item in the felt's north/south flow, just above the
   hand -------------------------------------------------------------------
   F4's "Your lead — include 3♦" line (first play of the hand only) shares
   .b2-controls__label with the ordinary selection feedback rather than
   taking a spot of its own — see big2.js's renderControls(): the two never
   apply at once, and the felt has no free band left for a fifth floating
   element at 844x330. */

.b2-controls {
  margin-bottom: 2px; z-index: 4; flex-shrink: 0; /* see .b2-seat--top's comment */
  display: flex; align-items: center; justify-content: center; gap: clamp(5px, 1vw, 12px); flex-wrap: nowrap;
  max-width: 96%; padding: 5px clamp(8px, 1.4vw, 14px); border-radius: var(--r-pill);
  background: rgba(4, 16, 12, 0.68); border: 1px solid var(--hairline-strong); box-shadow: var(--shadow-3);
}
.b2-controls .btn { padding: clamp(5px, 0.9vh, 8px) clamp(8px, 1.6vw, 16px); font-size: clamp(12px, 1.5vw, 15px); }
.b2-controls__label { font-size: clamp(11px, 1.4vw, 13.5px); color: var(--text-tertiary); white-space: nowrap; max-width: 30vw; overflow: hidden; text-overflow: ellipsis; }

/* --- your hand --------------------------------------------------------------
   Unlike Dou Di Zhu's fan, the whole card — including its bottom edge — must
   stay on screen (F4: "the DDZ LAN table currently clips 20px, do not repeat
   that"), so .b2-hand reserves real height for it instead of letting it run
   off the row, and .b2-dock gets no extra bottom padding to eat into. */

.b2-dock {
  display: flex; flex-direction: column; align-items: center;
  padding: 2px clamp(10px, 2vw, 22px) 4px;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), transparent);
}

.b2-hand {
  --b2-hand-h: clamp(62px, 21vh, 118px);
  position: relative; height: var(--b2-hand-h);
  margin: 0 auto; width: 100%;
}
/* Card height comes from --b2-hand-h minus a reserved headroom, not the box's
   full height: a card sitting bottom:0 and exactly as tall as the box (the
   original formula) has nowhere to go when raised on hover/select below, so
   the raise reached straight into .b2-controls floating just above — F4
   audit measured up to 13px of overlap. (var(--b2-hand-h) * 0.19 + 2px)
   clears the larger, .22-selected raise with >=2px still spare at every
   viewport this table supports: the raise and the headroom are both a fixed
   proportion of --b2-hand-h, so the margin between them holds as that
   variable scales (checked at 844x330, 844x390 and 1280x720). */
.b2-hand .card { --card-w: calc((var(--b2-hand-h) - (var(--b2-hand-h) * 0.19 + 2px)) / 1.4); }
.b2-hand__inner { position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); height: 100%; }

.b2-hand .card {
  position: absolute; bottom: 0; left: calc(var(--i) * var(--step));
  transition: transform 120ms var(--ease-std), filter 120ms var(--ease-std);
  cursor: pointer; border-radius: var(--r-xs);
}
.b2-hand .card:hover { transform: translateY(calc(var(--card-w) * 1.4 * -0.08)); }
.b2-hand .card.is-selected { transform: translateY(calc(var(--card-w) * 1.4 * -0.22)); box-shadow: 0 10px 12px rgba(0, 0, 0, 0.5); }
.b2-hand .card:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 2px; }

/* --- shuffle and deal -------------------------------------------------------
   Transform and opacity only. One flight leg (b2-fly) is reused for every
   phase of the deal, the same way table.css's cg-fly is: big2.js writes the
   ten --f*/--t* custom properties per call and restarts the animation. */

.b2-dealer { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
.b2-dealer__card, .b2-dealer__flyer {
  position: absolute; left: 50%; top: 50%;
  width: clamp(34px, 7.5vh, 64px);
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
}

@keyframes b2-fly {
  from {
    transform: translate(calc(-50% + var(--fx, 0px)), calc(-50% + var(--fy, 0px)))
               rotate(var(--fr, 0deg)) scale(var(--fs, 1));
    opacity: var(--fo, 1);
  }
  to {
    transform: translate(calc(-50% + var(--tx, 0px)), calc(-50% + var(--ty, 0px)))
               rotate(var(--tr, 0deg)) scale(var(--ts, 1));
    opacity: var(--to, 1);
  }
}

.b2-table.is-dealing .b2-seat__backs .card,
.b2-table.is-dealing .b2-hand,
.b2-table.is-dealing .b2-controls {
  opacity: 0;
  pointer-events: none;
}

/* --- overlays ---------------------------------------------------------------
   Independent of table.css's .overlay/.result: same look, own classes, so a
   change to one table's result sheet can never silently move the other's. */

.b2-overlay {
  position: fixed; inset: 0; z-index: var(--z-overlay); display: grid;
  /* Read by .b2-result's max-height below too, so the clearance the padding
     promises and the cap that keeps the sheet inside it can't drift apart. */
  --b2-result-pad-y: max(18px, 23vh);
  /* "safe center", not plain center: a plain center overflows equally in both
     directions once the item is taller than the padded area, which is
     exactly what let an unusually long result (multiple optional lines at
     once — capped loss and a bankrupt notice together) push back up above
     the top padding and into seatTop's plate/revealed cards at 1280x720.
     "safe" falls back to start alignment rather than let that happen, so the
     23vh top padding below is a genuine floor on the sheet's top edge, not
     just the common case. */
  align-items: safe center; justify-items: center;
  /* Top padding alone, not the centering math, is what has to clear seatTop's
     plate and revealed cards. 23vh clears that band with margin at 720.
     Reverted to a plain 8px for the short-landscape query below, where this
     table is a different shape (phones use the collapse toggle for this,
     not headroom — see .is-collapsed there). */
  padding: var(--b2-result-pad-y) 18px 18px;
  background: rgba(3, 12, 9, 0.78); backdrop-filter: blur(3px);
}
.b2-result {
  width: min(92vw, 540px);
  /* Capped to the space the overlay's own padding actually leaves, not a flat
     90vh: "safe center" only protects the sheet's top edge from riding up
     over seatTop, it does nothing about the bottom edge. Content long enough
     to exceed this (worst case: 4 rows plus every optional line at once —
     measured 610px against ~536px available at 1280x720) now scrolls inside
     the box via overflow-y instead of pushing past the viewport's own edge. */
  max-height: min(90vh, calc(100vh - var(--b2-result-pad-y) - 18px));
  overflow-y: auto; text-align: center;
  padding: 24px 26px 20px; border-radius: var(--r-lg);
  border: 1px solid rgba(205, 174, 108, 0.4); background: linear-gradient(170deg, #123a2d, #07241b);
  box-shadow: var(--shadow-8);
}
.b2-result__head { margin: 0 0 14px; }
.b2-result__title { font-size: clamp(24px, 5vw, 36px); margin: 0 0 4px; }
.b2-result__title.is-win { color: var(--gold-bright); }
.b2-result__title.is-loss { color: #f0a58f; }
.b2-result__big-delta { font-size: clamp(20px, 4vw, 28px); margin: 0; font-variant-numeric: lining-nums tabular-nums; }
.b2-result__big-delta.is-win { color: var(--ok); }
.b2-result__big-delta.is-loss { color: var(--danger); }

.b2-result__rows { display: grid; gap: 4px; margin: 0 0 16px; padding: 10px 12px; border-radius: var(--r-md); background: rgba(0, 0, 0, 0.22); }
.b2-result__row { display: flex; align-items: baseline; gap: 10px; font-size: 14.5px; padding: 3px 0; }
.b2-result__row.is-winner .b2-result__name { color: var(--gold-bright); font-weight: 600; }
.b2-result__name { flex: 1; text-align: left; color: var(--text-secondary); }
.b2-result__cards { color: var(--text-tertiary); font-variant-numeric: lining-nums tabular-nums; }
.b2-result__delta { min-width: 6ch; text-align: right; font-variant-numeric: lining-nums tabular-nums; }
.b2-result__delta.is-win { color: var(--ok); }
.b2-result__delta.is-loss { color: var(--danger); }

.b2-result__lines { list-style: none; margin: 0 0 18px; padding: 0; font-size: 14.5px; line-height: 1.5; color: var(--text-secondary); display: grid; gap: 6px; }
.b2-result__lines span { color: var(--gold); }

/* Small, unobtrusive: this is a secondary escape hatch (Leave/Next hand are
   the primary actions), not another button competing with them. */
.b2-result__toggle {
  display: block; margin: 10px auto 0; padding: 4px 10px; background: none; border: 0;
  font-family: var(--font); font-size: 12.5px; color: var(--text-tertiary); text-decoration: underline;
  cursor: pointer;
}
.b2-result__toggle:hover { color: var(--gold); }

/* --- "Show table": collapses the sheet to a slim bar so F4's face-up reveal
   is actually visible, not just technically present under a dimmed modal.
   Docked over the HUD rather than the felt itself: the HUD is the one band
   on this table with no seat plate or card in it at any viewport, so a bar
   confined to that band can never cover a revealed hand by construction,
   without having to chase seat positions across three screen sizes. */
.b2-overlay.is-collapsed {
  place-items: start center; padding: 6px 12px; background: transparent; backdrop-filter: none;
  pointer-events: none;
}
.b2-overlay.is-collapsed .b2-result {
  display: flex; align-items: baseline; gap: 12px; width: auto; max-width: 92vw; max-height: none; overflow: visible;
  padding: 6px 8px 6px 16px; cursor: pointer; pointer-events: auto;
}
.b2-overlay.is-collapsed .b2-result__head { display: flex; align-items: baseline; gap: 8px; margin: 0; }
.b2-overlay.is-collapsed .b2-result__title { font-size: 14px; }
.b2-overlay.is-collapsed .b2-result__big-delta { font-size: 14px; }
.b2-overlay.is-collapsed .b2-result__rows,
.b2-overlay.is-collapsed .b2-result__lines,
.b2-overlay.is-collapsed .b2-result__toggle,
.b2-overlay.is-collapsed .btn-row .btn:not(.btn--primary) {
  display: none;
}
.b2-overlay.is-collapsed .btn-row { margin: 0; }
.b2-overlay.is-collapsed .btn-row .btn--primary { padding: 4px 10px; font-size: 12.5px; }

/* --- short landscape (phone browser bar): the sheet above is sized for a
   full-height screen and would run past a 330-390px-tall viewport, buttons
   included — see F4 audit. Every number below was checked against an actual
   settle() (4 seat rows, a capped-loss line) at 844x330, the tightest case,
   with >=8px still clear above and below the sheet. */
@media (orientation: landscape) and (max-height: 460px) {
  /* This table is a different shape at phone heights: the 23vh top padding
     above (sized for 1280x720's much taller HUD/seat band) would eat most of
     a 330-390px viewport on its own. Phones lean on the collapse toggle
     instead of headroom to keep the sheet off the seats. */
  .b2-overlay { padding: 8px; }
  .b2-result {
    padding: 10px 16px 12px; max-height: calc(100vh - 16px);
  }
  .b2-result__head { display: flex; align-items: baseline; justify-content: center; gap: 10px; margin: 0 0 6px; }
  .b2-result__title { font-size: 18px; margin: 0; }
  .b2-result__big-delta { font-size: 16px; }
  .b2-result__rows { gap: 0; margin: 0 0 6px; padding: 4px 8px; }
  .b2-result__row { font-size: 12.5px; padding: 1px 0; }
  .b2-result__lines { font-size: 12px; line-height: 1.3; margin: 0 0 8px; gap: 2px; }
  .b2-result__toggle { margin-top: 4px; }

  /* The collapsed bar's own safe band (the HUD strip above seatTop) is only
     ~40px tall at these heights — measured, not assumed, since it is the
     seat plate's own top clamp doing the work, not a plain fraction of the
     viewport — against the roomier defaults above, which alone measured
     tall enough to reach past seatTop's plate at 844x390. Every value below
     was sized to that ~40px, not guessed. */
  .b2-overlay.is-collapsed { padding: 2px 8px; }
  .b2-overlay.is-collapsed .b2-result { padding: 2px 6px; gap: 6px; }
  .b2-overlay.is-collapsed .b2-result__head { gap: 5px; }
  .b2-overlay.is-collapsed .b2-result__title,
  .b2-overlay.is-collapsed .b2-result__big-delta { font-size: 11.5px; }
  .b2-overlay.is-collapsed .btn-row .btn--primary { padding: 2px 7px; font-size: 10.5px; }
}

/* --- portrait guard, same idea as table.css's .rotate-gate ------------------ */

.b2-rotate-gate { display: none; }
@media (orientation: portrait) and (max-width: 960px) {
  .b2-rotate-gate {
    position: fixed; inset: 0; z-index: var(--z-rotate-gate); display: grid; place-items: center; text-align: center;
    padding: 30px; background: linear-gradient(170deg, #0f3b2d, #061a14); color: var(--text);
  }
  .b2-rotate-gate__icon { font-size: 46px; margin-bottom: 14px; color: var(--gold); }
  .b2-rotate-gate h2 { margin: 0 0 8px; font-size: 25px; color: var(--ivory); }
  .b2-rotate-gate p { margin: 0; max-width: 34ch; color: var(--text-tertiary); line-height: 1.6; }
}

/* Short landscape (phone browser bar): every size below is already vh-driven
   (seat backs, play cards, the hand), so it shrinks on its own — only the HUD
   padding needs trimming to give that shrunk felt a little more of the height back. */
@media (orientation: landscape) and (max-height: 460px) {
  .b2-hud { padding-top: 3px; padding-bottom: 3px; }
}

/* At the shortest phone heights, a hand with plays showing both north and
   south fills the whole column, the spacer reaches zero and the controls
   are pushed down into the hand's raise headroom. Trimming the controls'
   padding and the play cards frees the ~15px that squeeze needs. */
@media (orientation: landscape) and (max-height: 350px) {
  .b2-controls { padding-top: 2px; padding-bottom: 2px; }
  .b2-controls .btn { padding-top: 3px; padding-bottom: 3px; }
  .b2-play__cards .card { --card-w: clamp(22px, 7vh, 58px); }
}
