/* ===========================================================================
   Ruée vers l'Or — interface en verre fumé.
   Sur l'écran de jeu, le plateau occupe toute la fenêtre et des panneaux de verre fumé flottent par-dessus ;
   l'accueil et le salon se posent sur l'image du plateau à l'heure dorée, assombrie.
   Texte en Inter, logo et titres en Playfair Display ; Rye reste pour les vignettes des événements.
   =========================================================================== */
:root {
  --verre:        rgba(20, 15, 11, .50);
  --verre-opaque: rgba(20, 15, 11, .88);
  --verre-flou:   blur(14px) saturate(1.25);
  --verre-bord:   rgba(255, 255, 255, .15);
  --verre-ombre:  0 12px 40px rgba(0, 0, 0, .35);
  --rayon:        16px;
  --rayon-petit:  11px;
  --or:           #ffd57a;
  --or-haut:      #ffe29a;
  --or-bas:       #f4b544;
  --or-encre:     #2a1806;
  --texte:        #fff;
  --texte-doux:   rgba(255, 255, 255, .65);
  --fond:         #1b140e;
  --alerte:       #e0805f;
  --papier:       #ecdfb9;     /* fond des vignettes (js/scenes.js) */
  --police:       'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --titre:        'Playfair Display', Georgia, serif;
  --affiche:      'Rye', Georgia, serif;
  --marge:        16px;
  /* La zone libre de la carte : bords réservés par les barres, posés par js/interface.js. */
  --zone-haut: 0px;
  --zone-bas: 0px;
  --zone-gauche: 0px;
  --zone-droite: 0px;
  /* Un seul jeu de mouvements pour l'interface (projet 6d) : trois durées, une sortie douce, un ressort léger.
     js/interface.js en garde les valeurs (Interface.MOUVEMENTS) pour ses minuteries. */
  --duree-vite: 140ms;
  --duree: 240ms;
  --duree-lente: 420ms;
  --sortie: cubic-bezier(.22, .61, .36, 1);
  --ressort: linear(0, .32 10%, .68 20%, .93 30%, 1.07 42%, 1.02 56%, .99 70%, 1);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

html { background: var(--fond); }
body {
  min-height: 100vh;
  font-family: var(--police); font-size: 16px; line-height: 1.45;
  background: var(--fond); color: var(--texte);
  -webkit-font-smoothing: antialiased;
}
button, input { font: inherit; color: inherit; }
h1, h2 { font-weight: 700; line-height: 1.1; }
:focus-visible { outline: 3px solid var(--or); outline-offset: 2px; }
.ic { width: 20px; height: 20px; flex: none; }

/* ---------------------------------------------------------------- le verre fumé */
.vitre {
  background: var(--verre);
  -webkit-backdrop-filter: var(--verre-flou);
  backdrop-filter: var(--verre-flou);
  border: 1px solid var(--verre-bord);
  border-radius: var(--rayon);
  box-shadow: var(--verre-ombre);
  color: var(--texte);
}

/* ---------------------------------------------------------------- boutons */
/* Au clic, un bouton s'enfonce et revient avec un ressort léger (projet 6d, js/interface.js pose `presse`). */
.presse { animation: enfonce var(--duree) var(--ressort); }
.slot.utilisable.presse { animation: enfonce var(--duree) var(--ressort), appel 1.6s ease-in-out infinite; }
@keyframes enfonce { from { scale: .94; } to { scale: 1; } }
.bouton-or {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 48px; padding: 0 26px; border: 0; border-radius: 999px; cursor: pointer;
  font-weight: 700; font-size: 16px; color: var(--or-encre); text-decoration: none; white-space: nowrap;
  background: linear-gradient(var(--or-haut), var(--or-bas));
  box-shadow: 0 0 0 4px rgba(255, 213, 122, .25), 0 12px 30px rgba(0, 0, 0, .45);
  transition: transform 80ms ease, filter 120ms ease;
}
.bouton-or:hover { filter: brightness(1.06); }
.bouton-or:active { transform: translateY(1px); }
.bouton-or:disabled { cursor: not-allowed; opacity: .55; filter: grayscale(.5); }
.btn-verre {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 16px; cursor: pointer;
  font-weight: 600; font-size: 14px; text-decoration: none; white-space: nowrap;
}
.btn-verre:hover { background: rgba(60, 46, 34, .62); }
.btn-verre:disabled { cursor: not-allowed; opacity: .5; }
.btn-icone { width: 42px; height: 42px; padding: 0; display: inline-grid; place-items: center; cursor: pointer; }
.btn-lien { padding: 6px 8px; border: 0; background: none; cursor: pointer; font-size: 14px; color: var(--texte-doux); text-decoration: underline; text-underline-offset: 3px; }
.btn-lien:hover { color: var(--texte); }

/* ---------------------------------------------------------------- messages (opération refusée, partie disparue) */
.toast {
  position: fixed; left: 50%; top: var(--marge); transform: translateX(-50%); z-index: 50;
  max-width: min(92vw, 520px); padding: 10px 18px; font-size: 14px; font-weight: 500;
  box-shadow: var(--verre-ombre), inset 3px 0 0 var(--alerte);
}
.toast.info { box-shadow: var(--verre-ombre), inset 3px 0 0 var(--or); }

/* ---------------------------------------------------------------- avatars (salon, chercheurs, classement) */
.avatar {
  --couleur: #888;
  width: 32px; height: 32px; flex: none; display: grid; place-items: center; border-radius: 50%;
  background: var(--couleur); box-shadow: 0 0 0 2px rgba(255, 255, 255, .3);
  font-weight: 700; font-size: 14px; color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .45);
}
.avatar-vide { background: none; box-shadow: none; border: 2px dashed rgba(255, 255, 255, .3); }

/* ---------------------------------------------------------------- accueil et salon : sur l'image du plateau à l'heure dorée */
/* Le fond en couche fixe (et non background-attachment: fixed, coûteux sur téléphone, qui bloque aussi les captures du banc
   d'essai) : l'image reste en place quand la page défile. Le fond sombre de secours est celui de <html>. */
