/* ==========================================================================
   dice_board.css — scène des jeux de DÉS (Yams, Yahtzee)
   --------------------------------------------------------------------------
   DÉCISION DE COMPOSITION (25/10/2026 — « chaque jeu a son gabarit »)

   Un jeu de dés n'a pas de main. L'écran porte donc deux choses, et rien
   d'autre :
     · un OBJET de jeu — cinq dés, qu'on lance et qu'on tient ;
     · une MÉMOIRE de partie — la feuille de score, 16 lignes × 2 à 6 joueurs.

   La feuille EST le jeu : c'est elle qui domine. Les dés sont l'instrument :
   une seule rangée, à la hauteur d'un dé. Aucun autre jeu n'a cette
   répartition, et c'est voulu.

       [ HUD     ] auto                        mode · tour · lancers (1 ligne)
       [ DÉS     ] auto  (= dé + 12 px)        cinq dés, état « tenu » visible
       [ TABLEAU ] minmax(0, 1fr)              LA FEUILLE — prioritaire
       [ ACTIONS ] auto                        LANCER, rangée de la grille

   RÔLES ET DIMENSIONNEMENT
     1. HUD (26 / 30 px) : une seule ligne, jamais de retour à la ligne. Il ne
        raconte que le tour et les lancers restants ; le reste vit ailleurs.
     2. DÉS (dé + 8 px, jamais en %) : la rangée ne réclame PAS de pourcentage
        de la hauteur, elle vaut la taille d'un dé plus l'air autour (3 px de
        padding + 1 px de bordure). Le dé suit la largeur ET la hauteur
        (min(14.5vw, 9.5vh), borné 30–56 px). Un dé tenu porte un anneau teal
        en plus de sa face indigo (dice_3d.css).
     3. TABLEAU (1fr) : il absorbe toute la hauteur restante. Ses 16 lignes se
        partagent la zone avec un plancher de 19 px ; au-dessus du plancher,
        pas de défilement vertical. Deux repères de lecture sont collants :
        la colonne des catégories (gauche) et la ligne Total (bas). Ils ne
        sortent jamais de l'écran, même quand la feuille défile.
     4. ACTIONS (46 / 52 px) : LANCER est une rangée de la grille, donc
        structurellement visible et cliquable — pas de position: fixed.

   COLONNES
     · catégories : clamp(112px, 22%, 176px). 112 px est le minimum lisible (le
       plus long libellé demande 102 px), 176 px le plafond : sur tablette une
       colonne de 264 px de vide n'a aucun sens, l'espace va aux joueurs.
     · joueurs : minmax(56px, 1fr). 56 px est le minimum d'une colonne de score ;
       les pseudos sont tronqués par des points de suspension (jamais au milieu
       d'une lettre) et le nom complet reste dans `title`.

   COMPORTEMENT AU-DELÀ DU MINIMUM (mesuré, pas supposé)
     · 360 × 560 : les 16 lignes tiennent, aucun défilement (~19,6 px/ligne).
     · 360 × 420 : la zone du tableau passe sous 16 × 19 px → le corps défile
       en vertical (10 lignes + 1 partielle, 113 px mesurés), la ligne Total
       reste collée en bas, LANCER reste visible.
     · 5–6 joueurs : 112 + 6 × 56 = 448 px > 350 px disponibles → 98 px de
       défilement horizontal, colonne des catégories collante, ombre portée à
       sa droite dès qu'on a défilé. L'en-tête est un frère du scroller et
       suit le défilement par transform (voir §4) : un `position: sticky` de
       cellule ne tient pas dans une grille plate.
     · ≥ 768 px : colonne des catégories plafonnée à 176 px, les joueurs
       récupèrent la largeur, les lignes s'étirent (1fr) sans repasser sous
       19 px.

   Aucune règle de game.css / dice_3d.css n'est réécrite : tout est ciblé via
   `body.in-game #game-area.dice-stage`, et les classes `ss-*` / `dst-*` sont
   neuves. La coque (#view-game, 100svh) n'est pas touchée.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Chaîne de hauteur : #view-game devient une colonne qui porte la scène.
   :has() restreint la règle aux parties de dés : aucun autre jeu n'est touché.
   -------------------------------------------------------------------------- */
body.in-game #view-game:has(#game-area.dice-stage) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding-bottom: 0;
}

/* --------------------------------------------------------------------------
   1. La scène
   -------------------------------------------------------------------------- */
body.in-game #game-area.dice-stage {
    --dst-page: #12131f;
    --dst-panel: #1b1d2b;
    --dst-table: #232636;
    --dst-cell: #1b1d2b;
    --dst-cell-mine: #1a2b31;
    --dst-row-alt: #191b28;
    --dst-line: rgba(255, 255, 255, .08);
    --dst-ink: #e8ebf2;
    --dst-muted: #9aa3b5;
    --dst-accent: #00d4aa;
    --dst-warn: #ffd700;
    --dst-danger: #e94560;
    --dst-radius: 12px;

    position: relative;
    display: grid;
    /* Les dés ne réclament plus un pourcentage : leur rangée vaut un dé plus
       l'air autour (auto), donc la feuille récupère tout le reste. */
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
    box-sizing: border-box;
    width: 100% !important;
    max-width: 100% !important;
    height: 100%;
    flex: 1 1 auto !important;
    min-height: 0;
    margin: 0 !important;
    /* Les 175 px de padding de game.css (compensation de l'ancienne boîte
       fixed) sont supprimés : la grille n'a plus rien à compenser. */
    padding: 4px
             calc(4px + env(safe-area-inset-right, 0px))
             calc(4px + env(safe-area-inset-bottom, 0px))
             calc(4px + env(safe-area-inset-left, 0px)) !important;
    overflow: hidden;
    background: var(--dst-page);
    color: var(--dst-ink);
    font-size: 14px;
    line-height: 1.2;
}

