/* =====================================================================
   President — scène compacte (refonte 25/10/2026, v2)
   ---------------------------------------------------------------------
   Budget de hauteur (le DECK passe avant la table) :

       [ HUD         ] auto    manche · tour · dernier coup
       [ ADVERSARIES ] auto    boîtes horizontales, 100 % de la largeur
       [ TABLE       ] 32 %    les 2 derniers coups, l'ancien recule
       [ MA MAIN     ] 1fr     cartes sur PLUSIEURS lignes, défile au besoin
       [ ACTIONS     ] auto    toujours visible

   La table est plafonnée : c'est le deck qui porte l'information (15 à 18
   cartes), donc c'est lui qui reçoit la place.

   Aucune règle de president.css n'est modifiée : ce fichier charge après
   boards_clean.css et ne cible que les classes `pstage-*`.
   ===================================================================== */

/* La scène occupe la vue de jeu : chaîne flex pour que la rangée « main »
   (1fr) reçoive tout l'espace restant, quel que soit le chemin de rendu. */
body.in-game #view-game {
    display: flex;
    flex-direction: column;
}

.pstage {
    --ps-bg: #12131f;
    --ps-panel: #1b1d2b;
    --ps-table: #232636;
    --ps-line: rgba(255, 255, 255, .08);
    --ps-text: #e8ebf2;
    --ps-muted: #a3abbb;
    --ps-accent: #00d4aa;
    --ps-warn: #ffd700;
    --ps-danger: #e94560;
    --ps-radius: 12px;

    position: relative;
    display: grid;
    grid-template-rows: auto auto minmax(152px, 33%) minmax(0, 1fr) auto;
    gap: 6px;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    flex: 1 1 auto;
    min-height: 0;
    padding: 6px 6px calc(6px + env(safe-area-inset-bottom, 0px));
    overflow: hidden;
    color: var(--ps-text);
    font-size: 14px;
    line-height: 1.3;
}

/* ------------------------------------------------------------------ HUD */
.pstage-hud {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 30px;
    padding: 4px 9px;
    background: var(--ps-panel);
    border: 1px solid var(--ps-line);
    border-radius: 10px;
    font-size: 13px;
    overflow: hidden;
}

.pstage-round {
    flex: 0 0 auto;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(0, 212, 170, .14);
    color: var(--ps-accent);
    font-weight: 800;
    white-space: nowrap;
}