body.ecran-accueil, body.ecran-salon { background: transparent; }
body.ecran-accueil::before, body.ecran-salon::before {
  content: ''; position: fixed; inset: 0; z-index: -1;
  background: linear-gradient(rgba(14, 10, 7, .55), rgba(14, 10, 7, .82)), url('../img/rendu/repli.webp') center / cover no-repeat;
}
.surtitre { font-size: 12px; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--or); }
.accueil { max-width: 980px; margin: 0 auto; padding: 40px var(--marge) 64px; }
.accueil-titre { margin-bottom: 32px; text-align: center; }
.accueil-logo { display: block; width: 96px; height: 96px; margin: 0 auto 10px; filter: drop-shadow(0 8px 24px rgba(0, 0, 0, .55)); }
.accueil-titre h1 {
  margin: 8px 0 14px; font-family: var(--titre); font-weight: 700; font-size: clamp(44px, 9vw, 88px); line-height: 1.05;
  color: var(--or); text-shadow: 0 6px 30px rgba(0, 0, 0, .55);
}
.accroche { max-width: 560px; margin: 0 auto; font-size: 17px; color: rgba(255, 255, 255, .85); }
.accueil-cartes { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.carte { padding: 22px 22px 24px; }
.carte h2 { margin-bottom: 8px; font-family: var(--titre); font-size: 24px; color: var(--or); }
.carte p { margin-bottom: 14px; color: var(--texte-doux); }
.carte label { display: block; margin: 10px 0; font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--texte-doux); }
.carte input {
  display: block; width: 100%; margin-top: 6px; padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 10px; background: rgba(0, 0, 0, .3);
  font-size: 17px; letter-spacing: normal; text-transform: none; color: var(--texte);
}
.carte input::placeholder { color: rgba(255, 255, 255, .4); }
.carte input:focus { outline: none; border-color: var(--or); box-shadow: 0 0 0 3px rgba(255, 213, 122, .3); }
#code-rejoindre { font-family: var(--titre); font-weight: 600; font-size: 26px; letter-spacing: .3em; text-transform: uppercase; }
.carte .bouton-or { margin-top: 14px; }
.reprise { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 20px; padding: 16px 20px; }
.reprise p { flex: 1 1 200px; margin: 0; color: var(--texte); }
.regles { margin-top: 28px; }
.regles summary { padding: 16px 20px; cursor: pointer; font-family: var(--titre); font-weight: 700; font-size: 20px; color: var(--or); }
.regles-corps { display: grid; gap: 14px; padding: 0 20px 20px; }
.regle { display: grid; grid-template-columns: 360px 1fr; align-items: center; gap: 18px; padding: 10px 12px; border-radius: 12px; background: rgba(0, 0, 0, .22); }
/* Les vignettes filmées dans le plateau (img/tuto/, tools/tuto/) : 960 × 600, montrées à 360 × 225 (ou toute la largeur sur téléphone) */
.regle-vignette { aspect-ratio: 960 / 600; overflow: hidden; border-radius: 10px; background: #1b140e; box-shadow: 0 6px 18px rgba(0, 0, 0, .35); }
.regle-vignette picture, .regle-vignette img { display: block; width: 100%; height: 100%; }
.regle-vignette img { object-fit: cover; }
.regle p { margin: 0; color: rgba(255, 255, 255, .88); }
/* La liste des douze numéros de la Gazette (projet 12d) : sous le texte de son bloc, dans sa colonne ; la vignette reste en haut,
   à côté des deux */
.regle:has(> .regle-liste) { row-gap: 8px; }
.regle:has(> .regle-liste) > .regle-vignette { grid-row: span 2; align-self: start; }
.regle-liste { grid-column: 2; margin: 0; padding-left: 20px; color: rgba(255, 255, 255, .88); }
.regle-liste li + li { margin-top: 4px; }
.regle-liste li::marker { color: var(--or); }

.salon { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 40px var(--marge); }
.salon-carte { width: min(620px, 100%); padding: 26px 24px; text-align: center; }
.salon-code {
  margin: 6px 0 4px; padding-left: .22em; font-family: var(--titre); font-weight: 700;
  font-size: clamp(56px, 14vw, 110px); line-height: 1.1; letter-spacing: .22em; color: var(--or);
}
.salon-aide { margin-bottom: 22px; color: var(--texte-doux); }
.salon-aide strong { color: var(--texte); }
.sieges { list-style: none; display: grid; gap: 8px; margin-bottom: 22px; text-align: left; }
.siege { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border: 1px solid rgba(255, 255, 255, .08); border-radius: 12px; background: rgba(255, 255, 255, .06); }
.siege-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.siege-nom small { font-weight: 400; color: var(--texte-doux); }
.siege-role { font-size: 13px; color: var(--texte-doux); }
.siege-vide { border-style: dashed; border-color: rgba(255, 255, 255, .25); background: none; color: var(--texte-doux); }
.salon-actions { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.salon-hote { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.salon-attente { font-style: italic; color: var(--texte-doux); }
@media (max-width: 760px) {
  .accueil-cartes { grid-template-columns: 1fr; }
  .regle { grid-template-columns: 1fr; }
  .regle-vignette { width: 100%; max-width: 480px; }
  .regle:has(> .regle-liste) > .regle-vignette { grid-row: auto; margin-bottom: 10px; }
  .regle-liste { grid-column: auto; }
}

/* ---------------------------------------------------------------- écran de jeu : le plateau occupe toute la fenêtre */
body.ecran-partie { overflow: hidden; overscroll-behavior: none; }
.partie { position: fixed; inset: 0; overflow: hidden; }
.plateau { position: absolute; inset: 0; overflow: hidden; z-index: 0; touch-action: none; }   /* son propre empilement : ses pièces restent sous les panneaux */
.plateau:focus-visible { outline: 3px solid var(--or); outline-offset: -3px; }

/* Au centre de la zone libre de la carte (entre les barres ; les --zone-* sont posées par js/interface.js). */
.au-centre {
  position: absolute; z-index: 15; pointer-events: none;
  left: calc(var(--zone-gauche) + (100% - var(--zone-gauche) - var(--zone-droite)) / 2);
  top: calc(var(--zone-haut) + (100% - var(--zone-haut) - var(--zone-bas)) / 2);
}

/* ---- le passage de l'accueil à la partie (js/app.js) : l'image de l'accueil, cadrée et voilée comme sur l'accueil, glisse
   jusqu'à la place du plateau puis s'efface ; les barres apparaissent ensuite en fondu */
.passage { position: fixed; inset: 0; z-index: 60; overflow: hidden; background: var(--fond); }   /* il retient les clics : rien d'invisible ne se touche */
.passage-image { position: absolute; transform-origin: 0 0; will-change: transform; }
.passage-voile { position: absolute; inset: 0; background: linear-gradient(rgba(14, 10, 7, .55), rgba(14, 10, 7, .82)); }
.passage-attente { position: absolute; left: 50%; bottom: 14%; transform: translateX(-50%); margin: 0; padding: .45em 1.1em;
  border-radius: 999px; background: rgba(20, 13, 8, .72); color: #f3d79a; font-size: 1.05rem; letter-spacing: .02em;
  opacity: 0; transition: opacity .5s; pointer-events: none; }
.passage.attend .passage-attente { opacity: 1; animation: passage-pouls 1.6s ease-in-out infinite alternate; }
@keyframes passage-pouls { from { opacity: .55; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .passage.attend .passage-attente { animation: none; } }
.barre-haut, .barre-bas { transition: opacity .6s ease; }
.en-passage .barre-haut, .en-passage .barre-bas { opacity: 0; }

/* ---- barre du haut : logo et code, pilule du tour, jauge du train, réglages, Quitter ; les chercheurs dessous, à gauche */
.barre-haut {
  position: absolute; z-index: 20; left: var(--marge); right: var(--marge); top: var(--marge);
  display: flex; align-items: center; gap: 12px; pointer-events: none;
}
.barre-haut > * { pointer-events: auto; }
.logo-partie {
  display: flex; align-items: baseline; gap: 10px; padding: 9px 18px; white-space: nowrap;
  font-family: var(--titre); font-weight: 700; font-size: 21px; line-height: 1.2; color: var(--or);
}
.logo-image { display: none; }
.partie-code { font-family: var(--police); font-size: 12px; font-weight: 600; letter-spacing: .2em; color: var(--texte-doux); }
.tour {
  position: relative; overflow: hidden;
  min-width: 0; margin: 0 auto; display: flex; align-items: center; gap: 10px; padding: 9px 20px 9px 12px;
  border-radius: 999px; font-weight: 600; font-size: 15px; white-space: nowrap;
}
#tour-texte { overflow: hidden; text-overflow: ellipsis; }
.pastille { width: 22px; height: 22px; flex: none; border-radius: 50%; box-shadow: 0 0 0 3px rgba(255, 255, 255, .25); transition: background-color var(--duree-lente) ease; }
/* quand c'est à moi, un reflet passe une fois sur la pilule (projet 6d, js/interface.js pose `reflet`) */
.tour.reflet::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .22) 50%, transparent 62%) no-repeat;
  background-size: 260% 100%; animation: reflet var(--duree-lente) var(--sortie) both;
}
.tour.a-vous { box-shadow: var(--verre-ombre), 0 0 0 2px rgba(255, 213, 122, .6); }
.jauge-train { display: flex; align-items: center; gap: 10px; width: 260px; padding: 10px 16px; font-size: 12px; color: rgba(255, 255, 255, .8); }
.jauge-train > .ic { color: var(--or); }
.jauge-corps { position: relative; flex: 1; min-width: 0; display: grid; gap: 7px; }
.jauge-texte { white-space: nowrap; }
.jauge-texte b { color: var(--or); font-variant-numeric: tabular-nums; }
.jauge-barre { position: relative; height: 6px; overflow: hidden; border-radius: 3px; background: rgba(255, 255, 255, .18); }
.jauge-barre i {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 3px;
  background: linear-gradient(90deg, #ffb347, var(--or)); box-shadow: 0 0 10px rgba(255, 200, 90, .7); transition: width var(--duree-lente) var(--sortie);
}
/* à chaque case, une bouffée de vapeur au bout de la barre (projet 6d, js/interface.js pose `bouffee` et --part sur le
   corps de la jauge : la barre, elle, coupe le halo de son remplissage) */
.jauge-corps.bouffee::after {
  content: ''; position: absolute; left: calc(var(--part, 0) * 100%); bottom: 3px; width: 10px; height: 10px; margin: 0 0 -5px -5px;
  border-radius: 50%; pointer-events: none; background: radial-gradient(circle, rgba(255, 255, 255, .95), rgba(255, 255, 255, 0) 70%);
  animation: bouffee var(--duree-lente) var(--sortie) both;
}
@keyframes bouffee { from { opacity: .95; scale: .5; translate: 0 0; } to { opacity: 0; scale: 2.2; translate: 6px -12px; } }
.reglages { position: relative; }
.menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 30; min-width: 210px; padding: 6px; display: grid; gap: 2px; }
.menu-choix {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; width: 100%; padding: 10px 12px;
  border: 0; border-radius: var(--rayon-petit); background: none; cursor: pointer; font-weight: 600; font-size: 14px; text-align: left;
}
.menu-choix:hover, .menu-choix:focus-visible { background: rgba(255, 255, 255, .1); }
.menu-telephone { display: none; }
.interrupteur { position: relative; width: 34px; height: 20px; flex: none; border-radius: 999px; background: rgba(255, 255, 255, .2); }
.interrupteur::after {
  content: ''; position: absolute; left: 3px; top: 3px; width: 14px; height: 14px; border-radius: 50%;
  background: rgba(255, 255, 255, .7); transition: transform .15s ease;
}
.menu-choix[aria-checked="true"] .interrupteur { background: rgba(255, 213, 122, .45); }
.menu-choix[aria-checked="true"] .interrupteur::after { transform: translateX(14px); background: var(--or); }

.chercheurs {
  position: absolute; left: 0; top: calc(100% + 12px); width: 252px; padding: 8px;
  list-style: none; display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px;   /* un nom trop long se coupe au lieu d'élargir la liste */
  max-height: calc(100vh - 230px); max-height: calc(100dvh - 230px); overflow-y: auto;
}
.joueur { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: var(--rayon-petit); }
.joueur.actif { background: rgba(255, 213, 122, .16); box-shadow: inset 0 0 0 1px rgba(255, 213, 122, .55); }
.joueur-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-size: 14px; }
.joueur-nom small { display: block; overflow: hidden; text-overflow: ellipsis; font-weight: 400; font-size: 11px; color: var(--texte-doux); }
.chiffres { display: flex; gap: 9px; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.chiffres > span { display: inline-flex; align-items: center; gap: 3px; }
.chiffres .ic { width: 15px; height: 15px; color: var(--or); }
/* un compteur qui défile (projet 6d, js/interface.js) : un éclat doré le temps du défilement */
.compte { display: inline-block; min-width: 1ch; text-align: right; }
.compte.eclat { animation: eclat var(--duree-lente) ease; }
@keyframes eclat { 30% { color: var(--or); text-shadow: 0 0 10px rgba(255, 213, 122, .9); scale: 1.2; } }
.btn-ia { flex: none; padding: 2px 7px; border: 1px solid var(--verre-bord); border-radius: 8px; background: rgba(255, 255, 255, .08); cursor: pointer; font-size: 11px; font-weight: 700; }
.btn-ia:hover { background: rgba(255, 255, 255, .16); }

/* ---- les boutons d'action au milieu de la carte : lancer le dé, la mine, annuler la lanterne, revanche ; cachés pendant les
   scènes (js/interface.js), le dé roule à leur place */
.actions-centre {
  z-index: 17; transform: translate(-50%, -50%); flex-wrap: wrap; justify-content: center;
  width: max-content; max-width: calc(100vw - 32px);
}
.actions-centre #btn-action { min-height: 60px; padding: 0 34px; font-size: 19px; box-shadow: 0 12px 30px rgba(0, 0, 0, .5); }
.actions-centre #btn-second { min-height: 48px; box-shadow: 0 10px 26px rgba(0, 0, 0, .4); }
/* les objets à utiliser maintenant (billet, lanterne), en boutons dorés à côté du dé */
.actions-objets { display: flex; gap: 10px; }
.actions-objets:empty { display: none; }
.bouton-objet { min-height: 48px; padding: 0 18px 0 14px; font-size: 15px; box-shadow: 0 10px 26px rgba(0, 0, 0, .4), 0 0 0 4px rgba(255, 213, 122, .25); animation: appel 1.6s ease-in-out infinite; }
.bouton-objet .ic { width: 22px; height: 22px; }
.bouton-objet b { margin-left: 2px; font-size: 12px; opacity: .85; }

/* ---- barre du bas : la consigne et l'inventaire ; à droite, le journal */
.barre-bas {
  position: absolute; z-index: 20; left: var(--marge); right: var(--marge); bottom: 20px;
  display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none;
}
.consigne {
  max-width: min(600px, 100%); min-height: 34px; padding: 7px 16px; border-radius: 999px; pointer-events: auto;
  font-size: 14px; font-weight: 500; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.barre-bas-ligne { display: flex; align-items: center; gap: 12px; min-height: 56px; }
.actions { display: flex; align-items: center; gap: 12px; }
.actions > *, .inventaire { pointer-events: auto; }
#btn-action { min-height: 56px; padding: 0 30px; font-size: 17px; }
.inventaire { display: flex; gap: 6px; padding: 7px; border-radius: 999px; }
.slot {
  position: relative; width: 42px; height: 42px; display: grid; place-items: center; padding: 0;
  border: 0; border-radius: 50%; color: var(--or); background: rgba(255, 255, 255, .08); cursor: default;
}
.slot .ic { width: 22px; height: 22px; }
.slot.vide { opacity: .35; }
.slot b {
  position: absolute; right: -3px; top: -3px; min-width: 18px; padding: 1px 5px; border-radius: 9px;
  background: var(--or); color: var(--or-encre); font-size: 10px; font-weight: 700; line-height: 14px; text-align: center;
}
.slot.utilisable {
  cursor: pointer; background: rgba(255, 213, 122, .22);
  box-shadow: 0 0 0 2px rgba(255, 213, 122, .75), 0 0 14px rgba(255, 200, 90, .55); animation: appel 1.6s ease-in-out infinite;
}
.slot.utilisable:hover { background: rgba(255, 213, 122, .32); }
.slot.en-cours { background: rgba(255, 213, 122, .35); box-shadow: 0 0 0 2px var(--or); }
@keyframes appel { 50% { box-shadow: 0 0 0 5px rgba(255, 213, 122, .35), 0 0 22px rgba(255, 200, 90, .8); } }
.fil {
  position: absolute; right: 0; bottom: 0; width: 280px; pointer-events: none;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
}
.fil > * { pointer-events: auto; }
/* De 761 à 1100 px de large, le journal monte au-dessus de la barre du bas pour ne pas la heurter. */
@media (max-width: 1100px) and (min-width: 761px) { .fil { bottom: calc(100% + 10px); } }
/* ---- notifications : les derniers événements, au-dessus du bouton Journal ; les clics passent à la carte */
.notifications { list-style: none; width: 100%; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.fil > .notifications { pointer-events: none; }
.notification {
  position: relative; overflow: hidden; max-width: 100%; padding: 9px 13px; border-radius: 12px; font-size: 12.5px; line-height: 1.35;
  transition: opacity var(--duree) ease, translate var(--duree) var(--sortie), height var(--duree-lente) var(--sortie),
    padding var(--duree-lente) var(--sortie), margin var(--duree-lente) var(--sortie), border-width var(--duree-lente) var(--sortie);
}
.notification:nth-last-child(3) { opacity: .55; }
.notification:nth-last-child(2) { opacity: .8; }
/* elle glisse depuis la droite, un reflet passe (projet 6d) ; partie, elle s'efface et la pile se tasse en douceur */
.notification.entre { animation: notification-entre var(--duree) var(--sortie) both; }
@keyframes notification-entre { from { opacity: 0; translate: 24px 0; } }
.notification.entre::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .16) 50%, transparent 62%) no-repeat;
  background-size: 260% 100%; animation: reflet var(--duree-lente) var(--sortie) var(--duree) 1 both;
}
.notification.part { opacity: 0; translate: 14px 0; height: 0 !important; padding-top: 0; padding-bottom: 0; margin-top: -8px; border-top-width: 0; border-bottom-width: 0; }
.notification.part-vite { opacity: 0; transition: opacity var(--duree-vite) ease; }
.notification.j-rixe, .notification.j-voleur_vol, .notification.j-locomotive_vol, .notification.j-voleur_capture { font-weight: 700; }
.notification.j-fin { font-weight: 700; color: var(--or); }
/* Sur l'écran de jeu, les messages passent sous la barre du haut. */
body.ecran-partie .toast { top: var(--zone-haut); }

/* ---- panneaux à la demande : boutique, fin de partie, journal */
.panneau { position: absolute; z-index: 40; display: flex; flex-direction: column; gap: 12px; padding: 14px 16px 16px; }
.panneau:focus { outline: none; }
/* L'entrée et la sortie des panneaux de verre et du menu (projet 6d, js/interface.js pose `entre` puis `sort`) : à
   l'ouverture, 10 px plus bas → en place, 0,98 → 1, le flou de 0 à celui du verre, puis un reflet qui passe une fois ;
   à la fermeture, l'inverse, puis `hidden`. `translate` et `scale` s'ajoutent au `transform` qui centre le panneau. */
.panneau.entre, .menu.entre { animation: panneau-entre var(--duree) var(--sortie) both; }
html:not(.sans-flou) .panneau.entre, html:not(.sans-flou) .menu.entre { animation-name: panneau-entre, flou-entre; animation-duration: var(--duree), var(--duree); }
.panneau.sort, .menu.sort { animation: panneau-sort var(--duree) var(--sortie) forwards; pointer-events: none; }
@keyframes panneau-entre { from { opacity: 0; translate: 0 10px; scale: .98; } }
@keyframes panneau-sort { to { opacity: 0; translate: 0 10px; scale: .98; } }
@keyframes flou-entre { from { -webkit-backdrop-filter: blur(0) saturate(1); backdrop-filter: blur(0) saturate(1); } }
.panneau.entre::after, .menu.entre::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .14) 50%, transparent 62%) no-repeat;
  background-size: 260% 100%; animation: reflet var(--duree-lente) var(--sortie) var(--duree) 1 both;
}
@keyframes reflet { from { background-position: 130% 0; } to { background-position: -130% 0; } }
@keyframes fondu-entre { from { opacity: 0; } }
@keyframes fondu-sort { to { opacity: 0; } }
.panneau-entete { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
.panneau-entete h2 { font-family: var(--titre); font-weight: 700; font-size: 22px; color: var(--or); }
.btn-fermer { width: 36px; height: 36px; flex: none; display: grid; place-items: center; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .08); cursor: pointer; }
.btn-fermer:hover { background: rgba(255, 255, 255, .16); }
.boutique {
  left: 50%; top: calc(var(--zone-haut) + (100% - var(--zone-haut) - var(--zone-bas)) / 2); transform: translate(-50%, -50%);
  width: min(640px, calc(100vw - 32px)); max-height: calc(100% - var(--zone-haut) - var(--zone-bas));
}
.boutique-banque { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--texte-doux); }
.boutique-banque strong { font-size: 15px; color: var(--or); font-variant-numeric: tabular-nums; }
.boutique-liste { min-height: 0; overflow-y: auto; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.article {
  display: grid; grid-template-columns: 40px 1fr auto; grid-template-areas: 'icone texte prix' 'icone texte bouton';
  align-items: center; gap: 4px 10px; padding: 10px; border-radius: 12px; background: rgba(0, 0, 0, .24);   /* lisible sur le sable clair */
}
/* à l'ouverture de la boutique, les articles entrent en cascade (6d, js/interface.js pose `cascade` sur la liste) ;
   sans translation : la liste défile, un décalage ferait clignoter son ascenseur */
.boutique-liste.cascade .article { animation: article-entre var(--duree) var(--sortie) both; animation-delay: calc(var(--i, 0) * 40ms); }
@keyframes article-entre { from { opacity: 0; scale: .97; } }
/* à l'achat, l'icône de l'article vole jusqu'à sa case de l'inventaire (projet 6d, js/interface.js) */
.icone-en-vol { position: fixed; z-index: 60; pointer-events: none; color: var(--or); filter: drop-shadow(0 0 8px rgba(255, 213, 122, .9)); }
.boutique.consultation .article { grid-template-areas: 'icone texte prix'; }
.article-icone { grid-area: icone; justify-self: center; width: 30px; height: 30px; color: var(--or); }
.article-non .article-icone { opacity: .45; }
.article-texte { grid-area: texte; min-width: 0; }
.article-texte strong { font-size: 14px; }
.article-texte p { margin-top: 2px; font-size: 12px; line-height: 1.35; color: rgba(255, 255, 255, .78); }
.article-stock { margin-left: 6px; font-size: 11px; font-weight: 700; color: var(--or); }
.article-prix { grid-area: prix; justify-self: end; display: inline-flex; align-items: center; gap: 4px; font-weight: 700; font-variant-numeric: tabular-nums; }
.btn-acheter { grid-area: bouton; justify-self: end; }
.bouton-petit { min-height: 32px; padding: 0 14px; font-size: 13px; box-shadow: 0 6px 16px rgba(0, 0, 0, .35); }
#btn-boutique-fermer { align-self: center; }
.panneau-journal { right: var(--marge); top: var(--zone-haut); width: min(360px, calc(100vw - 32px)); max-height: calc(100% - var(--zone-haut) - var(--zone-bas)); }
/* Le classement au milieu de la carte, comme les boutons d'action : sa « Revanche » ne passe pas inaperçue. */
.fin {
  left: calc(var(--zone-gauche) + (100% - var(--zone-gauche) - var(--zone-droite)) / 2);
  top: calc(var(--zone-haut) + (100% - var(--zone-haut) - var(--zone-bas)) / 2); transform: translate(-50%, -50%);
  width: min(380px, calc(100vw - 32px)); max-height: calc(100% - var(--zone-haut) - var(--zone-bas));
}
.panneau-journal { z-index: 41; height: calc(100% - var(--zone-haut) - var(--zone-bas)); }
/* Les lignes gardent leur hauteur (max-content) : sous le plafond de la feuille, c'est la liste qui défile. Sans cela les
   lignes, `overflow: hidden`, rétrécissent toutes ensemble et rognent leur titre (projet 12a, petits écrans). */
.classement { list-style: none; min-height: 0; overflow-y: auto; display: grid; grid-auto-rows: max-content; gap: 6px; }
.classement li {
  position: relative; overflow: hidden; display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 12px;
  background: rgba(0, 0, 0, .24); font-variant-numeric: tabular-nums;
  animation: ligne-entre var(--duree-lente) var(--sortie) both; animation-delay: calc(var(--i, 0) * 120ms);   /* du dernier au premier (6d) */
}
@keyframes ligne-entre { from { opacity: 0; translate: -10px 0; } }
.classement li.gagnant { background: rgba(255, 213, 122, .18); box-shadow: inset 0 0 0 1px rgba(255, 213, 122, .55); }
/* le vainqueur garde un miroitement doré */
.classement li.gagnant::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 225, 150, .22) 50%, transparent 60%) no-repeat; background-size: 260% 100%;
  animation: miroitement 2.8s linear infinite;
}
@keyframes miroitement { from { background-position: 130% 0; } to { background-position: -130% 0; } }
.classement .rang { width: 22px; text-align: center; font-family: var(--titre); font-weight: 700; font-size: 20px; color: var(--or); }
.classement .nom { flex: 1; min-width: 0; font-weight: 600; }
.classement .nom small { display: block; font-weight: 400; font-size: 12px; color: var(--texte-doux); }
/* le titre de fin de partie (projet 12a) sous le détail : le nom du titre en gras, puis ce qui le justifie, en or doux
   (--or à 85 %) ; la phrase passe à la ligne plutôt que de finir en ellipse, et une ligne sans titre reste comme avant */