body.in-game #game-area.dice-stage > * { box-sizing: border-box; min-width: 0; }

/* --------------------------------------------------------------------------
   2. HUD — rangée 1
   -------------------------------------------------------------------------- */
body.in-game #game-area.dice-stage > .dst-hud {
    grid-area: 1 / 1;
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 26px;
    padding: 2px 8px;
    background: var(--dst-panel);
    border: 1px solid var(--dst-line);
    border-radius: 10px;
    /* 13 px = plancher de lisibilité demandé (l'ancien 12 px était illisible). */
    font-size: 13px;
    overflow: hidden;
}

.dst-mode {
    flex: 0 0 auto;
    padding: 1px 8px;
    border-radius: 999px;
    background: rgba(0, 212, 170, .14);
    color: var(--dst-accent);
    font-size: 13px;
    font-weight: 800;
    line-height: 1.5;
    white-space: nowrap;
}

.dst-turn {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--dst-muted);
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dst-turn.is-mine { color: var(--dst-accent); }

.dst-turn b {
    color: var(--dst-ink);
    font-weight: 800;
}

.dst-turn.is-mine b { color: var(--dst-accent); }

.dst-progress {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 3px;
}

.dst-progress .seg {
    width: 14px;
    height: 6px;
    border-radius: 3px;
    background: rgba(255, 255, 255, .16);
}

.dst-progress .seg.on { background: var(--dst-accent); }

/* --------------------------------------------------------------------------
   3. Boîte de dés — rangée 2
   Redevient un élément de flux : les `position: fixed !important` de
   game.css ne peuvent pas être battus par une classe, d'où le sélecteur
   par identifiant (2 ids + 3 classes) qui gagne même à spécificité égale.
   -------------------------------------------------------------------------- */
body.in-game #game-area.dice-stage > #dice-container.dice-container {
    grid-area: 2 / 1;
    position: static !important;
    inset: auto !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    display: flex !important;
    flex-direction: column !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    height: 100%;
    min-height: 0;
    margin: 0 !important;
    padding: 3px 6px !important;
    background: var(--dst-panel) !important;
    border: 1px solid var(--dst-line) !important;
    border-radius: var(--dst-radius) !important;
    box-shadow: none !important;
    z-index: auto !important;
    overflow: hidden;
    transition: none !important;
    /* La taille de dé suit la hauteur d'écran autant que la largeur ; la
       rangée vaut ce dé + 12 px de padding + 2 px de bordure, jamais plus.
       Elle ne vole donc plus 4 px de hauteur à la feuille pour du vide. */
    --dice-size: clamp(30px, min(14.5vw, 9.5vh), 56px);
    height: auto;
}

/* Halo du tour actif : la boîte de dés, c'est MA main — comme le deck du
   Président, elle pulse quand c'est à moi. */
body.in-game #game-area.dice-stage > #dice-container.is-turn {
    border-color: rgba(0, 212, 170, .55) !important;
    animation: dst-halo 2.2s ease-in-out infinite;
}

/* `.disabled` (hors tour) vient de dice_3d.css : il ne doit pas éteindre la
   boîte entière, seulement les dés. */
body.in-game #game-area.dice-stage > #dice-container.disabled {
    opacity: 1 !important;
    pointer-events: auto !important;
}

body.in-game #game-area.dice-stage > #dice-container.disabled .dice-row {
    opacity: .5;
}

body.in-game #game-area.dice-stage > #dice-container .dice-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(4px, 2vw, 12px) !important;
    width: 100%;
    min-width: 0;
}

/* game.css impose 40 px !important sur le wrapper : on le reprend. */
body.in-game #game-area.dice-stage > #dice-container .dice-3d-wrapper {
    flex: 0 0 auto;
    width: var(--dice-size) !important;
    height: var(--dice-size) !important;
    min-width: 0 !important;
    max-width: none !important;
}

/* Dé TENU : la face indigo de dice_3d.css signale déjà l'état, mais à 52 px
   sur un téléphone en plein jour elle ne suffit pas. On ajoute un anneau teal
   qui reste lisible sur les cinq dés sans toucher au transform (dice_3d.css
   impose `transform: none !important` : un scale serait neutralisé). */
/* Le dé a un rayon de 3 px (dice_3d.css) : un anneau à 12 px laissait ses
   quatre coins sortir de la bordure. On tient UNE variable, utilisée à la fois
   par la face et par l'anneau, pour qu'ils ne puissent plus diverger. */
body.in-game #game-area.dice-stage > #dice-container .dice-3d-wrapper {
    --die-radius: 3px;
}

body.in-game #game-area.dice-stage > #dice-container .dice-3d-wrapper .dice-face {
    border-radius: var(--die-radius, 3px);
}

body.in-game #game-area.dice-stage > #dice-container .dice-3d-wrapper.selected {
    border-radius: var(--die-radius, 3px);
    box-shadow: 0 0 0 2px var(--dst-accent), 0 0 12px rgba(0, 212, 170, .28);
}

/* --------------------------------------------------------------------------
   3 bis. ANIMATION D'ARRIVÉE VERTICALE DES DÉS
   --------------------------------------------------------------------------
   Les dés « tombent » depuis le haut de la boîte et se posent avec un petit
   rebond (chute → contact → remontée → contact).

   Pourquoi la propriété `translate` et non `transform` : dice_3d.css impose
   `transform: none !important` sur .dice-3d-wrapper, et l'animation de
   rotation `diceRoll` travaille déjà sur `transform` de .dice-3d. `translate`
   est une propriété indépendante : elle ne rentre en conflit ni avec l'une
   ni avec l'autre, et aucune règle `!important` de transform ne la neutralise.
   Le décalage par enfant (nth-child) fait tomber les dés en cascade.
   -------------------------------------------------------------------------- */