.pstage-turn {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

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

.pstage-last {
    flex: 0 1 auto;
    min-width: 0;
    color: var(--ps-muted);
    font-size: 12px;
    font-weight: 600;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pstage-badge {
    flex: 0 0 auto;
    padding: 2px 7px;
    border-radius: 999px;
    background: rgba(255, 215, 0, .16);
    color: var(--ps-warn);
    font-size: 12px;
    font-weight: 800;
    white-space: nowrap;
}

/* ----------------------------------------------------------- ADVERSARIES
   Boîte HORIZONTALE : avatar à gauche, prénom + compteur à droite. On ne
   gaspille plus la hauteur (l'écran en manque) et le texte grossit. Les
   boîtes se partagent TOUTE la largeur : à 2 joueurs, 50 % / 50 %. */
.pstage-opponents {
    display: flex;
    gap: 6px;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    touch-action: pan-x;
    scrollbar-width: none;
}

.pstage-opponents::-webkit-scrollbar { height: 0; }

.pstage-opp {
    flex: 1 1 0;
    min-width: 104px;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 10px;
    background: var(--ps-panel);
    border: 1px solid var(--ps-line);
    border-radius: var(--ps-radius);
    scroll-snap-align: start;
}

.pstage-opp.is-turn { border-color: var(--ps-accent); }
.pstage-opp.is-out { opacity: .55; }

.pstage-opp-avatar {
    position: relative;
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 2px solid var(--ps-line);
    background: rgba(0, 0, 0, .3);
    display: grid;
    place-items: center;
    font-size: 19px;
    overflow: hidden;
}

.pstage-opp-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.pstage-opp.is-turn .pstage-opp-avatar { border-color: var(--ps-accent); }

/* Sablier : boîte CARRÉE, centrée sur elle-même (16 × 16). L'ancien élément
   mesurait 15 × 66 px : en tournant, le glyphe décrivait un arc. */
.pstage-hourglass {
    position: absolute;
    right: -5px;
    bottom: -3px;
    width: 18px;
    height: 18px;
    display: grid;
    place-items: center;
    font-size: 12px;
    line-height: 1;
    border-radius: 50%;
    background: var(--ps-panel);
    border: 1px solid var(--ps-warn);
    transform-origin: center center;
    transform-box: border-box;
    animation: pstage-hourglass-spin 2s ease-in-out infinite;
}

@keyframes pstage-hourglass-spin {
    0%, 100% { transform: rotate(0deg); }
    50%      { transform: rotate(180deg); }
}

.pstage-opp-info {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.pstage-opp-name {
    font-size: 15px;
    font-weight: 700;
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pstage-opp-meta {
    display: flex;
    align-items: baseline;
    gap: 4px;
    font-size: 14px;
    font-weight: 600;
    color: var(--ps-muted);
    white-space: nowrap;
}

.pstage-opp-meta b {
    font-size: 16px;
    color: var(--ps-text);
    font-weight: 800;
}

.pstage-opp.is-turn .pstage-opp-meta b { color: var(--ps-accent); }

.pstage-opp-role { font-size: 13px; }

/* Halo animé : signale le tour actif sur une BOÎTE (adversaire) comme sur le
   DECK (moi). Il double le sablier, il ne le remplace pas. */
@keyframes pstage-halo {
    0%, 100% {
        box-shadow: inset 0 0 0 1px rgba(0, 212, 170, .75),
                    0 0 0 0 rgba(0, 212, 170, 0);
    }
    50% {
        box-shadow: inset 0 0 0 2px var(--ps-accent),
                    0 0 16px 3px rgba(0, 212, 170, .38);
    }
}

.pstage-opp.is-turn {
    animation: pstage-halo 2.2s ease-in-out infinite;
}

/* --------------------------------------------------------------- TABLE */
.pstage-table {
    position: relative;
    display: grid;
    place-items: center;
    min-height: 0;
    padding: 2px;
    background: var(--ps-table);
    border: 1px solid var(--ps-line);
    border-radius: var(--ps-radius);
    overflow: hidden;
}

.pstage-pile {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.pstage-play {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    max-width: 100%;
}

.pstage-play.is-last {
    position: relative;
    z-index: 2;
}

/* Le coup précédent RECULE : plus petit, remonté, transparent. Il vit en
   absolu dans la table pour ne pas pousser la carte courante. */
.pstage-play.is-prev {
    position: absolute;
    z-index: 1;
    top: 50%;
    left: 4px;
    /* Le coup précédent occupe la place libre à GAUCHE de la table : empilé
       exactement derrière la carte courante, il serait invisible. Il recule
       en glissant vers la gauche et en rétrécissant. */
    transform: translate(0, -50%) scale(.66);
    transform-origin: left center;
    opacity: .45;
    filter: saturate(.6);
    pointer-events: none;
}

.pstage-play.is-prev.is-receding {
    animation: pstage-recede .4s ease-out both;
}

@keyframes pstage-recede {
    from { opacity: 1; transform: translate(46%, -50%) scale(1); }
    to   { opacity: .45; transform: translate(0, -50%) scale(.66); }
}

/* La carte jouée ARRIVE depuis la boîte du joueur et se pose sur la pile. */
.pstage-play.is-last.is-entering {
    animation: pstage-drop .4s cubic-bezier(.23, 1, .32, 1) both;
}

@keyframes pstage-drop {
    0% {
        opacity: 0;
        transform: translate(var(--from-x, 0px), var(--from-y, -140px)) scale(.5) rotate(-6deg);
    }
    55% { opacity: 1; }
    100% { opacity: 1; transform: translate(0, 0) scale(1) rotate(0deg); }
}

/* Bulle : qui vient de jouer — plus grosse que l'ancien libellé nu. */
.pstage-bubble {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    padding: 3px 12px;
    border-radius: 999px;
    background: var(--ps-panel);
    border: 1px solid var(--ps-line);
    font-size: 13px;
    font-weight: 800;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .35);
}

.pstage-play.is-last .pstage-bubble {
    border-color: var(--ps-accent);
    color: var(--ps-accent);
}

.pstage-bubble img {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    object-fit: cover;
}

.pstage-bubble em {
    font-style: normal;
    font-weight: 600;
    font-size: 12px;
    color: var(--ps-muted);
}

.pstage-cards {
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: 100%;
    --card-w: clamp(48px, min(22vw, 16vh), 96px);
}

.pstage-cards .pile-card {
    position: relative;
    /* Chevauchement proportionnel : une suite de 5 cartes reste dans la table. */
    margin-left: calc(var(--card-w) * -0.28);
    filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .45));
}

.pstage-cards .pile-card:first-child { margin-left: 0; }

.pstage-status {
    font-size: 13px;
    font-weight: 600;
    color: var(--ps-muted);
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.pstage-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    color: var(--ps-muted);
    font-size: 13px;
    font-weight: 600;
    text-align: center;
}

.pstage-empty .cardv { opacity: .3; }

/* ---------------------------------------------------------------- MAIN
   Le deck prend tout l'espace restant. Les cartes se placent sur plusieurs
   lignes selon la hauteur réelle du téléphone ; ce qui ne tient pas fait
   défiler la BOÎTE DU DECK, jamais la page. */
.pstage-hand {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    background: var(--ps-panel);
    border: 1px solid var(--ps-line);
    border-radius: var(--ps-radius);
    overflow: hidden;
}

.pstage-hand.is-mine {
    border-color: var(--ps-accent);
    animation: pstage-halo 2.2s ease-in-out infinite;
}

.pstage-hand-label {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 9px 3px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ps-muted);
    white-space: nowrap;
    overflow: hidden;
}

.pstage-hand-label b {
    font-size: 14px;
    color: var(--ps-text);
    font-weight: 800;
}

.pstage-hand.is-mine .pstage-hand-label b { color: var(--ps-accent); }

.pstage-role {
    margin-left: auto;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .07);
    color: var(--ps-text);
    font-size: 13px;
    font-weight: 700;
}