.classement .titre-fin { display: block; margin-top: 3px; font-weight: 400; font-size: 13px; line-height: 1.3; color: rgba(255, 213, 122, .85); overflow-wrap: anywhere; }
.classement .titre-fin strong { font-weight: 700; }
.classement .total { font-weight: 700; font-size: 18px; color: var(--or); }
/* La mission secrète de chacun (projet 12c), un bloc sous son titre : l'icône de mission puis « « Nom » : accomplie, +5 »
   (en or) ou « : ratée » (barrée d'un trait doux). Pendant la révélation de fin (js/interface.js, revelerFin), elle est
   d'abord face cachée (« Mission secrète », sur un verre plus sombre), puis se retourne (rotateX, de la tranche à plat). */
.classement .mission-fin {
  display: flex; align-items: center; gap: 5px; width: fit-content; max-width: 100%; margin-top: 4px;
  font-weight: 600; font-size: 13px; line-height: 1.3; overflow-wrap: anywhere;
}
.classement .mission-fin .ic { flex: none; width: 14px; height: 14px; }
.classement .mission-fin.cachee { padding: 1px 8px; border-radius: 6px; background: rgba(0, 0, 0, .32); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12); font-weight: 400; color: var(--texte-doux); }
.classement .mission-fin.reussie { color: var(--or); }
.classement .mission-fin.ratee { color: var(--texte-doux); text-decoration: line-through; text-decoration-color: rgba(255, 255, 255, .45); text-decoration-thickness: 1px; }
.classement .mission-fin.retournee { transform-origin: 50% 50%; animation: mission-fin-retourne var(--duree) var(--sortie) both; }
@keyframes mission-fin-retourne { from { transform: perspective(300px) rotateX(90deg); opacity: .2; } }
/* Pendant la révélation, ni Revanche, ni Tableau des scores, ni Quitter : ils reviennent quand le vainqueur s'illumine. Les
   lignes déjà entrées n'ont plus d'animation d'entrée (`posees`) : déplacées d'une place à l'autre, elles la rejoueraient. */
.fin.revelation #btn-revanche, .fin.revelation #btn-scores-fin, .fin.revelation #btn-quitter-fin { display: none; }
.classement.posees li { animation: none; }
.fin-boutons { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
.journal { list-style: none; flex: 1; min-height: 0; overflow-y: auto; display: grid; align-content: start; gap: 2px; padding-right: 4px; font-size: 13px; line-height: 1.45; }
.journal li { padding: 3px 8px; border-left: 2px solid transparent; border-radius: 4px; color: rgba(255, 255, 255, .85); }
.journal:empty::before { content: 'Rien encore : le journal se remplit au fil de la partie.'; padding: 3px 8px; font-style: italic; color: var(--texte-doux); }
.journal li.nouveau { border-left-color: var(--or); }
.journal li.j-rixe, .journal li.j-voleur_vol, .journal li.j-locomotive_vol, .journal li.j-voleur_capture { font-weight: 700; color: var(--texte); }
.journal li.j-fin { font-weight: 700; color: var(--or); }

/* ---- jusqu'au projet 4a : la vignette d'un événement, le compte à rebours de la marche, le dé 3D au centre de la carte */
.scene-cadre {
  width: min(360px, 72vw); padding: 8px;
  transform: translate(-50%, -50%) scale(.92); opacity: 0; transition: opacity 180ms ease, transform 180ms ease;
}
.scene-cadre.visible { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.scene-cadre:has(.scene-combat), .scene-cadre:has(.scene-fermer) { pointer-events: auto; }
.scene-vue { position: relative; aspect-ratio: 240 / 150; overflow: hidden; border-radius: 10px; background: var(--papier); }
.scene-vue svg { display: block; width: 100%; height: 100%; }
.scene-legende { margin: 7px 4px 1px; font-size: 13px; font-weight: 500; line-height: 1.35; text-align: center; }
.scene-combat {
  position: absolute; left: 50%; bottom: 10%; transform: translateX(-50%); pointer-events: auto;
  min-height: 44px; padding: 0 24px; font-family: var(--affiche); font-weight: 400; font-size: 20px; letter-spacing: .06em;
  animation: appel 1.2s ease-in-out infinite;
}
.scene-combat:active { transform: translateX(-50%) translateY(1px); }
/* Le bouton « Combat ! » sur le plateau (projet 6c) : au-dessus des combattants, il suit la caméra (js/app.js). */
.scene-combat-plateau {
  position: fixed; z-index: 18; transform: translateX(-50%); min-height: 48px; min-width: 128px; padding: 0 24px;
  font-family: var(--affiche); font-weight: 400; font-size: 20px; letter-spacing: .06em; animation: appel 1.2s ease-in-out infinite;
}
.scene-combat-plateau:active { transform: translateX(-50%) translateY(1px); }
.scene-fermer { position: absolute; right: 8px; top: 8px; min-height: 30px; padding: 0 12px; font-size: 12px; pointer-events: auto; }
/* Le compte à rebours et le dé du centre (17) passent au-dessus des bulles des réactions (16, projet 12b), et sous les
   boutons du milieu (17 aussi, plus loin dans la page). */
.compteur-centre {
  z-index: 17; transform: translate(-50%, -50%); min-width: 110px; padding: 4px 22px; text-align: center;
  font-family: var(--titre); font-weight: 700; font-size: 80px; line-height: 1.05; color: var(--or);
  font-variant-numeric: lining-nums tabular-nums;   /* des chiffres de capitale, tous sur la ligne (pas ceux de bas de casse) */
}
/* La ligne rognée au chiffre, de la ligne de base au haut des capitales : le chiffre au milieu exact de sa vitre. */
@supports (text-box: trim-both cap alphabetic) {
  .compteur-centre { text-box: trim-both cap alphabetic; padding-block: .2em; }
}
.compteur-centre.tic { animation: compteur-tic .3s ease-out; }
@keyframes compteur-tic { 0% { transform: translate(-50%, -50%) scale(1.25); } 100% { transform: translate(-50%, -50%) scale(1); } }
.de-centre { z-index: 17; transform: translate(-50%, -50%); display: grid; justify-items: center; gap: 12px; }
.de-centre-etiquette { padding: 6px 16px; border-radius: 999px; white-space: nowrap; font-weight: 600; font-size: 14px; }
/* L'étiquette du dé lancé sur le plateau (projet 6b) : au-dessus du dé, le temps qu'il reste. */
.de-etiquette { position: fixed; z-index: 17; transform: translate(-50%, -100%); padding: 6px 16px; border-radius: 999px;
  white-space: nowrap; font-weight: 600; font-size: 14px; pointer-events: none; opacity: 0; transition: opacity .25s ease; }
.de-etiquette.visible { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .de-etiquette { transition: none; } }

/* ---------------------------------------------------------------- tablette en hauteur, petit portable (761 à 1100 px de large) :
   la barre du haut se resserre (logo en image, jauge sans ses mots) pour que la pilule du tour garde le nom du joueur */
@media (max-width: 1100px) and (min-width: 761px) {
  .logo-partie { align-items: center; padding: 7px 14px; }
  .logo-texte { display: none; }
  .logo-image { display: block; width: 28px; height: 28px; }
  .jauge-train { width: auto; }
  .jauge-mot { display: none; }
  .jauge-barre { width: 64px; }
}

/* ---------------------------------------------------------------- téléphone tenu en hauteur (760 px de large ou moins) :
   la carte au milieu, en pleine largeur ; l'interface en deux bandes de verre, en haut et en bas ; les panneaux montent du bas */
@media (max-width: 760px) {
  .barre-haut, .barre-bas {
    left: 0; right: 0; border-radius: 0; pointer-events: auto;
    background: var(--verre); -webkit-backdrop-filter: var(--verre-flou); backdrop-filter: var(--verre-flou); box-shadow: var(--verre-ombre);
  }
  /* pas de verre sur le verre : dans les bandes, les éléments sont à plat */
  .barre-haut > .vitre, #btn-reglages, .barre-bas .vitre { background: none; -webkit-backdrop-filter: none; backdrop-filter: none; border: 0; box-shadow: none; }
  .barre-haut { top: 0; flex-wrap: wrap; gap: 6px 8px; padding: max(8px, env(safe-area-inset-top)) 10px 8px; border-bottom: 1px solid var(--verre-bord); }
  .logo-partie { padding: 0; }
  .logo-texte, .partie-code { display: none; }
  .logo-image { display: block; width: 28px; height: 28px; }
  .tour { flex: 1; margin: 0; padding: 4px 6px; font-size: 14px; }
  .tour.a-vous { box-shadow: none; color: var(--or); }
  .pastille { width: 18px; height: 18px; }
  .jauge-train { width: auto; gap: 6px; padding: 4px 2px; }
  .jauge-corps { gap: 4px; }
  .jauge-mot { display: none; }
  .jauge-texte b { font-size: 14px; }
  .jauge-barre { width: 44px; height: 5px; }
  .btn-icone { width: 36px; height: 36px; }
  #btn-quitter-partie { display: none; }
  .menu-telephone { display: flex; }
  .chercheurs {
    position: static; flex-basis: 100%; width: auto; max-height: none; padding: 0 0 2px;
    display: flex; gap: 6px; overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  }
  .joueur { flex: none; gap: 6px; padding: 3px 10px 3px 3px; border-radius: 999px; background: rgba(255, 255, 255, .06); }
  .joueur-nom { display: none; }
  .avatar { width: 26px; height: 26px; font-size: 12px; }
  .chiffres { gap: 6px; font-size: 12px; }
  .chiffres .ic { width: 13px; height: 13px; }

  .barre-bas { bottom: 0; gap: 6px; padding: 8px 10px max(8px, env(safe-area-inset-bottom)); border-top: 1px solid var(--verre-bord); }
  .consigne {
    width: 100%; max-width: none; min-height: 2.7em; padding: 0 4px; border-radius: 0; font-size: 13px; line-height: 1.35;
    white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  }
  .barre-bas-ligne { width: 100%; flex-direction: column; gap: 6px; min-height: 0; }
  .actions-centre #btn-action { min-height: 52px; padding: 0 26px; font-size: 17px; }
  .bouton-objet { min-height: 44px; padding: 0 14px 0 12px; font-size: 14px; }
  #btn-second, #btn-journal { min-height: 36px; border-radius: 999px; background: rgba(255, 255, 255, .08); }
  .inventaire { gap: 4px; padding: 0; }
  .slot { width: 38px; height: 38px; }
  .slot .ic { width: 20px; height: 20px; }
  .fil { position: static; width: 100%; flex-direction: row; align-items: center; gap: 8px; }
  .notifications { flex: 1; min-width: 0; display: block; }
  .notification { display: none; padding: 0; border-radius: 0; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .notification:last-child { display: block; opacity: 1; }
  .notification.part:last-child, .notification.part-vite:last-child { opacity: 0; }
  #btn-journal { flex: none; padding: 0 12px; }

  .panneau {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; width: auto; height: auto; transform: none;
    max-height: 85vh; max-height: 85dvh; border-radius: var(--rayon) var(--rayon) 0 0;
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }
  /* sur téléphone, le panneau monte du bas de l'écran */
  .panneau.entre { animation-name: panneau-entre-tel; }
  html:not(.sans-flou) .panneau.entre { animation-name: panneau-entre-tel, flou-entre; }
  .panneau.sort { animation-name: panneau-sort-tel; }
  .panneau-journal { height: 70vh; height: 70dvh; }
  .boutique-liste { grid-template-columns: 1fr; }
  .scene-cadre { width: min(320px, 86vw); }
  .compteur-centre { min-width: 84px; font-size: 56px; }
}
@keyframes panneau-entre-tel { from { opacity: 0; translate: 0 40px; } }
@keyframes panneau-sort-tel { to { opacity: 0; translate: 0 40px; } }

/* ---------------------------------------------------------------- petites hauteurs (téléphone tenu en largeur) :
   la disposition ordinateur, en barres compactes */
@media (max-height: 500px) and (min-width: 761px) {
  :root { --marge: 8px; }
  .barre-haut { gap: 8px; }
  .logo-partie { padding: 6px 12px; font-size: 17px; }
  .tour { padding: 6px 14px 6px 8px; font-size: 13px; }
  .pastille { width: 18px; height: 18px; }
  .jauge-train { width: 200px; padding: 6px 12px; }
  .btn-icone { width: 36px; height: 36px; }
  .btn-verre { min-height: 34px; padding: 0 12px; }
  .chercheurs { top: calc(100% + 8px); width: 210px; padding: 6px; max-height: calc(100vh - 160px); max-height: calc(100dvh - 160px); }
  .joueur { padding: 5px 6px; }
  .joueur-nom small { display: none; }
  .avatar { width: 26px; height: 26px; font-size: 12px; }
  .barre-bas { bottom: 8px; gap: 6px; }
  .consigne { min-height: 28px; padding: 4px 12px; font-size: 13px; }
  .barre-bas-ligne, #btn-action { min-height: 44px; }
  #btn-action { padding: 0 20px; font-size: 15px; }
  .slot { width: 34px; height: 34px; }
  .slot .ic { width: 19px; height: 19px; }
  .fil { width: 240px; }
  .scene-cadre { width: min(300px, 50vw); }
  .compteur-centre { font-size: 56px; }
}

/* ---------------------------------------------------------------- sans flou (navigateur qui ne sait pas flouter, ou garde-fou de
   fluidité déclenché par js/interface.js) : des panneaux presque opaques */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .vitre { background: var(--verre-opaque); }
}
html.sans-flou .vitre { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--verre-opaque); }
@media (max-width: 760px) {
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .barre-haut, .barre-bas { background: var(--verre-opaque); }
  }
  html.sans-flou .barre-haut, html.sans-flou .barre-bas { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--verre-opaque); }
  html.sans-flou .barre-haut > .vitre, html.sans-flou #btn-reglages, html.sans-flou .barre-bas .vitre { background: none; }
}