@keyframes dst-dice-fall {
    0%   { translate: 0 -180%; opacity: 0; }
    48%  { translate: 0 0; opacity: 1; }
    64%  { translate: 0 -30%; }
    80%  { translate: 0 0; }
    90%  { translate: 0 -10%; }
    100% { translate: 0 0; opacity: 1; }
}

/* :not(.selected) — un dé GARDÉ ne bouge pas. Sans cette exclusion, toute la
   rangée tombait à chaque lancer : les dés tenus semblaient relancés alors que
   leur valeur ne changeait pas. */
body.in-game #game-area.dice-stage > #dice-container .dice-row.is-dropping .dice-3d-wrapper:not(.selected) {
    animation: dst-dice-fall .58s cubic-bezier(.33, 1.25, .6, 1) both;
}

body.in-game #game-area.dice-stage > #dice-container .dice-row.is-dropping .dice-3d-wrapper:nth-child(2) { animation-delay: .045s; }
body.in-game #game-area.dice-stage > #dice-container .dice-row.is-dropping .dice-3d-wrapper:nth-child(3) { animation-delay: .09s; }
body.in-game #game-area.dice-stage > #dice-container .dice-row.is-dropping .dice-3d-wrapper:nth-child(4) { animation-delay: .135s; }
body.in-game #game-area.dice-stage > #dice-container .dice-row.is-dropping .dice-3d-wrapper:nth-child(5) { animation-delay: .18s; }

/* --------------------------------------------------------------------------
   4. Tableau de score — rangée 3 (1fr), seule zone défilante
   --------------------------------------------------------------------------
   Boîte = [ en-tête fixe ] + [ corps défilant ].

   Pourquoi l'en-tête est HORS du conteneur défilant : un `position: sticky`
   posé sur une cellule de GRILLE est contraint par sa zone de grille (une
   seule rangée), donc il se décolle au bout de quelques dizaines de pixels
   de défilement — mesuré, pas supposé. Un en-tête frère du scroller ne peut
   pas bouger : il est épinglé par la structure, pas par le moteur.
   Les colonnes restent alignées par la même variable --ss-cols, et le
   défilement horizontal de l'en-tête est synchronisé sur celui du corps.
   -------------------------------------------------------------------------- */
body.in-game #game-area.dice-stage > #score-sheet-box.dst-sheet-box {
    grid-area: 3 / 1;
    /* 132 px : le plus long libellé (« Total supérieur », 117 px mesurés à
       16 px de police) + l'icône ℹ + le padding. 176 px de plafond : sur
       tablette, une colonne de 264 px de vide n'a aucun sens, l'espace va
       aux colonnes de score. */
    --ss-cat-w: clamp(132px, 22%, 176px);
    position: relative;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    height: 100%;
    min-height: 0;
    overflow: hidden;
    background: var(--dst-panel);
    border: 1px solid var(--dst-line);
    border-radius: var(--dst-radius);
}

/* Ombre portée à droite de la colonne des catégories : elle n'apparaît que
   quand on a réellement défilé horizontalement (classe posée par le JS), et
   elle est POSÉE SUR LA BOÎTE — donc elle ne défile pas et ne bloque aucun
   tap. Sans elle, à 6 joueurs, la colonne collante ressemble à une colonne
   ordinaire et le défilement horizontal n'est pas annoncé. */
body.in-game #game-area.dice-stage > #score-sheet-box.dst-sheet-box.is-scrolled-x::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--ss-cat-w);
    width: 14px;
    z-index: 6;
    pointer-events: none;
    background: linear-gradient(to right, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0));
}

/* --- En-tête : les pseudos ------------------------------------------------ */
body.in-game #game-area.dice-stage .dst-head {
    display: grid;
    box-sizing: border-box;
    grid-template-columns: var(--ss-cols, var(--ss-cat-w, 112px) repeat(2, minmax(56px, 1fr)));
    min-height: 0;
    overflow: hidden;
    background: var(--dst-table);
    border-radius: 11px 11px 0 0;
    box-shadow: inset 0 -1px 0 rgba(255, 255, 255, .14);
}

/* Le pseudo est une DONNÉE (le nom du joueur) : il doit être tronqué
   proprement. Sans `text-overflow: ellipsis`, un nom de 96 px dans une colonne
   de 56 px (mesuré à 6 joueurs) est coupé au milieu d'une lettre — « JoueurQ »
   — et le joueur ne peut pas savoir que le nom continue. Avec les points de
   suspension, la troncature devient une information ; le nom complet reste
   dans `title` et dans le tooltip au clic. */
body.in-game #game-area.dice-stage .dst-head > .ss-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    height: clamp(24px, 3.6vh, 30px);
    min-width: 0;
    padding: 0 4px;
    overflow: hidden;
    white-space: nowrap;
    background: var(--dst-table);
    color: var(--dst-ink);
    font-size: clamp(14px, 1.7vh, 16px);
    font-weight: 700;
    line-height: 1.1;
}

body.in-game #game-area.dice-stage .dst-head .ss-name {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.in-game #game-area.dice-stage .dst-head .ss-dot {
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
    margin-bottom: 1px;
    border-radius: 50%;
}

/* Le coin reste épinglé à gauche pendant que les colonnes joueurs défilent
   (miroir de la colonne des catégories, collante dans le corps). */
body.in-game #game-area.dice-stage .dst-head > .ss-corner {
    position: relative;
    z-index: 3;
    background: var(--dst-table);
}

/* --- Halo du tour actif ---------------------------------------------------
   La colonne du joueur qui doit jouer porte le halo. Pour ne pas animer
   seize cellules à la fois (coût de repeint sur un téléphone), l'animation
   pulsée vit sur l'EN-TÊTE de la colonne — un seul nœud, comme
   `.pstage-opp.is-turn` — et les cellules du corps portent une bande teal
   statique qui dessine la colonne entière. */
