/* ==========================================================================
   BATTLE SHEEP — plateau natif (Game Hub)
   --------------------------------------------------------------------------
   Une seule planche fournie par le propriétaire, utilisée telle quelle :
     `assets/images/games/battlesheep_tokens.png` 241×778
       colonne 0      : 4 hexagones de terrain, 61×71 (positions 0, -71, -142, -213)
       colonnes 1..4  : 16 moutons de 45×45 par couleur (blanc, rouge, noir, bleu)

   Le pâturage est donc une grille HEXAGONALE dessinée case par case. Toutes les
   positions sont calculées dans un repère virtuel (60 px par colonne, 53 px par
   rangée) puis mises à l'échelle par UNE variable `--bs-s` posée par le client
   sur `.bs-world` : cases et jetons gardent leurs proportions, et une seule
   mesure suffit (aucune taille circulaire à résoudre).

   La scène suit le contrat commun : `barre / sièges / plateau 1fr / actions`,
   la rangée d'action étant une RANGÉE de la grille et jamais un `fixed`.
   ========================================================================== */

.bs-stage {
    --bs-s: 1;
    --bs-line: rgba(255, 255, 255, .10);
    --bs-soft: rgba(255, 255, 255, .76);
    --bs-dim: rgba(255, 255, 255, .48);
    --bs-accent: #9ad63f;
    --bs-gold: #f5c518;

    position: relative;
    display: grid;
    /* barre / sièges / plateau de rotation / carte / actions */
    grid-template-rows: auto auto auto minmax(0, 1fr) auto;
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
    box-sizing: border-box;
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
    width: 100%;
    padding: 6px 6px calc(env(safe-area-inset-bottom) + 6px);
    color: #f2f6ff;
    font-size: 14px;
    font-family: inherit;
    background-color: #0a1410;
    background-image:
        radial-gradient(120% 80% at 50% -10%, rgba(154, 214, 63, .16) 0%, transparent 62%),
        radial-gradient(90% 70% at 50% 110%, rgba(245, 197, 24, .10) 0%, transparent 64%),
        linear-gradient(rgba(11, 22, 16, .93), rgba(6, 12, 9, .97));
    border-radius: 0;
    overflow: hidden;
    -webkit-tap-highlight-color: transparent;
}

/* Chaque rangée est NOMMÉE explicitement. Sans cela, le plateau de rotation
   masqué (`display: none`) ne compte pas comme case de grille : la carte
   glissait dans la rangée `auto` du plateau de rotation et la rangée d'action
   prenait le `1fr` — 402 px d'actions et un plateau de 0 px en phase de choix.
   Constaté à 360×560, invisible tant que le plateau de rotation est affiché. */
.bs-bar     { grid-row: 1; }
.bs-seats   { grid-row: 2; }
.bs-tray    { grid-row: 3; }
.bs-table   { grid-row: 4; }
.bs-actions { grid-row: 5; }

/* `game.css` réserve `#game-area { padding-top: 175px }` : on cible ID + classe
   pour gagner le combat de spécificité, sinon le plateau flotte sous le header. */
body.in-game #game-area.bs-host {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    padding: 0;
    overflow: hidden;
    position: relative;      /* la couche StageFeed est en position absolue */
}

body.in-game #view-game.bs-view {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    height: auto;
}

/* Bouton journal du socle : 44 px pour le doigt. */
.bs-host .sf-toggle {
    width: 44px;
    height: 44px;
    font-size: 18px;
    top: 4px;
    right: 4px;
    border-radius: 11px;
}

/* ------------------------------------------------------------------ barre */

/* Hauteur de barre FIXE : le bandeau du journal se cale dessus en CSS. Une
   position mesurée en JS était fausse de 6 px (la barre bougeait entre le
   calage et l'affichage du bandeau) et le bandeau mordait sur « À vous de
   jouer ». Contenu d'une seule ligne → aucune raison de la laisser libre. */
body.bs-game {
    --bs-bar-h: 34px;
    --bs-pad: 6px;
}