body.in-game .pstage .cards-hand {
    flex: 1 1 auto;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: 6px;
    min-height: 0;
    width: 100%;
    padding: 10px 6px 6px;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    touch-action: pan-y;
    scrollbar-width: thin;
}

body.in-game .pstage .hand-card {
    flex: 0 0 auto;
    border-radius: 10px;
    transition: transform .12s ease;
    cursor: pointer;
    --card-w: clamp(40px, 11.5vw, 56px);
}

body.in-game .pstage .hand-card.selected {
    transform: translateY(-6px);
    outline: 2px solid var(--ps-accent);
    outline-offset: 1px;
}

body.in-game .pstage .hand-card.disabled {
    opacity: .6;
    cursor: default;
}

/* --------------------------------------------------------- BARRE D'ACTION
   Rangée de la grille (jamais masquable), boutons centrés sur la hauteur.
   Le sélecteur par identifiant est indispensable : boards_mobile.css impose
   `position: fixed !important` via `html body.in-game .action-buttons.fixed-footer`. */
.pstage-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

html body.in-game #pstage-actions .fixed-footer,
html body.in-game #pstage-actions .fixed-footer.action-buttons,
html body.in-game #pstage-actions .action-buttons {
    position: static !important;
    display: flex !important;
    align-items: center !important;
    gap: 8px;
    width: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    padding: 0 !important;
    background: none !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    transform: none !important;
    z-index: auto !important;
}

