    :root {
      --mana-white: #f4efc8;
      --mana-blue: #0d6aad;
      --mana-black: #3a332c;
      --mana-red: #c4332b;
      --mana-green: #0f6b3c;
      --mana-colorless: #c5c0b8;
      --mana-gold: #d4a017;
    }

    html, body {
      margin: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
      position: fixed;
      inset: 0;
      touch-action: manipulation;
      overscroll-behavior: none;
      -webkit-user-select: none;
      user-select: none;
      -webkit-tap-highlight-color: transparent;
      -webkit-touch-callout: none;
      background: #0f172a;
      font-family: Outfit, system-ui, sans-serif;
    }

    #board {
      width: 100%;
      height: 100%;
    }

    #board.players-2 {
      display: grid;
      grid-template-columns: 1fr;
      grid-template-rows: 1fr 1fr;
    }

    #board.players-2 .p2 { grid-area: 1 / 1; }
    #board.players-2 .p1 { grid-area: 2 / 1; }

    #board.players-3 {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-template-rows: 1fr 1fr;
    }

    #board.players-3 .p2 { grid-area: 1 / 1; }
    #board.players-3 .p3 { grid-area: 1 / 2; }
    #board.players-3 .p1 { grid-area: 2 / 1 / 3 / 3; }

    #board.players-4 {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-template-rows: 1fr 1fr;
    }

    #board.players-4 .p1 { grid-area: 2 / 1; }
    #board.players-4 .p2 { grid-area: 1 / 1; }
    #board.players-4 .p3 { grid-area: 1 / 2; }
    #board.players-4 .p4 { grid-area: 2 / 2; }

    /* Five players: two down each side, the fifth across the bottom. */
    #board.players-5 {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-template-rows: 1fr 1fr 1fr;
    }

    #board.players-5 .p2 { grid-area: 1 / 1; }
    #board.players-5 .p3 { grid-area: 1 / 2; }
    #board.players-5 .p4 { grid-area: 2 / 1; }
    #board.players-5 .p5 { grid-area: 2 / 2; }
    #board.players-5 .p1 { grid-area: 3 / 1 / 4 / 3; }

    .slot {
      position: relative;
      min-height: 0;
      overflow: hidden;
    }

    #board.players-2 .p3,
    #board.players-2 .p4,
    #board.players-2 .p5,
    #board.players-3 .p4,
    #board.players-3 .p5,
    #board.players-4 .p5 { display: none; }

    .face {
      position: absolute;
      inset: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      padding-bottom: 3.15rem;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
      /* Every rule below re-declares this transform ending in the same
         rotate(); --seat-turn is the one manual per-seat override (see the
         "Diseño de mesa" panel) and defaults to a no-op. */
      transform: rotate(var(--seat-turn, 0deg));
    }

    .face.has-photo-bg {
      background-size: cover;
      background-position: center;
    }

    #board.players-2 .face { padding-bottom: 3.6rem; }
    #board.players-2 .p2 .face { transform: rotate(180deg) rotate(var(--seat-turn, 0deg)); }

    #board.players-3 .p2 .face,
    #board.players-3 .p3 .face,
    #board.players-4 .p1 .face,
    #board.players-4 .p2 .face,
    #board.players-4 .p3 .face,
    #board.players-4 .p4 .face {
      inset: auto;
      width: 50dvh;
      height: 50dvw;
      top: 50%;
      left: 50%;
    }

    #board.players-3 .p2 .face,
    #board.players-4 .p1 .face,
    #board.players-4 .p2 .face {
      transform: translate(-50%, -50%) rotate(90deg) rotate(var(--seat-turn, 0deg));
    }

    #board.players-3 .p3 .face,
    #board.players-4 .p3 .face,
    #board.players-4 .p4 .face {
      transform: translate(-50%, -50%) rotate(-90deg) rotate(var(--seat-turn, 0deg));
    }

    /*
     * Alternate 4-player template: north/east/south/west instead of two
     * facing pairs sharing each side. Reuses the exact box shapes already
     * proven for players-5 (a full-width strip top and bottom, a rotated
     * quadrant left and right) rather than inventing new geometry, so a
     * shape that already renders correctly elsewhere cannot come out
     * mismatched here.
     */
    #board.players-4.layout-cross {
      grid-template-rows: 1fr 1fr 1fr;
    }

    #board.players-4.layout-cross .p4 { grid-area: 1 / 1 / 2 / 3; }
    #board.players-4.layout-cross .p2 { grid-area: 2 / 1; }
    #board.players-4.layout-cross .p3 { grid-area: 2 / 2; }
    #board.players-4.layout-cross .p1 { grid-area: 3 / 1 / 4 / 3; }

    #board.players-4.layout-cross .p2 .face,
    #board.players-4.layout-cross .p3 .face {
      inset: auto;
      width: 33.33dvh;
      height: 50dvw;
      top: 50%;
      left: 50%;
    }

    #board.players-4.layout-cross .p2 .face {
      transform: translate(-50%, -50%) rotate(90deg) rotate(var(--seat-turn, 0deg));
    }

    #board.players-4.layout-cross .p3 .face {
      transform: translate(-50%, -50%) rotate(-90deg) rotate(var(--seat-turn, 0deg));
    }

    #board.players-4.layout-cross .p1 .face,
    #board.players-4.layout-cross .p4 .face {
      inset: 0;
      width: auto;
      height: auto;
    }

    #board.players-4.layout-cross .p1 .face {
      transform: rotate(var(--seat-turn, 0deg));
    }

    #board.players-4.layout-cross .p4 .face {
      transform: rotate(180deg) rotate(var(--seat-turn, 0deg));
    }

    /*
     * Two players down the sides instead of stacked, for a phone laid between
     * two people sitting across a corner. Each cell is 50vw x 100vh, so the
     * rotated face swaps those into 100dvh x 50dvw.
     */
    #board.players-2.layout-side {
      grid-template-columns: 1fr 1fr;
      grid-template-rows: 1fr;
    }

    #board.players-2.layout-side .p2 { grid-area: 1 / 1; }
    #board.players-2.layout-side .p1 { grid-area: 1 / 2; }

    #board.players-2.layout-side .p1 .face,
    #board.players-2.layout-side .p2 .face {
      inset: auto;
      width: 100dvh;
      height: 50dvw;
      top: 50%;
      left: 50%;
    }

    #board.players-2.layout-side .p2 .face {
      transform: translate(-50%, -50%) rotate(90deg) rotate(var(--seat-turn, 0deg));
    }

    #board.players-2.layout-side .p1 .face {
      transform: translate(-50%, -50%) rotate(-90deg) rotate(var(--seat-turn, 0deg));
    }

    /*
     * Franjas: one full-width strip per player, stacked bottom to top, the far
     * half turned 180deg. No rotated quadrants at all, so every face just
     * fills its own cell — these rules mostly undo the ±90 geometry the
     * built-in templates set up for the same player counts.
     */
    #board.layout-rows { grid-template-columns: 1fr; }

    #board.players-3.layout-rows { grid-template-rows: repeat(3, 1fr); }
    #board.players-4.layout-rows { grid-template-rows: repeat(4, 1fr); }
    #board.players-5.layout-rows { grid-template-rows: repeat(5, 1fr); }

    #board.players-3.layout-rows .p1 { grid-area: 3 / 1; }
    #board.players-3.layout-rows .p2 { grid-area: 2 / 1; }
    #board.players-3.layout-rows .p3 { grid-area: 1 / 1; }

    #board.players-4.layout-rows .p1 { grid-area: 4 / 1; }
    #board.players-4.layout-rows .p2 { grid-area: 3 / 1; }
    #board.players-4.layout-rows .p3 { grid-area: 2 / 1; }
    #board.players-4.layout-rows .p4 { grid-area: 1 / 1; }

    #board.players-5.layout-rows .p1 { grid-area: 5 / 1; }
    #board.players-5.layout-rows .p2 { grid-area: 4 / 1; }
    #board.players-5.layout-rows .p3 { grid-area: 3 / 1; }
    #board.players-5.layout-rows .p4 { grid-area: 2 / 1; }
    #board.players-5.layout-rows .p5 { grid-area: 1 / 1; }

    /* `.slot .face` rather than just `.face`: the built-in templates target
       #board.players-N .pM .face, and this reset has to outrank them. */
    #board.players-3.layout-rows .slot .face,
    #board.players-4.layout-rows .slot .face,
    #board.players-5.layout-rows .slot .face {
      /* inset already resets the top/left the rotated templates set to 50% —
         re-declaring those as auto would drop the face out of its cell and
         let it shrink to fit its own text. */
      inset: 0;
      width: auto;
      height: auto;
      transform: rotate(var(--seat-turn, 0deg));
    }

    #board.players-3.layout-rows .p2 .face,
    #board.players-3.layout-rows .p3 .face,
    #board.players-4.layout-rows .p3 .face,
    #board.players-4.layout-rows .p4 .face,
    #board.players-5.layout-rows .p3 .face,
    #board.players-5.layout-rows .p4 .face,
    #board.players-5.layout-rows .p5 .face {
      transform: rotate(180deg) rotate(var(--seat-turn, 0deg));
    }

    /* Height is what runs out first in a strip, so these clamp on vh. Again
       `.slot` is here to outrank the per-seat #board.players-N .pM .life
       sizes, which are tuned for tall cells and come later in the file. */
    #board.players-3.layout-rows .slot .life { font-size: clamp(3rem, 15vh, 7rem); }
    #board.players-4.layout-rows .slot .life { font-size: clamp(2.5rem, 11vh, 5.5rem); }
    #board.players-5.layout-rows .slot .life { font-size: clamp(2.1rem, 8.5vh, 4.4rem); }

    #board.big.players-3.layout-rows .slot .life { font-size: clamp(3.4rem, 16vh, 7.5rem); }
    #board.big.players-4.layout-rows .slot .life { font-size: clamp(2.8rem, 12.5vh, 6rem); }
    #board.big.players-5.layout-rows .slot .life { font-size: clamp(2.4rem, 10vh, 4.8rem); }

    /* Each side cell is 50vw x 33.33vh, so the rotated face swaps them. */
    #board.players-5 .p2 .face,
    #board.players-5 .p3 .face,
    #board.players-5 .p4 .face,
    #board.players-5 .p5 .face {
      inset: auto;
      width: 33.33dvh;
      height: 50dvw;
      top: 50%;
      left: 50%;
    }

    #board.players-5 .p2 .face,
    #board.players-5 .p4 .face {
      transform: translate(-50%, -50%) rotate(90deg) rotate(var(--seat-turn, 0deg));
    }

    #board.players-5 .p3 .face,
    #board.players-5 .p5 .face {
      transform: translate(-50%, -50%) rotate(-90deg) rotate(var(--seat-turn, 0deg));
    }

    .zone {
      position: absolute;
      top: 0;
      bottom: 3.15rem;
      width: 50%;
      z-index: 2;
      margin: 0;
      padding: 0;
      border: 0;
      background: transparent;
      appearance: none;
      -webkit-appearance: none;
    }

    .zone-left { left: 0; }
    .zone-right { right: 0; }
    .zone:active { background: rgba(0, 0, 0, 0.12); }
    #board.players-2 .zone { bottom: 3.6rem; }

    .life-wrap {
      position: relative;
      z-index: 4;
      pointer-events: none;
      text-align: center;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .life {
      font-size: clamp(7rem, 36vw, 11.5rem);
      font-weight: 700;
      line-height: 0.9;
      letter-spacing: -0.04em;
      text-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
    }

    .life-block {
      position: relative;
    }

    .delta {
      position: absolute;
      left: 50%;
      top: 0.12em;
      transform: translate(-50%, -100%);
      z-index: 5;
      font-size: clamp(1.55rem, 6.2vw, 2.5rem);
      font-weight: 800;
      line-height: 1;
      letter-spacing: -0.03em;
      opacity: 0;
      pointer-events: none;
      color: #f8fafc;
      background: rgba(15, 23, 42, 0.9);
      padding: 0.18rem 0.62rem;
      border-radius: 0.7rem;
      text-shadow: none;
      box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
      transition: opacity 0.35s ease;
    }

    .delta.show { opacity: 1; }

    .delta.bump { animation: delta-bump 180ms ease-out; }

    @keyframes delta-bump {
      0% { transform: translate(-50%, -100%) scale(0.82); }
      70% { transform: translate(-50%, -100%) scale(1.14); }
      100% { transform: translate(-50%, -100%) scale(1); }
    }

    #board.players-3 .delta,
    #board.players-4 .delta {
      font-size: clamp(1.05rem, 3.6vw, 1.55rem);
      padding: 0.1rem 0.42rem;
      border-radius: 0.5rem;
    }

    #board.players-3 .p2 .life,
    #board.players-3 .p3 .life,
    #board.players-4 .life {
      font-size: clamp(4.6rem, 26vw, 7.4rem);
    }

    #board.players-5 .p2 .life,
    #board.players-5 .p3 .life,
    #board.players-5 .p4 .life,
    #board.players-5 .p5 .life {
      font-size: clamp(3.4rem, 20vw, 5.6rem);
    }

    #board.players-5 .p1 .life {
      font-size: clamp(4.6rem, 26vw, 7.4rem);
    }

    /* Cross mode's middle row is a third of the height, same as players-5's
       side seats — reuse that sizing instead of the half-height default. */
    #board.players-4.layout-cross .p2 .life,
    #board.players-4.layout-cross .p3 .life {
      font-size: clamp(3.4rem, 20vw, 5.6rem);
    }

    #board.big.players-4.layout-cross .p2 .life,
    #board.big.players-4.layout-cross .p3 .life {
      font-size: clamp(4.4rem, 26vw, 7rem);
    }

    /* Big-numbers mode: the trackers step aside so the life total can grow.
       Commander damage stays reachable through the popup. */
    #board.big .trackers { display: none; }
    #board.big .face { padding-bottom: 0; }
    #board.big .zone { bottom: 0; }

    #board.big.players-2 .life { font-size: clamp(9rem, 46vw, 15rem); }
    #board.big.players-3 .p1 .life,
    #board.big.players-4 .life { font-size: clamp(6rem, 34vw, 9.5rem); }
    #board.big.players-3 .p2 .life,
    #board.big.players-3 .p3 .life { font-size: clamp(6rem, 34vw, 9.5rem); }
    #board.big.players-5 .p2 .life,
    #board.big.players-5 .p3 .life,
    #board.big.players-5 .p4 .life,
    #board.big.players-5 .p5 .life { font-size: clamp(4.4rem, 26vw, 7rem); }
    #board.big.players-5 .p1 .life { font-size: clamp(6rem, 34vw, 9.5rem); }

    .player-label {
      max-width: min(60vw, 16rem);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      /* The only part of the life block that takes input: it is the handle
         for dragging a player to another seat. Short taps still fall through
         to the life zones underneath, in JS. */
      pointer-events: auto;
      padding: 0.15rem 0.5rem;
      margin-left: -0.5rem;
      margin-right: -0.5rem;
      border-radius: 0.4rem;
      touch-action: none;
    }

    .player-label:active { background: rgba(0, 0, 0, 0.16); }

    /* While a seat is in the air, nothing else should look tappable. */
    body.seat-dragging .zone,
    body.seat-dragging .trackers { pointer-events: none; }

    .slot.dragging .face {
      opacity: 0.45;
      transform-origin: center center;
    }

    .slot.dragging .player-label {
      background: rgba(15, 23, 42, 0.9);
      box-shadow: 0 0 0 2px #fbbf24;
    }

    .slot.drop-target::after {
      content: '';
      position: absolute;
      inset: 0.35rem;
      z-index: 8;
      pointer-events: none;
      border: 3px dashed #fbbf24;
      border-radius: 0.6rem;
      background: rgba(251, 191, 36, 0.12);
    }

    #board.players-3 .player-label,
    #board.players-4 .player-label {
      font-size: 0.75rem;
      margin-bottom: 0.1rem;
      max-width: 40vw;
    }

    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border: 0;
    }

    .shade {
      position: absolute;
      inset: 0;
      pointer-events: none;
      background:
        linear-gradient(180deg, rgba(0, 0, 0, 0.16), transparent 32%, transparent 68%, rgba(0, 0, 0, 0.22));
    }

    .trackers {
      position: absolute;
      left: 5%;
      right: 5%;
      bottom: 2.5%;
      z-index: 4;
      display: flex;
      justify-content: center;
      align-items: center;
      gap: 0.3rem;
      pointer-events: auto;
    }

    #board.players-3 .trackers,
    #board.players-4 .trackers { gap: 0.25rem; }

    .trackers-extras {
      display: flex;
      justify-content: center;
      align-items: center;
      gap: 0.3rem;
    }

    .mini-sq {
      position: relative;
      width: 2.7rem;
      height: 2.7rem;
      border-radius: 0.45rem;
      background: rgba(15, 23, 42, 0.55);
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 0.12rem;
      overflow: hidden;
      padding: 0;
      margin: 0;
      border: 0;
      color: #f8fafc;
      appearance: none;
    }

    #board.players-3 .mini-sq,
    #board.players-4 .mini-sq {
      width: 2.75rem;
      height: 2.75rem;
    }

    .mini-sq.lethal {
      box-shadow: inset 0 0 0 2px #f8fafc, 0 0 10px rgba(248, 250, 252, 0.35);
    }

    .mini-hit {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 50%;
      margin: 0;
      padding: 0;
      border: 0;
      background: transparent;
      appearance: none;
    }

    .mini-hit.left { left: 0; }
    .mini-hit.right { right: 0; }
    .mini-hit:active { background: rgba(0, 0, 0, 0.16); }

    .mini-icon,
    .mini-value {
      position: relative;
      z-index: 1;
      pointer-events: none;
      font-weight: 700;
      line-height: 1;
    }

    .mini-value { font-size: 0.82rem; }
    #board.players-4 .mini-value { font-size: 0.8rem; }

    /* One button per rival commander, on the player's own panel. */
    .cmd-row {
      display: flex;
      align-items: stretch;
      gap: 0.25rem;
      min-width: 0;
    }

    .cmd-hit {
      position: relative;
      min-width: 2.9rem;
      min-height: 2.9rem;
      padding: 0.15rem 0.3rem;
      border-radius: 0.45rem;
      border: 2px solid transparent;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 0.05rem;
      font-weight: 700;
      appearance: none;
      overflow: hidden;
      flex: 0 1 auto;
    }

    #board.players-3 .cmd-hit,
    #board.players-4 .cmd-hit {
      min-width: 2.75rem;
      min-height: 2.75rem;
    }

    .cmd-hit:active { transform: scale(0.95); }

    .cmd-hit-name {
      font-size: 0.5rem;
      line-height: 1;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      opacity: 0.85;
      max-width: 3.4rem;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      pointer-events: none;
    }

    .cmd-hit-amt {
      font-size: 1.1rem;
      line-height: 1.05;
      font-variant-numeric: tabular-nums;
      pointer-events: none;
    }

    .cmd-hit.warn { border-color: #fbbf24; }

    .cmd-hit.lethal {
      border-color: #f8fafc;
      box-shadow: 0 0 10px rgba(248, 250, 252, 0.4);
    }

    /* Compact fallback for seats that cannot fit one button per rival. */
    .cmd-collapsed {
      display: none;
      min-width: 2.9rem;
      min-height: 2.9rem;
      padding: 0.15rem 0.3rem;
      border-radius: 0.45rem;
      border: 2px solid transparent;
      background: rgba(15, 23, 42, 0.55);
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
      color: #f8fafc;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 0.05rem;
      font-weight: 700;
      appearance: none;
      flex-shrink: 0;
    }

    .trackers.tight .cmd-hit { display: none; }
    .trackers.tight .cmd-collapsed { display: flex; }

    .cmd-collapsed:active { transform: scale(0.95); }
    .cmd-collapsed.warn { border-color: #fbbf24; }

    .cmd-collapsed.lethal {
      border-color: #f8fafc;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28),
        0 0 10px rgba(248, 250, 252, 0.4);
    }

    .cmd-collapsed-name {
      font-size: 0.5rem;
      line-height: 1;
      letter-spacing: 0.08em;
      opacity: 0.8;
      pointer-events: none;
    }

    .cmd-collapsed-amt {
      font-size: 1.1rem;
      line-height: 1.05;
      font-variant-numeric: tabular-nums;
      pointer-events: none;
    }

    /* "How close am I to killing them" — the same data, from your seat. */
    .cmd-mine {
      min-width: 2.9rem;
      min-height: 2.9rem;
      padding: 0.15rem 0.3rem;
      border-radius: 0.45rem;
      border: 1px dashed rgba(255, 255, 255, 0.45);
      background: rgba(15, 23, 42, 0.5);
      color: #f8fafc;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 0.08rem;
      appearance: none;
      flex-shrink: 0;
    }

    #board.players-3 .cmd-mine,
    #board.players-4 .cmd-mine,
    #board.players-5 .cmd-mine {
      min-width: 2.75rem;
      min-height: 2.75rem;
    }

    .cmd-mine:active { transform: scale(0.95); }
    .cmd-mine-icon { display: block; opacity: 0.75; pointer-events: none; }

    .cmd-mine-amt {
      font-size: 0.95rem;
      font-weight: 800;
      line-height: 1;
      font-variant-numeric: tabular-nums;
      pointer-events: none;
    }

    .kill-list {
      display: flex;
      flex-direction: column;
      gap: 0.4rem;
    }

    .kill-row {
      display: flex;
      align-items: center;
      gap: 0.6rem;
      padding: 0.6rem 0.7rem;
      border-radius: 0.7rem;
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid rgba(255, 255, 255, 0.08);
    }

    .kill-row.dead { opacity: 0.45; }

    .kill-swatch {
      width: 0.55rem;
      height: 2rem;
      border-radius: 0.18rem;
      flex-shrink: 0;
    }

    .kill-main { flex: 1; min-width: 0; }

    .kill-name {
      font-size: 0.9rem;
      font-weight: 600;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .kill-meta {
      font-size: 0.72rem;
      color: #94a3b8;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .kill-need {
      flex-shrink: 0;
      text-align: right;
      display: flex;
      flex-direction: column;
      align-items: flex-end;
      line-height: 1;
      font-weight: 800;
    }

    .kill-need-num {
      font-size: 1.5rem;
      font-variant-numeric: tabular-nums;
    }

    .kill-need-unit {
      font-size: 0.6rem;
      font-weight: 600;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    .kill-need.ready { color: #fbbf24; font-size: 1.1rem; }

    #stat-overlay {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 45;
      align-items: center;
      justify-content: center;
      background: rgba(2, 6, 23, 0.72);
      padding: 1rem;
    }

    #stat-overlay.open { display: flex; }

    #stat-overlay[data-side="left"] { justify-content: flex-start; padding-left: 6vw; }
    #stat-overlay[data-side="right"] { justify-content: flex-end; padding-right: 6vw; }
    #stat-overlay[data-side="top"] { align-items: flex-start; padding-top: 6vh; }
    #stat-overlay[data-side="bottom"] { align-items: flex-end; padding-bottom: 6vh; }

    .cmd-card {
      width: min(22rem, 92vw);
      max-height: min(78vh, 36rem);
      overflow: auto;
      background: #0f172a;
      border: 1px solid rgba(255, 255, 255, 0.12);
      border-radius: 1.15rem;
      padding: 0.9rem;
      color: #f8fafc;
      box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
      transform-origin: center center;
    }

    #stat-overlay[data-rot="90"] .cmd-card,
    #stat-overlay[data-rot="-90"] .cmd-card {
      width: min(20rem, 78vh);
    }

    .cmd-burst-delta {
      display: none;
      margin: 0 auto 0.55rem;
      width: fit-content;
      font-size: 1.7rem;
      font-weight: 800;
      line-height: 1;
      color: #f8fafc;
      background: rgba(15, 23, 42, 0.95);
      padding: 0.2rem 0.7rem;
      border-radius: 0.7rem;
      box-shadow: 0 8px 22px rgba(0, 0, 0, 0.4);
    }

    .cmd-burst-delta.show { display: block; }

    .cmd-burst-delta.bump { animation: cmd-delta-bump 180ms ease-out; }

    @keyframes cmd-delta-bump {
      0% { transform: scale(0.82); }
      70% { transform: scale(1.12); }
      100% { transform: scale(1); }
    }

    .cmd-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 0.5rem;
    }

    .cmd-grid.cols-1 { grid-template-columns: 1fr; }

    .cmd-self-title {
      margin: 0.75rem 0 0.4rem;
      font-size: 0.68rem;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    .cmd-self {
      display: flex;
      gap: 0.4rem;
    }

    .cmd-self .cmd-opp {
      flex: 1;
      min-height: 3.35rem;
    }

    .cmd-opp {
      min-height: 4.8rem;
      border-radius: 1rem;
      border: 2px solid transparent;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 0.2rem;
      font-weight: 700;
      appearance: none;
      padding: 0.45rem;
    }

    .cmd-opp:active { transform: scale(0.97); }

    .cmd-opp .cmd-name {
      font-size: 0.68rem;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      opacity: 0.8;
    }

    .cmd-opp .cmd-amt { font-size: 1.65rem; line-height: 1; }

    .cmd-adjust {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 0.5rem;
    }

    .cmd-step {
      width: 3rem;
      height: 3rem;
      border-radius: 0.8rem;
      background: rgba(255, 255, 255, 0.08);
      border: 1px solid rgba(255, 255, 255, 0.12);
      color: #f8fafc;
      font-size: 1.6rem;
      font-weight: 700;
      appearance: none;
    }

    /* The mana orb. It sits where four seats meet, so it can land on any
       colour a player has picked: everything that carries meaning (the five
       arcs, the glyph) is drawn over its own dark plinth rather than trusting
       the board behind it. 3rem clears the 44px touch target without eating
       into the life-tap area around it. */
    #menu-btn {
      position: fixed;
      left: 50%;
      top: 50%;
      z-index: 40;
      width: 3rem;
      height: 3rem;
      padding: 0;
      transform: translate(-50%, -50%);
      border-radius: 9999px;
      border: 0;
      background: transparent;
      color: #f5edd6;
      display: grid;
      place-items: center;
      appearance: none;
      filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.55));
    }

    #menu-btn .orb {
      display: block;
      width: 3rem;
      height: 3rem;
    }

    /* A slow gold breath under the orb, so the eye finds the centre of the
       table without anything moving fast enough to distract mid-game. */
    #menu-btn::before {
      content: "";
      position: absolute;
      inset: -0.6rem;
      border-radius: 9999px;
      background: radial-gradient(circle,
        rgba(212, 160, 23, 0.38) 0%,
        rgba(212, 160, 23, 0.14) 46%,
        rgba(212, 160, 23, 0) 72%);
      pointer-events: none;
      animation: orb-breathe 5s ease-in-out infinite;
    }

    @keyframes orb-breathe {
      0%, 100% { opacity: 0.5; transform: scale(0.94); }
      50% { opacity: 1; transform: scale(1.06); }
    }

    /* Brightened WUBRG: at a 3px stroke the board palette goes muddy, and the
       black slice would vanish outright against the table. */
    .orb-w { stroke: #f6f0cf; }
    .orb-u { stroke: #2f9fe2; }
    .orb-b { stroke: #8d8275; }
    .orb-r { stroke: #e2564b; }
    .orb-g { stroke: #29a862; }

    #menu-btn:active { transform: translate(-50%, -50%) scale(0.92); }
    #menu-btn:active .orb-glyph { stroke: #ffffff; }

    /* Until the menu has been opened once it pings and names itself; after
       that the orb is quiet and the ring does the talking. */
    #menu-btn.is-new::after {
      content: "";
      position: absolute;
      inset: 0;
      border-radius: 9999px;
      border: 2px solid rgba(246, 240, 207, 0.5);
      animation: orb-ping 2.6s ease-out infinite;
      pointer-events: none;
    }

    /* Capped at 1.28: any wider and the ring sweeps across the game timer
       sitting just above the orb. */
    @keyframes orb-ping {
      0% { opacity: 0.55; transform: scale(1); }
      70%, 100% { opacity: 0; transform: scale(1.28); }
    }

    #menu-hint {
      position: fixed;
      left: 50%;
      top: calc(50% + 2.15rem);
      transform: translateX(-50%);
      z-index: 39;
      display: none;
      padding: 0.14rem 0.55rem;
      border-radius: 9999px;
      border: 1px solid rgba(212, 160, 23, 0.45);
      background: rgba(15, 23, 42, 0.9);
      color: #f5edd6;
      font-size: 0.56rem;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      white-space: nowrap;
      pointer-events: none;
    }

    #menu-hint.show { display: block; }
    #undo-btn.show ~ #menu-hint { display: none; }

    #undo-btn {
      position: fixed;
      left: 50%;
      top: calc(50% + 2.15rem);
      z-index: 40;
      transform: translateX(-50%);
      border-radius: 9999px;
      border: 1px solid rgba(255, 255, 255, 0.16);
      background: rgba(15, 23, 42, 0.88);
      color: #e2e8f0;
      font-size: 0.62rem;
      font-weight: 700;
      letter-spacing: 0.04em;
      padding: 0.3rem 0.85rem;
      white-space: nowrap;
      display: none;
      overflow: hidden;
    }

    #undo-btn.show { display: block; }

    #undo-btn .undo-label {
      position: relative;
      z-index: 1;
    }

    /* Discreet countdown: a thin bar that drains as the undo window closes. */
    #undo-progress {
      position: absolute;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 2px;
      background: rgba(248, 250, 252, 0.55);
      transform: scaleX(1);
      transform-origin: left center;
      pointer-events: none;
    }

    #undo-progress.run {
      animation: undo-countdown 4000ms linear forwards;
    }

    @keyframes undo-countdown {
      from { transform: scaleX(1); }
      to { transform: scaleX(0); }
    }

    .face.is-out { filter: saturate(0.4) brightness(0.7); }

    .first-badge {
      display: none;
      position: absolute;
      left: 50%;
      top: 6%;
      transform: translateX(-50%);
      z-index: 6;
      pointer-events: none;
      font-size: 0.78rem;
      font-weight: 800;
      letter-spacing: 0.08em;
      padding: 0.12rem 0.48rem;
      border-radius: 9999px;
      background: #fbbf24;
      color: #1a1710;
      box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
    }

    .face.is-first .first-badge { display: block; }

    .out-banner {
      display: none;
      position: absolute;
      left: 50%;
      top: 12%;
      transform: translateX(-50%);
      z-index: 6;
      pointer-events: none;
      font-size: 1.1rem;
      font-weight: 800;
      letter-spacing: 0.18em;
      padding: 0.15rem 0.55rem;
      border-radius: 0.4rem;
      background: rgba(15, 23, 42, 0.82);
      color: #f8fafc;
    }

    .face.is-out .out-banner {
      display: block;
      animation: out-stamp 0.45s cubic-bezier(0.2, 1.4, 0.4, 1) both;
    }

    @keyframes out-stamp {
      0% { transform: translateX(-50%) scale(2.4) rotate(-10deg); opacity: 0; }
      60% { transform: translateX(-50%) scale(0.92) rotate(3deg); opacity: 1; }
      100% { transform: translateX(-50%) scale(1) rotate(-4deg); opacity: 1; }
    }

    @keyframes lethal-pulse {
      0% { transform: scale(1); }
      35% { transform: scale(1.18); }
      100% { transform: scale(1); }
    }

    .mini-sq.lethal,
    .cmd-summary.lethal,
    .cmd-opp.lethal,
    .cmd-cell.lethal {
      animation: lethal-pulse 0.45s ease-out;
    }

    @keyframes comeback-sparkle {
      0% { box-shadow: inset 0 0 0 0 rgba(251, 191, 36, 0); }
      30% { box-shadow: inset 0 0 0 6px rgba(251, 191, 36, 0.55), 0 0 40px rgba(251, 191, 36, 0.5); }
      100% { box-shadow: inset 0 0 0 0 rgba(251, 191, 36, 0); }
    }

    .face.comeback::after {
      content: '';
      position: absolute;
      inset: 0;
      pointer-events: none;
      z-index: 7;
      animation: comeback-sparkle 0.9s ease-out;
    }

    .cmd-opp.warn { box-shadow: inset 0 0 0 2px #fbbf24; }
    .cmd-opp.lethal { outline: 2px solid #f8fafc; }

    /* ── Mesa compartida ─────────────────────────────────── */
    .table-status {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      font-size: 0.8rem;
      color: #cbd5e1;
      margin-bottom: 0.6rem;
      min-height: 1.4rem;
    }

    .table-dot {
      width: 0.55rem;
      height: 0.55rem;
      border-radius: 9999px;
      background: #64748b;
      flex-shrink: 0;
    }

    .table-dot.online { background: #22c55e; }
    .table-dot.connecting { background: #fbbf24; }
    .table-dot.error { background: #ef4444; }

    .join-row {
      display: flex;
      gap: 0.5rem;
    }

    .code-input {
      flex: 1;
      min-width: 0;
      border-radius: 0.8rem;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #f8fafc;
      padding: 0.55rem 0.7rem;
      font-size: 1.05rem;
      font-weight: 700;
      letter-spacing: 0.35em;
      text-transform: uppercase;
      text-align: center;
    }

    #invite-overlay {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 60;
      align-items: center;
      justify-content: center;
      background: rgba(2, 6, 23, 0.88);
      padding: 1.25rem;
    }

    #invite-overlay.open { display: flex; }

    .invite-card {
      width: min(20rem, 100%);
      background: #0f172a;
      border: 1px solid rgba(255, 255, 255, 0.12);
      border-radius: 1.15rem;
      padding: 1.25rem;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 0.85rem;
      box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
    }

    .invite-card h2 {
      margin: 0;
      font-size: 1rem;
      font-weight: 600;
      letter-spacing: 0.02em;
    }

    .invite-code {
      margin-top: 0.15rem;
      padding: 0.5rem 1rem;
      border-radius: 0.9rem;
      background: rgba(255, 255, 255, 0.06);
      border: 1px solid rgba(255, 255, 255, 0.12);
      font-size: 2.9rem;
      font-weight: 800;
      letter-spacing: 0.32em;
      text-indent: 0.32em;
      line-height: 1;
      font-variant-numeric: tabular-nums;
    }

    .invite-hint {
      font-size: 0.8rem;
      color: #94a3b8;
      text-align: center;
      line-height: 1.45;
      margin: 0;
    }

    .invite-wa,
    .invite-copy {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 0.5rem;
      width: 100%;
      min-height: 3rem;
      border-radius: 0.9rem;
      font-size: 0.92rem;
      font-weight: 600;
      appearance: none;
    }

    .invite-wa {
      border: 1px solid rgba(37, 211, 102, 0.4);
      background: rgba(37, 211, 102, 0.12);
      color: #6ee7a8;
    }

    .invite-wa:active { background: rgba(37, 211, 102, 0.2); }
    .invite-wa-icon { display: block; line-height: 0; }
    .invite-wa-icon svg { display: block; }

    .invite-copy {
      border: 1px solid rgba(255, 255, 255, 0.14);
      background: rgba(255, 255, 255, 0.06);
      color: #f8fafc;
    }

    .invite-actions {
      display: flex;
      gap: 0.5rem;
      width: 100%;
      margin-top: 0.2rem;
    }

    .invite-actions button {
      flex: 1;
      border-radius: 0.8rem;
      padding: 0.6rem 0.5rem;
      font-size: 0.85rem;
      font-weight: 600;
      border: 1px solid rgba(255, 255, 255, 0.14);
      background: rgba(255, 255, 255, 0.06);
      color: #f8fafc;
      appearance: none;
    }

    .invite-actions button.leave {
      background: rgba(239, 68, 68, 0.12);
      border-color: rgba(239, 68, 68, 0.4);
      color: #fca5a5;
    }

    /* Stacked just above the menu button, in the dead centre of the table
       where it reads the same from every seat. */
    #game-timer {
      position: fixed;
      left: 50%;
      top: calc(50% - 2.95rem);
      transform: translateX(-50%);
      z-index: 39;
      padding: 0.1rem 0.5rem;
      border-radius: 9999px;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(15, 23, 42, 0.8);
      color: #94a3b8;
      font-size: 0.6rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      font-variant-numeric: tabular-nums;
      pointer-events: none;
      white-space: nowrap;
    }

    /* Small badge on the board so you can see the pod is live. */
    #pod-badge {
      position: fixed;
      left: 50%;
      top: calc(50% - 4.6rem);
      transform: translateX(-50%);
      z-index: 40;
      display: none;
      align-items: center;
      gap: 0.32rem;
      padding: 0.16rem 0.55rem;
      border-radius: 9999px;
      border: 1px solid rgba(255, 255, 255, 0.16);
      background: rgba(15, 23, 42, 0.88);
      color: #e2e8f0;
      font-size: 0.58rem;
      font-weight: 700;
      letter-spacing: 0.12em;
      white-space: nowrap;
    }

    #pod-badge.show { display: flex; }

    /* Sits above the menu button, below the popups: visible but never in the
       way of a life tap. */
    #update-bar {
      position: fixed;
      left: 50%;
      bottom: max(0.9rem, env(safe-area-inset-bottom));
      transform: translateX(-50%);
      z-index: 55;
      display: flex;
      align-items: center;
      gap: 0.5rem;
      max-width: calc(100% - 1.5rem);
      padding: 0.6rem 1rem;
      border-radius: 9999px;
      border: 1px solid rgba(212, 160, 23, 0.5);
      background: rgba(15, 23, 42, 0.96);
      color: #f8fafc;
      font-size: 0.8rem;
      font-weight: 600;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
      appearance: none;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    #update-bar[hidden] { display: none; }

    .update-dot {
      width: 0.5rem;
      height: 0.5rem;
      border-radius: 9999px;
      background: #fbbf24;
      flex-shrink: 0;
    }

    .name-input {
      width: 100%;
      border-radius: 0.8rem;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #f8fafc;
      padding: 0.55rem 0.7rem;
      font-size: 0.95rem;
    }

    /* ── Tarjeta de jugador (acordeón) ───────────────────── */
    .player-card {
      margin-bottom: 0.6rem;
      border-radius: 1rem;
      border: 1px solid rgba(255, 255, 255, 0.1);
      background: rgba(255, 255, 255, 0.03);
      overflow: hidden;
    }

    .player-card.open { background: rgba(255, 255, 255, 0.05); }

    .player-card-head {
      display: flex;
      align-items: center;
      gap: 0.6rem;
      padding: 0.5rem;
    }

    .player-card-avatar {
      width: 2.5rem;
      height: 2.5rem;
      border-radius: 9999px;
      flex-shrink: 0;
      background-position: center;
      background-size: cover;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
    }

    .player-card-head .name-input { flex: 1; min-width: 0; }

    .player-card-toggle {
      flex-shrink: 0;
      width: 2.2rem;
      height: 2.2rem;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 9999px;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.05);
      color: #cbd5e1;
      appearance: none;
      transition: transform 0.2s ease;
    }

    .player-card.open .player-card-toggle { transform: rotate(180deg); }

    .player-card-body {
      padding: 0 0.85rem 0.9rem;
      border-top: 1px solid rgba(255, 255, 255, 0.07);
      margin-top: 0.1rem;
      padding-top: 0.7rem;
    }

    /* ── Foto del comandante (Scryfall) ──────────────────── */
    .cmd-photo-row {
      display: flex;
      align-items: flex-start;
      gap: 0.6rem;
      margin-bottom: 0.3rem;
    }

    .cmd-avatar {
      width: 3.2rem;
      height: 3.2rem;
      flex-shrink: 0;
      border-radius: 0.7rem;
      background: rgba(255, 255, 255, 0.06) center/cover no-repeat;
      border: 1px solid rgba(255, 255, 255, 0.14);
    }

    .cmd-photo-controls { flex: 1; min-width: 0; }

    .cmd-photo-search { display: flex; gap: 0.4rem; }

    .cmd-photo-input {
      flex: 1;
      min-width: 0;
      padding: 0.45rem 0.6rem;
      border-radius: 0.6rem;
      border: 1px solid rgba(255, 255, 255, 0.14);
      background: rgba(255, 255, 255, 0.05);
      color: #f8fafc;
      font-size: 0.82rem;
    }

    .cmd-photo-btn {
      flex-shrink: 0;
      padding: 0 0.85rem;
      border-radius: 0.6rem;
      border: 1px solid rgba(255, 255, 255, 0.16);
      background: rgba(255, 255, 255, 0.08);
      color: #f8fafc;
      font-size: 0.78rem;
      font-weight: 600;
      appearance: none;
    }

    .cmd-photo-btn[disabled] { opacity: 0.5; }

    .cmd-photo-suggestions {
      display: flex;
      flex-direction: column;
      gap: 0.15rem;
      margin-top: 0.35rem;
      max-height: 12rem;
      overflow-y: auto;
      border-radius: 0.6rem;
      border: 1px solid rgba(255, 255, 255, 0.14);
      background: rgba(15, 23, 42, 0.92);
    }

    .cmd-photo-suggestions.hidden { display: none; }

    .cmd-photo-suggestion {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      padding: 0.35rem 0.5rem;
      border: 0;
      background: none;
      color: #f8fafc;
      font-size: 0.78rem;
      text-align: left;
      appearance: none;
    }

    .cmd-photo-suggestion:hover,
    .cmd-photo-suggestion:focus-visible {
      background: rgba(255, 255, 255, 0.08);
    }

    .cmd-photo-suggestion-thumb {
      width: 1.8rem;
      height: 1.8rem;
      flex-shrink: 0;
      border-radius: 0.4rem;
      background: rgba(255, 255, 255, 0.06) center/cover no-repeat;
    }

    .cmd-photo-suggestion-name {
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .cmd-photo-status {
      margin: 0.3rem 0 0;
      font-size: 0.7rem;
      min-height: 0.9rem;
      color: #64748b;
    }

    .cmd-photo-status.error { color: #f87171; }

    .cmd-photo-actions {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 0.7rem;
      margin-top: 0.35rem;
    }

    .cmd-photo-bg-toggle {
      display: flex;
      align-items: center;
      gap: 0.35rem;
      font-size: 0.7rem;
      color: #94a3b8;
    }

    .cmd-photo-clear {
      padding: 0;
      border: 0;
      background: none;
      font-size: 0.7rem;
      color: #94a3b8;
      text-decoration: underline;
      appearance: none;
    }

    /* Commander portrait in the big damage popup's header. */
    .pop-avatar {
      width: 2.15rem;
      height: 2.15rem;
      border-radius: 9999px;
      flex-shrink: 0;
      background-position: center;
      background-size: cover;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
    }

    #board .life.is-roll {
      width: 7.4rem;
      height: 7.4rem;
      font-size: 3.7rem;
      display: grid;
      place-items: center;
      margin: 0 auto;
      border-radius: 1.2rem;
      background: linear-gradient(155deg, #fff 0%, #e2e8f0 58%, #94a3b8 100%);
      color: #0f172a;
      text-shadow: none;
      letter-spacing: 0;
      line-height: 1;
      box-shadow: 0 18px 42px rgba(0, 0, 0, 0.38), inset 0 2px 0 #fff,
        inset 0 -8px 14px rgba(15, 23, 42, 0.2);
      animation: die-land 0.75s cubic-bezier(0.22, 1.15, 0.36, 1);
    }

    #board .life.is-roll.spinning {
      animation: die-shake 0.11s linear infinite;
    }

    #board .life.is-roll.winner {
      box-shadow: 0 0 0 4px #fbbf24, 0 0 38px rgba(251, 191, 36, 0.7),
        0 18px 42px rgba(0, 0, 0, 0.38);
    }

    #board.players-3 .p2 .life.is-roll,
    #board.players-3 .p3 .life.is-roll,
    #board.players-4 .life.is-roll {
      width: 5.4rem;
      height: 5.4rem;
      font-size: 2.7rem;
      border-radius: 0.95rem;
    }

    @keyframes die-land {
      0% { transform: rotate(-52deg) scale(0.3); filter: blur(7px); opacity: 0.35; }
      38% { transform: rotate(20deg) scale(1.2); filter: blur(1px); opacity: 1; }
      68% { transform: rotate(-9deg) scale(0.92); filter: none; }
      100% { transform: rotate(0) scale(1); }
    }

    @keyframes die-shake {
      0%, 100% { transform: rotate(-10deg) scale(1.04); }
      50% { transform: rotate(10deg) scale(0.94); }
    }

    #dice-overlay {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 70;
      place-items: center;
      background: rgba(2, 6, 23, 0.78);
    }

    #dice-overlay.open { display: grid; }

    .dice-shell {
      width: min(72vw, 18.5rem);
      aspect-ratio: 1;
      border-radius: 1.7rem;
      display: grid;
      place-items: center;
      align-content: center;
      gap: 0.15rem;
      background: linear-gradient(155deg, #fff 0%, #e2e8f0 55%, #94a3b8 100%);
      color: #0f172a;
      box-shadow: 0 0 0 10px rgba(248, 250, 252, 0.14),
        0 28px 70px rgba(0, 0, 0, 0.55), inset 0 3px 0 #fff,
        inset 0 -10px 18px rgba(15, 23, 42, 0.2);
      animation: die-land 0.8s cubic-bezier(0.22, 1.15, 0.36, 1);
    }

    .dice-shell.spinning { animation: die-shake 0.1s linear infinite; }

    .dice-shell.crit {
      box-shadow: 0 0 0 10px rgba(251, 191, 36, 0.35),
        0 28px 70px rgba(0, 0, 0, 0.55), inset 0 3px 0 #fff,
        inset 0 -10px 18px rgba(15, 23, 42, 0.2), 0 0 50px rgba(251, 191, 36, 0.65);
    }

    .dice-shell.fumble {
      box-shadow: 0 0 0 10px rgba(196, 51, 43, 0.3),
        0 28px 70px rgba(0, 0, 0, 0.55), inset 0 3px 0 #fff,
        inset 0 -10px 18px rgba(15, 23, 42, 0.2);
      filter: saturate(0.6);
    }

    #dice-kind.crit { color: #fbbf24; opacity: 1; }
    #dice-kind.fumble { color: #c4332b; opacity: 1; }

    #dice-result {
      font-size: 7rem;
      font-weight: 800;
      line-height: 0.9;
    }

    /* "Cara"/"Cruz" at 7rem would run off a phone. */
    #dice-result.word { font-size: 3.4rem; letter-spacing: -0.01em; }

    #dice-kind {
      font-size: 0.85rem;
      font-weight: 700;
      letter-spacing: 0.22em;
      text-transform: uppercase;
      opacity: 0.45;
    }

    .hidden { display: none !important; }

    #wake-video {
      position: fixed;
      left: 0;
      bottom: 0;
      width: 3px;
      height: 3px;
      opacity: 0.02;
      pointer-events: none;
      z-index: 0;
    }

    #overlay {
      position: fixed;
      inset: 0;
      z-index: 50;
      display: none;
      align-items: flex-end;
      justify-content: center;
      background: rgba(2, 6, 23, 0.62);
      padding: 1rem;
      padding-bottom: max(1rem, env(safe-area-inset-bottom));
    }

    #overlay.open { display: flex; }

    #drawer {
      width: min(28rem, 100%);
      max-height: min(86dvh, 42rem);
      overflow: auto;
      overscroll-behavior: contain;
      touch-action: pan-y;
      display: flex;
      flex-direction: column;
      padding: 0;
    }

    .drawer-head {
      position: sticky;
      top: 0;
      z-index: 2;
      display: flex;
      align-items: center;
      gap: 0.6rem;
      padding: 1rem 1.15rem 0.85rem;
      background: #0f172a;
      border-bottom: 1px solid rgba(255, 255, 255, 0.08);
      border-radius: 1.5rem 1.5rem 0 0;
    }

    .drawer-head h2 {
      flex: 1;
      margin: 0;
      font-size: 1.05rem;
      font-weight: 600;
      letter-spacing: 0.01em;
    }

    .drawer-back {
      width: 2rem;
      height: 2rem;
      flex-shrink: 0;
      display: grid;
      place-items: center;
      border-radius: 9999px;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #e2e8f0;
      appearance: none;
    }

    .drawer-back.hidden { display: none !important; }

    .drawer-close {
      flex-shrink: 0;
      border-radius: 9999px;
      padding: 0.3rem 0.8rem;
      font-size: 0.82rem;
      color: #cbd5e1;
      background: rgba(255, 255, 255, 0.06);
      border: 1px solid rgba(255, 255, 255, 0.12);
      appearance: none;
    }

    .drawer-body { padding: 0.9rem 1.15rem 1.15rem; }

    .drawer-panel {
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }

    .drawer-panel.hidden { display: none !important; }

    /* The three things reached most often, as icon buttons that need no
       explaining once you have opened the menu twice. */
    .action-row {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 0.5rem;
      margin: 0.85rem 0 0.35rem;
    }

    /* Sin botón de pantalla completa (iPhone) quedan cuatro: en tres columnas
       el último cae solo en su fila, estrecho y descolgado. Con dos salen dos
       filas iguales y de paso caben mejor las etiquetas largas. */
    .action-row.is-compact { grid-template-columns: repeat(2, 1fr); }

    .action {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 0.4rem;
      min-height: 4.6rem;
      padding: 0.6rem 0.4rem;
      border-radius: 0.9rem;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #f8fafc;
      appearance: none;
    }

    .action:active { background: rgba(255, 255, 255, 0.12); }

    .action.danger {
      background: rgba(239, 68, 68, 0.1);
      border-color: rgba(239, 68, 68, 0.4);
      color: #fca5a5;
    }

    .action-icon { display: block; line-height: 0; }
    .action-icon svg { display: block; }

    .action-label {
      font-size: 0.78rem;
      font-weight: 600;
      letter-spacing: 0.01em;
    }

    /* ── "Añádeme a la pantalla de inicio" ────────────────────
       El mismo bloque de texto en dos sitios: dentro del menú, donde vive
       siempre en lugar del botón de pantalla completa, y en la tarjeta que
       sale sola una vez. Tres alturas: qué ganas, por qué, y qué tocar. */
    .install-hint-title {
      margin: 0 0 0.3rem;
      font-size: 0.88rem;
      font-weight: 700;
      color: #f8fafc;
      letter-spacing: 0.01em;
    }

    .install-hint-body {
      margin: 0;
      font-size: 0.78rem;
      line-height: 1.45;
      color: #94a3b8;
    }

    /* Los pasos, separados del párrafo y con el glifo real de Safari: el botón
       que hay que buscar no lleva la palabra "Compartir" escrita en ninguna
       parte, así que dibujarlo es la instrucción. */
    .install-hint-steps {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 0.3rem;
      margin: 0.55rem 0 0;
      padding-top: 0.5rem;
      border-top: 1px solid rgba(255, 255, 255, 0.08);
      font-size: 0.78rem;
      font-weight: 600;
      line-height: 1.35;
      color: #e2e8f0;
    }

    .install-hint-icon {
      display: block;
      line-height: 0;
      flex-shrink: 0;
      color: #d4a017;
    }

    .install-hint-icon svg { display: block; }

    /* Lo que se ve en iPhone en lugar del botón de pantalla completa. */
    .fullscreen-note {
      margin: 0.1rem 0 0.35rem;
      padding: 0.7rem 0.8rem;
      border-radius: 0.75rem;
      border: 1px solid rgba(255, 255, 255, 0.1);
      background: rgba(255, 255, 255, 0.04);
    }

    /* La misma nota, pero saliendo sola por abajo una única vez. Va por debajo
       del overlay del menú (50) para que el drawer la tape en vez de flotar
       sobre él, y por encima del orbe (40). */
    #install-tip {
      position: fixed;
      left: 50%;
      bottom: max(0.9rem, env(safe-area-inset-bottom));
      transform: translateX(-50%);
      z-index: 44;
      width: min(22rem, calc(100% - 1.5rem));
      animation: install-tip-in 0.32s ease-out both;
    }

    /* Nada de aparecer de golpe encima del tablero a media partida. */
    @keyframes install-tip-in {
      from { opacity: 0; transform: translate(-50%, 0.9rem); }
      to { opacity: 1; transform: translate(-50%, 0); }
    }

    .install-tip-card {
      padding: 0.85rem 0.95rem 0.8rem;
      border-radius: 1rem;
      border: 1px solid rgba(212, 160, 23, 0.45);
      background: rgba(15, 23, 42, 0.97);
      box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
    }

    .install-tip-ok {
      width: 100%;
      min-height: 2.5rem;
      margin-top: 0.7rem;
      border-radius: 0.7rem;
      border: 1px solid rgba(255, 255, 255, 0.14);
      background: rgba(255, 255, 255, 0.07);
      color: #f8fafc;
      font-size: 0.82rem;
      font-weight: 600;
      appearance: none;
    }

    .install-tip-ok:active { background: rgba(255, 255, 255, 0.14); }

    @media (prefers-reduced-motion: reduce) {
      #install-tip { animation: none; }
    }

    /* Root menu: one tappable row per area, with its current value on the right. */
    .menu-row {
      display: flex;
      align-items: center;
      gap: 0.7rem;
      width: 100%;
      min-height: 3.25rem;
      padding: 0.7rem 0.9rem;
      border-radius: 0.9rem;
      border: 1px solid rgba(255, 255, 255, 0.1);
      background: rgba(255, 255, 255, 0.05);
      color: #f8fafc;
      font-size: 0.95rem;
      font-weight: 600;
      text-align: left;
      appearance: none;
    }

    .row-icon {
      flex-shrink: 0;
      line-height: 0;
      color: #94a3b8;
    }

    .row-icon svg { display: block; }

    .menu-row[aria-disabled="true"] {
      opacity: 0.55;
    }

    .menu-row:active { background: rgba(255, 255, 255, 0.1); }

    .menu-row-main { flex: 1; min-width: 0; }

    .menu-row-value {
      font-size: 0.8rem;
      font-weight: 500;
      color: #94a3b8;
      text-align: right;
      max-width: 11rem;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .menu-row[data-go]::after {
      content: '';
      width: 0.42rem;
      height: 0.42rem;
      flex-shrink: 0;
      border-right: 2px solid #64748b;
      border-bottom: 2px solid #64748b;
      transform: rotate(-45deg);
      margin-left: 0.1rem;
    }

    .menu-row.danger {
      background: rgba(239, 68, 68, 0.1);
      border-color: rgba(239, 68, 68, 0.4);
      color: #fca5a5;
      margin-top: 0.35rem;
    }

    .menu-row.danger .row-icon { color: #fca5a5; }

    .panel-label {
      margin: 0.55rem 0 0.1rem;
      font-size: 0.7rem;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    .panel-label:first-child { margin-top: 0; }

    .panel-hint {
      margin: 0;
      font-size: 0.8rem;
      line-height: 1.45;
      color: #94a3b8;
    }

    .panel-btn {
      width: 100%;
      min-height: 3rem;
      border-radius: 0.9rem;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #f8fafc;
      font-size: 0.95rem;
      font-weight: 600;
      appearance: none;
    }

    .panel-btn.primary {
      background: #f8fafc;
      border-color: #f8fafc;
      color: #0f172a;
    }

    .panel-btn.narrow { width: auto; padding: 0 1.1rem; flex-shrink: 0; }

    .panel-btn.danger {
      background: rgba(239, 68, 68, 0.1);
      border-color: rgba(239, 68, 68, 0.4);
      color: #fca5a5;
    }

    .panel-btn.hidden { display: none !important; }

    .opt-grid {
      display: grid;
      gap: 0.5rem;
    }

    .opt-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
    .opt-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }

    .opt {
      min-height: 3rem;
      border-radius: 0.9rem;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #f8fafc;
      font-size: 1rem;
      font-weight: 600;
      appearance: none;
    }

    .opt.on,
    .panel-btn.on {
      background: #f8fafc;
      border-color: #f8fafc;
      color: #0f172a;
    }

    /* ── Diseño de mesa ──────────────────────────────────── */
    /* Templates are picked by looking at them, not by reading their names, so
       the cards are mostly preview and the label is a caption underneath. */
    .layout-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(5rem, 1fr));
      gap: 0.55rem;
      margin-bottom: 0.35rem;
    }

    .layout-card {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 0.5rem;
      padding: 0.6rem 0.45rem 0.55rem;
      border-radius: 0.9rem;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.05);
      color: #cbd5e1;
      appearance: none;
    }

    .layout-card:active { background: rgba(255, 255, 255, 0.1); }

    .layout-card.on {
      border-color: #f8fafc;
      background: rgba(248, 250, 252, 0.14);
      color: #f8fafc;
    }

    .layout-card-label {
      font-size: 0.72rem;
      font-weight: 600;
      line-height: 1.2;
      text-align: center;
    }

    /* A phone-shaped miniature of the board the template actually builds. */
    .layout-mini {
      display: grid;
      gap: 2px;
      width: 100%;
      max-width: 3.6rem;
      aspect-ratio: 10 / 17;
      padding: 2px;
      border-radius: 0.35rem;
      background: rgba(0, 0, 0, 0.45);
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
    }

    .layout-seat {
      display: flex;
      align-items: center;
      justify-content: center;
      min-width: 0;
      min-height: 0;
      border-radius: 0.18rem;
    }

    /* Turned to match the seat: which way each player reads is the one thing
       these previews exist to show. */
    .layout-seat-num {
      font-size: 0.58rem;
      font-weight: 700;
      line-height: 1;
      opacity: 0.85;
    }

    .seat-flip-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 0.6rem;
      padding: 0.55rem 0;
      border-bottom: 1px solid rgba(255, 255, 255, 0.07);
      font-size: 0.88rem;
      color: #e2e8f0;
    }

    .seat-flip-row:last-child { border-bottom: 0; }

    .seat-flip-btn {
      flex-shrink: 0;
      min-width: 6.5rem;
      padding: 0.4rem 0.7rem;
      border-radius: 0.7rem;
      border: 1px solid rgba(255, 255, 255, 0.14);
      background: rgba(255, 255, 255, 0.05);
      color: #cbd5e1;
      font-size: 0.78rem;
      font-weight: 600;
      appearance: none;
    }

    /* Deliberately quiet and at the very bottom of the menu: useful once,
       then never again. */
    .share-wa {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 0.45rem;
      width: 100%;
      margin-top: 0.9rem;
      padding: 0.55rem;
      border-radius: 0.7rem;
      border: 1px solid rgba(37, 211, 102, 0.35);
      background: rgba(37, 211, 102, 0.08);
      color: #6ee7a8;
      font-size: 0.78rem;
      font-weight: 600;
      appearance: none;
    }

    .share-wa:active { background: rgba(37, 211, 102, 0.16); }

    /* Development-only escape hatch; quiet enough to ignore at a real table. */
    .dev-btn {
      width: 100%;
      margin-top: 1.4rem;
      padding: 0.5rem;
      border-radius: 0.7rem;
      border: 1px dashed rgba(148, 163, 184, 0.35);
      background: transparent;
      color: #94a3b8;
      font-size: 0.75rem;
      font-weight: 600;
      appearance: none;
    }

    .dev-btn:active { background: rgba(148, 163, 184, 0.1); }
    .dev-btn[disabled] { opacity: 0.5; }

    .dev-hint {
      margin: 0.4rem 0 0;
      font-size: 0.68rem;
      line-height: 1.5;
      color: #64748b;
    }
    .version-line {
      margin: 1.1rem 0 0.1rem;
      text-align: center;
      font-size: 0.62rem;
      font-weight: 600;
      letter-spacing: 0.09em;
      color: #475569;
    }

    .version-line.stale { color: #d4a017; }

    .share-wa-icon { display: block; line-height: 0; }
    .share-wa-icon svg { display: block; }

    /* ── Elección de dado, centrada ──────────────────────── */
    #dice-choice {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 72;
      align-items: center;
      justify-content: center;
      background: rgba(2, 6, 23, 0.88);
      padding: 1.5rem;
    }

    #dice-choice.open { display: flex; }

    .choice-card {
      width: min(20rem, 100%);
      background: #0f172a;
      border: 1px solid rgba(255, 255, 255, 0.14);
      border-radius: 1.3rem;
      padding: 1.5rem 1.35rem 1.2rem;
      text-align: center;
      box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
    }

    .choice-card h2 {
      margin: 0 0 1.1rem;
      font-size: 1.2rem;
      font-weight: 700;
    }

    .choice-actions {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 0.7rem;
      margin-bottom: 0.7rem;
    }

    .choice-die {
      min-height: 5rem;
      border-radius: 1rem;
      border: 1px solid rgba(255, 255, 255, 0.16);
      background: linear-gradient(155deg, #fff 0%, #e2e8f0 58%, #94a3b8 100%);
      color: #0f172a;
      font-size: 1.6rem;
      font-weight: 800;
      letter-spacing: -0.02em;
      appearance: none;
    }

    .choice-die:active { transform: scale(0.96); }

    /* The coin is not a die: gold, and its label needs room for a word. */
    .choice-die.coin {
      background: linear-gradient(155deg, #fde68a 0%, #f5c04a 55%, #b4801f 100%);
      font-size: 1.05rem;
      letter-spacing: 0;
    }

    .choice-cancel {
      width: 100%;
      min-height: 2.75rem;
      border-radius: 0.8rem;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #cbd5e1;
      font-size: 0.9rem;
      font-weight: 600;
      appearance: none;
    }

    /* ── Confirmación centrada ───────────────────────────── */
    #confirm-overlay {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 80;
      align-items: center;
      justify-content: center;
      background: rgba(2, 6, 23, 0.88);
      padding: 1.5rem;
    }

    #confirm-overlay.open { display: flex; }

    .confirm-card {
      width: min(22rem, 100%);
      background: #0f172a;
      border: 1px solid rgba(255, 255, 255, 0.14);
      border-radius: 1.3rem;
      padding: 1.6rem 1.4rem 1.3rem;
      text-align: center;
      box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
    }

    .confirm-card h2 {
      margin: 0 0 0.6rem;
      font-size: 1.3rem;
      font-weight: 700;
      line-height: 1.25;
    }

    .confirm-card p {
      margin: 0 0 1.35rem;
      font-size: 0.9rem;
      line-height: 1.5;
      color: #94a3b8;
    }

    .confirm-actions {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 0.6rem;
    }

    .confirm-actions button {
      min-height: 3.4rem;
      border-radius: 0.9rem;
      font-size: 1.05rem;
      font-weight: 700;
      appearance: none;
      border: 1px solid transparent;
    }

    .confirm-no {
      background: rgba(255, 255, 255, 0.08);
      border-color: rgba(255, 255, 255, 0.16);
      color: #f8fafc;
    }

    .confirm-yes {
      background: #dc2626;
      color: #fff;
    }

    /* ── Resumen de partida ──────────────────────────────── */
    #summary-overlay {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 75;
      align-items: center;
      justify-content: center;
      background: rgba(2, 6, 23, 0.9);
      padding: 1.25rem;
    }

    #summary-overlay.open { display: flex; }

    .summary-card {
      width: min(26rem, 100%);
      max-height: min(88dvh, 46rem);
      overflow: auto;
      overscroll-behavior: contain;
      background: #0f172a;
      border: 1px solid rgba(255, 255, 255, 0.12);
      border-radius: 1.3rem;
      box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
    }

    .summary-head {
      position: sticky;
      top: 0;
      z-index: 2;
      display: flex;
      align-items: center;
      gap: 0.75rem;
      padding: 1rem 1.15rem 0.8rem;
      background: #0f172a;
      border-bottom: 1px solid rgba(255, 255, 255, 0.08);
      border-radius: 1.3rem 1.3rem 0 0;
    }

    .summary-head h2 {
      flex: 1;
      margin: 0;
      font-size: 1.05rem;
      font-weight: 600;
    }

    /* Los tres datos de la partida como fichas: se leen de un vistazo, sin
       tener que descifrar una frase gris suelta. */
    .sum-stats {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 0.4rem;
      padding: 0.9rem 1.15rem 0;
    }

    .sum-stats.hidden { display: none; }

    .sum-stat {
      min-width: 0;
      padding: 0.5rem 0.55rem 0.55rem;
      border-radius: 0.8rem;
      border: 1px solid rgba(255, 255, 255, 0.1);
      background: rgba(255, 255, 255, 0.05);
    }

    .sum-stat-value {
      font-size: 1.05rem;
      font-weight: 800;
      line-height: 1.1;
      color: #f8fafc;
      font-variant-numeric: tabular-nums;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .sum-stat-label {
      margin-top: 0.2rem;
      font-size: 0.62rem;
      font-weight: 700;
      line-height: 1.2;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    .sum-bar {
      display: flex;
      align-items: center;
      gap: 0.6rem;
      padding: 0.95rem 1.15rem 0.55rem;
    }

    .sum-bar.hidden { display: none; }

    .sum-bar-title {
      flex: 1;
      min-width: 0;
      font-size: 0.68rem;
      font-weight: 700;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    /* Abrir/cerrar todas las fichas a la vez. Es un atajo, no la única
       manera de llegar al detalle: cada jugador se abre por su cuenta. */
    .sum-more {
      display: flex;
      align-items: center;
      gap: 0.35rem;
      flex-shrink: 0;
      min-height: 2.75rem;
      padding: 0 0.85rem;
      border-radius: 9999px;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: rgba(255, 255, 255, 0.06);
      color: #cbd5e1;
      font-size: 0.8rem;
      font-weight: 600;
      appearance: none;
    }

    .sum-more:active { background: rgba(255, 255, 255, 0.12); }
    .sum-more.hidden { display: none; }

    .sum-chevron {
      display: block;
      line-height: 0;
      color: #94a3b8;
      transition: transform 0.18s ease;
    }

    .sum-chevron svg { display: block; }

    [aria-expanded="true"] .sum-chevron { transform: rotate(180deg); }

    #summary-body { padding: 0 1.15rem 1.3rem; }

    .sum-item {
      margin-bottom: 0.5rem;
      border-radius: 0.9rem;
      border: 1px solid rgba(255, 255, 255, 0.1);
      background: rgba(255, 255, 255, 0.04);
      overflow: hidden;
    }

    .sum-item:last-child { margin-bottom: 0; }

    /* Quien va ganando no se busca: se ve. */
    .sum-item.lead {
      border-color: rgba(212, 160, 23, 0.5);
      background: rgba(212, 160, 23, 0.08);
    }

    .sum-head {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr) auto auto;
      align-items: center;
      column-gap: 0.7rem;
      row-gap: 0.45rem;
      width: 100%;
      min-height: 3.5rem;
      padding: 0.6rem 0.7rem;
      background: none;
      border: 0;
      color: #f8fafc;
      text-align: left;
      appearance: none;
    }

    .sum-head:active { background: rgba(255, 255, 255, 0.06); }

    .sum-rank {
      display: grid;
      place-items: center;
      width: 2.3rem;
      height: 2.3rem;
      flex-shrink: 0;
      border-radius: 0.7rem;
      font-size: 0.9rem;
      font-weight: 800;
      font-variant-numeric: tabular-nums;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2);
    }

    /* Solo cuando hay curva debajo la ficha de puesto ocupa las dos filas:
       sin ella no se abre una segunda fila vacía que deje aire muerto. */
    .sum-item.has-trend .sum-rank { grid-row: 1 / span 2; }

    .sum-item.dead .sum-rank { opacity: 0.45; }

    .sum-main { min-width: 0; }

    .sum-name {
      display: flex;
      align-items: center;
      gap: 0.4rem;
      min-width: 0;
      font-size: 0.95rem;
      font-weight: 700;
      line-height: 1.2;
    }

    .sum-name-text {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .sum-item.dead .sum-name-text { color: #cbd5e1; }

    .sum-badge {
      display: inline-flex;
      align-items: center;
      gap: 0.22rem;
      flex-shrink: 0;
      padding: 0.14rem 0.42rem;
      border-radius: 9999px;
      background: rgba(212, 160, 23, 0.18);
      color: #fbbf24;
      font-size: 0.62rem;
      font-weight: 800;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      line-height: 1;
    }

    .sum-badge svg {
      display: block;
      width: 0.78rem;
      height: 0.78rem;
    }

    .sum-sub {
      margin-top: 0.15rem;
      font-size: 0.76rem;
      line-height: 1.25;
      color: #94a3b8;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .sum-sub.fallen { color: #fca5a5; }

    .sum-life {
      flex-shrink: 0;
      min-width: 2.3rem;
      text-align: right;
      font-size: 1.35rem;
      font-weight: 800;
      line-height: 1;
      font-variant-numeric: tabular-nums;
    }

    .sum-item.dead .sum-life { color: #64748b; }

    /* La curva de vida ocupa todo el ancho de la ficha en vez de un sello de
       68px: así se distingue una remontada de una caída libre. */
    .sum-trend {
      grid-column: 2 / -1;
      line-height: 0;
    }

    .sum-trend svg {
      display: block;
      width: 100%;
      height: 1.6rem;
    }

    .sum-empty {
      margin: 0;
      padding: 1.1rem 0 0.3rem;
      font-size: 0.88rem;
      line-height: 1.5;
      color: #94a3b8;
    }

    .sum-hint {
      margin: 0.75rem 0 0;
      font-size: 0.72rem;
      text-align: center;
      color: #64748b;
    }

    /* ── Detalle de un jugador ───────────────────────────── */
    .sum-drop {
      padding: 0.75rem 0.7rem 0.85rem;
      border-top: 1px solid rgba(255, 255, 255, 0.08);
    }

    .sum-drop.hidden { display: none; }

    .sum-cmd {
      display: flex;
      align-items: center;
      gap: 0.55rem;
      min-width: 0;
      margin-bottom: 0.7rem;
      padding: 0.45rem 0.55rem;
      border-radius: 0.7rem;
      background: rgba(255, 255, 255, 0.05);
    }

    .sum-cmd-art {
      width: 2.1rem;
      height: 2.1rem;
      flex-shrink: 0;
      border-radius: 0.5rem;
      background-position: center;
      background-size: cover;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2);
    }

    .sum-cmd-text { min-width: 0; }

    .sum-cmd-label {
      font-size: 0.6rem;
      font-weight: 700;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    .sum-cmd-name {
      font-size: 0.85rem;
      font-weight: 600;
      line-height: 1.25;
      color: #e2e8f0;
    }

    .sum-chart { line-height: 0; }

    .sum-chart svg {
      display: block;
      width: 100%;
      height: 4.25rem;
    }

    .sum-legend {
      margin: 0.3rem 0 0.7rem;
      font-size: 0.66rem;
      color: #64748b;
    }

    /* Números como fichas, no como una lista de "etiqueta — valor". Solo
       aparece lo que ha pasado de verdad: un cero no gasta una línea. */
    .sum-chips {
      display: flex;
      flex-wrap: wrap;
      gap: 0.35rem;
    }

    .sum-chip {
      min-width: 3.4rem;
      padding: 0.35rem 0.55rem 0.4rem;
      border-radius: 0.6rem;
      border: 1px solid rgba(255, 255, 255, 0.08);
      background: rgba(255, 255, 255, 0.05);
    }

    .sum-chip-value {
      font-size: 0.92rem;
      font-weight: 800;
      line-height: 1.1;
      color: #f1f5f9;
      font-variant-numeric: tabular-nums;
    }

    .sum-chip-label {
      margin-top: 0.1rem;
      font-size: 0.6rem;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    .sum-chip.up .sum-chip-value { color: #86efac; }
    .sum-chip.down .sum-chip-value { color: #fca5a5; }

    .sum-drop-label {
      margin: 0.85rem 0 0.3rem;
      font-size: 0.62rem;
      font-weight: 700;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      color: #94a3b8;
    }

    /* Daño de comandante contra los 21 letales: la barra dice a cuánto
       estabas de morir, que es la pregunta real en una mesa de Commander. */
    .sum-dmg {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto;
      align-items: center;
      column-gap: 0.6rem;
      row-gap: 0.2rem;
      padding: 0.3rem 0 0.35rem;
    }

    .sum-dmg-name {
      font-size: 0.78rem;
      color: #cbd5e1;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .sum-dmg-value {
      font-size: 0.78rem;
      font-weight: 700;
      color: #f1f5f9;
      font-variant-numeric: tabular-nums;
    }

    .sum-dmg-value.lethal { color: #fca5a5; }

    .sum-dmg-track {
      grid-column: 1 / -1;
      height: 0.34rem;
      border-radius: 9999px;
      background: rgba(255, 255, 255, 0.08);
      overflow: hidden;
    }

    .sum-dmg-fill {
      display: block;
      height: 100%;
      border-radius: 9999px;
    }

    .sum-fall {
      display: flex;
      align-items: baseline;
      gap: 0.4rem;
      margin-top: 0.8rem;
      padding: 0.5rem 0.6rem;
      border-radius: 0.7rem;
      border: 1px solid rgba(239, 68, 68, 0.28);
      background: rgba(239, 68, 68, 0.1);
      font-size: 0.78rem;
      font-weight: 600;
      color: #fca5a5;
    }

    .sum-fall-when {
      margin-left: auto;
      flex-shrink: 0;
      font-weight: 500;
      color: #94a3b8;
      font-variant-numeric: tabular-nums;
    }

    .swatch-label {
      margin: 0.7rem 0 0.35rem;
      font-size: 0.68rem;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: #94a3b8;
    }

    .swatch-row {
      display: flex;
      flex-wrap: wrap;
      gap: 0.5rem;
      margin-bottom: 0.2rem;
    }

    .color-swatch {
      width: 2.35rem;
      height: 2.35rem;
      border-radius: 9999px;
      border: 2px solid transparent;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
      font-weight: 700;
      font-size: 0.85rem;
      appearance: none;
      padding: 0;
      flex-shrink: 0;
      transition: transform 0.15s ease, box-shadow 0.15s ease;
    }

    .color-swatch.plain {
      width: 2.05rem;
      height: 2.05rem;
    }

    .color-swatch.active {
      border-color: #f8fafc;
      box-shadow: 0 0 0 3px rgba(248, 250, 252, 0.35), 0 0 0 1px rgba(0, 0, 0, 0.25);
      transform: scale(1.08);
    }

    /* Our own picker: a single hue strip, no native OS colour dialog. */
    .custom-color {
      padding: 0.55rem 0.7rem;
      border-radius: 1rem;
      border: 1px solid rgba(255, 255, 255, 0.14);
      background: rgba(255, 255, 255, 0.05);
    }

    .custom-color.active {
      border-color: rgba(255, 255, 255, 0.3);
    }

    .custom-color-head {
      display: flex;
      align-items: center;
      gap: 0.55rem;
      margin-bottom: 0.55rem;
    }

    .custom-preview {
      width: 1.6rem;
      height: 1.6rem;
      border-radius: 9999px;
      flex-shrink: 0;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
    }

    .custom-preview.empty {
      background: conic-gradient(red, #eab308, #22c55e, #06b6d4, #3b82f6, #d946ef, red);
    }

    .custom-hex {
      font-size: 0.78rem;
      font-weight: 600;
      color: #cbd5e1;
      letter-spacing: 0.02em;
    }

    .hue-bar {
      position: relative;
      height: 1.15rem;
      border-radius: 9999px;
      background: linear-gradient(
        to right,
        hsl(0, 75%, 55%), hsl(60, 75%, 55%), hsl(120, 75%, 55%),
        hsl(180, 75%, 55%), hsl(240, 75%, 55%), hsl(300, 75%, 55%), hsl(360, 75%, 55%)
      );
      touch-action: none;
      cursor: pointer;
    }

    .hue-thumb {
      position: absolute;
      top: 50%;
      width: 1.5rem;
      height: 1.5rem;
      border-radius: 9999px;
      border: 3px solid #f8fafc;
      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
      transform: translate(-50%, -50%);
      pointer-events: none;
    }

    .life-is-zero .life { opacity: 0.55; }

    @media (orientation: landscape) {
      #board.players-2 {
        grid-template-columns: 1fr 1fr;
        grid-template-rows: 1fr;
      }

      #board.players-2 .p2 { grid-area: 1 / 1; }
      #board.players-2 .p1 { grid-area: 1 / 2; }

      #board.players-2 .p2 .face,
      #board.players-2 .p1 .face {
        inset: auto;
        width: 100dvh;
        height: 50dvw;
        top: 50%;
        left: 50%;
      }

      #board.players-2 .p2 .face {
        transform: translate(-50%, -50%) rotate(90deg) rotate(var(--seat-turn, 0deg));
      }

      #board.players-2 .p1 .face {
        transform: translate(-50%, -50%) rotate(-90deg) rotate(var(--seat-turn, 0deg));
      }

      #board.players-2 .life { font-size: clamp(5.8rem, 26vh, 10.5rem); }
      #board.players-2 .life.is-roll {
        width: 6.4rem;
        height: 6.4rem;
        font-size: 3.2rem;
      }
      #board.players-3 .p2 .life,
      #board.players-3 .p3 .life,
      #board.players-4 .life { font-size: clamp(4.2rem, 20vh, 7rem); }

      /* The seat that spans the bottom row is the one landscape squeezes:
         its height is a third or a half of an already-short viewport, and a
         vw-based clamp does not know that. Left unconstrained, the digits
         grow taller than the seat and spill over the tracker strip. */
      #board.players-3 .p1 .life { font-size: clamp(3rem, 26vh, 7rem); }
      #board.players-5 .p1 .life { font-size: clamp(2rem, 12vh, 4.6rem); }

      /* A third of a landscape phone leaves roughly 75px once the tracker
         strip has its share, so the name label has to give up its margin. */
      #board.players-5 .player-label,
      #board.players-4.layout-cross .player-label { margin-bottom: 0; font-size: 0.68rem; }

      #board.players-5 .p2 .life,
      #board.players-5 .p3 .life,
      #board.players-5 .p4 .life,
      #board.players-5 .p5 .life { font-size: clamp(2.4rem, 17vh, 4.6rem); }

      /* Same three-row squeeze as players-5, mapped onto the cross template. */
      #board.players-4.layout-cross .p1 .life,
      #board.players-4.layout-cross .p4 .life { font-size: clamp(2rem, 12vh, 4.6rem); }
      #board.players-4.layout-cross .p2 .life,
      #board.players-4.layout-cross .p3 .life { font-size: clamp(2.4rem, 17vh, 4.6rem); }

      #board.big.players-3 .p1 .life { font-size: clamp(3.4rem, 30vh, 8rem); }
      #board.big.players-5 .p1 .life { font-size: clamp(2.8rem, 22vh, 5.6rem); }
      #board.big.players-5 .p2 .life,
      #board.big.players-5 .p3 .life,
      #board.big.players-5 .p4 .life,
      #board.big.players-5 .p5 .life { font-size: clamp(2.8rem, 22vh, 5.6rem); }
      #board.big.players-4.layout-cross .p1 .life,
      #board.big.players-4.layout-cross .p4 .life { font-size: clamp(2.8rem, 22vh, 5.6rem); }
      #board.big.players-4.layout-cross .p2 .life,
      #board.big.players-4.layout-cross .p3 .life { font-size: clamp(2.8rem, 22vh, 5.6rem); }

      /*
       * Franjas turned sideways: five strips share a short viewport, so a row
       * can end up ~75px tall. The tracker strip is a fixed cost in that box,
       * so it shrinks here along with the life — otherwise the numbers spill
       * straight through the seat below.
       */
      #board.layout-rows .slot .face { padding-bottom: 1.75rem; }
      #board.layout-rows .zone { bottom: 1.75rem; }
      #board.layout-rows .mini-sq { width: 1.6rem; height: 1.6rem; }
      #board.layout-rows .mini-value { font-size: 0.62rem; }
      #board.layout-rows .trackers { gap: 0.2rem; }
      #board.layout-rows .player-label { margin-bottom: 0; font-size: 0.6rem; }

      #board.players-3.layout-rows .slot .life { font-size: clamp(1.8rem, 13vh, 4rem); }
      #board.players-4.layout-rows .slot .life { font-size: clamp(1.3rem, 8.5vh, 3rem); }
      #board.players-5.layout-rows .slot .life { font-size: clamp(1rem, 5.5vh, 2rem); }

      #board.big.players-3.layout-rows .slot .life { font-size: clamp(2.2rem, 17vh, 5rem); }
      #board.big.players-4.layout-rows .slot .life { font-size: clamp(1.6rem, 11vh, 3.4rem); }
      #board.big.players-5.layout-rows .slot .life { font-size: clamp(1.1rem, 6.5vh, 2.4rem); }
    }

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

      #board .life.is-roll.spinning,
      .dice-shell.spinning {
        animation: none !important;
      }
    }