@keyframes dst-halo {
    0%, 100% {
        box-shadow: inset 0 0 0 1px rgba(0, 212, 170, .55),
                    inset 0 -1px 0 var(--dst-line),
                    0 0 0 0 rgba(0, 212, 170, 0);
    }
    50% {
        box-shadow: inset 0 0 0 2px var(--dst-accent),
                    inset 0 -1px 0 var(--dst-line),
                    0 0 14px 2px rgba(0, 212, 170, .34);
    }
}

body.in-game #game-area.dice-stage .dst-head > .ss-cell.ss-turn {
    background: rgba(0, 212, 170, .12);
    color: var(--dst-accent);
    animation: dst-halo 2.2s ease-in-out infinite;
}

/* --- Corps défilant ------------------------------------------------------- */
body.in-game #game-area.dice-stage > #score-sheet-box > #score-sheet-container {
    position: relative;
    height: 100%;
    min-height: 0;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    touch-action: auto;
    border: 0;
    border-radius: 0 0 11px 11px;
    background: var(--dst-panel);
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .22) transparent;
}

/* `touch-action` n'est restreint que sur l'axe réellement défilable : sinon
   on casserait le geste de l'autre axe sur un tableau à 6 joueurs. */
body.in-game #game-area.dice-stage > #score-sheet-box > #score-sheet-container.is-more-y {
    touch-action: pan-y;
}

body.in-game #game-area.dice-stage > #score-sheet-box > #score-sheet-container.is-more-x {
    touch-action: pan-x;
}

body.in-game #game-area.dice-stage > #score-sheet-box > #score-sheet-container.is-more-x.is-more-y {
    touch-action: pan-x pan-y;
}

/* --- Le corps : une grille, pas un tableau -------------------------------- */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet {
    display: grid;
    grid-template-columns: var(--ss-cols, var(--ss-cat-w, 112px) repeat(2, minmax(56px, 1fr)));
    /* LE cœur du contrat : les 16 lignes se partagent la hauteur, avec un
       plancher lisible de 19 px (18 px ne tenait pas le 13 px de texte).
       Sous le plancher, la grille déborde et c'est #score-sheet-container
       qui défile. */
    grid-auto-rows: minmax(19px, 1fr);
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0;
    border-collapse: unset;
    border-spacing: 0;
    background: var(--dst-panel);
    font-size: 14px;
    line-height: 1.12;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 0;
    padding: 0 6px;
    overflow: hidden;
    white-space: nowrap;
    background: var(--dst-cell);
    color: var(--dst-ink);
    /* 13 px minimum (demande produit), 15 px quand les rangées s'étirent. */
    font-size: clamp(13px, 1.75vh, 15px);
    font-variant-numeric: tabular-nums;
    /* Séparateur dessiné en inset : il ne consomme aucune hauteur, donc il
       ne fausse pas le calcul des 19 px par ligne. */
    box-shadow: inset 0 -1px 0 var(--dst-line);
}

/* --- Suivi de ligne -------------------------------------------------------
   À 6 joueurs les colonnes tombent à 56 px : suivre « Chance » d'un joueur à
   l'autre à travers six colonnes demande un repère qui court sur toute la
   largeur. Le zébrage est peint en background-IMAGE (3 % de blanc) et non en
   background-color : il se superpose donc à la couleur de la colonne « moi »
   et à la bande du tour sans jamais les écraser — aucune guerre de
   spécificité, et zéro pixel de hauteur consommé. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-alt {
    background-image: linear-gradient(rgba(255, 255, 255, .032), rgba(255, 255, 255, .032));
}

/* --- Ligne TOTAL : collante en bas ---------------------------------------
   C'est le deuxième repère fixe de la feuille, avec la colonne des
   catégories. Quand la zone est trop basse pour les 16 lignes (360 × 420),
   le corps défile mais le Total reste posé sur le bord bas du scroller :
   le score ne sort jamais de l'écran. Vérifié : `position: sticky` sur les
   cellules d'une grille plate suit bien le scrollport (mesuré : top constant
   à 347 px pendant que scrollTop parcourt 0 → 113).
   Elle est posée en `bottom: 0` sur chaque cellule (pas de wrapper de ligne)
   et passe AU-DESSUS des cellules qui défilent dessous (z-index 3), la
   colonne des catégories restant au-dessus d'elle (z-index 4). */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-total {
    position: sticky;
    bottom: 0;
    z-index: 3;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-total.ss-cat {
    z-index: 4;
}

/* Colonne des catégories : collante à gauche (utile quand 5-6 joueurs
   imposent un défilement horizontal). */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cat {
    position: sticky;
    left: 0;
    z-index: 2;
    justify-content: flex-start;
    text-align: left;
    background: var(--dst-cell);
    color: var(--dst-muted);
    /* Les libellés de catégorie sont l'information à lire : 14 px plancher. */
    font-size: clamp(14px, 1.95vh, 16px);
    font-weight: 600;
    gap: 3px;
}

.ss-cat .ss-label {
    overflow: hidden;
    text-overflow: ellipsis;
}

.ss-cat .help-icon {
    flex: 0 0 auto;
    font-size: 11px;
    opacity: .5;
}

/* --- 5-6 joueurs : la colonne des catégories est à son minimum ------------
   À 6 joueurs la colonne tombe à 112 px. Trois coupes, mesurées :
     · l'icône ℹ coûte 14 px et fait déborder « Total supérieur » ; le libellé
       entier passe avant l'indice, et toute la cellule ouvre déjà la règle ;
     · la police des libellés redescend à 14 px (à 16 px, « Total supérieur »
       demande 117 px pour 104 disponibles) ;
     · le padding tombe à 4 px de chaque côté.
   Résultat : 112 − 8 = 104 px utiles pour 102 px de libellé. */
body.in-game #game-area.dice-stage > #score-sheet-box.ss-many {
    --ss-cat-w: clamp(112px, 22%, 176px);
}