html body.in-game #pstage-actions .btn {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    width: auto !important;
    max-width: none !important;
    height: 52px;
    min-height: 52px;
    margin: 0 !important;
    padding: 0 12px !important;
    border-radius: 14px !important;
    font-size: 16px !important;
    font-weight: 800 !important;
    letter-spacing: .2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

html body.in-game #pstage-actions .btn-secondary {
    background: #2a2e44 !important;
    color: var(--ps-text) !important;
    border: 1px solid rgba(255, 255, 255, .18) !important;
}

html body.in-game #pstage-actions .waiting-turn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    height: 52px;
    width: 100%;
    font-size: 14px;
    font-weight: 600;
    color: var(--ps-muted);
}

html body.in-game #pstage-actions .waiting-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    overflow: hidden;
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, .06);
}

html body.in-game #pstage-actions .waiting-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ------------------------------------------------------------ ADAPTATIONS
   Écran court : on rogne d'abord la table, jamais le deck. */
@media (max-height: 640px) {
    .pstage {
        grid-template-rows: auto auto minmax(132px, 30%) minmax(0, 1fr) auto;
        gap: 5px;
        padding-top: 4px;
    }
    .pstage-hud { min-height: 28px; font-size: 12px; }
    .pstage-opp { padding: 5px 8px; gap: 8px; }
    .pstage-opp-avatar { flex-basis: 36px; width: 36px; height: 36px; }
    .pstage-opp-name { font-size: 14px; }
    .pstage-opp-meta { font-size: 13px; }
    .pstage-opp-meta b { font-size: 15px; }
    html body.in-game #pstage-actions .btn { height: 48px; min-height: 48px; font-size: 15px !important; }
    html body.in-game #pstage-actions .btn-secondary {
    background: #2a2e44 !important;
    color: var(--ps-text) !important;
    border: 1px solid rgba(255, 255, 255, .18) !important;
}

html body.in-game #pstage-actions .waiting-turn { height: 48px; }
}

/* Écran très bas (paysage téléphone). */
@media (max-height: 460px) {
    .pstage { grid-template-rows: auto auto minmax(110px, 26%) minmax(0, 1fr) auto; }
    .pstage-opp-avatar { flex-basis: 30px; width: 30px; height: 30px; }
    .pstage-opp-name { font-size: 12px; }
    .pstage-cards { --card-w: clamp(40px, 14vh, 64px); }
    body.in-game .pstage .hand-card { --card-w: clamp(32px, 9vh, 44px); }
}

/* Écrans hauts : la main gagne encore, avec des cartes plus lisibles. */
@media (min-height: 700px) {
    body.in-game .pstage .hand-card { --card-w: clamp(44px, 11vw, 60px); }
    .pstage-opp { padding: 9px 12px; }
    .pstage-opp-avatar { flex-basis: 44px; width: 44px; height: 44px; }
    .pstage-opp-name { font-size: 16px; }
}

/* ------------------------------------------------- PHASES ÉCHANGE / VOTE
   Elles ne sont pas des grilles : un flux défilant, borné à la vue, pour que
   la page ne défile jamais et que les boutons restent atteignables. */
