/* Belotte entre amis — client web.
   Deux styles de table, imposés par l'hôte (data-style sur <html>) :
   - sobre (la refonte) : nuit ardoise ou jour brumeux, table pétrole désaturée, accent sauge-sarcelle, corail pour l'urgence ;
   - classique : la table de café — feutre vert profond sous la lampe, rebord en noyer et liseré laiton,
     cartes ivoire aux index à empattements, carmin et noir d'encre.
   À l'accueil, pas de data-style : thème personnel (sombre par défaut, clair via data-theme).
   Mobile d'abord (portrait), vidéos aux 4 coins, centre libre pour le pli et les enchères. */
:root {
  /* Thème sombre (par défaut) : table nettement plus claire que le fond, cadres plus sombres que la table. */
  --bg: #0b1013;
  --table: #1c2b33;
  --table-hi: #24373f;
  --surface: #121b20;
  --surface-2: #2a3a43;
  --hover: #344751;
  --line: rgba(241, 245, 246, .12);
  --line-strong: rgba(241, 245, 246, .26);
  --text: #f1f5f6;
  --muted: #a9bac2;
  --accent: #8fd6c6;
  --accent-hover: #a6e0d3;
  --on-accent: #0b1a1d;
  --accent-soft: rgba(143, 214, 198, .16);
  --warn: #f49a8f;
  --on-warn: #1d0f0d;
  --warn-soft: rgba(244, 154, 143, .16);
  --team-0: #8fd6c6;
  --team-1: #c3b3f7;
  --card: #fbfcfb;
  --card-ink: #1b2328;
  --card-red: #d6495b;
  --suit-on-surface: #f1f5f6;
  --red-on-surface: #ff9aa6;
  --speaking: #a8e8b0;
  --glass: rgba(11, 16, 19, .86);
  --scrim: rgba(5, 8, 10, .72);
  --ring-track: rgba(241, 245, 246, .14);
  --shadow: 0 8px 24px rgba(0, 0, 0, .4);
  --card-shadow: 0 2px 8px rgba(0, 0, 0, .4);
  --radius: 14px;
  --tap: 44px;
  /* Cartes : bord, police des index, contour des atouts dans la main. */
  --card-edge: 0 0 #0000;
  --card-font: "Manrope", "Noto Sans Symbols 2", system-ui, -apple-system, "Segoe UI", sans-serif;
  --card-weight: 800;
  --trump-ring: #2fae95;
  --trump-edge: rgba(11, 26, 29, .35);
  --control-bg: var(--bg);
  --serif: "Libre Caslon Text", "Noto Sans Symbols 2", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  color-scheme: dark;
}

/* Thème clair, doux : gris-bleu brumeux, table sauge pâle, texte ardoise foncé. */
:root[data-theme="light"] {
  --bg: #d7dfe2;
  --table: #bfd0cf;
  --table-hi: #cddcdb;
  --surface: #eef3f4;
  --surface-2: #f8fafa;
  --hover: #e3eaec;
  --line: rgba(20, 40, 48, .14);
  --line-strong: rgba(20, 40, 48, .3);
  --text: #13222a;
  --muted: #3b4e58;
  --accent: #1d5f53;
  --accent-hover: #174d43;
  --on-accent: #ffffff;
  --accent-soft: rgba(29, 95, 83, .14);
  --warn: #9a3428;
  --on-warn: #ffffff;
  --warn-soft: rgba(154, 52, 40, .12);
  --team-0: #1d5f53;
  --team-1: #6a55c2;
  --card: #ffffff;
  --card-ink: #17212a;
  --card-red: #c8364a;
  --suit-on-surface: #17212a;
  --red-on-surface: #c8364a;
  --speaking: #2f9a4c;
  --glass: rgba(238, 243, 244, .92);
  --scrim: rgba(19, 34, 42, .45);
  --ring-track: rgba(20, 40, 48, .14);
  --shadow: 0 8px 24px rgba(19, 34, 42, .18);
  --card-shadow: 0 1px 4px rgba(19, 34, 42, .25);
  --trump-ring: var(--accent);
  --trump-edge: transparent;
  color-scheme: light;
}