body.in-game #game-area.dice-stage > #score-sheet-box.ss-many .ss-cat .help-icon {
    display: none;
}

body.in-game #game-area.dice-stage > #score-sheet-box.ss-many .score-sheet.dst-sheet > .ss-cell.ss-cat {
    padding: 0 4px;
    font-size: 14px;
}

/* Sous 440 px de large, l'icône ℹ ne rentre plus à côté des libellés : on la
   retire au profit du mot entier (la cellule reste cliquable). Au-delà, elle
   revient — à 768 px la colonne fait 167 px, l'icône y tient sans coûter un
   caractère. */
@media (max-width: 440px) {
    body.in-game #game-area.dice-stage .ss-cat .help-icon {
        display: none;
    }
}

/* --- États de colonne ---------------------------------------------------- */
body.in-game #game-area.dice-stage .ss-mine { background: var(--dst-cell-mine); }

body.in-game #game-area.dice-stage .dst-head > .ss-head.ss-mine { color: var(--dst-accent); }

/* Colonne du joueur au tour : bande teal continue (bordures internes
   gauche/droite, pas de ring par cellule qui ferait des rayures). */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-turn {
    background: rgba(0, 212, 170, .075);
    box-shadow: inset 1px 0 0 rgba(0, 212, 170, .34),
                inset -1px 0 0 rgba(0, 212, 170, .34),
                inset 0 -1px 0 var(--dst-line);
}

/* --- États de valeur -----------------------------------------------------
   Les sélecteurs ci-dessous DOIVENT égaler la spécificité de la règle de
   cellule (`body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell`),
   sinon l'aperçu d'un score prenable prend la couleur et la graisse d'un score
   déjà acquis : les deux deviennent indiscernables. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-potential {
    color: var(--dst-muted);
    font-style: italic;
    font-weight: 400;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-filled {
    color: var(--dst-ink);
    font-weight: 700;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-zero {
    color: var(--dst-danger);
    font-weight: 700;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-editable {
    color: var(--dst-accent);
    font-weight: 700;
    box-shadow: inset 0 0 0 1px var(--dst-accent), inset 0 -1px 0 var(--dst-line);
}

/* Boni : la ligne ne répète plus « 0/63 » (la progression vers 63 est déjà
   portée par « Total supérieur »). Elle affiche l'ENJEU — +35 — tant qu'il
   n'est pas acquis, puis le boni réel, ou ✗ s'il est manqué : une information
   par ligne. Le sélecteur doit égaler celui de la cellule de base, sinon la
   règle `.ss-cell` (couleur d'encre) gagne et l'enjeu se lit comme un acquis. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-stake {
    color: var(--dst-muted);
    font-weight: 700;
    opacity: .8;
}

.ss-val.is-empty { color: var(--dst-muted); opacity: .55; }

.ss-val.is-potential {
    color: var(--dst-muted);
    font-style: italic;
}

.ss-val.is-filled { color: var(--dst-ink); font-weight: 700; }

.ss-val.is-zero { color: var(--dst-danger); font-weight: 700; }

.ss-val.is-editable {
    color: var(--dst-accent);
    font-weight: 700;
    cursor: pointer;
    background: rgba(0, 212, 170, .12);
    box-shadow: inset 0 0 0 1px rgba(0, 212, 170, .40), inset 0 -1px 0 var(--dst-line);
}

.ss-val.is-editable:active { background: rgba(0, 212, 170, .26); }

/* --- Score validé : la cellule se marque (flash + léger grossissement) ---- */
@keyframes dst-score-pop {
    0%   { background-color: rgba(0, 212, 170, .55); transform: scale(1); }
    32%  { background-color: rgba(0, 212, 170, .38); transform: scale(1.07); }
    100% { background-color: var(--dst-cell); transform: scale(1); }
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-just-scored {
    animation: dst-score-pop .62s ease-out both;
    color: var(--dst-ink);
    font-weight: 800;
}

/* --- Lignes de synthèse -------------------------------------------------- */
/* Les classes de rangée sont portées par CHAQUE cellule : la grille est plate
   (pas de wrapper de ligne), ce qui évite une rangée par <tr>. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-sub,
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-bonus {
    background: var(--dst-row-alt);
    font-weight: 700;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-sub.ss-cat,
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-bonus.ss-cat {
    color: var(--dst-muted);
    font-weight: 600;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-total {
    background: var(--dst-table);
    font-weight: 800;
    color: var(--dst-ink);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14);
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-total.ss-cat {
    color: var(--dst-ink);
}

/* Première ligne de la section basse : séparateur franc (remplace l'ancienne
   ligne vide « section-separator » qui coûtait une rangée entière). */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-first-lower {
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, .16), inset 0 -1px 0 var(--dst-line);
}

/* --- Indice de défilement ------------------------------------------------ */
/* Dégradé en bas de la BOÎTE (pas dans le scroller) : il est donc toujours
   au bord visible, ne défile pas, et ne bloque aucun tap (pointer-events).
   Il n'apparaît que lorsque le plancher de 19 px par ligne est atteint et
   qu'il reste du contenu sous la dernière ligne visible.
   Il est remonté de la hauteur de la ligne Total (`--ss-total-h`, mesurée par
   le JS) : cette ligne étant collante en bas, un dégradé posé sur le bord de
   la boîte passerait SOUS elle et ne signalerait plus rien. */
body.in-game #game-area.dice-stage > #score-sheet-box.dst-sheet-box::after {
    content: "";
    position: absolute;
    left: 1px;
    right: 1px;
    bottom: calc(1px + var(--ss-total-h, 20px));
    height: 20px;
    pointer-events: none;
    opacity: 0;
    transition: opacity .15s ease;
    background: linear-gradient(to top, rgba(18, 19, 31, .96), rgba(18, 19, 31, 0));
    border-radius: 0 0 11px 11px;
}

