/* ============================================================
   Swap or Stay — everything the shared card table does not already do.
   Every selector is scoped under .ss-* so nothing here can leak into
   another game's screen. Loaded after style.css, so equal-specificity
   rules on .ct-* elements deliberately win inside .ss-wrap.
   ============================================================ */

/* ---------- layout ---------- */
.ss-wrap { --gold: 212, 175, 55; }

/* The status strip under the table: round, dealer, and where the round is up to. */
.ss-status {
  display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap;
  padding: 8px 12px;
  font-size: 13px; font-weight: 700; color: var(--ink-dim); letter-spacing: 0.3px;
}
.ss-status .ss-round {
  color: rgb(var(--gold)); text-transform: uppercase; letter-spacing: 1.4px; font-size: 12px;
}
.ss-status .ss-dealer { color: var(--ink-dim); }
.ss-status .ss-phase { color: var(--ink); }

/* The control dock sits in the flow below the table rather than floating over it,
   because the bottom strip of the stage is where the parked deck lives. */
.ss-dock { display: grid; gap: 10px; }
.ss-note { text-align: center; color: var(--ink-dim); font-size: 14.5px; font-weight: 600; padding: 6px 0; }

/* ---------- the choice bar ---------- */
/* Slides up when it is your call: the one moment the game asks something of you.
   The rise runs only under .ss-enter, which index.js grants on a face's first
   appearance — the dock is rebuilt on every snapshot, and a rebuild is not an entrance. */
.ss-choice { text-align: center; }
.ss-choice.ss-enter { animation: ss-rise 0.35s cubic-bezier(0.2, 1.2, 0.4, 1) both; }
@keyframes ss-rise {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}
.ss-choice-title { font-weight: 800; font-size: 17px; margin-bottom: 12px; }
.ss-choice-row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.ss-choice-hint { margin-top: 10px; font-size: 12.5px; color: var(--ink-faint); }

.ss-btn {
  background: var(--glass-2);
  border: 1px solid rgba(var(--gold), 0.35);
  border-radius: var(--r-md);
  font-weight: 800;
  transition: transform 0.15s, background 0.2s, border-color 0.2s, box-shadow 0.25s;
}
.ss-btn:hover { background: rgba(var(--gold), 0.12); transform: translateY(-1px); }
.ss-btn:active { transform: scale(0.96); }
.ss-btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }
.ss-btn.ss-next {
  background: linear-gradient(135deg, rgba(var(--gold), 0.28), rgba(var(--gold), 0.12));
  border-color: rgba(var(--gold), 0.55);
}
/* An armed button is mid-confirm: it glows like the card it is about to commit,
   so "this is the point of no return" reads the same everywhere on the table. */
.ss-btn.ss-armed {
  border-color: rgb(var(--gold));
  background: rgba(var(--gold), 0.18);
  color: rgb(var(--gold));
  animation: ss-armed-pulse 1.1s ease-in-out infinite;
}
@keyframes ss-armed-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--gold), 0.0); }
  50%      { box-shadow: 0 0 18px 2px rgba(var(--gold), 0.45); }
}

/* ---------- hearts ---------- */
/* Pips ride inside the chair's name tag so they stay upright at every seat. */
/* Hearts get their own line beside the figure rather than sharing the name tag: the
   name is allowed to ellipsis when a chair is tight against the table edge, the hearts
   never are. */