/* Style classique : la table de belote traditionnelle. Feutre, noyer, laiton, ivoire, carmin, encre. */
:root[data-style="classique"] {
  --bg: #16120e;
  --table: #1e5c3a;
  --table-hi: #2a6f47;
  --surface: #10251a;
  --surface-2: #193524;
  --hover: #22432f;
  --line: rgba(222, 196, 128, .16);
  --line-strong: rgba(222, 196, 128, .36);
  --text: #f3ecda;
  --muted: #d0c7ad;
  --accent: #c9a227;
  --accent-hover: #d9b647;
  --on-accent: #1f1604;
  --accent-soft: rgba(201, 162, 39, .17);
  --warn: #e46f60;
  --on-warn: #210a06;
  --warn-soft: rgba(228, 111, 96, .16);
  --team-0: #d9b84f;
  --team-1: #a9c0d6;
  --card: #fbf8f0;
  --card-ink: #17130e;
  --card-red: #b3122e;
  --suit-on-surface: #f3ecda;
  --red-on-surface: #f2939a;
  --speaking: #a6dca2;
  --glass: rgba(12, 31, 21, .9);
  --scrim: rgba(10, 7, 4, .72);
  --ring-track: rgba(243, 236, 218, .18);
  --shadow: 0 10px 28px rgba(0, 0, 0, .55);
  --card-shadow: 0 1px 1px rgba(0, 0, 0, .28), 0 3px 9px rgba(0, 0, 0, .34);
  --card-edge: inset 0 0 0 1px #dcd2ba;
  --card-font: var(--serif);
  --card-weight: 700;
  --trump-ring: #c9a227;
  --trump-edge: rgba(92, 68, 8, .6);
  --control-bg: rgba(6, 18, 11, .42);
  --brass: #c9a227;
  /* Grain du feutre et veinage du bois : bruit SVG en niveaux de gris, fondu en « overlay ». */
  --felt-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23f)' opacity='.5'/%3E%3C/svg%3E");
  --wood-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.006 .22' numOctaves='4' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='600' height='600' filter='url(%23w)'/%3E%3C/svg%3E");
  --felt: radial-gradient(90% 75% at 50% 40%, #2a6e47 0%, #1f5e3b 45%, #164a2e 78%, #103a24 100%);
  --wood: linear-gradient(160deg, #5e3c22, #3d2614 55%, #28170c);
  color-scheme: dark;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; height: 100%; }
html {
  background: var(--bg);
  /* Taille de base fluide : textes et espacements en rem suivent la largeur du téléphone
     (14 px à 320 px de large, 16 px dès 393 px), tout en respectant la taille de police choisie dans le navigateur. */
  font-size: clamp(0.875rem, 0.327rem + 2.74vw, 1rem);
  /* Chrome Android n'agrandit pas le texte de lui-même (le réglage d'accessibilité reste respecté par le zoom). */
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  overflow-x: clip;
}
body, .felt, .panel, button, .video { transition: background-color .25s ease, border-color .25s ease, color .25s ease; }
body {
  font-family: "Manrope", "Noto Sans Symbols 2", system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--text);
  display: flex; flex-direction: column; min-height: 100dvh;
  -webkit-tap-highlight-color: transparent;
  /* Jouer vite (double tapotement sur les cartes) ne doit jamais zoomer la page ; le pincement reste possible. */
  touch-action: manipulation;
  overflow-x: clip;
}
/* À table : écran d'application, exactement à la taille de l'écran — ni défilement, ni « tirer pour rafraîchir » (Android). */
html.at-table, html.at-table body { overflow: hidden; overscroll-behavior: none; }
html.at-table body { height: 100dvh; min-height: 0; }
button, input { font: inherit; }
svg { display: block; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Barre supérieure */
.bar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 8px max(16px, env(safe-area-inset-right)) 8px max(16px, env(safe-area-inset-left));
  padding-top: max(8px, env(safe-area-inset-top));
  border-bottom: 1px solid var(--line);
}
.brand { font-weight: 700; letter-spacing: .01em; display: flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; }
.brand-name { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.brand-mark { width: 24px; height: 24px; border-radius: 6px; flex-shrink: 0; display: block; }
.brand em { font-style: normal; font-weight: 500; color: var(--muted); }
/* Versions de test : transport vidéo (« P2P », « Local ») en pastille, gardée sur les plus petits écrans. */
.brand .brand-video { font-size: .72em; font-weight: 700; letter-spacing: .03em; padding: 1px 7px; border-radius: 999px;
  border: 1px solid currentColor; color: var(--muted); flex-shrink: 0; }
.bar-right { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
.badge { white-space: nowrap; background: var(--surface); border: 1px solid var(--line); padding: 4px 10px; border-radius: 999px; font-size: .85rem; color: var(--muted); }
.badge strong { letter-spacing: .18em; color: var(--text); }
.bar-btn { min-height: 40px; width: 40px; padding: 0; display: grid; place-items: center; border-radius: 10px; flex-shrink: 0; position: relative; }
/* Zone de toucher agrandie (44 px et plus) sans changer le dessin. */
.bar-btn::after, .bar-pill::after { content: ''; position: absolute; inset: -4px; }
.bar-btn svg { width: 18px; height: 18px; }
.bar-btn.off { color: var(--warn); border-color: var(--warn); background: var(--warn-soft); }
#gear[aria-expanded="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.conn { width: 8px; height: 8px; border-radius: 50%; background: var(--warn); font-size: 0; flex-shrink: 0; }
.conn.on { background: var(--accent); }

/* Panneaux (accueil, salon) */
.panel {
  width: min(460px, calc(100% - 32px)); margin: 28px auto; padding: 24px 20px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 20px;
}
.panel h1 { margin: 0 0 6px; font-size: 1.35rem; font-weight: 700; line-height: 1.3; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.hint { font-size: .8rem; color: var(--muted); margin-top: 22px; }
.hint code { color: var(--accent); }
label { display: block; margin: 18px 0 8px; font-weight: 600; font-size: .95rem; }
input {
  /* 16 px écrits en px : sous 16 px, Safari (iPhone) zoome la page au toucher du champ et ne dézoome plus. */
  font-size: 16px;
  width: 100%; min-height: var(--tap); padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--line-strong); background: var(--bg); color: var(--text); margin-top: 6px;
}
input::placeholder { color: var(--muted); opacity: 1; }
input:focus-visible, button:focus-visible, summary:focus-visible, .card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.row { display: flex; gap: 10px; margin-top: 14px; align-items: center; }
.row.join input { text-transform: uppercase; letter-spacing: .3em; margin: 0; }
button {
  min-height: var(--tap); padding: 10px 16px; border-radius: 10px; border: 1px solid var(--line-strong);
  background: var(--surface-2); color: var(--text); cursor: pointer; font-weight: 600;
  transition: background .18s ease, border-color .18s ease, transform .1s ease;
}
/* Survol seulement avec une souris : sur écran tactile, l'effet resterait collé au bouton touché
   (micro coupé ou bouton « Installer » ouvert affichés en gris au lieu de leur couleur d'état). */
@media (hover: hover) { button:hover:not(:disabled) { background: var(--hover); } }
button:active:not(:disabled) { transform: scale(.97); }
button:disabled { opacity: .4; cursor: default; }
button.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
@media (hover: hover) { button.primary:hover:not(:disabled) { background: var(--accent-hover); } }
button.danger { background: var(--warn); color: var(--on-warn); border-color: var(--warn); }
button.link { background: none; border: none; color: var(--muted); text-decoration: underline; padding: 6px 0; }
.error { color: var(--warn); min-height: 1.2em; margin: 10px 0 0; }
.big-code { font-size: 2.4rem; font-weight: 700; letter-spacing: .35em; color: var(--accent); text-align: center; margin: 12px 0 20px; }
.players { list-style: none; padding: 0; margin: 0 0 16px; }
.players li { padding: 10px 4px; border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; gap: 8px; }
.players li.empty { color: var(--muted); font-style: italic; }

/* Règles de la partie et réglages de table (accueil) */
.opt { margin-top: 14px; }
.opt-label { display: block; font-size: .85rem; color: var(--muted); margin-bottom: 6px; }
.seg { display: flex; flex-wrap: wrap; gap: 6px; }
.seg button { font-size: .9rem; padding: 8px 12px; background: var(--control-bg); }
.seg button.on { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
/* Réglage visible mais réservé à l'hôte : la valeur choisie reste lisible. */
.seg button.on:disabled { opacity: 1; }
.seg button:disabled:not(.on) { opacity: .35; }
.help { font-size: .8rem; color: var(--muted); margin: 6px 0 0; line-height: 1.45; }
.help strong { color: var(--text); font-weight: 600; }
.or { font-size: .8rem; color: var(--muted); text-align: center; margin: 20px 0 0; }
.panel .sub { font-size: .95rem; color: var(--accent); margin: 18px 0 6px; }
.rules-recap { list-style: none; padding: 0; margin: 0 0 12px; font-size: .9rem; }
.rules-recap li { padding: 6px 0; display: flex; justify-content: space-between; gap: 12px; border-bottom: 1px solid var(--line); }
.rules-recap li span:first-child { color: var(--muted); }
.rules-recap li span:last-child { text-align: right; }

/* ---------------------------------------------------------------- Accueil : création de partie sur un écran
   Trois sections repliées (Partie, Règles, Table) ; le titre de chacune résume les choix en cours, en couleur
   d'accent, et se met à jour à chaque toucher. Une seule section ouverte à la fois. */
.home-hero h1 { font-size: 1.22rem; margin: 0 0 4px; }
.home-hero p { margin: 0; font-size: .88rem; line-height: 1.4; }
label.field { margin: 14px 0 0; }
.config { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.cfg { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); transition: border-color .18s ease, background-color .18s ease; }
.cfg[open] { border-color: var(--accent); background: var(--surface); }
.cfg > summary {
  list-style: none; cursor: pointer; position: relative; border-radius: inherit;
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  min-height: 56px; padding: 8px 44px 8px 14px; -webkit-user-select: none; user-select: none;
}
.cfg > summary::-webkit-details-marker { display: none; }
.cfg > summary::after {
  content: ''; position: absolute; right: 19px; top: 50%; width: 8px; height: 8px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: translateY(-70%) rotate(45deg); transition: transform .2s ease;
}
.cfg[open] > summary::after { transform: translateY(-25%) rotate(-135deg); border-color: var(--accent); }
.cfg-title { font-weight: 700; font-size: .95rem; color: var(--text); }
.cfg-recap { font-size: .84rem; font-weight: 600; line-height: 1.35; color: var(--accent); border-radius: 4px; }
.cfg-recap.bump { animation: recap-bump .7s ease-out; }
@keyframes recap-bump { from { background: var(--accent-soft); box-shadow: 0 0 0 3px var(--accent-soft); } to { background: transparent; box-shadow: 0 0 0 3px transparent; } }
.cfg-body { padding: 0 12px 12px; container-type: inline-size; }
.cfg-body .opt {
  display: grid; grid-template-columns: 4.8rem minmax(0, 1fr); column-gap: 8px; align-items: center; margin-top: 8px;
}
/* Choix visuel (styles de table) : libellé au-dessus, tuiles sur toute la largeur. */
.cfg-body .opt.stack { grid-template-columns: minmax(0, 1fr); }
.cfg-body .opt.stack .opt-label { margin-bottom: 5px; }
.cfg-body > .opt:first-child { margin-top: 0; }
.cfg-body .opt-label { margin: 0; font-size: .8rem; line-height: 1.25; }
.cfg-body .help { grid-column: 1 / -1; margin: 4px 0 0; font-size: .76rem; line-height: 1.35; }
@container (max-width: 18em) {
  .cfg-body .opt { grid-template-columns: minmax(0, 1fr); }
  .cfg-body .opt-label { margin-bottom: 4px; }
}
/* Choix sur une ligne, à parts égales ; un libellé long passe sur deux lignes dans son bouton. */
.cfg .seg { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.cfg .seg button { padding: 6px 5px; line-height: 1.15; font-size: .86rem; overflow-wrap: anywhere; hyphens: auto; }
.cfg .seg.styles { grid-auto-flow: row; }
/* Score : les quatre valeurs habituelles et le champ « autre » sur une seule ligne. */
.seg-line { display: flex; gap: 4px; }
.seg-line .seg { flex: 4 1 0; gap: 4px; min-width: 0; }
.seg-line .seg button { padding: 6px 2px; }
#target-custom { flex: 1 1 0; min-width: 0; width: auto; min-height: 44px; margin: 0; padding: 6px 2px; text-align: center; }
#target-custom::placeholder { font-size: 13px; }
.help.warn { color: var(--warn); font-weight: 600; }
.home-actions { margin-top: 18px; }
.home-actions #create { width: 100%; }
.home-actions .or { margin: 12px 0 0; }
/* Plus de saisie de code : on rejoint une partie par le lien reçu (accueil ouvert par une invitation). */
.home-actions .row.join { display: none; margin-top: 6px; }
html.invited .home-actions .row.join { display: flex; }
.home-actions .error:empty { min-height: 0; margin: 0; }

/* Choix du style de table : trois tuiles, chacune avec un tapis miniature et sa carte. */
.seg.styles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.seg.styles button { display: flex; flex-direction: column; align-items: stretch; gap: 6px; padding: 7px 7px 8px; font-size: .85rem; text-align: center; }
.swatch { position: relative; display: block; height: 26px; border-radius: 6px; }
.swatch::after {
  content: ''; position: absolute; left: 50%; top: 50%; width: 11px; height: 15px; border-radius: 2px;
  transform: translate(-50%, -50%) rotate(-6deg); box-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
.sw-classique { background: radial-gradient(circle at 50% 40%, #2c7149, #123f27); box-shadow: inset 0 0 0 3px #4a2e19, inset 0 0 0 4px #c9a227; }
.sw-classique::after { background: #fbf8f0; }
.sw-nuit { background: radial-gradient(circle at 50% 40%, #24373f, #1c2b33); box-shadow: inset 0 0 0 1px rgba(241, 245, 246, .2); }
.sw-nuit::after { background: #fbfcfb; }
.sw-jour { background: radial-gradient(circle at 50% 40%, #cddcdb, #bfd0cf); box-shadow: inset 0 0 0 1px rgba(20, 40, 48, .25); }
.sw-jour::after { background: #ffffff; }

/* Salon : les deux équipes, places libres, choix du partenaire par l'hôte */
.teams { display: grid; gap: 10px; margin: 0 0 6px; }
.team-block { border: 1px solid var(--line); border-radius: var(--radius); padding: 2px 12px; }
.team-head { display: flex; align-items: center; gap: 8px; margin: 0; padding: 10px 0 4px; font-size: .9rem; font-weight: 700; }
.team-head .count { margin-left: auto; color: var(--muted); font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.team-block .players { margin: 0; }
/* Prénom long à côté de « Avec moi / Contre moi » : le choix passe sous le prénom plutôt que de le couper
   (l'hôte doit pouvoir distinguer deux « Jean-… » au moment de choisir son partenaire). */
.team-block .players li { align-items: center; min-height: 52px; padding: 6px 0; flex-wrap: wrap; row-gap: 6px; }
.team-block .players li:last-child { border-bottom: none; }
.who { display: flex; align-items: center; gap: 6px; min-width: 0; }
.who .nm { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag { flex-shrink: 0; font-size: .7rem; font-weight: 700; color: var(--muted); border: 1px solid var(--line-strong); border-radius: 999px; padding: 1px 7px; }
.tag.me { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.seg.pick { flex-wrap: nowrap; flex-shrink: 0; gap: 4px; margin-left: auto; }
.seg.pick button { min-height: 38px; padding: 6px 10px; font-size: .82rem; }
.lobby-wait { font-size: .9rem; margin: 16px 0 0; line-height: 1.45; }
.icon-btn { display: inline-flex; align-items: center; gap: 8px; }
.icon-btn svg { width: 18px; height: 18px; flex-shrink: 0; }

/* Micro / caméra coupés par l'hôte : pastilles barrées (cadres à table, lignes du salon) */
.host-muted { display: flex; gap: 3px; }
.hm {
  width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; flex-shrink: 0;
  background: var(--warn); color: var(--on-warn); box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
}
.hm svg { width: 13px; height: 13px; stroke-width: 2.4; }
.who .hm { width: 20px; height: 20px; box-shadow: none; }
.who .hm svg { width: 12px; height: 12px; }

/* ---------------------------------------------------------------- Menu de réglages */
.settings {
  position: fixed; top: 60px; right: 12px; z-index: 30;
  width: min(360px, calc(100vw - 24px)); max-height: calc(100vh - 72px); max-height: calc(100dvh - 72px); overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: 18px; box-shadow: var(--shadow);
  padding: 2px 16px 8px;
}
.settings:focus { outline: none; }
.settings-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 0; }
.settings-head h2 { margin: 0; font-size: 1.05rem; }
.set-group { border-top: 1px solid var(--line); padding: 10px 0 12px; }
.set-group h3 { margin: 0 0 6px; font-size: .8rem; font-weight: 700; color: var(--muted); }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 0; }
.set-row.column { flex-direction: column; align-items: stretch; gap: 6px; }
.set-label { font-size: .9rem; font-weight: 600; }
.set-row .seg { flex-wrap: nowrap; flex-shrink: 0; gap: 4px; }
.set-row .seg button { min-height: 38px; padding: 6px 12px; font-size: .85rem; }
.set-row.column .seg button { flex: 1 1 0; justify-content: center; padding: 6px 8px; }
#set-table-note { margin: 0 0 6px; }
.mod-list { list-style: none; margin: 0; padding: 0; }
.mod-list li { padding: 8px 0; border-bottom: 1px solid var(--line); }
.mod-list li:last-child { border-bottom: none; }
.mod-list li.empty { color: var(--muted); font-size: .85rem; }
.mod-name { display: flex; align-items: center; gap: 6px; font-weight: 700; margin-bottom: 6px; min-width: 0; }
.mod-name .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mod-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mod-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 40px; padding: 6px 8px; font-size: .8rem; }
.mod-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.mod-btn.cut { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }
.set-rules { padding-bottom: 4px; }
.set-rules > summary { list-style: none; cursor: pointer; font-weight: 700; font-size: .9rem; min-height: 36px; display: flex; align-items: center; justify-content: space-between; }
.set-rules > summary::-webkit-details-marker { display: none; }
.set-rules > summary::after {
  content: ''; width: 7px; height: 7px; margin-right: 6px; transform: rotate(45deg); transition: transform .2s ease;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
}
.set-rules[open] > summary::after { transform: rotate(-135deg); }
.set-rules .rules-recap { margin: 4px 0 0; font-size: .85rem; }

/* ---------------------------------------------------------------- Table */
#table { flex: 1; display: flex; flex-direction: column; min-height: 0; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.hud {
  display: grid; grid-template-columns: minmax(max-content, 1fr) minmax(0, 1.4fr) minmax(max-content, 1fr); align-items: center; gap: 8px;
  padding: 6px max(12px, env(safe-area-inset-right)) 6px max(12px, env(safe-area-inset-left));
  border-bottom: 1px solid var(--line); font-size: .85rem;
}
.hud .score { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.hud .score.end { align-items: flex-end; }
.score-line { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.hud .score b { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
/* Progression vers le score à atteindre */
.progress { width: min(110px, 100%); height: 4px; border-radius: 999px; background: var(--ring-track); overflow: hidden; }
.progress i { display: block; height: 100%; width: calc(var(--v, 0) * 100%); background: var(--team-0); border-radius: inherit; transition: width .4s ease; }
.score.end .progress i { margin-left: auto; background: var(--team-1); }
.dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.dot-0 { background: var(--team-0); }
.dot-1 { background: var(--team-1); }
.hud .meta { text-align: center; color: var(--muted); line-height: 1.3; min-width: 0; }
.hud .meta > div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hud .meta > div:last-child { display: flex; justify-content: center; gap: 4px; }
#round-no { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#litige { flex: none; }
#litige::before { content: '· '; }
.litige { color: var(--warn); }
.trick-totals b { color: var(--text); font-variant-numeric: tabular-nums; }

.felt {
  position: relative; box-shadow: inset 0 0 0 1px var(--line); flex: 1; min-height: 0; margin: 8px; border-radius: 22px;
  margin-left: max(8px, env(safe-area-inset-left)); margin-right: max(8px, env(safe-area-inset-right));
  background: radial-gradient(120% 80% at 50% 45%, var(--table-hi) 0%, var(--table) 70%);
  border: 1px solid var(--line);
  --edge: 10px;          /* marge entre le bord du tapis et les vidéos */
  --gap: 8px;            /* espace entre les vidéos et la colonne centrale */
  --name-h: 44px;        /* nom et nombre de cartes sous une vidéo (mesuré : 2 lignes + espacements) */
  --lt-vis: calc(var(--mini-w) * 1.42 * .56);   /* partie visible des cartes du dernier pli (coupées) */
  --lt-h: calc(var(--lt-vis) + 6px);             /* bloc « dernier pli » */
  --info-h: 22px;        /* points des plis de la donne (l'annonce est sous la vidéo du preneur) */
  --status-h: 26px;      /* ligne de statut */
  --tag-h: 30px;         /* annonce en pastille sous la vidéo du preneur (portrait) */
  --corner-h: max(calc(.8 * var(--hw) + 6px), 76px); /* coins du haut : dernier pli à gauche, points des plis à droite */
  --tag-space: 35px;     /* annonce sous la vidéo du partenaire */
  --cw-max: 200px;       /* carte du pli : la taille d'une carte de la main (--hw), si la place le permet */
  --video-max: clamp(170px, 30vmin, 380px);
  /* Repli pour les navigateurs sans unités de conteneur (iOS 15, Chrome / WebView < 105, Samsung Internet < 20) :
     tailles calculées sur la largeur de l'écran ; en hauteur, la réduction de la zone de jeu (fitPlayZone) suffit.
     Une propriété personnalisée invalide au calcul ne retombe sur rien (largeur 0) : d'où ce repli complet. */
  --lt-step: .42;        /* dernier pli : part visible de chaque carte (sauf la dernière) */
  --cw: clamp(36px, min(var(--hw), (100vw - 18px - 2 * (var(--edge) + var(--gap)) - 120px) / 2.05), var(--cw-max));
  /* Pli en tas : les quatre cartes se chevauchent au centre (voir .trick), 2,05 × 2,3 largeurs de carte. */
  --trick-w: calc(var(--cw) * 2.05);
  --trick-h: calc(var(--cw) * 2.3);
  --video-w: clamp(56px, min(var(--video-max), 24vw - 4px,
    (100vw - 18px - 2 * (var(--edge) + var(--gap)) - var(--trick-w)) / 2), var(--video-max));
  --vth: 60px;
  --vt: calc(var(--vth) * 4 / 3);
  --vb: var(--vt);
  --side-vh: calc(var(--video-w) * 4 / 3);
  --corner-w: calc((100vw - 18px - var(--vt)) / 2 - var(--edge) - var(--gap));
  --mini-w: clamp(30px, min(var(--hw), (var(--corner-w) - 6px) / (1 + 3 * var(--lt-step))), 120px);
}
/* Les tailles se calculent sur le tapis lui-même (unités cqw / cqh) quand le navigateur les connaît. */
@supports (width: 1cqw) {
  .felt {
    container-type: size;
    /* Carte du pli : aussi grande qu'une carte de la main, tant que le tas tient entre les deux adversaires (au moins
       60 px chacun) et, en hauteur, entre le partenaire et moi (vidéos d'au moins 48 px de haut). */
    --cw: clamp(36px, min(var(--hw), var(--cw-max),
      (100cqw - 2 * (var(--edge) + var(--gap)) - 120px) / 2.05,
      (100cqh - 2 * (var(--edge) + var(--gap)) - var(--status-h) - 2 * 48px - 8px) / 2.3), var(--cw-max));
    /* Adversaires (côtés) : la place qui reste de chaque côté du pli ; en hauteur, sous le dernier pli. */
    --video-w: clamp(56px, min(var(--video-max), 30cqw,
      (100cqw - 2 * (var(--edge) + var(--gap)) - var(--trick-w)) / 2,
      (100cqh - 2 * (var(--edge) + var(--gap)) - 2 * var(--corner-h) - var(--name-h)) * .75), var(--video-max));
    /* Adversaires : cadres plus hauts que larges (jusqu'au 9/16), dans la hauteur libre sous les coins du haut. */
    --side-vh: clamp(calc(var(--video-w) * 4 / 3),
      100cqh - 2 * (var(--edge) + var(--gap)) - 2 * var(--corner-h) - var(--name-h), calc(var(--video-w) * 16 / 9));
    /* Partenaire (haut) et moi (bas) : cadres plus larges que hauts, prénom incrusté ; la hauteur qui reste au-dessus
       et au-dessous du pli, la largeur entre les deux adversaires. */
    --vth: clamp(40px, min((100cqh - 2 * (var(--edge) + var(--gap)) - var(--status-h) - var(--trick-h) - var(--tag-space) - 8px) / 2,
      (100cqw - 2 * (var(--edge) + var(--video-w) + var(--gap))) * .75, var(--video-max) * .75), 400px);
    --vt: calc(var(--vth) * 4 / 3);
    /* Moi (bas) : les coins du bas sont libres, le cadre s'élargit jusqu'au 16/9 entre les deux adversaires. */
    --vb: min(calc(var(--vth) * 16 / 9), (100cqw - 2 * (var(--edge) + var(--video-w) + var(--gap))) * .9);
    /* Coins du haut, de part et d'autre du partenaire : dernier pli à gauche, points des plis à droite. */
    --corner-w: calc((100cqw - var(--vt)) / 2 - var(--edge) - var(--gap));
    --mini-w: clamp(30px, min(var(--hw), (var(--corner-w) - 6px) / (1 + 3 * var(--lt-step))), 120px);
  }
}
/* Comme autour d'une vraie table : partenaire en face (en haut), adversaires à mi-hauteur sur les côtés, moi en bas. */
.seat { position: absolute; width: var(--video-w); display: flex; flex-direction: column; align-items: center; gap: 4px; }
.seat[data-pos="top"] { --video-w: var(--vt); --seat-h: var(--vth); left: calc(50% - var(--vt) / 2); }
.seat[data-pos="bottom"] { --video-w: var(--vb); --seat-h: var(--vth); left: calc(50% - var(--vb) / 2); }
.seat[data-pos="top"] { top: var(--edge); }
.seat[data-pos="bottom"] { bottom: var(--edge); }
.seat[data-pos="left"], .seat[data-pos="right"] { top: calc(50% - (var(--side-vh) + var(--name-h)) / 2); }
html[data-layout="portrait"] .seat:is([data-pos="left"], [data-pos="right"]) .video { aspect-ratio: auto; height: var(--side-vh); }
.seat[data-pos="left"] { left: var(--edge); }
.seat[data-pos="right"] { right: var(--edge); }
.seat { z-index: 1; }
/* Annonces dévoilées : une ligne de plus sous chaque vidéo, la place est réservée pour toutes. */
.felt.has-decl { --name-h: 62px; }
.frame { position: relative; width: 100%; }
.video {
  width: 100%; aspect-ratio: 3 / 4; border-radius: 14px; overflow: hidden; position: relative;
  background: var(--surface); border: 2px solid var(--line-strong);
  display: grid; place-items: center; font-size: 1.6rem; font-weight: 700; color: var(--muted);
  transition: border-color .2s ease;
}
.video video { width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.video.speaking { border-color: var(--speaking); }
.video.turn { border-color: transparent; }
.video.offline { opacity: .45; }
/* Robot : pictogramme sobre à la place de la vidéo ; sans décompte, son tour est marqué par le liseré. */
.video.bot .avatar { display: block; width: 44%; color: var(--muted); }
.video.bot .avatar svg { width: 100%; height: auto; stroke-width: 1.6; }
.video.bot.turn { border-color: var(--accent); }
/* Coin haut-gauche du cadre : badge « robot » et pastille « D » du donneur, côte à côte
   (la ligne du nom garde ainsi toute la largeur de la vidéo pour le prénom). */
.seat .frame .frame-tags { position: absolute; left: -7px; top: -7px; z-index: 1; display: flex; align-items: center; gap: 3px; }
.seat .frame .bot-tag {
  padding: 1px 7px; border-radius: 999px;
  background: var(--surface-2); color: var(--muted); border: 1px solid var(--line-strong);
  font-size: max(10px, .62rem); font-weight: 800; letter-spacing: .02em;
}
/* Donneur : grand « D » dans le coin bas droit de sa vidéo, lisible sur n'importe quelle image. */
.seat .frame .dealer-mark {
  position: absolute; right: 5px; bottom: 5px; z-index: 3; pointer-events: none;
  width: clamp(20px, min(calc(var(--video-w) * .2), calc(var(--seat-h, 999px) * .42)), 34px); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center; background: var(--accent); color: var(--on-accent);
  border: 2px solid #fff; box-shadow: 0 1px 6px rgba(0, 0, 0, .55);
  font-family: var(--card-font); font-size: clamp(11px, min(calc(var(--video-w) * .11), calc(var(--seat-h, 999px) * .2)), 19px); font-weight: 800; line-height: 1;
}
.seat .frame .host-muted { position: absolute; left: -6px; top: -6px; z-index: 2; }
/* Un prénom long peut déborder de la vidéo de la moitié de l'espace qui la sépare de la colonne centrale,
   de chaque côté (centré, il reste dans le tapis et loin du pli). */
.seat .name { font-size: .8rem; line-height: 1.25; display: flex; gap: 5px; align-items: center; max-width: calc(100% + var(--gap)); }
.seat .name span.nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seat .cards-left { font-size: max(11px, .7rem); line-height: 1.2; color: var(--muted); }
.seat .cards-left:empty { display: none; }
.bubble {
  position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%);
  background: var(--glass); color: var(--text); border: 1px solid var(--line-strong);
  padding: 3px 9px; border-radius: 999px; font-size: .78rem; font-weight: 700; white-space: nowrap;
}
.ring {
  position: absolute; inset: -5px; border-radius: 18px; padding: 3px; pointer-events: none;
  background: conic-gradient(var(--ring, var(--accent)) calc(var(--p, 1) * 1turn), var(--ring-track) 0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.ring.low { --ring: var(--warn); }
.secs {
  position: absolute; top: -9px; right: -9px; min-width: 24px; height: 24px; border-radius: 999px; padding: 0 6px;
  background: var(--accent); color: var(--on-accent); font-size: .78rem; font-weight: 800;
  display: grid; place-items: center; font-variant-numeric: tabular-nums;
  /* Recréée toutes les 100 ms : si elle recevait l'appui, elle quitterait le DOM avant le relâchement et le clic
     serait perdu (bouton « Passe », cartes voisines). Purement indicative, elle laisse passer le pointeur. */
  pointer-events: none;
}
.secs.low { background: var(--warn); color: var(--on-warn); }
.decl-badges { display: flex; flex-wrap: nowrap; gap: 3px; justify-content: center; max-width: 100%; overflow: hidden; }
.decl-badges:empty { display: none; }
.decl { white-space: nowrap; }
.decl { font-size: max(10.5px, .66rem); background: var(--accent-soft); color: var(--accent); border-radius: 999px; padding: 1px 7px; font-weight: 700; }
.decl.off { opacity: .5; text-decoration: line-through; }

/* Points d'un pli, au-dessus du cadre du gagnant pendant le ramassage */
.gain {
  position: absolute; left: 50%; top: 46%; z-index: 3; pointer-events: none;
  padding: 3px 11px; border-radius: 999px; background: var(--accent); color: var(--on-accent);
  font-size: 1rem; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap;
  box-shadow: var(--shadow); transform: translate(-50%, -50%);
  animation: gain 2.6s ease forwards;
}
@keyframes gain {
  0% { opacity: 0; transform: translate(-50%, -20%) scale(.85); }
  10% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  78% { opacity: 1; transform: translate(-50%, -50%); }
  100% { opacity: 0; transform: translate(-50%, -85%); }
}

/* Dernier pli (portrait et paysage) : cartes du style de la main, aussi grandes que la place le permet, serrées comme
   elle (55 % de chaque carte visible) et coupées par le bas, dans l'ordre où elles ont été jouées. La gagnante est
   entourée et porte les points du pli, sur sa propre partie visible. En haut au milieu (portrait), dans le panneau du
   haut à droite (paysage). Toujours visible pendant le jeu (cases vides avant le premier pli). */
.last-trick { flex: none; display: flex; flex-direction: column; align-items: center; max-width: 100%; }
.lt-row { display: flex; height: var(--lt-vis, 48px); overflow: hidden; padding: 3px 3px 0; margin: -3px -3px 0; }
.lt-cell { position: relative; flex: none; width: var(--mini-w); height: calc(var(--mini-w) * 1.42); margin-left: calc(var(--mini-w) * (var(--lt-step, .55) - 1)); }
.lt-cell:first-child { margin-left: 0; }
.lt-cell:empty { border: 1.5px dashed var(--line-strong); border-radius: calc(var(--mini-w) * .13); background: var(--glass); }
.lt-cell .card { --w: var(--mini-w); }
.lt-cell .card.won { box-shadow: var(--card-edge), 0 0 0 3px var(--accent); }
.lt-cell .won-mark {
  position: absolute; z-index: 1; right: calc(var(--mini-w) * (1 - var(--lt-step, .55)) + 2px);
  bottom: calc(var(--mini-w) * 1.42 - var(--lt-vis, 48px) + 3px);
  min-width: max(16px, calc(var(--mini-w) * .22)); height: max(16px, calc(var(--mini-w) * .22)); border-radius: 999px;
  background: var(--accent); color: var(--on-accent); display: grid; place-items: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .4);
}
.lt-cell .won-mark svg { width: 66%; height: 66%; }
.lt-cell .won-mark.pts { padding: 0 .35em; font-size: max(10px, calc(var(--mini-w) * .15)); font-weight: 800; font-variant-numeric: tabular-nums; }
.lt-caption { display: flex; align-items: center; gap: 5px; font-size: max(10.5px, .68rem); line-height: 1.2; white-space: nowrap; max-width: 100%; }
.lt-title { color: var(--muted); }
.lt-winner { display: flex; align-items: center; gap: 4px; font-weight: 700; min-width: 0; }
.lt-winner:empty { display: none; }
.lt-winner span.nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lt-points { color: var(--accent); font-weight: 800; font-variant-numeric: tabular-nums; flex-shrink: 0; }
.seat .frame .trick-mark {
  position: absolute; left: -7px; bottom: -7px; z-index: 1; padding: 1px 6px; border-radius: 999px;
  background: var(--accent); color: var(--on-accent); font-size: max(10px, .62rem); font-weight: 800;
}

/* Colonne centrale, entre les deux colonnes de vidéos. Ses blocs sont empilés (flex), donc jamais superposés. */
.center {
  position: absolute; z-index: 2;
  top: calc(var(--edge) + var(--vth) + var(--tag-space) + var(--gap)); bottom: calc(var(--edge) + var(--vth) + var(--gap));
  left: calc(var(--edge) + var(--video-w) + var(--gap)); right: calc(var(--edge) + var(--video-w) + var(--gap));
  display: flex; flex-direction: column; align-items: center; gap: 6px; pointer-events: none;
}
.center > * { pointer-events: auto; }
/* Zone de jeu : prend la hauteur restante ; si un écran est trop petit, son contenu est réduit (voir fitPlayZone). */
.play-zone { flex: 1 1 auto; min-height: 0; width: 100%; position: relative; }
/* Centré en position absolue : même plus haut que la zone, il reste centré, et la réduction (--fit, voir fitPlayZone)
   le fait tenir exactement dans la zone, sans déborder sur le dernier pli ni sur le contrat. */
.play-inner {
  position: absolute; left: 50%; top: 50%; width: max-content; max-width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  transform: translate(-50%, -50%) scale(var(--fit, 1)); transform-origin: center center;
}
#status { font-size: .9rem; color: var(--muted); text-align: center; min-height: var(--status-h); display: flex; align-items: center; justify-content: center; text-wrap: balance; }
#status.mine { color: var(--accent); font-weight: 700; }
/* Une notification (« Pli pour Bob », « Belote ! »…) prend la place du statut quelques secondes : rien ne flotte sur le pli. */
#status.notice { color: var(--text); font-weight: 600; background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: 999px; padding: 2px 12px; }
.trick { position: relative; flex: none; }
.trick .card { --w: var(--cw); }
.slot { position: absolute; }
/* Bas de colonne : contrat et points des plis de la donne */
.info-zone { flex: none; min-height: var(--info-h); max-width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 2px; text-align: center; }
.contract { font-size: .85rem; color: var(--muted); text-wrap: balance; }
.contract b { color: var(--text); }
.trick-totals { font-size: .8rem; color: var(--muted); grid-template-columns: auto auto; column-gap: 8px; row-gap: 1px; text-align: left; }
/* Portrait : points des plis bien lisibles dans le coin haut droit. */
.felt > .info-zone .trick-totals { font-size: 1.05rem; column-gap: 10px; line-height: 1.2; }
.felt > .info-zone .trick-totals b { font-size: 1.2em; font-family: var(--card-font); }
.felt > .info-zone .trick-totals .tt-title { font-weight: 700; }
.trick-totals:not([hidden]) { display: inline-grid; }
.trick-totals .tt-title { grid-column: 1 / -1; text-align: center; }
.trick-totals b { text-align: right; }
.trick-totals b { color: var(--text); font-variant-numeric: tabular-nums; }
.suit-red { color: var(--card-red); }
.turned { display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: .85rem; color: var(--muted); text-align: center; }
/* À mon tour d'enchérir : la colonne s'élargit à tout le tapis pour le panneau (il passe au-dessus des vidéos si besoin). */
.felt.bid-mode .center { left: var(--edge); right: var(--edge); top: var(--edge); bottom: var(--edge); z-index: 3; }
/* Portrait : le partenaire et moi en cadres larges (4/3), prénom incrusté en bas de l'image, nombre de cartes en haut
   à droite ; l'annonce et les annonces dévoilées à côté du cadre (dessous, il y a le pli). */
html[data-layout="portrait"] .seat[data-pos="top"] .video, html[data-layout="portrait"] .seat[data-pos="bottom"] .video { aspect-ratio: auto; height: var(--vth); }
html[data-layout="portrait"] .seat[data-pos="top"] .name, html[data-layout="portrait"] .seat[data-pos="bottom"] .name {
  position: absolute; left: 2px; right: 2px; top: calc(var(--vth) - 2px); transform: translateY(-100%); z-index: 2;
  justify-content: center; max-width: none; padding: 12px 6px 4px; font-size: .78rem; color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .7);
  background: linear-gradient(transparent, rgba(0, 0, 0, .55)); border-radius: 0 0 12px 12px; pointer-events: none;
}
html[data-layout="portrait"] .seat[data-pos="top"] .cards-left, html[data-layout="portrait"] .seat[data-pos="bottom"] .cards-left {
  position: absolute; right: 6px; top: 6px; z-index: 2; padding: 0 7px; border-radius: 999px; background: rgba(0, 0, 0, .45); color: #fff;
}
html[data-layout="portrait"] .seat[data-pos="top"] .contract-tag, html[data-layout="portrait"] .seat[data-pos="bottom"] .contract-tag,
html[data-layout="portrait"] .seat[data-pos="top"] .decl-badges, html[data-layout="portrait"] .seat[data-pos="bottom"] .decl-badges {
  position: absolute; left: calc(100% + 6px); z-index: 3;
}
html[data-layout="portrait"] .seat[data-pos="bottom"] .contract-tag { bottom: 0; }
html[data-layout="portrait"] .seat[data-pos="top"] .contract-tag { left: 50%; top: calc(var(--vth) + 5px); transform: translateX(-50%); }
html[data-layout="portrait"] .seat[data-pos="top"] .decl-badges, html[data-layout="portrait"] .seat[data-pos="bottom"] .decl-badges { top: 0; flex-direction: column; align-items: flex-start; }
html[data-layout="portrait"] .seat:is([data-pos="top"], [data-pos="bottom"]):has(.dealer-mark) .name { padding-right: 32px; }
/* Cadres larges : le nombre de cartes à gauche de l'étiquette « robot » ne la chevauche pas (il passe en bas à gauche). */
/* Cadres larges (souvent bas sur téléphone) : pas de « N cartes », le prénom passe avant (tout le monde a le même
   nombre de cartes, à une près). */
html[data-layout="portrait"] .seat:is([data-pos="top"], [data-pos="bottom"]) .cards-left { display: none; }
/* Portrait : dernier pli dans le coin haut gauche, points des plis dans le coin haut droit. */
.felt > .last-trick { position: absolute; z-index: 2; left: var(--edge); top: var(--edge); width: var(--corner-w); align-items: flex-start; }
.felt > .info-zone {
  position: absolute; z-index: 2; right: var(--edge); top: var(--edge); width: var(--corner-w); min-height: 0;
  align-items: flex-end; justify-content: flex-start; text-align: right;
}
.felt.bid-mode .info-zone { display: none; }

/* Panneau d'enchères au centre */
.bidding {
  width: min(330px, calc(100vw - 16px - 2 * var(--edge)));  /* repli sans unités de conteneur, cqw sous @supports */
  background: var(--glass); backdrop-filter: blur(6px);
  border: 1px solid var(--line-strong); border-radius: 18px; padding: 12px; display: flex; flex-direction: column; gap: 10px;
}
@supports (width: 1cqw) {
  .bidding { width: min(330px, calc(100cqw - 2 * var(--edge))); }
}

.bid-title { font-size: .8rem; color: var(--muted); text-align: center; }
.bid-best { font-size: .85rem; color: var(--muted); text-align: center; }
.bid-best:empty { display: none; }
.bid-best b { color: var(--text); }
.bid-values { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.bid-suits { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.bid-values button, .bid-suits button { padding: 0; min-height: 40px; background: var(--surface-2); font-variant-numeric: tabular-nums; }
.bid-values:empty, .bid-suits:empty, .bid-take:empty { display: none; }
.bid-suits button { font-size: 1.35rem; color: var(--suit-on-surface); }
.bid-suits button.red { color: var(--red-on-surface); }
.bid-values button.selected, .bid-suits button.selected { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.bid-take { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.bid-take button { flex: 1 1 auto; }
.bid-take .red { color: var(--card-red); }
.bid-actions { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 6px; }
/* Mon décompte, repris dans « Passe » : c'est l'action que le serveur jouera pour moi à l'échéance, et sur téléphone
   le panneau recouvre souvent mon cadre (donc ses secondes) au moment même où je dois décider. */
#bid-pass > .secs { position: static; display: inline-grid; vertical-align: middle; margin: -4px 0 -4px 6px; pointer-events: none; }
#bid-pass { white-space: nowrap; }
.bid-actions button { padding-left: 8px; padding-right: 8px; } /* « Passe » et ses secondes tiennent sur une ligne */

/* Cartes : un seul très grand symbole au centre (2/3 de la largeur, la moitié de la hauteur),
   valeur et petit symbole dans deux coins opposés. --w règle la taille de toute la carte. */
.card {
  --w: 52px;
  width: var(--w); height: calc(var(--w) * 1.42); border-radius: calc(var(--w) * .13);
  background: var(--card); color: var(--card-ink);
  box-shadow: var(--card-edge), var(--card-shadow);
  position: relative; user-select: none; flex-shrink: 0;
  font-family: var(--card-font); font-weight: var(--card-weight);
}
.card.red { color: var(--card-red); }
.card .idx {
  position: absolute; left: 7%; top: 4.5%; display: flex; flex-direction: column; align-items: center;
  font-size: calc(var(--w) * .25); line-height: 1; letter-spacing: -.04em;
}
.card .idx-b { left: auto; top: auto; right: 7%; bottom: 4.5%; transform: rotate(180deg); }
.card .pip { width: calc(var(--w) * .145); height: calc(var(--w) * .145); margin-top: calc(var(--w) * .025); fill: currentColor; }
.card .mid {
  position: absolute; left: 50%; top: 50%; width: 66%; height: auto; aspect-ratio: 1;
  transform: translate(-50%, -50%); fill: currentColor;
}
/* Atout posé au centre : liseré fin ; dans la main : contour épais (plus bas). */
.trick .card.trump { box-shadow: var(--card-edge), 0 0 0 2px var(--accent), var(--card-shadow); }
/* Mini-cartes du dernier pli : index sur une ligne pour laisser toute la place au symbole. */
.card.mini { --w: var(--mini-w, 26px); box-shadow: var(--card-edge); }
.card.mini .idx { flex-direction: row; gap: 1px; left: 2px; top: 2px; font-size: 8.5px; letter-spacing: -.06em; }
.card.mini .pip { width: 6px; height: 6px; margin: 0; }
.card.mini .idx-b { display: none; }
.card.mini .mid { width: 64%; top: 56%; }
.card.mini.won { box-shadow: var(--card-edge), 0 0 0 2px var(--accent); }

.my-decl { text-align: center; font-size: .8rem; color: var(--accent); padding: 0 12px; }
/* Carte de la main, définie sur toute la table : les cartes du pli prennent la même taille (--cw). */
#table {
  --n: 8; /* largeur calculée pour une main pleine : la taille des cartes reste la même pendant toute la donne */
  /* vh par défaut (Chrome < 108, Samsung Internet ≤ 20) ; dvh, qui suit la barre d'adresse, quand il est connu. */
  --hw: clamp(38px, min((100vw - 16px - env(safe-area-inset-left) - env(safe-area-inset-right)) / (0.68 * (var(--n) - 1) + 1), 10.5vh), clamp(68px, 13vmin, 140px));
}
.hand {
  display: flex; justify-content: center; padding: 10px max(8px, env(safe-area-inset-right)) 4px max(8px, env(safe-area-inset-left));
  min-height: calc(var(--hw) * 1.42 + 14px);
}
/* Main superposée : le coin haut-gauche reste lisible, le grand symbole peut passer sous la carte suivante. */
/* Largeur d'une carte : les n cartes se chevauchent d'un tiers et remplissent la largeur de l'écran,
   entre 38 et 68 px, et pas plus de 10,5 % de la hauteur (petits écrans en hauteur). */
.hand .card {
  --w: var(--hw);
  flex: none; cursor: pointer; margin-left: calc(var(--w) * -0.32); transition: transform .15s ease;
}
.hand .card:first-child { margin-left: 0; }
@supports (height: 1dvh) {
  #table { --hw: clamp(38px, min((100vw - 16px - env(safe-area-inset-left) - env(safe-area-inset-right)) / (0.68 * (var(--n) - 1) + 1), 10.5dvh), clamp(68px, 13vmin, 140px)); }
}
.hand .card.trump { box-shadow: inset 0 0 0 3px var(--trump-ring), inset 0 0 0 4px var(--trump-edge), var(--card-shadow); }
.hand .card.playable { transform: translateY(-8px); }
@media (hover: hover) { .hand .card.playable:hover { transform: translateY(-14px); } }
.hand .card.blocked { filter: saturate(.5) brightness(.65); cursor: not-allowed; }
/* Thème jour : la carte bloquée s'estompe vers le fond par un voile posé dessus, et reste opaque. Une opacité
   laissait voir, au travers, l'index retourné et le contour d'atout de la carte qu'elle recouvre. */
:root[data-theme="light"] .hand .card.blocked { filter: none; }
:root[data-theme="light"] .hand .card.blocked::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: rgba(215, 223, 226, .5); /* --bg du thème jour, à moitié : l'aspect de l'ancienne opacité .5 */
}

/* Commandes caméra / micro */
.controls {
  display: flex; gap: 8px; align-items: center; justify-content: flex-start; min-width: 0;
  padding: 6px max(12px, env(safe-area-inset-right)) max(10px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
}
.media-btn {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px clamp(10px, 3vw, 14px); border-radius: 999px;
  white-space: nowrap; flex: 0 1 auto; min-width: 0;
}
.media-btn svg { width: 20px; height: 20px; flex-shrink: 0; }
.media-btn .lbl { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; min-width: 0; overflow: hidden; }
.media-btn .lbl small { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
#quit { flex: none; margin-left: auto; }
.media-btn .lbl small { font-size: .68rem; font-weight: 700; }
.media-btn[aria-pressed="false"] { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }
/* Coupé par l'hôte : inutilisable, mais lisible (pas grisé). */
.media-btn.host-cut:disabled { opacity: 1; cursor: not-allowed; border-style: dashed; }
#video-status { flex: 1 1 0; min-width: 0; font-size: .75rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.overlay { position: fixed; inset: 0; background: var(--scrim); display: grid; place-items: center; z-index: 10; padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom)); }
.card-panel { background: var(--surface); border: 1px solid var(--line-strong); border-radius: 20px; padding: 22px; width: min(440px, 100%); box-shadow: var(--shadow); max-height: 100%; overflow-y: auto; }
.card-panel h2 { margin: 0 0 10px; font-size: 1.3rem; }
.card-panel table { width: 100%; border-collapse: collapse; margin-bottom: 16px; font-size: .9rem; }
.card-panel td { padding: 7px 2px; border-bottom: 1px solid var(--line); }
.card-panel td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.card-panel button { width: 100%; }

.toasts { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 76px); left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: 6px; z-index: 5; pointer-events: none; width: max-content; max-width: calc(100% - 32px); }
.toast { background: var(--surface-2); color: var(--text); border: 1px solid var(--line-strong); padding: 8px 14px; border-radius: 999px; font-size: .85rem; box-shadow: var(--shadow); animation: fade 3s forwards; text-align: center; }
.confirm {
  border: 1px solid var(--line-strong); border-radius: 20px; background: var(--surface); color: var(--text);
  padding: 22px; width: min(380px, calc(100% - 32px)); box-shadow: var(--shadow);
}
.confirm::backdrop { background: var(--scrim); }
.confirm h2 { margin: 0 0 8px; font-size: 1.2rem; }
.confirm p { margin: 0 0 18px; line-height: 1.45; font-size: .92rem; }
.confirm-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
@keyframes fade { 0% { opacity: 0; transform: translateY(-6px); } 10%, 80% { opacity: 1; transform: none; } 100% { opacity: 0; } }

/* ---------------------------------------------------------------- Installation de l'application (accueil) */
/* Bouton « Installer » de l'en-tête (accueil) et marche à suivre iPhone qu'il déplie. */
.bar-pill {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 12px; border-radius: 999px;
  border: 1px solid var(--accent); background: var(--accent-soft); color: var(--accent); font-size: .85rem; white-space: nowrap; flex-shrink: 0;
  position: relative;
}
.bar-pill svg { width: 17px; height: 17px; flex-shrink: 0; }
.bar-pill[aria-expanded="true"] { background: var(--accent); color: var(--on-accent); }
.install-steps { margin: 0 0 14px; padding: 12px 14px; border: 1px solid var(--accent); background: var(--accent-soft); border-radius: var(--radius); font-size: .86rem; line-height: 1.5; }
.install-steps ol { margin: 6px 0 0; padding-left: 20px; }
.install-steps li + li { margin-top: 3px; }
.share-glyph {
  display: inline-block; width: 15px; height: 17px; vertical-align: -3px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8'/%3E%3Cpolyline points='16 6 12 2 8 6'/%3E%3Cline x1='12' x2='12' y1='2' y2='15'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8'/%3E%3Cpolyline points='16 6 12 2 8 6'/%3E%3Cline x1='12' x2='12' y1='2' y2='15'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Téléphone tenu en paysage : la table n'y tient pas lisiblement, on invite à le tourner. */
.rotate-hint { display: none; }
html:has(input:focus) .rotate-hint { display: none !important; }
@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) and (min-aspect-ratio: 5 / 3) {
  html.at-table .rotate-hint {
    display: flex; position: fixed; inset: 0; z-index: 50; flex-direction: column; align-items: center; justify-content: center;
    gap: 14px; padding: 24px; text-align: center; background: var(--bg); color: var(--text); font-weight: 600;
  }
  .rotate-hint svg { width: 52px; height: 52px; color: var(--accent); transform: rotate(90deg); }
}

/* ---------------------------------------------------------------- Style classique : matières de la table de café */
:root[data-style="classique"] .brand,
:root[data-style="classique"] .panel h1,
:root[data-style="classique"] .big-code,
:root[data-style="classique"] .card-panel h2,
:root[data-style="classique"] .confirm h2,
:root[data-style="classique"] .settings-head h2,
:root[data-style="classique"] .hud .score b,
:root[data-style="classique"] .trick-totals b,
:root[data-style="classique"] .secs,
:root[data-style="classique"] .gain,
:root[data-style="classique"] .lt-points,
:root[data-style="classique"] .seat .dealer-mark { font-family: var(--serif); }
:root[data-style="classique"] .brand { font-weight: 700; letter-spacing: 0; }
:root[data-style="classique"] .brand-mark { box-shadow: 0 0 0 1px var(--brass); }
:root[data-style="classique"] .hud .score b { font-size: 1.25rem; font-weight: 700; }
:root[data-style="classique"] .big-code { font-weight: 700; letter-spacing: .28em; }
:root[data-style="classique"] .seat .dealer-mark { background: var(--card); color: var(--card-ink); font-weight: 700; }

/* Le tapis : feutre grainé éclairé par la lampe, rebord en noyer, liseré laiton entre les deux. */
:root[data-style="classique"] .felt,
:root[data-style="classique"] #lobby.panel {
  border: 11px solid transparent;
  background:
    var(--felt-grain) padding-box,
    var(--felt) padding-box,
    var(--wood-grain) border-box,
    var(--wood) border-box;
  background-blend-mode: overlay, normal, overlay, normal;
  box-shadow:
    inset 0 0 0 1.5px var(--brass),
    inset 0 0 0 3px rgba(38, 25, 4, .5),
    inset 0 3px 44px rgba(0, 0, 0, .42),
    0 12px 28px rgba(0, 0, 0, .55);
}
:root[data-style="classique"] .felt { border-radius: 26px; margin: 8px 6px; border-width: clamp(8px, 2.2vw, 11px); --edge: 7px; }
/* Filet imprimé du tapis, juste à l'intérieur du liseré */
:root[data-style="classique"] .felt::before {
  content: ''; position: absolute; inset: 5px; border-radius: 12px; pointer-events: none;
  border: 1px solid rgba(214, 186, 112, .2);
}
:root[data-style="classique"] #lobby.panel { border-radius: 26px; padding: 24px 20px; }
:root[data-style="classique"] #lobby .team-block { background: rgba(6, 18, 11, .28); }
:root[data-style="classique"] #status,
:root[data-style="classique"] .contract { color: var(--text); }
:root[data-style="classique"] #status.mine { color: #e7c75a; }
:root[data-style="classique"] .video { border-color: rgba(201, 162, 39, .45); }
:root[data-style="classique"] .video.speaking { border-color: var(--speaking); }
:root[data-style="classique"] .video.turn { border-color: transparent; }
:root[data-style="classique"] .video.bot.turn { border-color: var(--accent); }
:root[data-style="classique"] .gain { font-weight: 700; font-size: 1.05rem; }
/* Couleurs rouges lisibles hors des cartes : rose clair sur le feutre, carmin sombre sur le laiton. */
:root[data-style="classique"] .suit-red { color: var(--red-on-surface); }
:root[data-style="classique"] .bid-take button.primary .red { color: #7a0c20; }

/* Téléphone en portrait : vidéos plus compactes, centre calé entre les rangées de vidéos. */
@media (max-width: 600px) {
  #home.panel {
    width: auto; margin: 0; border: 0; border-radius: 0; background: none;
    padding: 14px max(16px, env(safe-area-inset-right)) max(14px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
    flex: 1 0 auto; display: flex; flex-direction: column;
  }
  #home.panel { padding-bottom: 0; }
  #home .home-hero { display: none; }
  #home label.field { margin-top: 0; }
  /* Créer / rejoindre : toujours à l'écran, sous le pouce, même quand une section ouverte fait défiler la page. */
  #home .home-actions {
    margin-top: auto; position: sticky; bottom: 0; z-index: 2; background: var(--bg);
    padding: 12px 0 max(12px, env(safe-area-inset-bottom)); box-shadow: 0 -1px 0 var(--line);
  }
  #home .home-actions .or { margin-top: 8px; }
  html:not(.at-table) { scroll-padding-bottom: calc(var(--actions-h, 150px) + 12px); }
  .bar { padding-left: max(12px, env(safe-area-inset-left)); padding-right: max(12px, env(safe-area-inset-right)); gap: 8px; }
  .bar-right { gap: 6px; }
  .hud { padding: 4px max(10px, env(safe-area-inset-right)) 4px max(10px, env(safe-area-inset-left)); }
  /* Litige sur sa propre ligne : à sa suite, la ligne de la donne était coupée (« Donne 5 · 10… », objectif illisible). */
  .hud .meta > div:last-child { flex-wrap: wrap; row-gap: 0; }
  #litige { flex-basis: 100%; text-transform: capitalize; }
  #litige::before { content: none; }
  .bidding { padding: 10px; gap: 8px; }
  .bid-values button, .bid-suits button { min-height: 38px; }
  .bid-actions button { min-height: 42px; padding: 8px 6px; }
  .media-btn .lbl { font-size: .9rem; }
}
/* Très petit écran : l'icône suffit dans l'en-tête ; le champ « autre » du score passe sous les valeurs. */
@media (max-width: 359px) {
  .brand-name, .brand em:not(.brand-video) { display: none; }
  .seg-line { flex-wrap: wrap; }
  .seg-line .seg { flex-basis: 100%; }
  #target-custom { flex-basis: 100%; }
}
@media (max-width: 480px) {
  .brand em:not(.brand-video) { display: none; }
}
/* v3 : plus de tailles fixes au-delà de 900 px ; tout suit l'espace disponible (voir layout.js). */
/* Mode contrasté (Windows) : le choix retenu ne tient pas qu'à la couleur. */
@media (forced-colors: active) {
  .seg button.on { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
}
/* Thème jour : pas d'assombrissement automatique imposé par le navigateur (Chrome, Samsung Internet). */
:root[data-theme="light"] { color-scheme: only light; }

/* Écran court (Android 360×640 dans Chrome, iPhone SE, navigateurs intégrés) : barres resserrées, le tapis garde
   la hauteur nécessaire au pli. */
@media (max-height: 640px) {
  .bar { padding-top: max(4px, env(safe-area-inset-top)); padding-bottom: 4px; }
  .bar-btn { min-height: 36px; width: 36px; }
  .bar-pill { min-height: 36px; }
  .hud { padding-top: 2px; padding-bottom: 2px; }
  .felt { margin-top: 6px; margin-bottom: 4px; }
  .hand { padding-top: 8px; }
  .controls { padding-top: 2px; padding-bottom: max(6px, env(safe-area-inset-bottom)); }
  .media-btn, #quit { min-height: 40px; }
}
/* Tapis très étroit (grande police ou zoom d'affichage Android) : marges internes réduites. */
@media (max-width: 340px) {
  .felt { --edge: 6px; --gap: 5px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation-duration: .01ms !important; }
  /* Sans animation, ces messages restent simplement affichés le temps prévu. */
  .gain, .toast { animation-name: none !important; }
}

/* ---------------------------------------------------------------- Comptes, abonnement, invitations */
.account-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 10px;
  margin-top: 12px; padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  font-size: .82rem; color: var(--muted); line-height: 1.4;
}
.account-bar b { color: var(--accent); }
.account-bar .acc-mail { color: var(--text); font-weight: 600; overflow-wrap: anywhere; }
.account-bar button.link { padding: 4px 0; min-height: 32px; color: var(--accent); font-weight: 700; }
#account-btn.on { color: var(--accent); border-color: var(--accent); }
.account-dlg { position: relative; width: min(400px, calc(100% - 32px)); max-height: calc(100dvh - 32px); overflow-y: auto; }
.account-dlg h2 { padding-right: 44px; }
.dlg-close { position: absolute; top: 12px; right: 12px; }
.dlg-form { display: flex; flex-direction: column; gap: 10px; }
.dlg-form label.field { margin: 0; }
.dlg-form button { width: 100%; }
#login-digits { font-size: 22px; letter-spacing: .4em; text-align: center; font-variant-numeric: tabular-nums; }
.account-email { margin: 0; font-weight: 700; overflow-wrap: anywhere; }
.account-plan { margin: 0; color: var(--muted); line-height: 1.45; }
.dlg-links { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 4px; }
.dlg-links button.link { width: auto; }
button.link.danger-link { color: var(--warn); }
.account-dlg .error:empty { display: none; }
.invite-banner {
  display: flex; flex-direction: column; gap: 2px; margin: 0 0 12px; padding: 12px 14px;
  border: 1px solid var(--accent); background: var(--accent-soft); border-radius: var(--radius); font-size: .9rem;
}
.invite-banner b { letter-spacing: .12em; color: var(--accent); }
/* Ouvert par une invitation : seulement le prénom et « Rejoindre ». */
html.invited #config, html.invited #create, html.invited .home-hero, html.invited .home-actions .or { display: none; }
html.invited .row.join { margin-top: 0; }
html.invited .row.join #join { flex: 1; }
#invite-own { display: block; margin: 6px auto 0; }
.invite-btn { width: 100%; margin: 0 0 18px; display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 48px; font-size: 1.02rem; }
.share-icon { display: inline-grid; width: 22px; height: 22px; }
.share-icon svg { width: 100%; height: 100%; }
/* Lien de la partie, lisible ; le toucher le copie. */
.invite-link {
  width: 100%; margin: 12px 0 10px; display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  background: var(--surface-2); border: 1px dashed var(--line-strong); border-radius: 12px; text-align: left;
}
.invite-url { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; color: var(--accent); }
.invite-copy { flex: none; font-size: .85rem; color: var(--muted); font-weight: 600; }
.legal-links { text-align: center; font-size: .78rem; color: var(--muted); margin: 6px 0 0; }
.legal-links a { color: var(--muted); }

/* ---------------------------------------------------------------- Espace de l'hôte */
.space-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.space-head h1 { margin: 0; }
.space-email { margin: 2px 0 6px; overflow-wrap: anywhere; }
.space-block { border-top: 1px solid var(--line); padding: 14px 0 4px; margin-top: 10px; }
.space-block h2 { font-size: 1rem; margin: 0 0 6px; color: var(--accent); }
.table-link { margin: 10px 0; padding: 10px 12px; border: 1px dashed var(--line-strong); border-radius: 10px; background: var(--bg); }
.table-link code { font-size: .85rem; overflow-wrap: anywhere; color: var(--text); }
.space-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.space-actions button { flex: 1 1 140px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; }
.stat { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 6px; border-radius: 12px; background: var(--surface-2); text-align: center; }
.stat b { font-size: 1.3rem; font-variant-numeric: tabular-nums; }
.stat span { font-size: .75rem; color: var(--muted); }
.friends, .history { list-style: none; padding: 0; margin: 6px 0 0; }
.friends li { display: grid; grid-template-columns: 44px 1fr; grid-template-rows: auto auto; column-gap: 6px; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--line); }
.friends .star { grid-row: 1 / 3; width: 44px; min-height: 44px; padding: 0; border: none; background: none; font-size: 1.3rem; color: var(--line-strong); }
.friends .star.on { color: var(--accent); }
.fr-name { font-weight: 700; overflow-wrap: anywhere; }
.fr-stats { font-size: .78rem; color: var(--muted); }
.history li { display: flex; flex-direction: column; gap: 1px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: .86rem; }
.h-date { font-size: .76rem; color: var(--muted); }
.h-teams { overflow-wrap: anywhere; }
.h-result b.won { color: var(--accent); }
.h-result b.lost { color: var(--warn); }
.overlay-wait { margin: 0 0 12px; font-size: .9rem; text-align: center; }
#overlay-rematch { margin-bottom: 8px; }
@media (max-width: 600px) {
  #space.panel { width: auto; margin: 0; border: 0; border-radius: 0; background: none; padding: 14px max(16px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
}


/* ======================================================================== v3 : joueur dont c'est le tour
   Sa vidéo est mise en avant : légèrement agrandie, au-dessus des autres, vers le centre de la table. */
.seat { transition: transform .25s ease; }
.seat.is-turn { z-index: 2; } /* au-dessus des autres vidéos, jamais au-dessus du panneau d'enchères */
.seat.is-turn[data-pos="left"] { transform: scale(1.06); transform-origin: left center; }
.seat.is-turn[data-pos="top"] { transform: scale(1.06); transform-origin: center top; }
.seat.is-turn[data-pos="right"] { transform: scale(1.06); transform-origin: right center; }
.seat.is-turn[data-pos="bottom"] { transform: scale(1.06); transform-origin: center bottom; }
.seat.is-turn .video { box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow); }
@media (prefers-reduced-motion: reduce) { .seat { transition: none; } }

/* Panneaux du paysage : absents en portrait. */
.pz { display: none; }

/* ======================================================================== v3 : paysage (layout.js)
   Le tapis occupe tout l'écran ; layout.js pose chaque zone en pixels (styles en ligne) et règle --u (échelle
   des textes et commandes), --cw (carte du pli), --mini-w (dernier pli), --video-w / --seat-h (vidéos), --hw (main). */
html.at-table[data-layout="paysage"] .bar,
html[data-layout="paysage"] #table > .hud,
html[data-layout="paysage"] #table > .controls { display: none; }
html[data-layout="paysage"] #table { position: relative; display: block; }
html[data-layout="paysage"] .felt {
  --lt-step: .55; /* dernier pli serré comme la main */
  position: absolute; inset: 0; margin: 0; border-radius: 0; overflow: hidden;
  overflow: clip; /* jamais de défilement du tapis (une carte touchée à moitié coupée le faisait défiler) */
  container-type: normal; /* les tailles viennent de layout.js */
}
html[data-layout="paysage"] .felt::before { display: none; }
html[data-layout="paysage"] .pz { display: flex; position: absolute; z-index: 3; overflow: hidden; min-width: 0; }

/* Vidéos : cadres plus larges que hauts, prénom incrusté en bas de l'image. */
html[data-layout="paysage"] .seat { position: absolute; display: block; gap: 0; }
html[data-layout="paysage"] .seat .video { aspect-ratio: auto; height: var(--seat-h); border-radius: calc(14px * var(--u)); font-size: calc(2.2rem * var(--u)); }
html[data-layout="paysage"] .seat .video .avatar { font-size: inherit; }
html[data-layout="paysage"] .seat .name {
  position: absolute; left: 2px; right: 2px; top: calc(var(--seat-h) - 2px); transform: translateY(-100%); z-index: 2;
  justify-content: center; max-width: none; padding: calc(16px * var(--u)) 8px calc(6px * var(--u));
  font-size: calc(.82rem * var(--u)); color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .7);
  background: linear-gradient(transparent, rgba(0, 0, 0, .55)); border-radius: 0 0 calc(12px * var(--u)) calc(12px * var(--u));
  pointer-events: none;
}
html[data-layout="paysage"] .seat .cards-left {
  position: absolute; right: 8px; top: 8px; z-index: 2; padding: 1px 8px; border-radius: 999px;
  background: rgba(0, 0, 0, .45); color: #fff; font-size: calc(.72rem * var(--u));
}
html[data-layout="paysage"] .seat .decl-badges { position: absolute; left: 0; right: 0; top: calc(var(--seat-h) + 4px); z-index: 2; }
/* Bulles d'enchère à côté du cadre, vers le centre de la table. */
html[data-layout="paysage"] .bubble { bottom: auto; top: 50%; font-size: calc(.85rem * var(--u)); z-index: 5; }
html[data-layout="paysage"] .seat[data-pos="left"] .bubble,
html[data-layout="paysage"] .seat[data-pos="bottom"] .bubble { left: 100%; transform: translate(10px, -50%); }
html[data-layout="paysage"] .seat[data-pos="right"] .bubble { left: auto; right: 100%; transform: translate(-10px, -50%); }
html[data-layout="paysage"] .seat[data-pos="top"] .bubble { left: 100%; transform: translate(10px, -50%); }
/* Joueur dont c'est le tour : agrandi vers le centre. */
html[data-layout="paysage"] .seat.is-turn { transform: scale(var(--turn-scale, 1.04)); }
html[data-layout="paysage"] .seat.is-turn[data-pos="top"] { transform-origin: center top; }
html[data-layout="paysage"] .seat.is-turn[data-pos="left"] { transform-origin: left center; }
html[data-layout="paysage"] .seat.is-turn[data-pos="right"] { transform-origin: right center; }
html[data-layout="paysage"] .seat.is-turn[data-pos="bottom"] { transform-origin: left bottom; }

/* Pli au centre, statut au-dessus. */
html[data-layout="paysage"] .center { position: absolute; }
html[data-layout="paysage"] #status { font-size: calc(.92rem * var(--u)); }
html[data-layout="paysage"] .felt.bid-mode .center { z-index: 6; }

/* Haut gauche : quitter, caméra, micro (boutons carrés empilés) et tableau des scores. */
html[data-layout="paysage"] .pz-tl { gap: 8px; align-items: stretch; }
.pz-buttons { display: flex; flex-direction: column; gap: 4px; }
html[data-layout="paysage"] .pz-buttons > button {
  width: var(--btn); height: var(--btn); min-height: 0; padding: 0; border-radius: calc(10px * var(--u));
  display: grid; place-items: center; flex: none; margin: 0;
}
html[data-layout="paysage"] .pz-buttons .media-btn svg { width: calc(20px * var(--u)); height: calc(20px * var(--u)); }
html[data-layout="paysage"] .pz-buttons .media-btn .lbl {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; /* lu, pas affiché */
}
html[data-layout="paysage"] #quit {
  font-size: 0; text-decoration: none; background: var(--warn-soft); border: 1px solid var(--warn); color: var(--warn);
}
html[data-layout="paysage"] #quit::before {
  content: ''; width: calc(20px * var(--u)); height: calc(20px * var(--u)); background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/%3E%3Cpolyline points='16 17 21 12 16 7'/%3E%3Cline x1='21' x2='9' y1='12' y2='12'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/%3E%3Cpolyline points='16 17 21 12 16 7'/%3E%3Cline x1='21' x2='9' y1='12' y2='12'/%3E%3C/svg%3E") center / contain no-repeat;
}
.scoreboard {
  flex: 1; min-width: 0; border-collapse: collapse; background: var(--glass); border: 1px solid var(--line);
  border-radius: calc(12px * var(--u, 1)); font-size: calc(.8rem * var(--u, 1)); overflow: hidden;
}
.scoreboard th, .scoreboard td { padding: calc(3px * var(--u, 1)) calc(8px * var(--u, 1)); text-align: right; }
.scoreboard thead th { color: var(--muted); font-weight: 600; font-size: .88em; white-space: nowrap; }
.scoreboard tbody th { text-align: left; font-weight: 800; white-space: nowrap; }
.scoreboard tbody th .dot { margin-right: 6px; }
.scoreboard td { font-size: 1.25em; font-weight: 800; font-variant-numeric: tabular-nums; }
.scoreboard tbody tr + tr { border-top: 1px solid var(--line); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Haut droite (paysage), réduit au minimum et sans fond : le dernier pli (--mini-w et --lt-vis viennent de layout.js)
   et, à côté, le son, les réglages et l'état de la connexion. */
html[data-layout="paysage"] .pz-tr {
  flex-direction: row; align-items: center; gap: calc(8px * var(--u)); padding: calc(6px * var(--u)) calc(8px * var(--u));
  background: none; border: 0; overflow: hidden;
}
.pz-tools { display: flex; align-items: center; justify-content: center; gap: 6px; min-width: 0; }
html[data-layout="paysage"] .pz-tools { flex-direction: column; flex: none; }
html[data-layout="paysage"] .pz-tools #conn { position: absolute; top: 5px; right: 5px; }
.pz-lt { display: flex; justify-content: center; align-items: center; min-width: 0; flex: 1; }
html[data-layout="paysage"] .pz-lt .last-trick { max-width: 100%; }
/* Contrat et points des plis : sous la vidéo du preneur et dans le tableau des scores (pas de doublon). */
.info-zone .contract { display: none; }
html[data-layout="paysage"] .pz-info .trick-totals, html[data-layout="paysage"] .pz-info #round-no { display: none; }

/* Annonce sous la vidéo de son joueur (paysage) : montant et symbole en couleur, comme sur une carte. */
.seat .contract-tag {
  order: 1; display: inline-flex; align-items: center; gap: 4px; height: var(--tag-h, 22px); padding: 0 10px; border-radius: 999px;
  background: var(--card); color: var(--card-ink); box-shadow: 0 2px 6px rgba(0, 0, 0, .4); white-space: nowrap;
  font-family: var(--card-font); font-weight: 800; font-size: 1.25rem; font-variant-numeric: tabular-nums;
}
.seat .cards-left, .seat .decl-badges { order: 2; }
html[data-layout="portrait"] .seat:has(.contract-tag) .cards-left { display: none; }
.felt.has-contract { --name-h: 62px; }
.felt.has-contract.has-decl { --name-h: 80px; }
html[data-layout="paysage"] .seat .contract-tag {
  display: inline-flex; position: absolute; left: 50%; top: calc(var(--seat-h) + 5px); transform: translateX(-50%); z-index: 3;
  align-items: center; gap: calc(5px * var(--u)); height: var(--tag-h, 28px); padding: 0 calc(12px * var(--u)); border-radius: 999px;
  background: var(--card); color: var(--card-ink); box-shadow: 0 2px 8px rgba(0, 0, 0, .45); white-space: nowrap;
  font-family: var(--card-font); font-weight: 800; font-size: calc(1.05rem * var(--u)); font-variant-numeric: tabular-nums;
}
html[data-layout="paysage"] .seat[data-pos="bottom"] .contract-tag { top: auto; bottom: calc(100% + 5px); }
.contract-tag svg { width: 1.15em; height: 1.15em; fill: currentColor; }
.contract-tag svg.red { color: var(--card-red); }
.contract-tag .ct-mult { padding: 0 6px; border-radius: 999px; background: var(--warn); color: var(--on-warn); font-size: .8em; }
html[data-layout="paysage"] .seat:has(.contract-tag) .decl-badges { top: calc(var(--seat-h) + var(--tag-h, 28px) + 9px); }
html[data-layout="paysage"] .pz-tools .bar-btn { width: max(36px, calc(34px * var(--u)), calc(28px / var(--table-zoom, 1))); min-height: max(36px, calc(34px * var(--u)), calc(28px / var(--table-zoom, 1))); }
/* Haut gauche (paysage) : sous le tableau des scores, l'état de la vidéo et le litige éventuel. */
.pz-score { display: flex; flex-direction: column; gap: calc(4px * var(--u, 1)); flex: 1; min-width: 0; }
.pz-score .scoreboard { flex: none; width: 100%; }
.pz-info { display: flex; flex-direction: column; gap: 2px; min-height: 0; overflow: hidden; font-size: calc(.74rem * var(--u, 1)); color: var(--muted); }
html[data-layout="paysage"] .pz-info .meta { text-align: left; }
html[data-layout="paysage"] .pz-info .meta > div { justify-content: flex-start; }
html[data-layout="paysage"] .pz-info .info-zone { min-height: 0; }
html[data-layout="paysage"] .pz-info #video-status { max-width: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Tableau des scores : points à atteindre à côté de son icône, numéro de la donne à côté de « Tour ». */
.sb-target, .sb-round { color: var(--text); font-weight: 800; font-variant-numeric: tabular-nums; }
.sb-target { margin-left: 4px; }


/* Bas centre : la main, grandes cartes serrées, coupées par le bas de l'écran ; les jouables se soulèvent. */
html[data-layout="paysage"] #hand {
  position: absolute; z-index: 3; padding: 0; min-height: 0; display: flex; justify-content: center; align-items: flex-start;
}
html[data-layout="paysage"] #hand .card { margin-left: calc(var(--w) * -0.45); }
html[data-layout="paysage"] #hand .card:first-child { margin-left: 0; }
html[data-layout="paysage"] #hand .card.playable { transform: translateY(calc(var(--w) * -0.16)); }
@media (hover: hover) { html[data-layout="paysage"] #hand .card.playable:hover { transform: translateY(calc(var(--w) * -0.26)); } }
html[data-layout="paysage"] #my-decl { position: absolute; left: 0; right: 0; bottom: calc(var(--hw, 60px) * .9); z-index: 4; }

/* Paysage sur écran bas (téléphone couché) : boutons et scores sur une ligne, informations réduites à l'essentiel. */
html[data-layout="paysage"] .felt.compact .pz-tl { align-items: center; }
html[data-layout="paysage"] .felt.compact .pz-buttons { flex-direction: row; }
html[data-layout="paysage"] .felt.compact .scoreboard { font-size: .7rem; table-layout: fixed; width: 100%; }
html[data-layout="paysage"] .felt.compact .scoreboard th, html[data-layout="paysage"] .felt.compact .scoreboard td { padding: 1px 4px; line-height: 1.15; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html[data-layout="paysage"] .felt.compact .scoreboard tbody th .dot { margin-right: 3px; }
html[data-layout="paysage"] .felt.compact .pz-info #video-status { display: none; } /* place gardée pour le contrat et les plis */
html[data-layout="paysage"] .felt.compact .scoreboard td { font-size: 1.1em; }
html[data-layout="paysage"] .felt.compact .pz-tr { padding: 4px 8px; gap: 2px; }
html[data-layout="paysage"] .felt.compact .pz-info #video-status { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }



/* Dans les panneaux, la zone de toucher des boutons reste dans le bouton (le panneau coupe ce qui dépasse). */
html[data-layout="paysage"] .pz .bar-btn::after, html[data-layout="paysage"] .pz .bar-pill::after { inset: 0; }

/* Installation : marche à suivre (Android, ordinateur) et page ouverte dans l'ancienne appli. */
.other-app-text { margin: 6px 0 10px; }
.button-link {
  display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap); padding: 10px 16px;
  border-radius: 10px; font-weight: 700; text-decoration: none; width: 100%;
}
.button-link.primary { background: var(--accent); color: var(--on-accent); }

/* ======================================================================== v3 paysage : choix validés sur la variante
   « Live Belotte Paysage » (cartes à figures, panneau d'annonce, scores Tour / Total, boutons carrés). */

/* Cartes (portrait et paysage) : valeur et petit symbole en haut à gauche ; gros symbole au centre, ou le personnage
   pour V, D, R. */
.card .fig { display: none; }
.card:not(.mini) .idx { left: 6%; top: 4%; font-size: calc(var(--w) * .3); }
.card:not(.mini) .pip { width: calc(var(--w) * .2); height: calc(var(--w) * .2); }
.card:not(.mini) .idx-b { display: none; }
.card:not(.mini) .mid { width: 62%; left: 56%; top: 59%; }
.card.has-fig:not(.mini) .mid { display: none; }
.card.has-fig:not(.mini) .fig {
  display: block; position: absolute; left: 30%; top: 6%; right: 6%; bottom: 6%; width: 64%; height: 88%;
  object-fit: cover; object-position: top center; border-radius: calc(var(--w) * .04); pointer-events: none;
}

/* Tableau des scores : NOUS au-dessus, EUX dessous ; Tour (plis de la donne, puis points marqués) et Total. */
.sb-icon { width: 1.15em; height: 1.15em; vertical-align: -.2em; color: var(--muted); }
html[data-layout="paysage"] .scoreboard tbody th { letter-spacing: .05em; }
html[data-layout="paysage"] .scoreboard td { font-family: var(--card-font); }

/* Boutons carrés du coin : quitter (rouge), caméra et micro (allumés : neutres ; coupés : rouges). */
html[data-layout="paysage"] .pz-buttons > button { box-shadow: 0 2px 6px rgba(0, 0, 0, .45); border-radius: calc(var(--btn) * .24); }
html[data-layout="paysage"] #quit { background: var(--warn); border-color: var(--warn); color: var(--on-warn); }
html[data-layout="paysage"] .pz-buttons .media-btn[aria-pressed="true"] { background: var(--surface); border-color: var(--line-strong); color: var(--text); }
html[data-layout="paysage"] .pz-buttons .media-btn[aria-pressed="false"] { background: var(--warn); border-color: var(--warn); color: var(--on-warn); }
html[data-layout="paysage"] .pz-buttons .media-btn.host-cut { background: var(--warn-soft); color: var(--warn); }
html[data-layout="paysage"] .pz-buttons .media-btn svg,
html[data-layout="paysage"] #quit::before { width: calc(var(--btn) * .56); height: calc(var(--btn) * .56); }

/* Panneau d'annonce : titre, meilleure enchère, montants en carrousel, couleurs en cartes, Coinche / Passer. */
.bidding.bid-paysage {
  width: 380px; max-width: calc(100% - 8px); background: var(--surface); padding: 10px 14px 12px;
  border: 1.5px solid color-mix(in srgb, var(--accent) 70%, transparent); box-shadow: 0 6px 18px rgba(0, 0, 0, .5);
}
.bidding.bid-paysage .bid-title { font-family: var(--card-font); font-size: 1.12rem; font-weight: 800; color: var(--text); }
.bidding.bid-paysage .bid-best { font-size: .78rem; margin-top: -6px; }
.bidding.bid-paysage .bid-values { display: flex; justify-content: center; gap: 6px; flex-wrap: nowrap; }
.bidding.bid-paysage .bid-values button, .bidding.bid-paysage .bid-empty {
  min-height: 50px; border-radius: 12px; border: 1.5px solid var(--line-strong); background: var(--surface-2);
  font-family: var(--card-font); font-size: 1.25rem; font-weight: 800; padding: 0;
}
.bidding.bid-paysage .bid-amount { flex: 1 1 0; min-width: 0; max-width: 78px; }
.bidding.bid-paysage .bid-empty { visibility: hidden; }
.bidding.bid-paysage .bid-arrow { flex: 0 0 40px; font-size: 1.6rem; line-height: 1; }
.bidding.bid-paysage .bid-values button.selected { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.bidding.bid-paysage .bid-suits { display: flex; justify-content: center; gap: 10px; }
.bidding.bid-paysage .suit-tile {
  flex: 1 1 0; min-width: 0; max-width: 70px; min-height: 62px; padding: 0; border-radius: 12px; display: grid; place-items: center;
  background: var(--card); color: var(--card-ink); border: 1.5px solid var(--line-strong); box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
}
.bidding.bid-paysage .suit-tile.red { color: var(--card-red); }
.bidding.bid-paysage .suit-tile svg { width: 38px; height: 38px; fill: currentColor; }
.bidding.bid-paysage .suit-tile.selected { outline: 3px solid var(--accent); outline-offset: 2px; }
.bidding.bid-paysage .bid-actions { display: flex; gap: 10px; }
.bidding.bid-paysage .bid-actions button { flex: 1; min-height: 46px; font-size: 1.05rem; font-weight: 800; }
.bidding.bid-paysage #bid-pass { background: transparent; border: 1.5px solid var(--warn); color: var(--warn); }
.bidding.bid-paysage #bid-coinche, .bidding.bid-paysage #bid-surcoinche { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.bidding.bid-paysage .bid-take button { min-height: 46px; font-weight: 800; }

/* Pli en tas (portrait et paysage) : cartes aussi grandes que celles de la main, qui se chevauchent au centre, chacune
   décalée vers son joueur et légèrement tournée ; la dernière posée passe dessus (z-index posé par app.js). Le cadre
   du tas fait 2,05 × 2,3 largeurs de carte (PILE_W, PILE_H dans layout.js). */
.trick { width: calc(var(--cw) * 2.05); height: calc(var(--cw) * 2.3); }
.trick .slot { left: 50%; top: 50%; right: auto; bottom: auto; }
.trick .slot-left { transform: translate(-50%, -50%) translate(calc(var(--cw) * -.42), 0) rotate(-11deg); }
.trick .slot-right { transform: translate(-50%, -50%) translate(calc(var(--cw) * .42), 0) rotate(12deg); }
.trick .slot-top { transform: translate(-50%, -50%) translate(0, calc(var(--cw) * -.36)) rotate(5deg); }
.trick .slot-bottom { transform: translate(-50%, -50%) translate(0, calc(var(--cw) * .36)) rotate(-5deg); }
.trick .card { box-shadow: var(--card-edge), 0 3px 10px rgba(0, 0, 0, .45); }

/* « D » du donneur en paysage : jamais sous 24 px à l'écran, même quand la table est réduite (téléphone couché). */
html[data-layout="paysage"] .seat .frame .dealer-mark {
  width: clamp(calc(24px / var(--table-zoom, 1)), calc(var(--video-w) * .14), 44px);
  font-size: clamp(calc(14px / var(--table-zoom, 1)), calc(var(--video-w) * .08), 24px);
  right: calc(6px * var(--u, 1)); bottom: calc(6px * var(--u, 1));
}
/* Le prénom incrusté en bas de l'image laisse la place du « D ». */
html[data-layout="paysage"] .seat:has(.dealer-mark) .name { padding-left: calc(var(--video-w) * .16 + 10px); padding-right: calc(var(--video-w) * .16 + 10px); }

/* ---------------------------------------------------------------- Effets : donne, carte posée, pli ramassé
   (app.js, « Effets »). Calque fixe sur toute la page, hors de #table qui peut être réduite d'un bloc en paysage :
   les copies des cartes y volent en coordonnées d'écran. Au-dessus du tapis, des vidéos et des panneaux ; sous le
   résultat de la donne (.overlay, 10), le menu de réglages et les fenêtres. Jamais de clic capturé. */
.fx { position: fixed; inset: 0; z-index: 9; pointer-events: none; overflow: hidden; contain: strict; }
/* Une piste par carte : découpée autour d'une vidéo (clip-path posé par app.js) quand la carte en sort ou y entre. */
.fx-lane { position: absolute; inset: 0; }
/* Trajet, rotation et taille sur trois éléments imbriqués : chacun sa courbe. */
.fx-move, .fx-turn, .fx-size { position: absolute; left: 0; top: 0; width: 0; height: 0; will-change: transform; }
.fx .card { position: absolute; left: calc(var(--w) / -2); top: calc(var(--w) * -.71); margin: 0; transform: none; cursor: default; box-shadow: var(--card-edge), 0 6px 16px rgba(0, 0, 0, .45); }
/* Dos des cartes distribuées aux autres : croisillons fins sur une teinte du thème, liseré blanc de carte. */
.card.fx-back {
  --back: #2c5a52;
  background-color: var(--back);
  background-image:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .16) 0 1px, transparent 1px calc(var(--w) * .11)),
    repeating-linear-gradient(-45deg, rgba(255, 255, 255, .16) 0 1px, transparent 1px calc(var(--w) * .11));
  box-shadow: inset 0 0 0 calc(var(--w) * .055) var(--card), inset 0 0 0 calc(var(--w) * .07) rgba(0, 0, 0, .22), 0 4px 12px rgba(0, 0, 0, .4);
}
:root[data-theme="light"] .card.fx-back { --back: #1d5f53; }
:root[data-style="classique"] .card.fx-back { --back: #7a1f2b; }
/* Carte arrivée à sa place pendant que sa copie vole encore : gardée masquée jusqu'à l'atterrissage. */
.card.fx-wait { visibility: hidden; }
/* Atout en vol : même liseré que posé sur le tapis. */
.fx .card.trump { box-shadow: var(--card-edge), 0 0 0 2px var(--accent), 0 6px 16px rgba(0, 0, 0, .45); }
/* « Donne 2 » au centre du tapis pendant la distribution. */
.fx-banner {
  position: absolute; transform: translate(-50%, -50%); padding: 8px 22px; border-radius: 999px; white-space: nowrap;
  background: var(--glass); color: var(--text); border: 1px solid var(--line-strong); box-shadow: var(--shadow);
  font-family: var(--card-font); font-size: 1.35rem; font-weight: 800; letter-spacing: .02em;
}
:root[data-style="classique"] .fx-banner { color: var(--brass); border-color: color-mix(in srgb, var(--brass) 55%, transparent); }

/* Coinche à la volée : gros bouton à côté de ma vidéo (à gauche en portrait, à droite en paysage), qui bat doucement
   pour attirer l'œil. */
.seat .fly-coinche {
  position: absolute; z-index: 6; right: calc(100% + 8px); bottom: 0; min-height: 52px; padding: 0 12px; margin: 0;
  max-width: var(--corner-w, 160px); border-radius: 14px; border: 2px solid #fff;
  background: var(--warn); color: var(--on-warn); box-shadow: 0 4px 14px rgba(0, 0, 0, .5);
  font-family: var(--card-font); font-size: 1.05rem; font-weight: 900; letter-spacing: .03em; text-transform: uppercase; white-space: nowrap;
  animation: coinche-pulse 1.1s ease-in-out infinite;
}
.seat .fly-coinche:disabled { opacity: .6; animation: none; }
/* Mon siège passe devant le tapis (zone du pli, main, panneaux) tant qu'il porte le bouton : il reste touchable. */
.seat:has(.fly-coinche) { z-index: 7; }
html[data-layout="paysage"] .seat[data-pos="bottom"] .fly-coinche {
  right: auto; left: calc(100% + 12px); top: 0; bottom: auto; max-width: none;
  min-height: calc(56px * var(--u, 1)); padding: 0 calc(18px * var(--u, 1)); font-size: calc(1.3rem * var(--u, 1));
}
@keyframes coinche-pulse { 50% { transform: scale(1.06); } }
@media (prefers-reduced-motion: reduce) { .seat .fly-coinche { animation: none; } }