/* ---------------------------------------------------------------- « réduire les animations » du système : ni glissement ni fondu */
@media (prefers-reduced-motion: reduce) {
  .toast, .scene-cadre, .jauge-barre i, .interrupteur::after, .bouton-or, .presse, .pastille,
  .slot.utilisable, .scene-combat, .scene-combat-plateau, .compteur-centre.tic, .tour.reflet::after, .compte.eclat {
    animation: none !important; transition: none !important;
  }
  .jauge-corps.bouffee::after { display: none; }
  html:root .notification { transition: opacity var(--duree-vite) ease; }
  html:root .notification.entre { animation: fondu-entre var(--duree-vite) ease both; }
  html:root .boutique-liste.cascade .article, html:root .classement li { animation: fondu-entre var(--duree-vite) ease both; animation-delay: 0s; }
  html:root .classement li.gagnant::after { animation: none; }
  .notification.entre::after { display: none; }
}
/* « Réduire les animations », du système ou du réglage du jeu (html.sans-animations) : les panneaux et le menu entrent et
   sortent en fondus courts, sans reflet. Après les règles du téléphone : à spécificité égale, celles-ci gagnent. */
html.sans-animations .panneau.entre, html.sans-animations .menu.entre { animation: fondu-entre var(--duree-vite) ease both; }
html.sans-animations .panneau.sort, html.sans-animations .menu.sort { animation: fondu-sort var(--duree-vite) ease forwards; }
html.sans-animations .panneau.entre::after, html.sans-animations .menu.entre::after { display: none; }
html.sans-animations .notification { transition: opacity var(--duree-vite) ease; }
html.sans-animations .notification.entre { animation: fondu-entre var(--duree-vite) ease both; }
html.sans-animations .notification.entre::after { display: none; }
html.sans-animations .presse, html.sans-animations .tour.reflet::after, html.sans-animations .compte.eclat,
html.sans-animations .classement li.gagnant::after { animation: none; }
html.sans-animations .jauge-corps.bouffee::after { display: none; }
html.sans-animations .boutique-liste.cascade .article, html.sans-animations .classement li { animation: fondu-entre var(--duree-vite) ease both; animation-delay: 0s; }
html.sans-animations .pastille, html.sans-animations .jauge-barre i { transition: none; }
/* La révélation de fin (projet 12c) : la mission se retourne en fondu ; les lignes posées n'ont toujours pas d'animation
   d'entrée (html:root : plus fort que les fondus des lignes, juste au-dessus). */
@media (prefers-reduced-motion: reduce) {
  html:root .classement .mission-fin.retournee { animation: fondu-entre var(--duree-vite) ease both; }
}
html.sans-animations .classement .mission-fin.retournee { animation: fondu-entre var(--duree-vite) ease both; }
html:root .classement.posees li { animation: none; }
@media (prefers-reduced-motion: reduce) {
  html:root .panneau.entre, html:root .menu.entre { animation: fondu-entre var(--duree-vite) ease both; }
  html:root .panneau.sort, html:root .menu.sort { animation: fondu-sort var(--duree-vite) ease forwards; }
  html:root .panneau.entre::after, html:root .menu.entre::after { display: none; }
}

/* ---------------------------------------------------------------- dé 3D (js/de3d.js) */
.de3d {
  --t: 64px; --demi: calc(var(--t) / 2); --rx: 0deg; --ry: 0deg;
  --tx: -26deg; --ty: 34deg;      /* inclinaison de la vue : on voit trois faces (dessus, devant, côté) */
  position: relative; width: var(--t); height: var(--t);
  perspective: calc(var(--t) * 6); perspective-origin: 50% 20%;
}
.de3d-ombre {
  position: absolute; left: 10%; right: 10%; bottom: -8%; height: 18%;
  border-radius: 50%; background: rgba(42, 31, 20, 0.35); filter: blur(2px);
}
.de3d-chute { position: absolute; inset: 0; }
.de3d-cube {
  position: absolute; inset: 0; transform-style: preserve-3d;
  /* la face demandée est d'abord amenée devant (rx, ry), puis toute la vue est inclinée (tx, ty) */
  transform: rotateX(var(--tx)) rotateY(var(--ty)) rotateX(var(--rx)) rotateY(var(--ry));
}
.de3d-face {
  position: absolute; inset: 0; border-radius: 14%;
  background: radial-gradient(circle at 35% 30%, #fffdf5, #efe6cc 70%, #d9ccab);
  box-shadow: inset 0 0 0 2px #2a1f14, inset 0 0 calc(var(--t) * 0.18) rgba(60, 40, 10, 0.25);
  backface-visibility: hidden;
}
.de3d-face i {
  position: absolute; width: 18%; height: 18%; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #4a3a2a, #1d1510 70%);
  transform: translate(-50%, -50%);
}
.de3d-face-loco svg { position: absolute; inset: 12%; width: 76%; height: 76%; }
.de3d.lance .de3d-chute { animation: de3d-chute 1.15s cubic-bezier(0.3, 0.6, 0.4, 1) both; }
.de3d.lance .de3d-cube  { animation: de3d-tourne 1.15s cubic-bezier(0.2, 0.8, 0.3, 1) both; }
.de3d.lance .de3d-ombre { animation: de3d-ombre 1.15s cubic-bezier(0.3, 0.6, 0.4, 1) both; }
@keyframes de3d-chute {
  0%   { transform: translateY(-160%); }
  42%  { transform: translateY(0); }
  58%  { transform: translateY(-38%); }
  72%  { transform: translateY(0); }
  84%  { transform: translateY(-10%); }
  100% { transform: translateY(0); }
}
@keyframes de3d-tourne {
  0%   { transform: rotateX(var(--tx)) rotateY(var(--ty)) rotateX(calc(var(--rx) + 1080deg)) rotateY(calc(var(--ry) + 810deg)) rotateZ(40deg); }
  42%  { transform: rotateX(var(--tx)) rotateY(var(--ty)) rotateX(calc(var(--rx) + 480deg)) rotateY(calc(var(--ry) + 300deg)) rotateZ(10deg); }
  72%  { transform: rotateX(var(--tx)) rotateY(var(--ty)) rotateX(calc(var(--rx) + 120deg)) rotateY(calc(var(--ry) + 60deg)) rotateZ(-4deg); }
  100% { transform: rotateX(var(--tx)) rotateY(var(--ty)) rotateX(var(--rx)) rotateY(var(--ry)) rotateZ(0deg); }
}
@keyframes de3d-ombre {
  0%   { transform: scale(0.4); opacity: 0.15; }
  42%  { transform: scale(1); opacity: 1; }
  58%  { transform: scale(0.75); opacity: 0.5; }
  72%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.scene-de3d { position: absolute; right: 14%; top: 22%; }
@media (prefers-reduced-motion: reduce) {
  .de3d.lance .de3d-chute, .de3d.lance .de3d-cube, .de3d.lance .de3d-ombre { animation: none; }
}

/* ---------------------------------------------------------------- vignettes (js/formes.js, js/scenes.js) et pépite */
.pixel { image-rendering: pixelated; image-rendering: crisp-edges; }
.pion { transition: transform 450ms cubic-bezier(.4, 0, .2, 1); }
.pion.saut { transition: transform 300ms cubic-bezier(.3, 1.4, .5, 1); }
.loco.roule { transition: transform 900ms ease-in-out, opacity 300ms ease; }
.loco .fumee { animation: fumee 0.9s ease-out both; }
@keyframes fumee { 0% { transform: translate(0, 0) scale(0.6); opacity: 0.6; } 100% { transform: translate(8px, -26px) scale(2.2); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .pion, .loco { transition: none; } }
.pepite {
  display: inline-block; width: 11px; height: 11px; flex: none; border-radius: 50%; vertical-align: -1px;
  background: radial-gradient(circle at 35% 30%, #ffe37a, #d8a21c 60%, #8a5f0a);
}

/* ---------------------------------------------------------------- plateau rendu en PixiJS (js/rendu/) */
.plateau-canevas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; touch-action: none; }
.plateau-attente { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }

/* ---------------------------------------------------------------- le tableau des scores (projet 8, js/scores.js) : un
   panneau de verre au-dessus de tout (sous le bandeau des messages), ouvert depuis l'accueil et depuis l'écran de fin.
   Son bouton de l'accueil, à côté de « Créer une carte » (projet 11) : deux boutons de verre côte à côte, empilés sur téléphone. */
.accueil-boutons { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px; }
.bouton-accueil {
  display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; padding: 14px 20px;
  border: 1px solid var(--verre-bord); border-radius: var(--rayon); cursor: pointer;
  font-family: var(--titre); font-weight: 700; font-size: 20px; color: var(--or);
}
.bouton-accueil:hover { background: rgba(60, 46, 34, .62); }
.bouton-accueil .ic { width: 24px; height: 24px; }
#scores {
  position: fixed; z-index: 45; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(880px, calc(100vw - 32px)); height: min(680px, calc(100vh - 32px)); height: min(680px, calc(100dvh - 32px)); max-height: none;
}
.scores-barre, .parties-barre { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; }
.onglets { display: flex; gap: 4px; padding: 4px; border-radius: 999px; background: rgba(0, 0, 0, .28); }
.onglet { min-height: 36px; padding: 0 16px; border: 0; border-radius: 999px; background: none; cursor: pointer; font-weight: 600; color: var(--texte-doux); }
.onglet[aria-selected="true"] { background: rgba(255, 213, 122, .2); color: var(--or); box-shadow: inset 0 0 0 1px rgba(255, 213, 122, .5); }
.case { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--texte-doux); cursor: pointer; }
.case input { width: 18px; height: 18px; margin: 0; accent-color: var(--or); }
.scores-vue { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
/* le tableau défile dans son cadre, jamais la page ; la colonne des joueurs reste fixe quand il défile de côté */
.scores-cadre, .liste-parties { scrollbar-width: thin; scrollbar-color: rgba(255, 213, 122, .35) transparent; }
.scores-cadre { flex: 0 1 auto; min-height: 0; overflow: auto; border-radius: 12px; background: rgba(0, 0, 0, .2); }
.scores-table { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.scores-table th, .scores-table td { padding: 9px 12px; text-align: right; white-space: nowrap; }
.scores-table thead th {
  position: sticky; top: 0; z-index: 1; background: rgb(32, 25, 18);
  font-size: 12px; font-weight: 600; letter-spacing: .04em; color: var(--texte-doux);
}
.scores-table thead th:first-child { text-align: left; }
.scores-table thead button { padding: 0; border: 0; background: none; cursor: pointer; font: inherit; letter-spacing: inherit; color: inherit; }
.scores-table thead th[aria-sort] button { color: var(--or); }
.scores-table thead th[aria-sort="descending"] button::after { content: ' \25BE'; }
.scores-table thead th[aria-sort="ascending"] button::after { content: ' \25B4'; }
.scores-table tbody tr { border-top: 1px solid rgba(255, 255, 255, .06); }
.scores-table tbody th { text-align: left; font-weight: 600; }
.table-detail thead th { white-space: normal; min-width: 4.5em; vertical-align: bottom; }
.scores-table .fort { font-weight: 700; color: var(--or); }
.scores-table small { font-weight: 400; font-size: 12px; color: var(--texte-doux); }
.lien-joueur {
  max-width: 14em; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-weight: 600; color: var(--texte); text-align: left; text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, .3); text-underline-offset: 3px;
}
.lien-joueur:hover { color: var(--or); }
.etiquette { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; margin: 0; padding: 4px 4px 4px 12px; border-radius: 999px; background: rgba(255, 213, 122, .16); font-size: 14px; }
.etiquette b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.btn-etiquette { width: 26px; height: 26px; flex: none; display: grid; place-items: center; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .1); cursor: pointer; }
.btn-etiquette .ic { width: 14px; height: 14px; }
.tri { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--texte-doux); }
.tri select { padding: 6px 10px; border: 1px solid rgba(255, 255, 255, .22); border-radius: 10px; background: rgba(0, 0, 0, .35); font: inherit; color: var(--texte); }
.liste-parties { list-style: none; flex: 0 1 auto; min-height: 0; overflow-y: auto; display: grid; align-content: start; gap: 6px; outline: none; }
.partie-ligne {
  display: grid; grid-template-columns: minmax(140px, auto) minmax(0, 1fr); align-items: center; gap: 6px 14px;
  padding: 8px 12px; border-radius: 12px; background: rgba(0, 0, 0, .24); cursor: pointer;
}
.partie-ligne:hover { background: rgba(0, 0, 0, .36); }
.partie-ouvrir { display: grid; justify-items: start; gap: 2px; padding: 0; border: 0; background: none; cursor: pointer; text-align: left; font-weight: 600; }
.partie-ouvrir small { font-weight: 400; font-size: 12px; color: var(--texte-doux); }
.partie-joueurs { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.partie-joueurs li { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 3px 10px 3px 3px; border-radius: 999px; background: rgba(255, 255, 255, .06); font-size: 13px; }
.partie-joueurs li.gagnant { background: rgba(255, 213, 122, .18); box-shadow: inset 0 0 0 1px rgba(255, 213, 122, .55); }
.partie-joueurs .avatar { width: 24px; height: 24px; font-size: 11px; }
.partie-joueurs .nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.partie-joueurs small { font-size: 11px; color: var(--texte-doux); }
.partie-joueurs b { color: var(--or); font-variant-numeric: tabular-nums; }
#btn-plus-parties { align-self: center; }
#btn-retour-parties { align-self: flex-start; }
#btn-retour-parties::before { content: '\2190  '; }
.scores-message, .cartes-message { margin: 8px 0; text-align: center; font-style: italic; color: var(--texte-doux); }
.detail-partie { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
.detail-entete h3 { font-family: var(--titre); font-size: 20px; color: var(--or); }
.detail-entete p { font-size: 14px; color: var(--texte-doux); }
.joueur-detail { display: inline-flex; align-items: center; gap: 8px; }
.joueur-detail .rang { width: 18px; text-align: center; font-family: var(--titre); font-size: 18px; color: var(--or); }
/* le titre de fin de chaque joueur (projet 12a), sous son pseudo : à la ligne, dans la largeur d'un pseudo (la colonne des joueurs
   ne s'élargit pas, elle reste fixe sur téléphone), en or doux comme à l'écran de fin (.classement .titre-fin) */
.scores-table .titre-detail { display: block; max-width: 16em; margin-top: 2px; line-height: 1.3; white-space: normal; color: rgba(255, 213, 122, .85); overflow-wrap: anywhere; }
.scores-table .titre-detail strong { font-weight: 700; }
/* la mission secrète de chaque joueur (projet 12c), sous son titre : la même mise en page, en couleur douce */
.scores-table .mission-detail { display: block; max-width: 16em; margin-top: 2px; line-height: 1.3; white-space: normal; color: var(--texte-doux); overflow-wrap: anywhere; }
.scores-table .mission-detail strong { font-weight: 700; }
.table-detail tr.gagnant th, .table-detail tr.gagnant td { background: rgba(255, 213, 122, .12); }
@media (max-width: 760px) {
  #scores {
    inset: 0; transform: none; width: auto; height: auto; max-height: none; border-radius: 0;
    padding-top: max(14px, env(safe-area-inset-top));
  }
  .partie-ligne { grid-template-columns: minmax(0, 1fr); }
  .accueil-boutons { grid-template-columns: 1fr; gap: 12px; }
  .bouton-accueil { font-size: 18px; }
  /* le tableau défile de côté : la colonne des joueurs reste fixe, sur un fond plein qui cache ce qui passe dessous */
  .scores-table tbody th, .scores-table thead th:first-child { position: sticky; left: 0; z-index: 1; background: rgb(32, 25, 18); }
  .scores-table thead th:first-child { z-index: 2; }
  .table-detail tr.gagnant th { background: rgb(58, 46, 29); }
}

/* ---------------------------------------------------------------- le lobby (projet 8, js/lobby.js) : les tables ouvertes,
   dans le cadre « Rejoindre une table » ; la case « Table privée » et l'interrupteur du salon */
.carte .case { display: flex; margin: 12px 0 4px; font-size: 14px; font-weight: 500; letter-spacing: normal; text-transform: none; }
.carte .case input { display: inline-block; flex: none; width: 18px; height: 18px; margin: 0; padding: 0; border: 0; box-shadow: none; }
.tables-ouvertes { margin: 14px 0 6px; }
.carte .tables-titre { margin: 0 0 8px; font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--texte-doux); }
.liste-tables {
  list-style: none; display: grid; gap: 6px; max-height: 236px; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: rgba(255, 213, 122, .35) transparent;
}
.table-ouverte {
  display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 10px;
  border: 1px solid rgba(255, 255, 255, .08); border-radius: 12px; background: rgba(255, 255, 255, .06);
}
.table-avatars { display: flex; flex: none; }
.table-avatars .avatar { width: 26px; height: 26px; margin-left: -7px; font-size: 12px; }
.table-avatars .avatar:first-child { margin-left: 0; }
.table-texte { flex: 1; min-width: 0; display: grid; }
.table-texte strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; }
.table-texte small { font-size: 12px; color: var(--texte-doux); }
.carte .table-ouverte .bouton-or { flex: none; margin: 0; }
.carte .tables-vide { margin: 0; font-size: 14px; font-style: italic; }
.salon-public { margin-top: -14px; }
.btn-interrupteur { display: inline-flex; align-items: center; gap: 10px; }
.btn-interrupteur[aria-checked="true"] .interrupteur { background: rgba(255, 213, 122, .45); }
.btn-interrupteur[aria-checked="true"] .interrupteur::after { transform: translateX(14px); background: var(--or); }