body.in-game #game-area.dice-stage > #score-sheet-box.dst-sheet-box.is-more-y::after {
    opacity: 1;
}

/* --------------------------------------------------------------------------
   5. Actions — rangée 4 (jamais fixed : une rangée est structurellement
   visible, même sous la barre d'URL).
   -------------------------------------------------------------------------- */
body.in-game #game-area.dice-stage > #game-controls.dst-actions {
    grid-area: 4 / 1;
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 8px;
    width: 100%;
    margin: 0;
    padding: 0;
    order: 0;
}

body.in-game #game-area.dice-stage > #game-controls .btn-roll {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    width: auto !important;
    max-width: none !important;
    height: 46px;
    min-height: 46px;
    margin: 0 !important;
    padding: 0 12px !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    border: 0 !important;
    border-radius: 12px !important;
    background: var(--dst-accent) !important;
    background-image: none !important;
    color: #08211c !important;
    box-shadow: none !important;
    font-size: 16px !important;
    font-weight: 800;
    text-shadow: none;
    cursor: pointer;
    /* Retour au toucher : la seule animation de cette rangée. 120 ms, ease-out
       fort, transform seul — le bouton répond au doigt, pas au clic. */
    transition: transform 120ms cubic-bezier(.23, 1, .32, 1), background 120ms linear;
}

body.in-game #game-area.dice-stage > #game-controls .btn-roll:not(:disabled):active {
    transform: scale(.98);
}

body.in-game #game-area.dice-stage > #game-controls .btn-roll:disabled {
    background: #2a2d3f !important;
    color: var(--dst-muted) !important;
    cursor: not-allowed;
}

body.in-game #game-area.dice-stage > #game-controls .btn-roll .btn-icon-left {
    font-size: 17px;
    line-height: 1;
}

/* --------------------------------------------------------------------------
   6. Adaptations
   -------------------------------------------------------------------------- */
/* Écran bas : on rogne d'abord la rangée des dés et le HUD, jamais le tableau. */
@media (max-height: 620px) {
    body.in-game #game-area.dice-stage { gap: 3px; padding-top: 3px !important; }
    body.in-game #game-area.dice-stage > .dst-hud { min-height: 24px; font-size: 13px; }
    body.in-game #game-area.dice-stage > #dice-container.dice-container {
        padding: 2px 5px !important;
        /* Le dé garde sa taille de largeur (14.5vw) mais son plafond baisse :
           à 360 × 560 il vaut 50 px au lieu de 56, et la rangée 60 px — la
           feuille garde de quoi loger ses 16 lignes (mesuré : 19,6 px). */
        --dice-size: clamp(28px, min(14.5vw, 9.5vh), 50px);
    }
    body.in-game #game-area.dice-stage > #game-controls .btn-roll {
        height: 46px;
        min-height: 46px;
        font-size: 15px !important;
    }
    body.in-game #game-area.dice-stage .dst-head > .ss-cell { height: 22px; }
    body.in-game #game-area.dice-stage .score-sheet.dst-sheet { grid-auto-rows: minmax(19px, 1fr); }
}

@media (max-width: 360px) {
    body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell { padding: 0 4px; }
}

/* Écrans hauts : les lignes s'étirent (16 lignes dans 80 % de la hauteur),
   donc le texte grandit avec elles — sinon une rangée de 36 px porterait
   toujours 13 px de texte et paraîtrait vide. */
@media (min-height: 760px) {
    body.in-game #game-area.dice-stage { font-size: 15px; }
    body.in-game #game-area.dice-stage > .dst-hud { min-height: 30px; }
    body.in-game #game-area.dice-stage .dst-turn,
    body.in-game #game-area.dice-stage .dst-mode { font-size: 14px; }
    body.in-game #game-area.dice-stage .dst-head > .ss-cell {
        height: clamp(26px, 3.6vh, 32px);
        font-size: clamp(14px, 1.9vh, 16px);
    }
    body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell { font-size: clamp(14px, 1.9vh, 16px); }
    body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cat { font-size: clamp(14px, 1.9vh, 16px); }
    body.in-game #game-area.dice-stage > #game-controls .btn-roll { height: 52px; min-height: 52px; }
}

/* Accessibilité : aucune animation continue ni d'arrivée. */
@media (prefers-reduced-motion: reduce) {
    /* Le seul mouvement restant (l'enfoncement du bouton) disparaît aussi :
       on garde le changement de couleur, qui suffit à confirmer le toucher. */
    body.in-game #game-area.dice-stage > #game-controls .btn-roll {
        transition: background 120ms linear;
    }
    body.in-game #game-area.dice-stage > #game-controls .btn-roll:active {
        transform: none;
    }
    body.in-game #game-area.dice-stage > #dice-container.is-turn,
    body.in-game #game-area.dice-stage .dst-head > .ss-cell.ss-turn,
    body.in-game #game-area.dice-stage > #dice-container .dice-row.is-dropping .dice-3d-wrapper,
    body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-just-scored {
        animation: none !important;
    }
    body.in-game #game-area.dice-stage > #dice-container.is-turn {
        box-shadow: inset 0 0 0 2px var(--dst-accent) !important;
    }
    body.in-game #game-area.dice-stage > #score-sheet-box.dst-sheet-box::after { transition: none; }
}