.bs-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-right: 52px;      /* le bouton journal occupe le coin haut-droit */
    height: var(--bs-bar-h);
    min-height: var(--bs-bar-h);
    max-height: var(--bs-bar-h);
}

.bs-phase {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--bs-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bs-turn {
    margin-left: auto;
    font-size: 14.5px;
    font-weight: 650;
    color: var(--bs-soft);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bs-turn.is-mine {
    color: #ffe08a;
    text-shadow: 0 0 14px rgba(245, 197, 24, .45);
}

/* ------------------------------------------------------------------ sièges */

.bs-seats {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 6px;
}

.bs-seat {
    position: relative;
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    padding: 6px 8px;
    border-radius: 12px;
    background: rgba(255, 255, 255, .04);
    border: 1px solid var(--bs-line);
    transition: border-color .18s ease, background-color .18s ease;
}

.bs-seat.is-me {
    background: rgba(154, 214, 63, .08);
}

/* Halo du tour : on doit voir « c'est à lui » sans lire (règle du 25/10). */
.bs-seat.is-turn {
    border-color: rgba(245, 197, 24, .55);
    background: rgba(245, 197, 24, .10);
    animation: bs-halo 1.9s ease-in-out infinite;
}

.bs-seat.is-stuck {
    opacity: .62;
}

/* Pastille de couleur : celle du sprite (blanc, rouge, noir, bleu). Un mouton
   blanc ou noir disparaîtrait sur le fond sans un liseré de contraste. */
.bs-seat-dot {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .45);
}

.bs-seat-dot.is-empty {
    background: rgba(255, 255, 255, .10);
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .22);
}

.bs-seat-dot.c-white { background: #f4f6f2; box-shadow: inset 0 0 0 2px #7d8a72, 0 2px 6px rgba(0, 0, 0, .45); }
.bs-seat-dot.c-red   { background: #d2342c; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .35), 0 2px 6px rgba(0, 0, 0, .45); }
.bs-seat-dot.c-black { background: #1b1f1c; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .45), 0 2px 6px rgba(0, 0, 0, .45); }
.bs-seat-dot.c-blue  { background: #2b62c9; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .30), 0 2px 6px rgba(0, 0, 0, .45); }

.bs-seat-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.2;
}

.bs-seat-name {
    font-size: 13.5px;
    font-weight: 650;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bs-seat-meta {
    font-size: 11.5px;
    color: var(--bs-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bs-seat-badge {
    margin-left: auto;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #ffe08a;
    white-space: nowrap;
}

/* ------------------------------------------------- plateau de rotation */

/* La pièce à poser, au-dessus de la carte, avec un bouton de chaque côté.
   Elle reste visible pendant qu'on choisit la case : on voit donc l'effet de
   la rotation sur la carte en bas. */
.bs-tray {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 2px 4px;
    min-height: 0;
}

.bs-tray[hidden] {
    display: none;
}

.bs-rot {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, .20);
    background: rgba(255, 255, 255, .08);
    color: #f2f6ff;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
    transition: transform .12s ease, background-color .18s ease;
}

.bs-rot:hover {
    background: rgba(255, 255, 255, .16);
}

.bs-rot:active {
    transform: scale(.94);
}

.bs-tray-mini {
    position: relative;
    flex: 0 0 auto;
}

/* Un hexagone de la pièce, mis à l'échelle depuis son coin : le sprite garde
   sa taille naturelle, donc aucun calcul de `background-size`. */
.bs-mini-hex {
    position: absolute;
    width: 61px;
    height: 71px;
    background-image: url('../images/games/battlesheep_tokens.png');
    background-repeat: no-repeat;
    background-position: 0 0;
    transform-origin: 0 0;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .45));
}

.bs-tray-label {
    font-size: 11.5px;
    color: var(--bs-dim);
    line-height: 1.25;
    max-width: 190px;
}

/* -------------------------------------------------- choix des couleurs */

/* Phase simultanée d'ouverture : chacun prend la couleur de ses moutons, puis
   se déclare prêt. Le panneau remplace la carte (qui est vide à ce moment-là). */
.bs-choose {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 12px;
    padding: 8px 6px;
    overflow-y: auto;
}

.bs-choose[hidden] {
    display: none;
}

.bs-choose-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.bs-choose-title {
    font-size: 14.5px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: #f2f6ff;
}

.bs-choose-timer {
    flex: 0 0 auto;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .07);
    border: 1px solid var(--bs-line);
    font-size: 13.5px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--bs-soft);
}

.bs-choose-timer.is-urgent {
    color: #ffd3c9;
    border-color: rgba(224, 69, 62, .55);
    background: rgba(224, 69, 62, .16);
}

.bs-colors {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}

.bs-color {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding: 10px 6px 8px;
    border-radius: 14px;
    border: 1px solid rgba(255, 255, 255, .16);
    background: rgba(255, 255, 255, .05);
    color: #f2f6ff;
    font-family: inherit;
    cursor: pointer;
    min-height: 92px;
    transition: transform .12s ease, border-color .18s ease, background-color .18s ease;
}

.bs-color:hover:not(:disabled) {
    background: rgba(255, 255, 255, .10);
    border-color: rgba(255, 255, 255, .30);
}

.bs-color:active:not(:disabled) {
    transform: scale(.97);
}

.bs-color.is-mine {
    border-color: rgba(154, 214, 63, .85);
    background: rgba(154, 214, 63, .14);
    box-shadow: 0 0 0 2px rgba(154, 214, 63, .25) inset;
}

.bs-color.is-taken {
    opacity: .5;
    cursor: default;
}

/* Le mouton de la couleur, découpé dans la planche (colonne et pose fixes). */
.bs-color-swatch {
    width: 45px;
    height: 45px;
    background-image: url('../images/games/battlesheep_tokens.png');
    background-repeat: no-repeat;
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .45));
}