/* ---------------------------------------------------------------- les cartes (projet 11, js/cartes.js) : la carte de la
   table au salon (sa vignette, son nom, son auteur) et le panneau du choix, ouvert par l'hôte ; sur téléphone, il monte du
   bas comme les autres panneaux */
.carte-table {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 14px;
  margin-bottom: 22px; padding: 10px; border: 1px solid rgba(255, 255, 255, .08); border-radius: 12px;
  background: rgba(255, 255, 255, .06); text-align: left;
}
.fiche-carte { flex: 1 1 240px; min-width: 0; display: flex; align-items: center; gap: 14px; }
.carte-vignette {
  flex: none; display: block; width: 132px; height: auto; aspect-ratio: 512 / 338; object-fit: cover;
  border-radius: 8px; background: rgba(0, 0, 0, .3); box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
}
.carte-texte { flex: 1; min-width: 0; display: grid; gap: 2px; }
/* un nom de carte long (40 caractères au plus) passe sur deux lignes, puis il est coupé */
.carte-texte strong {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere;
  font-family: var(--titre); font-weight: 700; font-size: 20px; line-height: 1.2; color: var(--or);
}
.carte-texte small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; color: var(--texte-doux); }
.carte-texte small:empty { display: none; }
#btn-changer-carte { flex: none; }
.cartes-choix { z-index: 45; }
@media (min-width: 761px) {
  .cartes-choix {
    position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
    width: min(640px, calc(100vw - 32px)); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px);
  }
}
.liste-cartes {
  list-style: none; min-height: 0; overflow-y: auto; display: grid; align-content: start; gap: 8px;
  scrollbar-width: thin; scrollbar-color: rgba(255, 213, 122, .35) transparent;
}
.carte-ligne { display: flex; align-items: center; gap: 14px; padding: 8px 12px 8px 8px; border-radius: 12px; background: rgba(0, 0, 0, .24); }
.carte-ligne.choisie { background: rgba(255, 213, 122, .14); box-shadow: inset 0 0 0 1px rgba(255, 213, 122, .5); }
.carte-ligne .carte-texte strong { font-size: 17px; }
.carte-ligne .bouton-petit { flex: none; }
.carte-ligne [aria-pressed="true"] { border-color: rgba(255, 213, 122, .55); border-radius: 999px; box-shadow: none; color: var(--or); }
@media (max-width: 760px) {
  .carte-vignette { width: 104px; }
  .carte-ligne { gap: 10px; }
}

/* ---------------------------------------------------------------- « Mes cartes » (projet 11, js/editeur/mes-cartes.js) : les
   cartes du joueur, ouvert par « Créer une carte » de l'accueil. Chaque carte avec sa vignette (ou sa place, un hexagone),
   son nom, son état en couleur et ses boutons. Au milieu de l'écran sur ordinateur ; sur téléphone, il monte du bas comme
   les autres panneaux, et les boutons d'une carte passent sous elle, assez hauts pour le doigt. */
#mes-cartes { z-index: 45; }
@media (min-width: 761px) {
  #mes-cartes {
    position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
    width: min(720px, calc(100vw - 32px)); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px);
  }
}
.mes-cartes-connexion { display: grid; justify-items: start; gap: 14px; }
.mes-cartes-connexion p { color: rgba(255, 255, 255, .88); }
.mes-cartes-compte { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
.mes-cartes-barre { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; }
.mes-cartes-nombre { font-size: 14px; color: var(--texte-doux); font-variant-numeric: tabular-nums; }
.mes-cartes-message { padding: 8px 12px; border-radius: 10px; background: rgba(255, 213, 122, .1); box-shadow: inset 3px 0 0 var(--or); font-size: 14px; }
.mes-cartes-message.erreur { background: rgba(224, 128, 95, .14); box-shadow: inset 3px 0 0 var(--alerte); }
/* vide, la ligne d'état reste dans la page (sa région vivante écoute) mais ne prend aucune place : hors du flux, invisible */
.mes-cartes-message:empty { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); box-shadow: none; }
.liste-mes-cartes {
  list-style: none; min-height: 0; overflow-y: auto; display: grid; align-content: start; gap: 8px;
  scrollbar-width: thin; scrollbar-color: rgba(255, 213, 122, .35) transparent;
}
.mes-cartes.occupe .liste-mes-cartes { cursor: progress; }
.ma-carte {
  display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: 'vignette texte' 'vignette actions';
  align-items: center; gap: 8px 14px; padding: 8px 12px 8px 8px; border-radius: 12px; background: rgba(0, 0, 0, .24);
}
.ma-carte > .carte-vignette { grid-area: vignette; }
.ma-carte > .carte-texte { grid-area: texte; }
.ma-carte .carte-texte strong { font-size: 17px; }
.ma-carte .carte-texte small { white-space: normal; overflow-wrap: anywhere; }     /* le message d'un échec se lit en entier */
.ma-carte-etat { font-weight: 600; }
.ma-carte-brouillon .ma-carte-etat { color: rgba(255, 255, 255, .85); }
.ma-carte-preparation .ma-carte-etat { color: var(--or); }
.ma-carte-prete .ma-carte-etat { color: #a3d993; }
.ma-carte-echec .ma-carte-etat { color: #ffb39b; }
.ma-carte-retiree .carte-vignette { opacity: .5; filter: grayscale(.7); }
.ma-carte-actions { grid-area: actions; display: flex; flex-wrap: wrap; gap: 6px 8px; }
.ma-carte-actions .bouton-petit { flex: none; }
.ma-carte-sans-image { display: grid; place-items: center; border: 1px dashed rgba(255, 255, 255, .18); box-shadow: none; color: rgba(255, 255, 255, .28); }
.ma-carte-sans-image svg { width: 34%; height: auto; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linejoin: round; }
.ma-carte-echec .ma-carte-sans-image { border-color: rgba(255, 179, 155, .3); color: rgba(255, 179, 155, .5); }
/* au four : un reflet doré passe sans fin sur la place de la vignette ; immobile quand on réduit les animations */
.ma-carte-preparation .ma-carte-sans-image {
  border-color: rgba(255, 213, 122, .35); color: rgba(255, 213, 122, .55);
  background: linear-gradient(115deg, rgba(0, 0, 0, .3) 35%, rgba(255, 213, 122, .16) 50%, rgba(0, 0, 0, .3) 65%) no-repeat;
  background-size: 260% 100%; animation: au-four 2.4s linear infinite;
}
@keyframes au-four { from { background-position: 130% 0; } to { background-position: -130% 0; } }
@media (prefers-reduced-motion: reduce) { .ma-carte-preparation .ma-carte-sans-image { animation: none; } }
html.sans-animations .ma-carte-preparation .ma-carte-sans-image { animation: none; }
@media (max-width: 760px) {
  .ma-carte { grid-template-areas: 'vignette texte' 'actions actions'; gap: 8px 10px; }
}
/* au doigt (téléphone en hauteur ou en largeur, tablette) : des boutons de 40 px */
@media (max-width: 760px), (pointer: coarse) {
  .ma-carte-actions .bouton-petit { min-height: 40px; }
}

/* ---------------------------------------------------------------- le message de panne du plateau (projet 10,
   js/rendu/panne.js) : sans WebGL, ou quand le plateau 3D est tombé trop souvent ; au milieu du plateau, sous les barres */
.panne-plateau {
  position: absolute; left: 50%; top: 50%; right: auto; bottom: auto; transform: translate(-50%, -50%);
  width: min(440px, calc(100% - 32px)); height: auto; max-height: none; border-radius: var(--rayon);   /* pas la feuille du téléphone */
  gap: 14px; padding: 22px 22px 20px; align-items: center; text-align: center;
}
.panne-plateau h2 { font-family: var(--titre); font-weight: 700; font-size: 22px; color: var(--or); }
.panne-plateau p { color: rgba(255, 255, 255, .88); line-height: 1.45; }
.panne-plateau .bouton-or { min-height: 48px; padding: 0 22px; }
/* Le message garde le milieu de l'écran : le dé, les scènes et les boutons du centre n'y servent plus (sans plateau, on
   ne joue pas son coup) ; les barres, le journal et les notifications restent. */
.partie:has(> .plateau > .panne-plateau) .au-centre { display: none !important; }

/* ---------------------------------------------------------------- les fenêtres du jeu (js/dialogue.js), à la place de celles
   du navigateur : au-dessus de tout, bandeau des messages compris, sur un fond qui assombrit et retient les clics */
.dialogue-fond { position: fixed; inset: 0; z-index: 54; background: rgba(8, 6, 4, .55); }
#dialogue {
  position: fixed; z-index: 55; left: 50%; top: 50%; right: auto; bottom: auto; transform: translate(-50%, -50%);
  width: min(440px, calc(100vw - 32px)); height: auto; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px);
  gap: 14px; padding: 22px 22px 20px; border-radius: var(--rayon);
}
#dialogue h2 { font-family: var(--titre); font-weight: 700; font-size: 22px; color: var(--or); }
.dialogue-texte { color: rgba(255, 255, 255, .88); }
.dialogue-champ {
  display: block; width: 100%; padding: 10px 12px; border: 1px solid rgba(255, 255, 255, .22); border-radius: 10px;
  background: rgba(0, 0, 0, .3); font-size: 17px; color: var(--texte);
}
.dialogue-champ::placeholder { color: rgba(255, 255, 255, .4); }
.dialogue-champ:focus { outline: none; border-color: var(--or); box-shadow: 0 0 0 3px rgba(255, 213, 122, .3); }
.dialogue-boutons { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: 4px; }
.dialogue-boutons .btn-verre { min-height: 48px; padding: 0 20px; border-radius: 999px; }
.dialogue-boutons .bouton-or:disabled { cursor: not-allowed; filter: grayscale(.6); opacity: .55; }
@media (max-width: 760px) {
  #dialogue { left: 50%; right: auto; top: 50%; bottom: auto; transform: translate(-50%, -50%); width: calc(100vw - 32px); border-radius: var(--rayon); }
  .dialogue-boutons > * { flex: 1 1 auto; }
}

/* ---------------------------------------------------------------- l'éditeur de cartes (projet 11, js/editeur/vue.js) : un
   écran à part sur l'image du plateau, plus voilée. L'en-tête (Retour, le nom, l'enregistrement, Publier) ; à gauche la
   palette, au milieu la carte et sous elle l'historique (Annuler, Rétablir, Tout effacer), à droite la vérification.
   Tablette : la vérification passe sous la carte ; téléphone : la carte en pleine largeur, la palette en bande qui défile
   sous elle. Seule la carte retient le doigt (touch-action) : ailleurs, la page défile. */
body.ecran-editeur { background: transparent; }
body.ecran-editeur::before {
  content: ''; position: fixed; inset: 0; z-index: -1;
  background: linear-gradient(rgba(14, 10, 7, .8), rgba(14, 10, 7, .92)), url('../img/rendu/repli.webp') center / cover no-repeat;
}
.editeur {
  --bon: #a3d993;           /* un compteur juste : vert tendre, lisible sur le verre */
  --mauvais: #ffb39b;       /* ce qui est à corriger : le corail de l'alerte, éclairci pour le texte */
  --colonne-outils: 208px;
  --colonne-verif: 284px;
  min-height: 100vh; min-height: 100dvh;
  display: grid; align-items: start; gap: 12px; padding: 12px var(--marge) 20px;
  grid-template-columns: var(--colonne-outils) minmax(0, 1fr) var(--colonne-verif);
  grid-template-rows: auto auto 1fr;
  grid-template-areas: 'entete entete entete' 'palette carte verif' 'palette commandes verif';
}
.editeur-entete { grid-area: entete; display: flex; align-items: center; gap: 14px; padding: 10px 14px; }
.editeur-retour::before { content: '\2190'; }
.editeur-nommer { flex: 1; min-width: 0; display: grid; gap: 3px; }
.editeur-nom {
  width: min(100%, 440px); padding: 5px 10px; border: 1px solid rgba(255, 255, 255, .22); border-radius: 10px; background: rgba(0, 0, 0, .3);
  font-family: var(--titre); font-weight: 700; font-size: 21px; line-height: 1.2; color: var(--or);
}
.editeur-nom:focus { outline: none; border-color: var(--or); box-shadow: 0 0 0 3px rgba(255, 213, 122, .3); }
.editeur.lecture .editeur-nom { padding-left: 0; border-color: transparent; background: none; box-shadow: none; }
.editeur-nom[aria-invalid="true"] { border-color: var(--alerte); }
.editeur-sous-titre { display: flex; flex-wrap: wrap; gap: 2px 12px; min-height: 18px; font-size: 13px; line-height: 1.35; color: var(--texte-doux); }
.editeur-etat[data-etat="enregistre"] { color: var(--bon); }
.editeur-etat[data-etat="echec"], .editeur-nom-refus { color: var(--mauvais); }
.editeur-publier { flex: none; }