.ss-wrap .ss-lives { display: flex; gap: 1px; line-height: 1; }
.ss-wrap .ss-pip {
  font-style: normal; font-size: 0.85em; line-height: 1;
  color: rgba(255, 255, 255, 0.16);
  transition: color 0.3s ease;
}
.ss-wrap .ss-pip.on { color: var(--red); text-shadow: 0 0 6px rgba(248, 113, 113, 0.55); }
/* A heart going out cracks: it flares, shakes, and dies down to an ember. */
.ss-wrap .ss-pip.ss-crack { animation: ss-crack 0.9s cubic-bezier(0.3, 0.9, 0.4, 1) both; }
@keyframes ss-crack {
  0%   { color: var(--red); transform: scale(1); }
  25%  { color: #fff; transform: scale(1.9) rotate(-14deg); }
  45%  { transform: scale(1.5) rotate(12deg); }
  100% { color: rgba(255, 255, 255, 0.16); transform: scale(1); }
}

/* ---------- table states driven from index.js ---------- */

/* A ghost card in flight: plain stage coordinates, above every seat, below nothing
   that matters. The inner .ct-card fills it and brings the shared back design. */
.ss-wrap .ss-ghost {
  position: absolute; z-index: 45; pointer-events: none;
  filter: drop-shadow(0 10px 14px rgba(0, 0, 0, 0.55));
}

/* Face-up in place (the reveal, and the Sentinel flash). The card itself is turned by
   an inline rotateY(180deg); these rules swap the faces at the midpoint of that turn.
   The .mine.live variants exist because the viewer's own live card carries stronger
   selectors in style.css that would otherwise keep its back on top. */
.ss-wrap .ct-seat.ss-up .ct-face.back,
.ss-wrap .ct-seat.mine.live.ss-up .ct-face.back { opacity: 0; transition: opacity 0s linear 0.2s; }
.ss-wrap .ct-seat.ss-up .ct-face.front,
.ss-wrap .ct-seat.mine.live.ss-up .ct-face.front { opacity: 1; transition: opacity 0s linear 0.2s; }

/* The Sentinel flash: gold flare and a firm "no" shake while the shield is up. */
.ss-wrap .ct-seat.ss-shield .ct-slot {
  animation: ss-refuse 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) 0.42s both;
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 18px rgba(var(--gold), 0.85));
}
.ss-wrap .ct-seat.ss-shield .ct-face.front {
  color: #8a6d1c;
  background: linear-gradient(170deg, #fdf6e0 0%, #f3e6bb 55%, #e8d79c 100%);
}
@keyframes ss-refuse {
  0%, 100% { translate: 0 0; }
  20% { translate: -6% 0; }
  40% { translate: 5% 0; }
  60% { translate: -4% 0; }
  80% { translate: 3% 0; }
}

/* The lowest card(s) at the reveal pulse red before the hearts crack. */
.ss-wrap .ct-seat.ss-loser .ct-face.front {
  animation: ss-doomed 0.8s ease-in-out 2;
  border-color: rgba(248, 113, 113, 0.9);
}
.ss-wrap .ct-seat.ss-loser .ct-slot {
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 16px rgba(248, 113, 113, 0.7));
}
@keyframes ss-doomed {
  0%, 100% { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.55); }
  50%      { box-shadow: 0 0 22px 4px rgba(248, 113, 113, 0.75), 0 1px 2px rgba(0, 0, 0, 0.55); }
}

/* Out of hearts: the chair goes grey and a skull settles over the head. */
.ss-wrap .ct-who.ss-dead { opacity: 0.55; filter: saturate(0.2); }
.ss-wrap .ct-who.ss-dead .ct-head::after {
  content: '💀';
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -54%);
  font-size: calc(var(--cw, 52px) * 0.34 * var(--s, 1));
  line-height: 1;
}
.ss-wrap .ct-who.ss-dead b { text-decoration: line-through; text-decoration-thickness: 1px; }

/* A spectating viewer's own seat: present, but visibly not in the round. */
.ss-wrap .ss-spectator .ct-seat.mine { opacity: 0.4; pointer-events: none; }

/* Somebody who left mid-round: the chair empties out — greyed, a door over the head,
   name struck through — instead of pretending to wait for a turn that will never come. */
.ss-wrap .ct-who.ss-left { opacity: 0.45; filter: saturate(0.15); }
.ss-wrap .ct-who.ss-left .ct-head::after {
  content: '🚪';
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -54%);
  font-size: calc(var(--cw, 52px) * 0.34 * var(--s, 1));
  line-height: 1;
}
.ss-wrap .ct-who.ss-left b { text-decoration: line-through; text-decoration-thickness: 1px; }
.ss-wrap .ct-seat.ss-left { opacity: 0.35; }

/* ---------- round result & winner ---------- */
/* Same one-shot rule as the choice bar: entrances only under .ss-enter, so a mid-scene
   broadcast rebuilding the dock never re-bounces the card or re-drops the trophy. */
.ss-result { text-align: center; }
.ss-result.ss-enter { animation: ss-rise 0.35s cubic-bezier(0.2, 1.2, 0.4, 1) both; }
.ss-verdict { font-size: 16px; font-weight: 700; margin-bottom: 12px; }