.bs-color-name {
    font-size: 13px;
    font-weight: 650;
}

.bs-color-owner {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--bs-dim);
}

.bs-color-owner.is-mine {
    color: #b9ea6a;
}

/* Bandeau d'actualité du socle : il se posait SUR la barre (phase + tour) et
   masquait « À vous de jouer » à l'instant où le joueur en avait besoin. Même
   parti pris que Papayoo : il descend sous la barre, au-dessus de la carte. */
body.bs-game .sf-banner {
    top: calc(var(--bs-pad) + var(--bs-bar-h) + 2px);
    left: 6px;
    right: 6px;
}

.bs-choose-note {
    margin: 0;
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--bs-dim);
    text-align: center;
}

/* ---------------------------------------------------------------- plateau */

.bs-table {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 0;
    min-width: 0;
    overflow: hidden;
}

.bs-board {
    position: relative;
    flex: 1 1 auto;
    align-self: stretch;
    min-height: 0;
    min-width: 0;
}

/* Repère virtuel : taille posée en px par le client, échelle par `--bs-s`.
   `translate(-50%,-50%)` + `transform-origin: 50% 50%` gardent le pâturage
   centré quelle que soit l'échelle (une boîte mise à l'échelle reste, elle,
   calée sur son coin). */
.bs-world {
    position: absolute;
    left: 50%;
    top: 50%;
    transform-origin: 50% 50%;
    transform: translate(-50%, -50%) scale(var(--bs-s, 1));
    will-change: transform;
    filter: drop-shadow(0 12px 26px rgba(0, 0, 0, .5));
}

.bs-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13.5px;
    color: var(--bs-dim);
}

.bs-hex {
    position: absolute;
    width: 61px;
    height: 71px;
    background-image: url('../images/games/battlesheep_tokens.png');
    background-repeat: no-repeat;
    background-position: 0 0;
    touch-action: manipulation;
}

.bs-hex.t1 { background-position: 0 0; }
.bs-hex.t2 { background-position: 0 -71px; }
.bs-hex.t3 { background-position: 0 -142px; }
.bs-hex.t4 { background-position: 0 -213px; }