/* --------------------------------------------------------------------------
   7. TENIR UN DÉ : retour immédiat au pointer-down
   --------------------------------------------------------------------------
   Le dé se soulève de 3 px dès que le doigt appuie (avant le round-trip du
   serveur). On anime `translate` — la propriété INDÉPENDANTE — parce que
   dice_3d.css verrouille `transform: none !important` sur .dice-3d-wrapper :
   un scale y serait neutralisé, `translate` ne l'est pas. Réservé aux dés
   réellement interactifs (`:not(.disabled)`) : un dé hors tour ne donne pas
   de fausse affordance.
   -------------------------------------------------------------------------- */
body.in-game #game-area.dice-stage > #dice-container .dice-3d-wrapper {
    /* Base translate EXPLICITE (identité) : `none` → `0 -3px` n'est pas
       interpolable, la transition de l'appui sauterait. `0 0` → `0 -3px`
       s'interpole proprement (le dé « se soulève » de 3 px, puis redescend). */
    translate: 0 0;
    transition: translate 110ms cubic-bezier(.23, 1, .32, 1);
}

body.in-game #game-area.dice-stage > #dice-container:not(.disabled) .dice-3d-wrapper:active {
    translate: 0 -3px;
}

@media (prefers-reduced-motion: reduce) {
    body.in-game #game-area.dice-stage > #dice-container .dice-3d-wrapper {
        transition: none;
    }
    body.in-game #game-area.dice-stage > #dice-container:not(.disabled) .dice-3d-wrapper:active {
        translate: none;
    }
}

/* --------------------------------------------------------------------------
   8. BANDEAU + JOURNAL (socle StageFeed) SUR LE TAPIS DE DÉS
   --------------------------------------------------------------------------
   Le socle (stage_feed.css) pose une couche absolue sur #game-area et un
   bandeau à `top: 6px`. Sur un tapis de dés, cette bande est occupée par le
   HUD (mode · tour · lancers) : sans réglage, le bandeau recouvrirait les dés
   ou la première ligne de la feuille, c'est-à-dire l'objet même du jeu.

   Décision : le bandeau vit EXACTEMENT dans la bande du HUD (`--sf-band`) et
   prend sa place le temps d'un message. Il ne couvre donc jamais les dés, ni
   la feuille, ni le bouton LANCER. Le HUD réserve la place du bouton 📜
   (30 px + air) qui occupe son extrémité droite ; ses segments de lancers
   restent visibles à gauche du bouton.
   -------------------------------------------------------------------------- */
body.in-game #game-area.dice-stage {
    --sf-band: 26px;
}

/* Le bouton 📜 se pose sur l'extrémité droite du HUD : on lui réserve la place. */
body.in-game #game-area.dice-stage > .dst-hud {
    padding-right: 38px;
}

body.in-game #game-area.dice-stage .sf-layer .sf-banner {
    top: 4px;
    left: 4px;
    right: 40px;
    height: var(--sf-band);
    min-height: var(--sf-band);
    max-height: var(--sf-band);
    padding: 0 10px;
    border-radius: 9px;
    font-size: 12.5px;
}

body.in-game #game-area.dice-stage .sf-layer .sf-toggle {
    top: 5px;
    right: 5px;
    width: 26px;
    height: 26px;
    font-size: 13px;
    border-radius: 8px;
}

/* Journal ouvert : il prend la place de la feuille (jamais celle des dés). */
body.in-game #game-area.dice-stage .sf-layer .sf-panel {
    top: calc(var(--sf-band) + 8px);
    left: 4px;
    right: 4px;
    bottom: 4px;
}

/* Écrans bas : le HUD descend à 24 px (voir §6), la bande suit. */
@media (max-height: 620px) {
    body.in-game #game-area.dice-stage { --sf-band: 24px; }
    body.in-game #game-area.dice-stage .sf-layer .sf-toggle { top: 3px; }
}

/* Écrans hauts : le HUD monte à 30 px. */
@media (min-height: 760px) {
    body.in-game #game-area.dice-stage { --sf-band: 30px; }
    body.in-game #game-area.dice-stage .sf-layer .sf-banner { font-size: 13.5px; }
    body.in-game #game-area.dice-stage .sf-layer .sf-toggle { top: 6px; }
}

/* --- Puce de dé (bandeau + journal) -------------------------------------- */
body.in-game #game-area.dice-stage .sf-die {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    height: 17px;
    margin: 0 1px;
    padding: 0 3px;
    vertical-align: middle;
    border-radius: 4px;
    border: 1px solid rgba(255, 255, 255, .22);
    background: rgba(255, 255, 255, .10);
    color: #e8ebf2;
    font-size: 11.5px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* Dé TENU : même code couleur que l'anneau teal de la boîte de dés. */
body.in-game #game-area.dice-stage .sf-die.is-kept {
    border-color: rgba(0, 212, 170, .65);
    background: rgba(0, 212, 170, .20);
    color: #7ef3dc;
}

body.in-game #game-area.dice-stage .sf-roll-no,
body.in-game #game-area.dice-stage .sf-kept {
    color: var(--dst-muted);
    font-size: 11.5px;
    font-weight: 700;
}

/* --- Journal : repères de lecture par type d'entrée ---------------------- */
body.in-game #game-area.dice-stage .sf-item.is-dice_score,
body.in-game #game-area.dice-stage .sf-item.is-dice_bonus {
    background: rgba(0, 212, 170, .12);
}

body.in-game #game-area.dice-stage .sf-item.is-dice_game_end {
    background: rgba(255, 209, 102, .14);
}

body.in-game #game-area.dice-stage .sf-item.is-dice_hold {
    background: rgba(255, 255, 255, .03);
}

/* Accessibilité : le bandeau ne glisse plus, il apparaît. (Le socle le fait
   déjà ; on le répète ici parce que la bande du HUD est un réglage local.) */
@media (prefers-reduced-motion: reduce) {
    body.in-game #game-area.dice-stage .sf-layer .sf-banner {
        transform: none;
        transition: none;
    }
}