body.in-game .pstage-flow {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px;
    overflow-y: auto;
    overscroll-behavior: contain;
    color: var(--ps-text, #e8ebf2);
    font-size: 13px;
}

body.in-game .pstage-flow > * { flex: 0 0 auto; }

@media (prefers-reduced-motion: reduce) {
    .pstage-hourglass,
    .pstage-opp.is-turn,
    .pstage-hand.is-mine,
    .pstage-play.is-last.is-entering,
    .pstage-play.is-prev.is-receding { animation: none; }
    body.in-game .pstage .hand-card { transition: none; }
}

/* ------------------------------------------- PHASES ÉCHANGE / VOTE (v2)
   Même contrat que le plateau : le contenu défile au-dessus, la barre
   d'action est une RANGÉE en bas. Avant, les boutons vivaient à la fin d'un
   flux de 789 px : sur un téléphone de 560 px ils étaient sous l'écran, et
   la partie qui dépassait n'était pas cliquable. */
.pstage-phase {
    grid-template-rows: minmax(0, 1fr) auto;
    gap: 6px;
}

.pstage-phase-body {
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 2px;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
}

.pstage-phase-body > * { flex: 0 0 auto; }

.pstage-phase-body .glass-panel,
.pstage-phase-body .round-results,
.pstage-phase-body .vote-status {
    background: var(--ps-panel);
    border: 1px solid var(--ps-line);
    border-radius: var(--ps-radius);
    padding: 10px 12px;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

.pstage-phase-body h2 {
    margin: 0 0 4px;
    font-size: 17px;
    font-weight: 800;
    color: var(--ps-text);
}

.pstage-phase-body h3,
.pstage-phase-body h4 {
    margin: 0 0 6px;
    font-size: 14px;
    font-weight: 800;
    color: var(--ps-text);
}

.pstage-phase-body p {
    margin: 0;
    font-size: 13px;
    color: var(--ps-muted);
}

.pstage-phase-body .result-row,
.pstage-phase-body .vote-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 0;
    font-size: 14px;
    border-bottom: 1px solid var(--ps-line);
}

.pstage-phase-body .result-row:last-child,
.pstage-phase-body .vote-row:last-child { border-bottom: 0; }

.pstage-phase-body .result-row .player-name { font-weight: 700; }
.pstage-phase-body .result-row .role-name,
.pstage-phase-body .result-row .position { color: var(--ps-muted); font-size: 13px; }
.pstage-phase-body .result-row .role-name { margin-left: auto; }
.pstage-phase-body .role-emoji { font-size: 16px; }

.pstage-phase-body .vote-row span:last-child { margin-left: auto; }

/* La main de l'échange garde la grille des cartes du plateau. */
.pstage-phase .pstage-hand { min-height: 180px; }

/* --------------------------------------- PHASE DE VOTE : classement lisible
   Un rang en pastille (médaille pour le podium), le pseudo, puis le rôle en
   chip colorée. Les votes deviennent des chips au lieu d'une liste. */
.pstage-phase-body .result-row {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    padding: 7px 0;
}

.pstage-phase-body .rank-badge {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .07);
    font-size: 14px;
    font-weight: 800;
}

.pstage-phase-body .rank-1 .rank-badge { background: rgba(255, 215, 0, .18); }
.pstage-phase-body .rank-2 .rank-badge { background: rgba(200, 200, 210, .16); }
.pstage-phase-body .rank-3 .rank-badge { background: rgba(205, 127, 50, .18); }

.pstage-phase-body .result-row .player-name {
    font-size: 15px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pstage-phase-body .role-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    background: rgba(255, 255, 255, .07);
    color: var(--ps-text);
    white-space: nowrap;
}

.pstage-phase-body .role-president { background: rgba(255, 215, 0, .16); color: var(--ps-warn); }
.pstage-phase-body .role-trou { background: rgba(233, 69, 96, .16); color: #ff8aa0; }
.pstage-phase-body .role-vice { background: rgba(0, 212, 170, .14); color: var(--ps-accent); }

.pstage-phase-body .vote-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.pstage-phase-body .vote-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    background: rgba(255, 255, 255, .06);
    border: 1px solid var(--ps-line);
}