/* Case proposée qui n'appartient pas encore au pâturage (ancre de pièce,
   destination fantôme) : le terrain est estompé pour rester un repère. */
/* Case proposée qui n'appartient PAS encore au pâturage : ni herbe, ni fleurs —
   seulement un voile blanc translucide, comme la référence du propriétaire.
   C'est ce qui la distingue au premier regard d'une tuile déjà posée ; une
   esquisse d'herbe à 78 % se confondait avec les pièces posées. */
/* ==========================================================================
   VOILES BLANCS — le langage unique de « on peut agir ici »
   --------------------------------------------------------------------------
   Une case disponible est un hexagone blanc translucide, jamais une esquisse
   d'herbe (elle se confondrait avec une pièce posée). Le voile est posé en
   `::before`, donc SOUS les moutons : la pile reste lisible pendant qu'on
   choisit. Quatre intensités, du plus discret au plus franc.
   ========================================================================== */

.bs-hex.is-virtual::before,
.bs-hex.is-spawn::before,
.bs-hex.is-target::before,
.bs-hex.is-selected::before,
.bs-hex.is-dest::before {
    content: "";
    position: absolute;
    inset: 0;
    clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
    background: #ffffff;
    opacity: 0;
    pointer-events: none;
    transition: opacity .14s ease;
}

/* Case proposée qui n'appartient PAS encore au pâturage : aucune herbe dessous. */
.bs-hex.is-virtual {
    background-image: none;
}

/* 20 % comme la référence, MAIS leur plateau est en bois clair : sur notre fond
   sombre, 20 % se lit comme un trou. 34 % donne le même « blanc translucide »
   sur le vert nuit du site (mesuré : centre ~(97,105,97) contre (16,22,14)). */
.bs-hex.is-virtual::before { opacity: .34; }

/* Aperçu de la pièce à poser : le voile le plus marqué. */
.bs-hex.is-ghost::before { opacity: .58; }

.bs-hex.is-anchor:hover::before { opacity: .48; }
.bs-hex.is-anchor:active::before { opacity: .58; }

/* Pâtures du bord où poser le troupeau, et pâtures où envoyer une partie de la
   pile : voile léger, l'herbe reste visible dessous. */
/* Mesuré sur capture : un voile à 30 % ne faisait gagner que 41 points de
   luminance sur l'herbe fleurie — visible, mais pas « surbrillance ». 42 %
   donne un contraste franc sans masquer les motifs du gazon. */
.bs-hex.is-spawn::before { opacity: .20; }
.bs-hex.is-spawn:hover::before { opacity: .32; }
.bs-hex.is-target::before { opacity: .42; }
.bs-hex.is-target:hover::before { opacity: .56; }

/* Case choisie (troupeau, pile, case d'arrivée) : voile franc, plus l'anneau. */
.bs-hex.is-selected::before,
.bs-hex.is-dest::before { opacity: .55; }

.bs-hex.is-playable { cursor: pointer; }

/* Anneau hexagonal : bordure de la pièce posée (couleur du joueur), contour de
   l'aperçu, ou mise en évidence d'une sélection (or). Trait FIN (3 dans un
   viewBox de 61, soit ~2 px à l'écran) : des bordures épaisses étaient le
   premier reproche du propriétaire. */
.bs-ring {
    position: absolute;
    inset: 0;
    background-image: var(--ring);
    background-repeat: no-repeat;
    background-size: 100% 100%;
    pointer-events: none;
}

.bs-hex.is-selected .bs-ring,
.bs-hex.is-dest .bs-ring {
    animation: bs-ring-pop 1.15s ease-in-out infinite;
}

@keyframes bs-ring-pop {
    0%, 100% { transform: scale(1);    opacity: 1; }
    50%      { transform: scale(1.05); opacity: .72; }
}

@keyframes bs-dest-pulse {
    from { opacity: .28; }
    to   { opacity: .55; }
}