.ss-winner { text-align: center; padding: 22px var(--card-pad); }
.ss-winner.ss-enter { animation: ss-rise 0.4s cubic-bezier(0.2, 1.2, 0.4, 1) both; }
.ss-win-emoji { font-size: 64px; display: inline-block; }
.ss-winner.ss-enter .ss-win-emoji { animation: ss-trophy 0.9s cubic-bezier(0.3, 1.6, 0.4, 1) both; }
@keyframes ss-trophy {
  from { transform: translateY(-40px) scale(0.4) rotate(-14deg); opacity: 0; }
  to   { transform: translateY(0) scale(1) rotate(0deg); opacity: 1; }
}
.ss-win-title {
  font-size: clamp(24px, 6vw, 32px); font-weight: 800; margin-top: 8px;
  background: linear-gradient(135deg, rgb(var(--gold)), #fff3c4 60%, rgb(var(--gold)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ss-win-you { margin-top: 6px; font-weight: 800; color: rgb(var(--gold)); }
.ss-win-quip { margin-top: 8px; color: var(--ink-dim); font-size: 15px; }
.ss-win-actions { display: grid; gap: 10px; margin-top: 16px; }

/* ---------- reduced motion ---------- */
/* The global reduce rule already collapses durations; these remove the loops and
   entrances outright so nothing pulses at anyone who asked for stillness. */
@media (prefers-reduced-motion: reduce) {
  .ss-choice.ss-enter, .ss-result.ss-enter, .ss-winner.ss-enter { animation: none; }
  .ss-winner.ss-enter .ss-win-emoji { animation: none; }
  .ss-btn.ss-armed { animation: none; box-shadow: 0 0 0 2px rgba(var(--gold), 0.6); }
  .ss-wrap .ss-pip.ss-crack { animation: none; }
  .ss-wrap .ct-seat.ss-shield .ct-slot { animation: none; }
  .ss-wrap .ct-seat.ss-loser .ct-face.front { animation: none; }
}

/* The Sentinel block: the one moment the whole table talks about. The shield slams into
   centre screen, rings, and the table itself flinches. */
.ss-slam {
  position: absolute; inset: 0; z-index: 60; pointer-events: none;
  display: grid; place-items: center; align-content: center; gap: 4px;
}
.ss-slam-shield {
  font-size: clamp(84px, 18vw, 150px); line-height: 1;
  filter: drop-shadow(0 0 34px rgba(212, 175, 55, 0.85)) drop-shadow(0 14px 22px rgba(0, 0, 0, 0.7));
  animation: ss-slam-in 1.5s cubic-bezier(0.2, 1.1, 0.3, 1) both;
}
.ss-slam-text {
  font-family: var(--display); font-weight: 800; letter-spacing: 6px;
  font-size: clamp(22px, 4.5vw, 34px); color: #f3e3b4;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.8);
  animation: ss-slam-text 1.5s ease both;
}
@keyframes ss-slam-in {
  0%   { opacity: 0; transform: scale(3.2) rotate(-14deg); }
  22%  { opacity: 1; transform: scale(1) rotate(0deg); }
  30%  { transform: scale(1.12); }
  38%  { transform: scale(1); }
  78%  { opacity: 1; }
  100% { opacity: 0; transform: scale(0.92); }
}
@keyframes ss-slam-text {
  0%, 20% { opacity: 0; transform: translateY(10px); }
  32% { opacity: 1; transform: translateY(0); }
  78% { opacity: 1; }
  100% { opacity: 0; }
}
.ss-quake { animation: ss-quake 0.5s ease 0.28s; }
@keyframes ss-quake {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-5px, 2px); }
  40% { transform: translate(5px, -2px); }
  60% { transform: translate(-3px, 1px); }
  80% { transform: translate(3px, -1px); }
}
@media (prefers-reduced-motion: reduce) {
  .ss-slam-shield, .ss-slam-text { animation: ss-fade 1.5s ease both; }
  .ss-quake { animation: none; }
  @keyframes ss-fade { 0% { opacity: 0; } 15%, 80% { opacity: 1; } 100% { opacity: 0; } }
}

/* Reactions under the table: always reachable, never rebuilt mid-tap. */
.ss-reactbar { display: flex; justify-content: center; gap: 8px; }
.ss-react-btn {
  font-size: 22px; line-height: 1; padding: 8px 12px; border-radius: 999px;
  border: 1px solid var(--stroke); background: var(--glass); cursor: pointer;
  transition: transform 0.12s ease, border-color 0.15s ease;
}
.ss-react-btn:hover { transform: translateY(-2px) scale(1.12); border-color: rgba(212, 175, 55, 0.5); }
.ss-react-btn:active { transform: scale(0.94); }

/* The round log: collapsed by default so it never competes with the table. */
.ss-logbox { padding: 10px 14px; }
.ss-logbox > summary { cursor: pointer; font-weight: 700; font-size: 13.5px; color: var(--ink-dim); list-style: none; }
.ss-logbox > summary::-webkit-details-marker { display: none; }
.ss-logbox[open] > summary { margin-bottom: 8px; }
.ss-log { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; max-height: 220px; overflow-y: auto; }
.ss-log-row { display: flex; gap: 8px; align-items: baseline; font-size: 13px; color: var(--ink-dim); }
.ss-log-round { flex: none; font-size: 11px; font-weight: 800; letter-spacing: 0.06em; color: var(--ink-faint); }
.ss-log-blocked { color: var(--ink); }

/* The Sentinel slam gets a photograph behind the shield: a flat palm refusing a card,
   screen-blended so it emerges out of the overlay's darkness rather than sitting in a box. */
.ss-slam-art { position: absolute; inset: 0; display: block; overflow: hidden; z-index: 0; }
.ss-slam-art img {
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  mix-blend-mode: screen; opacity: 0.55;
}
.ss-slam > :not(.ss-slam-art) { position: relative; z-index: 1; }