.pstage-phase-body .vote-chip.is-yes { border-color: rgba(0, 212, 170, .5); color: var(--ps-accent); }
.pstage-phase-body .vote-chip.is-no { border-color: rgba(233, 69, 96, .5); color: #ff8aa0; }
.pstage-phase-body .vote-chip.is-wait { color: var(--ps-muted); }

/* ---------------------------------------------- RESSENTI TACTILE (mobile-native)
   `touch-action: manipulation` supprime le délai de 300 ms sur le tap ; le
   retour visuel doit venir de :active (le navigateur ne le donne plus, le
   tap-highlight étant neutralisé globalement). Durées 100-160 ms, ease-out. */
html body.in-game #pstage-actions .btn,
body.in-game .pstage .hand-card {
    touch-action: manipulation;
    -webkit-touch-callout: none;
}

html body.in-game #pstage-actions .btn:active {
    transform: scale(.97);
}

body.in-game .pstage .hand-card:active {
    transform: translateY(-2px) scale(.97);
}

/* ------------------------------------------------------------------
   ANIMATIONS DE PLACEMENT (26/10/2026 — « ça manque d'animation »)
   ------------------------------------------------------------------
   Distribution initiale : la main arrive en cascade (opacity + translateY).
   `backwards` (jamais `both`) : une fois posée, la carte reprend ses styles,
   sinon le `:active` de sélection ne pourrait plus la soulever (une animation
   prime sur une déclaration). Stagger 35 ms, plafonné à la 7e carte.
   ------------------------------------------------------------------ */
.pstage-hand.is-dealing .hand-card {
    animation: pstage-deal-in 260ms cubic-bezier(.23, 1, .32, 1) backwards;
}

.pstage-hand.is-dealing .hand-card:nth-child(1) { animation-delay: 0ms; }
.pstage-hand.is-dealing .hand-card:nth-child(2) { animation-delay: 35ms; }
.pstage-hand.is-dealing .hand-card:nth-child(3) { animation-delay: 70ms; }
.pstage-hand.is-dealing .hand-card:nth-child(4) { animation-delay: 105ms; }
.pstage-hand.is-dealing .hand-card:nth-child(5) { animation-delay: 140ms; }
.pstage-hand.is-dealing .hand-card:nth-child(6) { animation-delay: 175ms; }
.pstage-hand.is-dealing .hand-card:nth-child(n+7) { animation-delay: 210ms; }

@keyframes pstage-deal-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

/* PASSER : la main « plie » brièvement — elle cède le tour. Feedback d'état,
   un seul cycle (jamais en boucle), posé par President.pass(). */
.pstage-hand.is-passed {
    animation: pstage-pass 320ms cubic-bezier(.23, 1, .32, 1);
}