/* Pile de moutons : 45×45 du sprite, centrée sur la case (marge 8 / 13). */
.bs-stack {
    position: absolute;
    left: 8px;
    top: 13px;
    width: 45px;
    height: 45px;
    background-image: url('../images/games/battlesheep_tokens.png');
    background-repeat: no-repeat;
    pointer-events: none;
    filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .38));
}

.bs-stack.is-flying {
    z-index: 5;
    pointer-events: none;
}

.bs-count {
    position: absolute;
    right: -3px;
    top: -1px;
    min-width: 17px;
    height: 17px;
    padding: 0 3px;
    border-radius: 999px;
    background: rgba(10, 18, 13, .92);
    border: 1.5px solid rgba(255, 255, 255, .82);
    color: #fff;
    font-size: 10.5px;
    font-weight: 800;
    line-height: 14px;
    text-align: center;
    letter-spacing: -.01em;
}

/* Troupeau fantôme : moutons qui vont ARRIVER sur la case (partage en cours ou
   pose du troupeau). Semi-transparent, cerclé de blanc pour se distinguer d'une
   pile réelle. */
.bs-stack.is-preview {
    opacity: .62;
    filter: drop-shadow(0 0 7px rgba(255, 255, 255, .45));
}

/* Dernier coup : la pile qui vient de se poser est cerclée. */
.bs-hex.is-dest .bs-stack {
    filter: drop-shadow(0 0 6px rgba(245, 197, 24, .85));
}

/* ---------------------------------------------------------------- actions */

.bs-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 48px;
}

.bs-hint {
    font-size: 13px;
    color: var(--bs-dim);
    line-height: 1.35;
}

.bs-hint.is-wide {
    flex: 1 1 auto;
    min-width: 0;
}

.bs-btn {
    flex: 0 0 auto;
    min-height: 44px;
    padding: 0 15px;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, .18);
    background: rgba(255, 255, 255, .07);
    color: #f2f6ff;
    font-family: inherit;
    font-size: 14.5px;
    font-weight: 650;
    cursor: pointer;
    transition: transform .12s ease, background-color .18s ease, border-color .18s ease;
}

.bs-btn:hover {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .28);
}

.bs-btn:active {
    transform: scale(.97);
}