.editeur-palette { grid-area: palette; min-width: 0; display: grid; gap: 7px; padding: 10px 8px; }
.pinceaux-groupe { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.pinceaux-titre { grid-column: 1 / -1; padding: 0 6px 2px; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--texte-doux); }
.pinceau {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; width: 100%; min-height: 29px; padding: 2px 8px 2px 4px;
  border: 0; border-radius: 9px; background: none; cursor: pointer; font-size: 13px; font-weight: 500; line-height: 1.2; text-align: left;
}
.pinceau[data-pinceau^="entree"] { grid-column: auto; gap: 6px; padding-right: 4px; white-space: nowrap; }   /* les quatre entrées de la mine, deux par ligne */
.pinceau:hover { background: rgba(255, 255, 255, .08); }
.pinceau[aria-pressed="true"] { background: rgba(255, 213, 122, .18); box-shadow: inset 0 0 0 1px rgba(255, 213, 122, .6); color: var(--or); font-weight: 600; }
.pinceau-echantillon { flex: none; width: 24px; height: 27px; }
.editeur-commandes { grid-area: commandes; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.editeur-lecture { grid-area: palette; display: grid; gap: 12px; padding: 14px; font-size: 14px; color: rgba(255, 255, 255, .88); }
.editeur-lecture .bouton-or { min-height: 44px; padding: 8px 18px; white-space: normal; line-height: 1.25; text-align: center; }
.editeur.lecture .editeur-palette, .editeur.lecture .editeur-commandes, .editeur.lecture .editeur-publier { display: none; }

/* la carte : aussi large que la colonne le permet, sans que l'historique, dessous, sorte de l'écran (la carte est
   1680 × 1108,5) */
.editeur-cadre {
  grid-area: carte; position: relative; justify-self: center; padding: 8px;
  width: min(100%, calc((100vh - 184px) * 1680 / 1108.5)); width: min(100%, calc((100dvh - 184px) * 1680 / 1108.5));
}
.editeur-carte {
  display: block; width: 100%; height: auto; border-radius: 10px;
  touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.editeur:not(.lecture) .editeur-carte { cursor: crosshair; }
.editeur.lecture .editeur-carte { touch-action: auto; }          /* rien à peindre : le doigt fait défiler la page */
.editeur-carte:focus { outline: none; }
.editeur-carte:focus-visible { outline: 3px solid var(--or); outline-offset: 3px; }
.editeur-attente { display: none; position: absolute; inset: 0; place-items: center; font-style: italic; color: var(--texte-doux); }
.editeur.charge .editeur-attente { display: grid; }
.editeur.charge .editeur-carte { visibility: hidden; }
/* les sols, des teintes sobres proches du terrain cuit (img/rendu/), plus claires pour se lire ; chaque matière a sa marque
   (herbe, vagues, roche, rails…) pour se reconnaître sans les couleurs */
.editeur-sol { stroke: rgba(28, 18, 10, .45); stroke-width: 1px; vector-effect: non-scaling-stroke; }
.sol-sable { fill: #d1a766; }
.sol-prairie { fill: #8e9348; }
.sol-gres { fill: #96513a; }
.sol-eau { fill: #3b86ad; }
.sol-place { fill: #c7b593; }
.sol-rue { fill: #8b7461; }
.sol-voie { fill: #a2988a; }
.sol-entree { fill: #594332; }
.sol-inconnu { fill: #6d6d6d; }
.editeur-herbe { fill: none; stroke: #5d6828; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.editeur-vague { fill: none; stroke: rgba(255, 255, 255, .5); stroke-width: 4; stroke-linecap: round; }
.editeur-roche { fill: none; stroke: #6a3222; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.editeur-paves { fill: none; stroke: #6c5747; stroke-width: 6; stroke-linecap: round; }
.editeur-puits { fill: #8f7b5d; stroke: #463626; stroke-width: 3; }
.editeur-puits-eau { fill: #3b86ad; }
.editeur-rail-fond { stroke: #403a34; stroke-width: 18; stroke-linecap: round; }
.editeur-rail { stroke: #d6cebf; stroke-width: 10; stroke-dasharray: 3 6; }
.editeur-quai { fill: #6e4f33; stroke: #2a1806; stroke-width: 3; }
.editeur-jetee { fill: #80562f; stroke: #34200f; stroke-width: 3; }
.editeur-planches { fill: none; stroke: #34200f; stroke-width: 2; }
.editeur-radeau rect { fill: #cf9958; stroke: #34200f; stroke-width: 2.5; }
.editeur-maison { stroke: #2a1806; stroke-width: 3; stroke-linejoin: round; }
.editeur-porte { fill: #2a1806; }
.editeur-batiment { fill: #7a5131; stroke: #2a1806; stroke-width: 3; stroke-linejoin: round; }
.editeur-fenetres { fill: #f0d49a; }
.editeur-grotte { fill: #1d130c; }
.editeur-numero { fill: var(--or); font-family: var(--police); font-weight: 700; font-size: 34px; text-anchor: middle; dominant-baseline: central; }
.editeur-jeton { fill: url(#editeur-or); stroke: #5e400c; stroke-width: 2.5; }
/* les cases de la faute, soulignées ; la case sous la souris, celle du curseur du clavier */
.editeur-fautes, .editeur-survol, .editeur-curseur { pointer-events: none; }
.editeur-faute-case { fill: rgba(255, 92, 64, .3); stroke: #ff6a4d; stroke-width: 3px; vector-effect: non-scaling-stroke; animation: faute 1.4s ease-in-out infinite alternate; }
@keyframes faute { from { opacity: .55; } }
.editeur-survol, .editeur-curseur { display: none; fill: rgba(255, 213, 122, .14); stroke: var(--or); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.editeur-curseur { fill: none; stroke-width: 3px; stroke-dasharray: 6 4; }
.editeur-survol.visible, .editeur-curseur.visible { display: inline; }

.editeur-verif { grid-area: verif; display: grid; gap: 12px; padding: 14px 16px 16px; }
.editeur-verif h2 { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-family: var(--titre); font-size: 20px; color: var(--or); }
.editeur-verdict { padding: 2px 10px; border-radius: 999px; font-family: var(--police); font-size: 12px; font-weight: 700; letter-spacing: .02em; }
.editeur-verdict:empty { display: none; }
.editeur-verdict.ok { background: rgba(163, 217, 147, .14); color: var(--bon); box-shadow: inset 0 0 0 1px rgba(163, 217, 147, .5); }
.editeur-verdict.ko { background: rgba(224, 128, 95, .16); color: var(--mauvais); box-shadow: inset 0 0 0 1px rgba(224, 128, 95, .55); }
.editeur-compteurs { list-style: none; display: grid; gap: 5px; font-size: 14px; font-variant-numeric: tabular-nums; }
.editeur-compteurs li { display: flex; align-items: baseline; gap: 8px; }
.editeur-compteurs li::before { content: ''; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--bon); transform: translateY(-1px); }
.editeur-compteurs li.ko { color: var(--mauvais); }
.editeur-compteurs li.ko::before { background: var(--alerte); }
.editeur-compteurs li.attente { font-style: italic; color: var(--texte-doux); }
.editeur-compteurs li.attente::before { display: none; }
.editeur-equite { display: grid; gap: 6px; }
.editeur-equite-titre { font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--texte-doux); }
.editeur-barres { list-style: none; display: grid; gap: 5px; }
.editeur-barres:empty { display: none; }
.editeur-barres li { position: relative; height: 8px; overflow: hidden; border-radius: 4px; background: rgba(255, 255, 255, .1); }
.editeur-barres li::after { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--part, 0) * 100%); border-radius: inherit; background: var(--couleur, #888); }
.editeur-equite-texte { font-size: 14px; color: var(--bon); }
.editeur-equite-texte.ko { color: var(--mauvais); }
.editeur-faute { padding: 10px 12px; border-radius: 10px; background: rgba(224, 128, 95, .16); box-shadow: inset 3px 0 0 var(--alerte); font-size: 14px; line-height: 1.4; overflow-wrap: anywhere; }
.editeur-verif-erreur { font-size: 13px; font-style: italic; color: var(--texte-doux); }
/* une vérification qui attend la nouvelle carte : l'ancienne reste, pâlie */
.editeur-verif.perimee :is(.editeur-compteurs, .editeur-equite, .editeur-faute, .editeur-verdict) { opacity: .5; }
.editeur-verif :is(.editeur-compteurs, .editeur-equite, .editeur-faute, .editeur-verdict) { transition: opacity var(--duree) ease; }
@media (max-height: 760px) and (min-width: 761px) {
  .editeur-palette { gap: 4px; padding: 8px; }
  .pinceau { min-height: 26px; }
}
/* tablette, petit portable : la palette à gauche, la carte et l'historique, puis la vérification dessous */
@media (max-width: 1100px) and (min-width: 761px) {
  .editeur {
    grid-template-columns: var(--colonne-outils) minmax(0, 1fr); grid-template-rows: auto auto auto 1fr;
    grid-template-areas: 'entete entete' 'palette carte' 'palette commandes' 'palette verif';
  }
}
/* téléphone tenu en largeur : l'écran est bas, la carte prend toute sa hauteur sous l'en-tête ; l'historique et la
   vérification viennent en faisant défiler la page */
@media (max-height: 560px) and (min-width: 761px) {
  .editeur { gap: 8px; padding: 8px var(--marge) 14px; }
  .editeur-entete { padding: 6px 10px; }
  .editeur-cadre { padding: 4px; width: min(100%, calc((100vh - 100px) * 1680 / 1108.5)); width: min(100%, calc((100dvh - 100px) * 1680 / 1108.5)); }
}
/* téléphone : la carte en pleine largeur, puis la palette en bande qui défile de côté, l'historique, la vérification */
@media (max-width: 760px) {
  .editeur {
    grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: 'entete' 'carte' 'palette' 'commandes' 'verif'; gap: 8px;
    padding: max(8px, env(safe-area-inset-top)) 8px max(14px, env(safe-area-inset-bottom));
  }
  .editeur-entete { gap: 8px; padding: 8px; }
  .editeur-retour { padding: 0 12px; }
  .editeur-nom { padding: 4px 8px; font-size: 17px; }
  .editeur-publier { min-height: 40px; padding: 0 16px; font-size: 15px; }
  .editeur-cadre { width: 100%; padding: 4px; }
  .editeur-commandes { flex-wrap: nowrap; gap: 8px; }
  .editeur-commandes .btn-verre { flex: 1 1 0; min-width: 0; padding: 0 8px; }
}
/* la palette en bande qui défile de côté : sur téléphone, et sur un écran bas tenu en largeur */
@media (max-width: 760px), (max-width: 1100px) and (max-height: 560px) and (orientation: landscape) {
  .editeur-palette {
    display: flex; gap: 10px; padding: 6px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
  }
  .editeur-palette::-webkit-scrollbar { display: none; }
  .pinceaux-groupe { display: flex; flex: none; gap: 4px; }
  .pinceaux-groupe + .pinceaux-groupe { padding-left: 10px; border-left: 1px solid rgba(255, 255, 255, .14); }
  .pinceaux-titre { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  /* la mise en bande des entrées a besoin du sélecteur des entrées (leur marge de droite, plus haut) ; leur fond, non : sous
     .pinceau seul, le pinceau choisi (aria-pressed) et le survol gardent le leur, Entrée N comme les autres */
  .pinceau, .pinceau[data-pinceau^="entree"] { flex: none; width: auto; min-height: 40px; padding: 2px 12px 2px 6px; white-space: nowrap; }
  .pinceau { background: rgba(255, 255, 255, .06); }
}
/* à la souris (une fenêtre d'ordinateur basse, 1024 × 500 : la bande en cache la plupart), la bande garde sa barre de
   défilement, pour que chaque pinceau soit à portée ; au doigt, elle défile sans barre */
@media (max-width: 760px) and (pointer: fine), (max-width: 1100px) and (max-height: 560px) and (orientation: landscape) and (pointer: fine) {
  .editeur-palette { scrollbar-width: thin; scrollbar-color: rgba(255, 213, 122, .35) transparent; }
  .editeur-palette::-webkit-scrollbar { display: block; height: 8px; }
  .editeur-palette::-webkit-scrollbar-thumb { border-radius: 4px; background: rgba(255, 213, 122, .35); }
}
/* téléphone tenu en largeur, petite tablette basse (l'écran bas, 1100 px de large au plus) : la carte à gauche, aussi haute
   que l'écran sous l'en-tête ; à sa droite la palette en bande, et l'historique juste dessous (sa rangée prend la hauteur de
   la carte) ; la vérification sous le tout. En pleine largeur, la carte dépasserait l'écran et retiendrait chaque glissé du
   doigt (touch-action) : la page ne défilerait plus jusqu'à la palette. */
@media (max-width: 1100px) and (max-height: 560px) and (orientation: landscape) {
  .editeur {
    --largeur-carte: min(62vw, calc((100vh - 100px) * 1680 / 1108.5));
    grid-template-columns: var(--largeur-carte) minmax(0, 1fr); grid-template-rows: auto auto 1fr auto;
    grid-template-areas: 'entete entete' 'carte palette' 'carte commandes' 'verif verif';
  }
  @supports (height: 100dvh) { .editeur { --largeur-carte: min(62vw, calc((100dvh - 100px) * 1680 / 1108.5)); } }
  .editeur-cadre { width: 100%; padding: 4px; }
  .editeur-commandes { flex-wrap: wrap; justify-content: stretch; }
  .editeur-commandes .btn-verre { flex: 1 1 auto; }
}
@media (prefers-reduced-motion: reduce) { .editeur-faute-case { animation: none; } }
html.sans-animations .editeur-faute-case { animation: none; }

/* ---------------------------------------------------------------- les réactions (projet 12b, js/reactions.js) : le bouton
   Réagir (dans la barre du bas à côté de l'inventaire ; sur téléphone, dans la ligne du Journal ; dans le classement de fin),
   la planche de verre des huit réactions, et la bulle de verre de chaque réaction, au-dessus de la figurine de son auteur
   et près de son nom, au liseré et à la pointe de sa couleur */
.btn-reagir { border-radius: 50%; color: var(--or); pointer-events: auto; }
.btn-reagir:not(:disabled):not([aria-disabled="true"]):hover { background: rgba(60, 46, 34, .62); }
/* Grisé par la cadence : aria-disabled (js/reactions.js : il garde ainsi le focus, et son clic n'ouvre rien). */
.btn-reagir:disabled, .btn-reagir[aria-disabled="true"] { cursor: not-allowed; opacity: .45; }
#btn-reagir { width: 48px; height: 48px; }
#btn-reagir .ic { width: 24px; height: 24px; }
/* En petites hauteurs (téléphone tenu en largeur), les icônes des barres passent à 36 px : Réagir aussi. */
@media (max-height: 500px) and (min-width: 761px) {
  #btn-reagir { width: 36px; height: 36px; }
  #btn-reagir .ic { width: 20px; height: 20px; }
}
#btn-reagir-tel { display: none; }
.fin-boutons .btn-reagir { width: 44px; height: 44px; margin-right: auto; }
.fin-boutons .btn-reagir .ic { width: 22px; height: 22px; }

/* La planche, au-dessus de la barre du bas, centrée (sur téléphone, elle monte du bas comme les autres panneaux) ; huit
   boutons de texte en Rye, sur quatre colonnes (deux sur téléphone) ; un texte trop long passe à la ligne, équilibré. */
.planche-reactions { z-index: 42; }
@media (min-width: 761px) {
  .planche-reactions { left: 50%; bottom: var(--zone-bas); transform: translateX(-50%); width: min(560px, calc(100vw - 32px)); }
}
.liste-reactions { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.reaction-choix {
  min-height: 46px; padding: 6px 8px; border: 0; border-radius: 12px; background: rgba(0, 0, 0, .24); cursor: pointer;
  font-family: var(--affiche); font-weight: 400; font-size: 16px; line-height: 1.15; letter-spacing: .02em; color: var(--texte);
  text-align: center; white-space: normal; text-wrap: balance;
  transition: background-color var(--duree-vite) ease, color var(--duree-vite) ease, box-shadow var(--duree-vite) ease;
}
.reaction-choix:not(:disabled):hover, .reaction-choix:focus-visible { background: rgba(255, 213, 122, .2); color: var(--or); box-shadow: inset 0 0 0 1px rgba(255, 213, 122, .55); }
.reaction-choix:disabled { cursor: not-allowed; opacity: .45; }

/* La bulle : en position fixe hors du plateau et hors du flux, placée à chaque image par js/reactions.js (left, top, et
   --pointe : où tombe la pointe, en pixels depuis le bord gauche de la bulle). Celle du plateau a sa pointe en bas, dont le
   bout dépasse de 8 px (son point au-dessus de la tête) ; celle de la liste des chercheurs, à gauche (8 px), au milieu de sa
   hauteur ; sur téléphone, en haut (6 px : le bout touche la bande du haut). La pointe part de l'intérieur du liseré
   (2 px), qu'elle recouvre : liseré et pointe ne font qu'un. Une bulle écartée d'une autre (empilee) n'a plus de pointe.
   Son étage : au-dessus de la vignette des événements (15), sous les boutons du milieu de la carte, l'étiquette du dé, le
   compte à rebours de la marche et le dé du centre (17) et sous le bouton « Combat ! » (18), posé lui aussi au-dessus des
   têtes : une bulle ne les cache jamais. À l'écran de fin, celles de la liste passent sur la feuille du classement (voir
   plus bas). */
.bulle {
  --couleur: #888;
  position: fixed; left: 0; top: 0; z-index: 16; pointer-events: none;
  white-space: nowrap; padding: 5px 14px; border: 2px solid var(--couleur); border-radius: 999px;
  font-family: var(--affiche); font-weight: 400; font-size: 17px; line-height: 1.25; letter-spacing: .02em;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6); box-shadow: 0 6px 18px rgba(0, 0, 0, .38);
  transform-origin: var(--pointe, 50%) calc(100% + 8px);
}
.bulle::after {
  content: ''; position: absolute; left: calc(var(--pointe, 50%) - 2px); top: 100%; width: 16px; height: 10px; margin-left: -8px;
  background: var(--couleur); clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.bulle-liste { transform-origin: -8px 50%; }
.bulle-liste::after { left: auto; right: 100%; top: 50%; width: 10px; height: 16px; margin: -8px 0 0; clip-path: polygon(100% 0, 100% 100%, 0 50%); }
.bulle.empilee::after { display: none; }
/* elle paraît avec un petit ressort, depuis sa pointe ; « On se dépêche ? » tapote trois fois ; puis elle s'efface */
.bulle.entre { animation: bulle-entre var(--duree) var(--ressort) both; }
.bulle.tapote { animation: bulle-tapote 1.2s linear both; }
.bulle.entre.tapote { animation: bulle-entre var(--duree) var(--ressort) both, bulle-tapote 1.2s linear both; }
.bulle.sort { animation: fondu-sort var(--duree) ease forwards; }
@keyframes bulle-entre { from { opacity: 0; scale: .7; } }
@keyframes bulle-tapote {
  0%, 33.3%, 66.6% { translate: 0 0; animation-timing-function: cubic-bezier(.2, .7, .4, 1); }     /* elle monte de 3 px… */
  9%, 42.3%, 75.6% { translate: 0 -3px; animation-timing-function: cubic-bezier(.5, 0, .8, .4); }  /* …et retombe */
  20%, 53.3%, 86.6%, 100% { translate: 0 0; }
}
/* L'écran de fin : tant que la feuille du classement est ouverte (un .panneau, 40), les bulles de la liste passent dessus
   (41 : sous la planche des réactions, 42, et sous le journal, 41 mais plus loin dans la page). Sur téléphone, la feuille
   monte jusque sous la bande du haut, où elles paraissent. Celles du plateau restent dessous : la bulle de la liste dit la
   même chose. Un navigateur sans :has() ignore la règle : elles restent sous la feuille. */
#ecran-partie:has(> #fin:not([hidden]):not(.sort)) .bulle-liste { z-index: 41; }

@media (max-width: 760px) {
  #btn-reagir { display: none; }
  #btn-reagir-tel { display: inline-grid; flex: none; width: 36px; height: 36px; background: rgba(255, 255, 255, .08); }
  .liste-reactions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bulle-liste { transform-origin: var(--pointe, 50%) -6px; }
  .bulle-liste::after {
    left: calc(var(--pointe, 50%) - 2px); right: auto; top: auto; bottom: 100%; width: 14px; height: 8px; margin: 0 0 0 -7px;
    clip-path: polygon(50% 0, 100% 100%, 0 100%);
  }
}

/* « Réduire les animations », du système ou du réglage du jeu (html.sans-animations) : la bulle entre en fondu court, sans
   ressort ni tapotement (la règle de l'entrée vient après celle du tapotement : une bulle qui a les deux entre en fondu). */
@media (prefers-reduced-motion: reduce) {
  html:root .bulle.tapote { animation: none; }
  html:root .bulle.entre { animation: fondu-entre var(--duree-vite) ease both; }
}
html.sans-animations .bulle.tapote { animation: none; }
html.sans-animations .bulle.entre { animation: fondu-entre var(--duree-vite) ease both; }

/* ---------------------------------------------------------------- la mission secrète (projet 12c, js/missions.js) : sa carte
   de verre (sur ordinateur en bas à gauche, sous la liste des chercheurs et à sa largeur ; sur téléphone une ligne en tête de
   la bande du bas ; de 761 à 1100 px de large et en petites hauteurs, derrière son bouton à côté de Réagir), le calque du
   milieu de l'écran (le retournement du début, « Mission accomplie ! ») et la pastille dorée d'une mission remplie. */
.carte-mission { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; padding: 12px 14px; pointer-events: auto; text-align: left; }
.mission-titre { font-size: 11px; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--or); }
.mission-ligne { font-size: 13px; line-height: 18px; }
.mission-nom { font-family: var(--titre); font-weight: 700; font-size: 16px; color: var(--texte); }
.mission-texte { font-size: 13px; color: rgba(255, 255, 255, .85); }
/* l'avancée à côté de la barre ; la prime à la suite, ou à la ligne, à droite, quand la place manque */
.mission-pied { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 12px; }
/* la barre comme la jauge du train : son remplissage d'après --part (posée sur lui par js/missions.js) */
.mission-barre { position: relative; flex: 0 0 56px; height: 6px; overflow: hidden; border-radius: 3px; background: rgba(255, 255, 255, .18); }
.mission-barre i {
  position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--part, 0) * 100%); border-radius: 3px;
  background: linear-gradient(90deg, #ffb347, var(--or)); box-shadow: 0 0 10px rgba(255, 200, 90, .7); transition: width var(--duree-lente) var(--sortie);
}
.mission-avancee { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-variant-numeric: tabular-nums; }
.mission-prime { font-weight: 600; color: var(--or); white-space: nowrap; }
.carte-mission .mission-prime { flex: none; margin-left: auto; }     /* à droite sur la carte ; centrée au recto du calque */
/* remplie : dorée, « Mission accomplie ! » en or ; ratée : grisée */
.carte-mission.reussie { box-shadow: var(--verre-ombre), inset 0 0 0 1px rgba(255, 213, 122, .6); }
.carte-mission.reussie .mission-avancee, .carte-mission.reussie .mission-nom { color: var(--or); }
.carte-mission.ratee { filter: grayscale(.9); }
.carte-mission.ratee .mission-ligne, .carte-mission.ratee .mission-avancee { color: var(--texte-doux); }
/* sur un appareil partagé, la carte reste de dos : on appuie sur le bouton pour voir la mission du joueur dont c'est le tour */
.mission-voir {
  min-height: 40px; padding: 6px 12px; border: 1px dashed rgba(255, 213, 122, .55); border-radius: var(--rayon-petit);
  background: rgba(255, 255, 255, .06); cursor: pointer; font-size: 13px; font-weight: 600; line-height: 1.3; text-align: center;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: none;
}
.carte-mission.montre .mission-voir { background: rgba(255, 213, 122, .2); border-style: solid; }
.carte-mission.partage:not(.montre) .mission-ligne, .carte-mission.partage:not(.montre) .mission-pied { display: none; }
/* sa place s'éclaire quand la carte du calque y arrive (arrive), s'illumine quand la mission est remplie (fete) */
.carte-mission.arrive, .btn-mission.arrive { animation: mission-arrive 800ms ease; }
.carte-mission.fete, .btn-mission.fete { animation: mission-fete 1.4s ease; }
@keyframes mission-arrive {
  35% { box-shadow: var(--verre-ombre), 0 0 0 3px rgba(255, 213, 122, .75), 0 0 26px rgba(255, 200, 90, .7); }
}
@keyframes mission-fete {
  20%, 60% { box-shadow: var(--verre-ombre), 0 0 0 3px var(--or), 0 0 36px rgba(255, 200, 90, .95); }
}
.btn-mission { border-radius: 50%; color: var(--or); pointer-events: auto; }
.btn-mission:hover { background: rgba(60, 46, 34, .62); }
#btn-mission { display: none; }

/* Sur ordinateur : en bas à gauche dans la barre du bas, sous la liste des chercheurs et à sa largeur ; la liste raccourcit
   pour lui laisser la place, la consigne se resserre pour ne pas la heurter (avec-mission : la carte visible). */
@media (min-width: 1101px) and (min-height: 501px) {
  .carte-mission { position: absolute; left: 0; bottom: 0; width: 252px; }
  .partie.avec-mission .chercheurs { max-height: calc(100vh - 380px); max-height: calc(100dvh - 380px); }
  .partie.avec-mission .consigne { max-width: min(600px, calc(100vw - 600px)); }
}
/* De 761 à 1100 px de large, et en petites hauteurs : cachée, sauf ouverte par son bouton, au-dessus de la barre du bas. */
@media (min-width: 761px) and (max-width: 1100px), (min-width: 761px) and (max-height: 500px) {
  .carte-mission {
    display: none; position: fixed; z-index: 42; left: 50%; bottom: var(--zone-bas); transform: translateX(-50%);
    width: min(320px, calc(100vw - 32px)); max-height: calc(100% - var(--zone-haut) - var(--zone-bas)); overflow-y: auto;
  }
  .carte-mission.ouverte { display: grid; animation: fondu-entre var(--duree) ease both; }
  #btn-mission { display: inline-grid; width: 48px; height: 48px; }
  #btn-mission .ic { width: 24px; height: 24px; }
}
@media (min-width: 761px) and (max-height: 500px) {
  #btn-mission { width: 36px; height: 36px; }
  #btn-mission .ic { width: 20px; height: 20px; }
}
/* Sur téléphone tenu en hauteur : une ligne pleine largeur en tête de la bande du bas, sans titre ni prime ; le nom et le
   texte coupés à une ligne (deux quand un toucher la déplie), l'avancée à droite, la barre dessous. Chaque règle vise la
   carte (.carte-mission) : le recto du calque porte les mêmes classes, et garde son titre et sa prime. */
@media (max-width: 760px) {
  .carte-mission {
    width: 100%; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 3px 10px; padding: 0 4px;
    border-radius: 0; cursor: pointer;
  }
  .carte-mission .mission-titre, .carte-mission .mission-prime { display: none; }
  .carte-mission .mission-pied { display: contents; }
  .carte-mission .mission-ligne { grid-column: 1; grid-row: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .carte-mission.deplie .mission-ligne { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .carte-mission .mission-nom { font-size: 14px; }
  .carte-mission .mission-avancee { grid-column: 2; grid-row: 1; flex: none; max-width: 40vw; font-size: 12px; }
  .carte-mission .mission-barre { grid-column: 1 / -1; grid-row: 2; height: 3px; }
  .carte-mission .mission-voir { grid-column: 1 / -1; min-height: 34px; padding: 4px 10px; font-size: 12.5px; }
}

/* La pastille dorée d'une mission remplie, en haut à droite de l'avatar du chercheur (« Mission secrète remplie »). */
.joueur.mission-remplie .avatar { position: relative; }
.joueur.mission-remplie .avatar::after {
  content: ''; position: absolute; right: -3px; top: -2px; width: 12px; height: 12px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--or-haut), var(--or-bas));
  box-shadow: 0 0 0 2px rgba(20, 15, 11, .85), 0 0 8px rgba(255, 200, 90, .8);
}

/* Le calque du milieu de l'écran : au-dessus des panneaux, il laisse passer les clics ; sa carte seule les prend (un clic la
   range). La carte de 340 px, ses deux faces sur le verre opaque (pas de flou d'arrière-plan sous une rotation 3D) : le dos,
   l'icône de mission en grand ; le recto, la mission. js/missions.js la retourne (rotateY) puis la fait voler à sa place ;
   « Mission accomplie ! » (fete) : le recto seul, qui monte avec un ressort. */
.mission-revele { position: fixed; inset: 0; z-index: 44; display: grid; place-items: center; padding: 16px; pointer-events: none; perspective: 1400px; }
.mission-revele.entre { animation: fondu-entre var(--duree) ease both; }
.mission-revele.sort { animation: fondu-sort var(--duree) ease forwards; }
.mission-revele.doux.entre { animation: fondu-entre var(--duree-vite) ease both; }
.mission-revele.doux.sort { animation: fondu-sort var(--duree-vite) ease forwards; }
.mission-retourne { position: relative; width: min(340px, calc(100vw - 32px)); transform-style: preserve-3d; pointer-events: auto; cursor: pointer; }
.mission-face {
  /* le verre opaque, posé deux fois : les boutons du milieu de la carte ne se lisent pas au travers */
  border: 1px solid rgba(255, 213, 122, .5); border-radius: var(--rayon);
  background: linear-gradient(var(--verre-opaque), var(--verre-opaque)), var(--verre-opaque);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .55); color: var(--texte);
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
}
.mission-recto { position: relative; display: grid; gap: 8px; padding: 22px 24px 20px; text-align: center; }
.mission-recto .mission-titre { font-size: 12px; }
.mission-recto .mission-nom { font-size: 26px; line-height: 1.15; color: var(--or); }
.mission-recto .mission-texte { font-size: 16px; line-height: 1.4; color: var(--texte); }
.mission-recto .mission-prime { font-size: 13px; color: var(--texte-doux); white-space: normal; }
.mission-dos {
  position: absolute; inset: 0; transform: rotateY(180deg); display: grid; place-content: center; justify-items: center; gap: 10px;
  color: var(--or);
  background: radial-gradient(circle at 50% 40%, rgba(255, 213, 122, .16), transparent 65%), linear-gradient(var(--verre-opaque), var(--verre-opaque)), var(--verre-opaque);
}
.mission-dos .ic { width: 88px; height: 88px; }
.mission-dos-titre { font-family: var(--titre); font-weight: 700; font-size: 22px; }
.mission-revele.fete .mission-dos { display: none; }
.mission-revele.fete .mission-titre { font-family: var(--titre); font-weight: 700; font-size: 24px; letter-spacing: normal; text-transform: none; color: var(--or); }
.mission-revele.fete .mission-retourne { animation: mission-monte var(--duree-lente) var(--ressort) both; }
@keyframes mission-monte { from { opacity: 0; translate: 0 40px; scale: .92; } }

/* « Réduire les animations » (le système, ou html.sans-animations) : fondus seulement — le calque entre et sort en fondus
   courts, sa carte ne monte pas, la barre se règle sans transition, sa place ne s'éclaire pas. js/missions.js n'y retourne
   ni ne fait voler la carte. */
@media (prefers-reduced-motion: reduce) {
  html:root .mission-revele.entre { animation: fondu-entre var(--duree-vite) ease both; }
  html:root .mission-revele.sort { animation: fondu-sort var(--duree-vite) ease forwards; }
  html:root .mission-revele .mission-retourne, html:root .carte-mission.arrive, html:root .carte-mission.fete,
  html:root .btn-mission.arrive, html:root .btn-mission.fete { animation: none; }
  html:root .carte-mission.ouverte { animation: fondu-entre var(--duree-vite) ease both; }
  html:root .mission-barre i { transition: none; }
}
html.sans-animations .mission-revele.entre { animation: fondu-entre var(--duree-vite) ease both; }
html.sans-animations .mission-revele.sort { animation: fondu-sort var(--duree-vite) ease forwards; }
html.sans-animations .mission-revele .mission-retourne, html.sans-animations .carte-mission.arrive, html.sans-animations .carte-mission.fete,
html.sans-animations .btn-mission.arrive, html.sans-animations .btn-mission.fete { animation: none; }
html.sans-animations .carte-mission.ouverte { animation: fondu-entre var(--duree-vite) ease both; }
html.sans-animations .mission-barre i { transition: none; }
.mission-revele.doux .mission-retourne { animation: none; }

/* ---------------------------------------------------------------- la Gazette de Golden City (projet 12d, js/gazette.js) : la une,
   une feuille de journal au milieu de l'écran, sur le papier crème et à l'encre brune (le nom du journal en Rye, le filet en
   petites capitales, le titre du jour en capitales Playfair grasses, la gravure à gauche et la règle à droite, empilées sur un
   écran étroit). Quand un numéro paraît, elle se déplie : js/gazette.js la double en deux moitiés (.gazette-pli), dont la haute,
   pliée par-dessus la basse, s'ouvre (rotateX) ; puis elle se replie et vole jusqu'au petit journal. Le petit journal : sur
   ordinateur, une pastille de verre dans la barre du haut, juste après la jauge du train ; ailleurs, une icône à côté du
   Journal, avec un point doré tant que le dernier numéro n'a pas été rouvert. */
:root {
  --gazette-papier: #efe3c4;
  --gazette-encre:  #2a1d10;
  --gazette-tampon: #a3261b;
}
/* Le calque, au-dessus des panneaux (à l'étage du calque des missions) : il laisse passer les clics, la feuille seule les prend. */
.gazette { position: fixed; inset: 0; z-index: 44; display: grid; place-items: center; padding: 16px; pointer-events: none; perspective: 1400px; }
.gazette-feuille {
  position: relative; display: grid; gap: 8px; width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow: auto; overscroll-behavior: contain;
  padding: 24px 28px 22px; border-radius: 3px; pointer-events: auto; outline: none; text-align: left; color: var(--gazette-encre);
  /* le grain du papier, en dégradés : un cœur plus clair, des taches roussies, des fibres croisées */
  background:
    radial-gradient(ellipse at 50% 42%, rgba(255, 251, 236, .5), transparent 68%),
    radial-gradient(circle at 16% 20%, rgba(150, 104, 44, .10), transparent 20%),
    radial-gradient(circle at 86% 74%, rgba(150, 104, 44, .12), transparent 24%),
    radial-gradient(circle at 64% 10%, rgba(120, 80, 32, .07), transparent 16%),
    radial-gradient(circle at 30% 88%, rgba(120, 80, 32, .07), transparent 18%),
    repeating-linear-gradient(97deg, rgba(110, 78, 38, .035) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(7deg, rgba(255, 255, 255, .06) 0 1px, transparent 1px 4px),
    var(--gazette-papier);
  box-shadow: inset 0 0 44px rgba(120, 76, 26, .30), 0 26px 70px rgba(0, 0, 0, .55), 0 6px 16px rgba(0, 0, 0, .35);
  -webkit-hyphens: auto; hyphens: auto;
}
/* le double filet noir du cadre */
.gazette-feuille::before { content: ''; position: absolute; inset: 9px; border: 3px double var(--gazette-encre); pointer-events: none; }
.gazette.rouverte .gazette-feuille { cursor: pointer; }
.gazette-entete { display: grid; gap: 5px; text-align: center; }
/* le nom du journal : sur un écran étroit, en deux lignes équilibrées (« La Gazette de / Golden City ») */
.gazette-nom { font-family: var(--affiche); font-size: clamp(24px, 7.4vw, 34px); line-height: 1.05; letter-spacing: .02em; text-wrap: balance; }
.gazette-filet {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 10px; padding: 3px 2px 2px;
  border-top: 1px solid var(--gazette-encre); border-bottom: 3px double var(--gazette-encre);
  font-family: var(--titre); font-size: 13px; line-height: 1.3; font-variant-caps: small-caps; letter-spacing: .07em;
}
.gazette-titre {
  margin: 4px 0 0; font-family: var(--titre); font-weight: 700; font-size: clamp(20px, 5.6vw, 28px); line-height: 1.1;
  text-transform: uppercase; letter-spacing: .01em; text-align: center; text-wrap: balance; overflow-wrap: anywhere; color: var(--gazette-encre);
}
.gazette-corps {
  display: grid; grid-template-columns: 40% minmax(0, 1fr); grid-template-areas: 'gravure regle'; align-items: start; gap: 16px;
  padding-top: 10px; border-top: 1px solid rgba(42, 29, 16, .6);
}
/* la gravure dans son cadre : un filet et le ciel gravé de lignes fines (le cadre se voit avant que l'image n'arrive en fondu) */
.gazette-corps::before {
  content: ''; grid-area: gravure; align-self: start; width: 100%; aspect-ratio: 4 / 5;
  box-shadow: inset 0 0 0 1px rgba(42, 29, 16, .55), inset 0 0 0 4px var(--gazette-papier), inset 0 0 0 5px rgba(42, 29, 16, .3);
  background: radial-gradient(ellipse at 50% 55%, transparent 55%, rgba(120, 80, 30, .12)), repeating-linear-gradient(rgba(58, 36, 20, .06) 0 1px, transparent 1px 5px);
}
.gazette-gravure { grid-area: gravure; align-self: start; display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; opacity: 0; transition: opacity 420ms ease; }
.gazette-gravure.prete { opacity: 1; }
.gazette-regle { grid-area: regle; margin: 0; font-family: var(--titre); font-weight: 400; font-size: 16px; line-height: 1.45; text-align: justify; }
/* la lettrine */
.gazette-regle::first-letter { float: left; margin: 5px 6px 0 0; font-weight: 700; font-size: 3.05em; line-height: .78; }
/* « Fini » : un tampon rouge, penché, quand l'effet s'est arrêté avant l'heure (la une rouverte) */
.gazette-fini {
  position: absolute; right: 9%; top: 50%; margin: 0; padding: 4px 16px 0; border: 4px double var(--gazette-tampon); border-radius: 8px;
  transform: rotate(-12deg); font-family: var(--affiche); font-size: 38px; line-height: 1.1; letter-spacing: .08em; text-transform: uppercase;
  color: var(--gazette-tampon); opacity: .82; mix-blend-mode: multiply; pointer-events: none;
}
.gazette-fermer {
  justify-self: end; min-height: 36px; padding: 0 18px; border: 1px solid var(--gazette-encre); border-radius: 999px; cursor: pointer;
  background: rgba(42, 29, 16, .06); font-family: var(--titre); font-weight: 700; font-size: 14px; letter-spacing: .04em; color: var(--gazette-encre);
}
.gazette-fermer:hover { background: rgba(42, 29, 16, .14); }
.gazette-fermer:focus-visible { outline-color: var(--gazette-encre); }
/* Un écran étroit : la gravure au-dessus de la règle. */
@media (max-width: 480px) {
  .gazette-feuille { gap: 7px; padding: 20px 20px 18px; }
  .gazette-filet { justify-content: center; font-size: 12px; }
  .gazette-corps { grid-template-columns: minmax(0, 1fr); grid-template-areas: 'gravure' 'regle'; gap: 10px; }
  .gazette-corps::before, .gazette-gravure { justify-self: center; width: min(56%, 26vh); width: min(56%, 26dvh); }
  .gazette-regle { font-size: 15px; line-height: 1.42; }
  .gazette-fini { top: 47%; font-size: 32px; }
}
/* Une petite hauteur (téléphone tenu en largeur) : tout plus serré, la gravure plus basse. */
@media (max-height: 500px) {
  .gazette-feuille { gap: 5px; padding: 15px 22px 13px; }
  .gazette-nom { font-size: 22px; }
  .gazette-filet { font-size: 11.5px; }
  .gazette-titre { margin-top: 1px; font-size: 18px; }
  .gazette-corps { grid-template-columns: 30% minmax(0, 1fr); gap: 12px; padding-top: 7px; }
  .gazette-corps::before, .gazette-gravure { aspect-ratio: 5 / 4; }
  .gazette-regle { font-size: 13.5px; line-height: 1.38; }
  .gazette-fermer { min-height: 30px; }
  .gazette-fini { top: 50%; font-size: 30px; }
}

/* Le pli (js/gazette.js) : deux copies de la feuille, chacune coupée à sa moitié. La basse reste à plat ; la haute, avec son
   envers (le papier de la page de dessous, ses colonnes à peine visibles par transparence), tourne autour du pli (rotateX) : à
   −180°, elle est rabattue sur la basse. Une ombre passe sur la basse tant que la haute la couvre. */
.gazette-pli { position: absolute; transform-style: preserve-3d; pointer-events: auto; transform-origin: 50% 75%; }
.gazette-moitie { position: absolute; left: 0; width: 100%; height: 50%; }
.gazette-moitie-bas { top: 50%; overflow: hidden; box-shadow: 0 26px 70px rgba(0, 0, 0, .55), 0 6px 16px rgba(0, 0, 0, .35); }
.gazette-moitie-haut { top: 0; transform-origin: 50% 100%; transform-style: preserve-3d; }
.gazette-recto, .gazette-verso { position: absolute; inset: 0; overflow: hidden; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.gazette-moitie .gazette-feuille { position: absolute; left: 0; top: 0; width: 100%; height: 200%; max-height: none; overflow: hidden; box-shadow: inset 0 0 44px rgba(120, 76, 26, .30); }
.gazette-moitie-bas > .gazette-feuille { top: -100%; }
.gazette-verso {
  transform: rotateX(180deg);
  background:
    repeating-linear-gradient(rgba(42, 29, 16, .09) 0 1px, transparent 1px 7px) 10% 72% / 37% 58% no-repeat,
    repeating-linear-gradient(rgba(42, 29, 16, .09) 0 1px, transparent 1px 7px) 90% 72% / 37% 58% no-repeat,
    linear-gradient(rgba(42, 29, 16, .14), rgba(42, 29, 16, .14)) 50% 20% / 64% 10% no-repeat,
    radial-gradient(ellipse at 50% 40%, rgba(255, 248, 226, .45), transparent 70%),
    #e7d8b3;
  box-shadow: inset 0 0 36px rgba(110, 70, 24, .32), inset 0 0 0 1px rgba(42, 29, 16, .25);
}
.gazette-ombre { position: absolute; inset: 0; pointer-events: none; opacity: 0; background: linear-gradient(rgba(20, 12, 4, .55), rgba(20, 12, 4, .2)); }

/* ---- le petit journal : sur ordinateur, la pastille de verre (l'icône, le titre coupé d'une ellipse, « Fini ») ; ailleurs,
   l'icône de 36 px, la taille du Journal, à côté de lui, et son point doré */
.gazette-petit {
  display: none; align-items: center; gap: 8px; min-width: 0; max-width: min(240px, max(150px, calc(100vw - 1040px)));
  min-height: 40px; padding: 0 15px 0 12px; border-radius: 999px; cursor: pointer; font-size: 13.5px; font-weight: 600; text-align: left;
}
.gazette-petit .ic { color: var(--or); }
.gazette-petit:hover { background: rgba(60, 46, 34, .62); }
.gazette-petit-titre { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--titre); font-weight: 700; }
.gazette-petit-fini {
  flex: none; padding: 1px 6px 0; border: 1px solid rgba(240, 150, 120, .75); border-radius: 5px;
  font-family: var(--affiche); font-size: 11px; line-height: 1.4; letter-spacing: .06em; text-transform: uppercase; color: #f3a88c;
}
#btn-gazette { position: relative; flex: none; width: 36px; height: 36px; border-radius: 50%; color: var(--or); }
#btn-gazette:hover { background: rgba(60, 46, 34, .62); }
#btn-gazette .ic { width: 20px; height: 20px; }
.gazette-point {
  position: absolute; right: 0; top: 0; width: 8px; height: 8px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--or-haut), var(--or-bas)); box-shadow: 0 0 0 2px rgba(20, 15, 11, .85), 0 0 8px rgba(255, 200, 90, .8);
}
/* sa place s'éclaire quand la une y arrive */
.gazette-petit.arrive, #btn-gazette.arrive { animation: gazette-arrive 900ms ease; }
@keyframes gazette-arrive { 35% { box-shadow: var(--verre-ombre), 0 0 0 3px rgba(255, 213, 122, .75), 0 0 26px rgba(255, 200, 90, .7); } }
@media (min-width: 1101px) and (min-height: 501px) {
  .gazette-petit { display: inline-flex; }
  #btn-gazette { display: none; }
}
/* De 761 à 1100 px de large : l'icône à gauche du Journal, sur sa ligne (les notifications au-dessus). En petites hauteurs
   (téléphone tenu en largeur), la carte descend jusqu'à cette ligne, et l'icône en couvrirait le coin : elle se tient juste
   au-dessus du Journal, dans la colonne du fil. */
@media (min-width: 761px) and (max-width: 1100px) and (min-height: 501px) {
  .fil { flex-flow: row wrap; justify-content: flex-end; align-items: center; }
  .fil > .notifications { flex: 0 0 100%; }
}
/* Sur téléphone tenu en hauteur : dans la ligne du Journal, comme Réagir. */
@media (max-width: 760px) {
  #btn-gazette { background: rgba(255, 255, 255, .08); }
}

/* « Réduire les animations » (le système, ou html.sans-animations) : la une paraît et s'en va en fondus courts, sans pli ni vol
   (js/gazette.js) ; sa gravure arrive en fondu court ; la place du petit journal ne s'éclaire pas. */
@media (prefers-reduced-motion: reduce) {
  html:root .gazette-gravure { transition-duration: var(--duree-vite); }
  html:root .gazette-petit.arrive, html:root #btn-gazette.arrive { animation: none; }
}
html.sans-animations .gazette-gravure { transition-duration: var(--duree-vite); }
html.sans-animations .gazette-petit.arrive, html.sans-animations #btn-gazette.arrive { animation: none; }