@keyframes pstage-pass {
    0%   { opacity: 1; transform: translateY(0); }
    40%  { opacity: .55; transform: translateY(6px); }
    100% { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .pstage-hand.is-dealing .hand-card,
    .pstage-hand.is-passed { animation: none; }
}

/* =====================================================================
   JOURNAL, BANDEAU ET COLLECTE MANUELLE (26/10/2026)
   ---------------------------------------------------------------------
   Le plateau est rendu dans `#game-area > .pstage-slot` : la couche du
   journal (`.sf-layer`, position absolue) vit À CÔTÉ du plateau et n'est
   plus effacée à chaque rendu. Aucune règle d'un autre jeu n'est touchée :
   tout est conditionné par la classe `pstage-host` posée par President.js.
   ===================================================================== */

body.in-game #game-area.pstage-host {
    position: relative;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

body.in-game #game-area.pstage-host > .pstage-slot {
    position: relative;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* --------------------------------------------------- Attente de collecte
   Le pli est complet : seul le ramasseur a un bouton, les autres lisent qui
   ramasse. Le reste du plateau est inerte (aucune carte n'est cliquable). */
.pstage-collect-wait {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    font-variant-numeric: tabular-nums;
}

.pstage-collect-wait strong { color: var(--ps-warn); font-weight: 800; }

.pstage-collect-pulse {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(255, 215, 0, .14);
    animation: pstage-collect-pulse 1.6s ease-in-out infinite;
}

@keyframes pstage-collect-pulse {
    0%, 100% { transform: scale(1); opacity: .85; }
    50%      { transform: scale(1.08); opacity: 1; }
}

html body.in-game #pstage-actions .btn.pstage-collect-btn {
    background: linear-gradient(180deg, #ffd700, #e0a800) !important;
    color: #1a1400 !important;
    border: 1px solid rgba(255, 255, 255, .35) !important;
    box-shadow: 0 6px 18px rgba(255, 215, 0, .28);
}

.pstage-collect-btn .pstage-collect-count {
    font-weight: 900;
    opacity: .8;
}

/* Le siège du ramasseur est mis en avant (le tour, lui, est suspendu). */
.pstage-opp.is-collect {
    border-color: rgba(255, 215, 0, .65);
    box-shadow: 0 0 0 1px rgba(255, 215, 0, .25) inset;
}

.pstage-hourglass.is-collect {
    background: rgba(255, 215, 0, .9);
    color: #1a1400;
}

/* Pendant l'attente, la table empile le pli ET la ligne de statut. */
.pstage-pile.has-status {
    flex-direction: column;
    gap: 4px;
}

.pstage-status.is-collect {
    color: var(--ps-warn);
    font-weight: 700;
}

/* Le HUD annonce le ramassage : il prend la couleur de l'action attendue. */
.pstage-hud.is-collect {
    border-color: rgba(255, 215, 0, .55);
}

.pstage-turn.is-collect { color: var(--ps-warn); }

/* ------------------------------------- Animation de ramassage du pli
   Clones des cartes du pli : ils partent du centre de la table et filent
   vers la boîte du vainqueur (son siège, ou la main si c'est moi).
   Le vecteur est calculé APRÈS rendu par President.js (`--fx` / `--fy`). */
.pstage-catch {
    position: absolute;
    z-index: 6;
    width: var(--card-w, 48px);
    transform: translate(-50%, -50%) scale(1);
    pointer-events: none;
    filter: drop-shadow(0 6px 12px rgba(0, 0, 0, .5));
    animation: pstage-catch 520ms cubic-bezier(.4, 0, .6, 1) forwards;
    animation-delay: var(--catch-delay, 0ms);
    will-change: transform, opacity;
}

@keyframes pstage-catch {
    0% {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1) rotate(0deg);
    }
    35% {
        opacity: 1;
        transform: translate(calc(-50% + var(--fx, 0px) * .18),
                             calc(-50% + var(--fy, 0px) * .18 - 12px)) scale(.92) rotate(-4deg);
    }
    100% {
        opacity: .1;
        transform: translate(calc(-50% + var(--fx, 0px)),
                             calc(-50% + var(--fy, 0px))) scale(.42) rotate(6deg);
    }
}

/* Le vainqueur « reçoit » : sa boîte pulse une fois au moment du ramassage. */
.pstage-opp.is-receiving,
.pstage-hand.is-receiving {
    animation: pstage-receive 420ms ease-out;
}

@keyframes pstage-receive {
    0%   { box-shadow: 0 0 0 0 rgba(255, 215, 0, .55); }
    100% { box-shadow: 0 0 0 14px rgba(255, 215, 0, 0); }
}

/* ------------------------------------------------ Bandeau (socle StageFeed)
   Le bandeau du socle écrit en 13,5 px : sur la scène du Président, il reste
   lisible mais ne doit pas recouvrir le HUD plus d'une seconde. */
body.in-game #game-area.pstage-host > .sf-layer .sf-banner {
    font-size: 13px;
    background: rgba(10, 14, 22, .96);
}

@media (max-height: 460px) {
    body.in-game #game-area.pstage-host > .sf-layer .sf-banner {
        max-height: 40px;
        font-size: 12px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .pstage-catch { animation: none; opacity: 0; }
    .pstage-collect-pulse { animation: none; }
    .pstage-opp.is-receiving,
    .pstage-hand.is-receiving { animation: none; }
}