/* ==========================================================================
   REFONTE DU TABLEAU DE SCORE — 26/10/2026
   --------------------------------------------------------------------------
   Constat : chaque cellule portait un fond propre + un liseré, et les trois
   feuilles (dice_board, boards_mobile, boards_clean) empilaient leurs règles.
   Résultat : une grille de cases toutes identiques où l'on ne distinguait
   plus une catégorie déjà jouée d'une catégorie encore disponible.

   Principe retenu : UNE ligne = UNE information, UN état = UNE apparence.
     · déjà joué      -> valeur pleine, encre normale ;
     · zéro assumé    -> valeur barrée, très atténuée ;
     · jouable (moi)  -> fond doré très léger + liseré pointillé doré ;
     · aperçu du coup -> valeur dorée en gras (le score que ça rapporterait) ;
     · ligne de total -> bande pleine, valeur dorée.
   Aucune bordure verticale : seules des séparations horizontales de 1 px.
   ========================================================================== */

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell {
    background: transparent;
    box-shadow: inset 0 -1px 0 rgba(255, 255, 255, .045);
}

/* Zébrage supprimé : il concurrençait les états. La lecture se fait par bandes
   de section, pas par rayures. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-alt {
    background: transparent;
    background-image: none;
}

/* --- Colonne des catégories ---------------------------------------------- */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-cat {
    background: rgba(255, 255, 255, .022);
    color: var(--dst-muted);
    font-size: clamp(12.5px, 1.7vh, 15px);
    font-weight: 550;
    letter-spacing: .1px;
    padding-left: 9px;
}

/* --- Mes valeurs --------------------------------------------------------- */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-empty {
    color: rgba(255, 255, 255, .22);
    opacity: 1;
}

/* Catégorie encore ouverte ET c'est mon tour : c'est ICI qu'on peut cliquer.
   Le contraste est volontairement franc — c'est la seule information qui
   compte au moment de choisir. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-empty.ss-mine.ss-turn,
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-editable {
    color: #ffd772;
    background: rgba(240, 180, 41, .16);
    box-shadow: inset 0 0 0 1.5px rgba(255, 215, 114, .8), inset 0 -1px 0 rgba(255, 255, 255, .045);
    font-weight: 700;
    cursor: pointer;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-editable:active {
    background: rgba(240, 180, 41, .3);
}

/* Aperçu : le score que rapporterait le lancer en cours. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-potential {
    color: #ffd772;
    font-weight: 800;
    font-style: normal;
    background: rgba(240, 180, 41, .14);
    box-shadow: inset 0 0 0 1.5px rgba(255, 215, 114, .7), inset 0 -1px 0 rgba(255, 255, 255, .045);
}

/* Colonnes des autres joueurs : en retrait, pour que MA colonne ressorte. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-val:not(.ss-mine) {
    color: rgba(255, 255, 255, .5);
    font-weight: 600;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-val:not(.ss-mine).is-empty {
    color: rgba(255, 255, 255, .12);
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-filled {
    color: var(--dst-ink);
    font-weight: 700;
}

/* Zéro assumé : lisible si on le cherche, invisible au premier regard. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-zero {
    color: rgba(255, 255, 255, .26);
    font-weight: 600;
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.is-stake {
    color: rgba(255, 255, 255, .34);
    font-weight: 600;
}

/* --- Ma colonne : deux filets dorés, pas un cadre ------------------------ */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-mine {
    background-image: linear-gradient(180deg, rgba(255, 215, 114, .05), rgba(255, 215, 114, .02));
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-mine.ss-val {
    box-shadow: inset 2px 0 0 rgba(255, 215, 114, .28), inset -2px 0 0 rgba(255, 215, 114, .28), inset 0 -1px 0 rgba(255, 255, 255, .045);
}

/* --- Séparations de section --------------------------------------------- */
/* Avant « Total supérieur » : la section haute est bouclée. */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-first-lower {
    box-shadow: inset 0 3px 0 -1px rgba(255, 255, 255, .16), inset 0 -1px 0 rgba(255, 255, 255, .045);
}

/* --- Lignes de synthèse -------------------------------------------------- */
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-sub,
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-bonus {
    background: rgba(255, 255, 255, .035);
    font-weight: 700;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-sub.ss-cat,
body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-bonus.ss-cat {
    color: rgba(255, 255, 255, .55);
    font-weight: 600;
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-total {
    background: #232636;
    color: #ffd772;
    font-size: clamp(14px, 1.9vh, 16px);
    font-weight: 800;
    box-shadow: inset 0 1px 0 rgba(255, 215, 114, .28);
}

body.in-game #game-area.dice-stage .score-sheet.dst-sheet > .ss-cell.ss-row-total.ss-cat {
    color: rgba(255, 215, 114, .9);
}

/* --- En-tête des joueurs ------------------------------------------------- */
body.in-game .dst-head > .ss-cell.ss-head {
    position: relative;
}

body.in-game .dst-head > .ss-cell.ss-head.ss-turn {
    color: #ffd772;
}

body.in-game .dst-head > .ss-cell.ss-head.ss-turn::after {
    content: '';
    position: absolute;
    left: 6px;
    right: 6px;
    bottom: 0;
    height: 2px;
    border-radius: 2px;
    background: #ffd772;
}

/* Sur ordinateur, deux colonnes de joueurs n'ont pas besoin de 1 400 px :
   les valeurs flottaient au milieu de cellules vides. La feuille est bornée
   et centrée ; au-delà de quatre joueurs elle reprend toute la largeur. */
@media (min-width: 900px) {
    /* `max-width` seul effondrait la boîte à sa largeur minimale (mesuré :
       238 px), car elle est enfant d'un conteneur flex : il faut une largeur
       explicite, pas un plafond. */
    body.in-game #game-area.dice-stage #score-sheet-box:not(.ss-many) {
        width: min(100%, 940px);
        margin-inline: auto;
    }
}