.bs-btn.is-primary {
    background: linear-gradient(180deg, #a8e04a, #6fae21);
    border-color: rgba(154, 214, 63, .70);
    color: #10200a;
}

.bs-btn.is-ghost {
    margin-left: auto;
}

/* Sélecteur de moutons à déplacer */
/* ------------------------------------------------------------ fin de partie */

/* L'annonce de fin vit SOUS le plateau, dans la rangée d'action : aucune
   superposition, donc le dernier glissement reste visible. */
.bs-end {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    animation: bs-end-in 260ms cubic-bezier(.23, 1, .32, 1) both;
}

.bs-end-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.bs-end-title {
    font-size: 15.5px;
    font-weight: 750;
    letter-spacing: -.01em;
    color: #ffe08a;
}

.bs-end-sub {
    font-size: 12.5px;
    color: var(--bs-dim);
}

.bs-end-actions {
    display: flex;
    gap: 8px;
}

.bs-end-actions .bs-btn {
    flex: 1 1 0;
    min-width: 0;
    padding: 0 10px;
    font-size: 14px;
}

.bs-end-actions .bs-btn.is-ghost {
    margin-left: 0;      /* la règle générale pousse « Quitter » à droite */
}

@keyframes bs-end-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

/* ------------------------------------------- bandeau « à vous de jouer » */

/* Le socle pose `#turn-badge` en `position: fixed` à 46 % de la hauteur, donc
   AU MILIEU du pâturage. Ici le bandeau remonte dans la bande vide au-dessus
   du plateau — position calculée par `fitBoard()`. L'animation du socle est
   remplacée, pas seulement décalée (ses keyframes recentrent verticalement). */
body.bs-game .turn-badge {
    top: var(--bs-badge-top, 96px);
    transform: translate(-50%, 0);
    padding: 7px 18px;
    font-size: 14.5px;
}

body.bs-game .turn-badge.is-flash {
    animation: bs-turn-pop 2.2s cubic-bezier(.23, 1, .32, 1) forwards;
}

@keyframes bs-turn-pop {
    0%   { opacity: 0; transform: translate(-50%, -8px) scale(.86); }
    9%   { opacity: 1; transform: translate(-50%, 0) scale(1.06); }
    18%  { transform: translate(-50%, 0) scale(1); }
    74%  { opacity: 1; transform: translate(-50%, 0) scale(1); }
    100% { opacity: 0; transform: translate(-50%, -6px) scale(.98); }
}

@keyframes bs-halo {
    0%, 100% { box-shadow: 0 0 0 0 rgba(245, 197, 24, .0); }
    50%      { box-shadow: 0 0 0 3px rgba(245, 197, 24, .22); }
}

/* ---------------------------------------------------------------- erreurs */

.bs-error,
.bs-waiting {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 70;
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: min(360px, calc(100% - 24px));
    padding: 16px;
    border-radius: 14px;
    background: rgba(20, 12, 16, .96);
    border: 1px solid rgba(224, 69, 62, .5);
    color: #ffe9e6;
    text-align: center;
    font-size: 14px;
}

.bs-waiting {
    border-color: rgba(255, 255, 255, .16);
    color: var(--bs-soft);
    background: rgba(11, 22, 16, .92);
}

.bs-error-msg {
    font-size: 13px;
    color: rgba(255, 255, 255, .72);
    word-break: break-word;
}

/* ------------------------------------------------------- écrans courts / paysage */

@media (max-height: 620px) {
    .bs-stage {
        gap: 4px;
        padding: 4px 4px calc(env(safe-area-inset-bottom) + 4px);
    }

    body.bs-game { --bs-bar-h: 30px; --bs-pad: 4px; }
    .bs-phase { font-size: 10.5px; }

    .bs-seat { padding: 4px 7px; gap: 5px; }
    .bs-seat-dot { width: 18px; height: 18px; }
    .bs-seat-name { font-size: 12.5px; }
    .bs-seat-meta { display: none; }   /* un compteur n'est pas une action */

    .bs-actions { min-height: 44px; }
    .bs-btn { min-height: 44px; }      /* cible tactile : jamais sous 44 px */
}

/* En paysage, les informations passent dans une COLONNE à droite et le
   pâturage prend toute la hauteur restante. */
@media (orientation: landscape) and (max-height: 620px) {
    .bs-stage {
        grid-template-columns: minmax(0, 1fr) 186px;
        grid-template-rows: auto auto auto minmax(0, 1fr);
        grid-template-areas:
            "bar    bar"
            "board  tray"
            "board  seats"
            "board  actions";
        gap: 5px 8px;
    }

    .bs-bar { grid-area: bar; height: 30px; min-height: 30px; }
    .bs-table { grid-area: board; }
    .bs-tray { grid-area: tray; gap: 6px; }
    .bs-tray-label { display: none; }
    .bs-rot { width: 40px; height: 40px; }

    .bs-seats {
        grid-area: seats;
        grid-auto-flow: row;
        grid-template-columns: minmax(0, 1fr);
        align-content: start;
    }

    .bs-seat { padding: 4px 7px; }
    .bs-seat-badge { display: none; }

    .bs-actions {
        grid-area: actions;
        flex-direction: column;
        align-items: stretch;
        align-self: end;
        gap: 6px;
        min-height: 0;
    }

    /* L'aide est un texte, pas une action : dans 186 px elle coûterait trois
       lignes au détriment du plateau. */
    .bs-hint { display: none; }
    .bs-end-actions { flex-direction: column; }
    .bs-btn { min-height: 44px; width: 100%; margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .bs-seat.is-turn,
    .bs-hex.is-selected .bs-ring,
    .bs-hex.is-dest .bs-ring,
    .bs-end {
        animation: none !important;
    }

    .bs-btn,
    .bs-hex::after {
        transition: none !important;
    }
}
