/* The Legend of Elelhem : interface par-dessus le canvas.
   Garde-fous de base : la page ne défile pas, ne rebondit pas et ne laisse
   pas le navigateur interpréter les gestes. Le jeu reçoit tout. */

/* Une seule police, EB Garamond (licence OFL, voir assets/fonts/OFL.txt) :
   une fonte variable pour toutes les graisses, plus l'italique, avec Georgia
   en repli le temps du chargement. Choisie en version 2.5 pour sa parenté
   avec les garaldes des RPG en HD-2D. */
@font-face {
  font-family: "EB Garamond";
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-variable-normal.woff2") format("woff2");
}

@font-face {
  font-family: "EB Garamond";
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  src: url("assets/fonts/eb-garamond-latin-400-italic.woff2") format("woff2");
}

:root {
  color-scheme: dark;
  --fond: #231b2b;
  --texte: #f3e6d4;
  --panneau: rgb(10 8 14 / 0.62);
  --police: "EB Garamond", Georgia, "Times New Roman", serif;
  --parchemin: #f3dfb8;
  --encre: #2a1d2e;
  --or: #ffd08a;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  width: 100%;
  height: var(--hauteur, 100%);
  overflow: hidden;
  background: var(--fond);
}

/* Safari grossit le texte quand on tourne le téléphone en paysage : non. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  position: fixed;
  inset: 0 0 auto 0;
  overscroll-behavior: none;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  color: var(--texte);
  font-family: var(--police);
}

#scene {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  outline: none;
}

/* Panneau ?debug : chiffres de mesure, jamais cliquable. Sous le compteur de
   parchemins. */
#debug {
  position: fixed;
  top: calc(64px + env(safe-area-inset-top));
  left: calc(8px + env(safe-area-inset-left));
  z-index: 10;
  padding: 6px 9px;
  border-radius: 4px;
  background: var(--panneau);
  color: #e9f2da;
  font: 12px/1.45 ui-monospace, Consolas, "Courier New", monospace;
  white-space: pre;
  pointer-events: none;
}

/* Message plein écran quand le village ne peut pas s'afficher. */
#message,
.noscript {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  padding: 24px calc(24px + env(safe-area-inset-right)) 24px calc(24px + env(safe-area-inset-left));
  background: var(--fond);
  font-size: 1.15rem;
  line-height: 1.55;
  text-align: center;
  text-wrap: balance;
}

#message[hidden] {
  display: none;
}

/* Le nom du fichier refusé, sur l'écran d'échec au chargement (index.html). */
.message-detail {
  margin: 8px 0 0;
  font-size: 0.85rem;
  opacity: 0.75;
}

/* Le bouton de l'écran d'échec au chargement (index.html). */
.message-recharger {
  min-height: 44px;
  margin-top: 16px;
  padding: 8px 22px;
  border: 1px solid #a8803e;
  border-radius: 4px;
  background: #f3d08c;
  color: #2a1d10;
  font: 600 1.05rem/1.2 var(--police);
  cursor: var(--curseur-actif);
}

/* Bulle d'interaction : posée par le jeu (translate) au-dessus de la tête de
   l'habitant. Le bouton fait 48 px, au-dessus des 44 px d'une cible tactile.
   Le translate du bouton place son coin haut gauche, la marge le recentre
   au-dessus du point d'ancrage. */
#indice {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 12;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin: -52px 0 0 -24px;
  padding: 0;
  border: 2px solid var(--encre);
  border-radius: 50%;
  background: var(--parchemin);
  color: var(--encre);
  box-shadow: 0 3px 10px rgb(0 0 0 / 0.45);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  animation: bulle-apparait 0.18s ease-out;
}

#indice[hidden] {
  display: none;
}

#indice svg {
  animation: bulle-flotte 1.6s ease-in-out infinite;
}

/* Rappel de la touche, seulement là où il y a un clavier. */
#indice .touche {
  display: none;
  position: absolute;
  right: -8px;
  bottom: -6px;
  min-width: 20px;
  padding: 1px 5px;
  border: 1.5px solid var(--encre);
  border-radius: 4px;
  background: var(--or);
  font: 600 0.8rem/1.2 var(--police);
  text-align: center;
}

@media (hover: hover) and (pointer: fine) {
  #indice .touche {
    display: block;
  }
}

@keyframes bulle-apparait {
  from {
    opacity: 0;
    scale: 0.6;
  }
}

@keyframes bulle-flotte {
  50% {
    translate: 0 -3px;
  }
}

/* Boîte de dialogue : en bas, large sur téléphone, plafonnée sur bureau. Le
   texte fait au moins 17 px et jusqu'à 22 px : lisible sans zoom. */
#dialogue {
  position: fixed;
  left: 50%;
  bottom: calc(14px + env(safe-area-inset-bottom));
  z-index: 15;
  width: min(700px, calc(100% - 24px - env(safe-area-inset-left) - env(safe-area-inset-right)));
  padding: 14px 20px 18px;
  border: 1px solid rgb(255 208 138 / 0.4);
  border-radius: 12px;
  background: rgb(24 17 31 / 0.9);
  box-shadow: 0 12px 34px rgb(0 0 0 / 0.5);
  color: var(--texte);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  transform: translateX(-50%);
  animation: dialogue-apparait 0.2s ease-out;
}

#dialogue[hidden] {
  display: none;
}

.dialogue-nom {
  margin: 0 0 6px;
  color: var(--or);
  font: 600 clamp(0.95rem, 0.6rem + 1.6vw, 1.1rem) / 1.2 var(--police);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.dialogue-texte {
  margin: 0;
  /* Trois lignes réservées : la boîte ne saute pas d'une page à l'autre. */
  min-height: 4.26em;
  padding-right: 22px;
  font: 500 clamp(1.06rem, 0.7rem + 1.5vw, 1.375rem) / 1.42 var(--police);
  text-wrap: pretty;
}

/* Ce qui n'est pas encore tapé occupe sa place mais reste invisible. */
.dialogue-texte .reste {
  color: transparent;
}

/* Marque de suite en bas à droite : un triangle qui bat, un losange à la
   dernière page. Visible seulement quand la page est entièrement tapée. */
.dialogue-suite {
  position: absolute;
  right: 18px;
  bottom: 16px;
  width: 0;
  height: 0;
  border: 7px solid transparent;
  border-top: 10px solid var(--or);
  border-bottom: 0;
  opacity: 0;
}

#dialogue[data-frappe="non"] .dialogue-suite {
  opacity: 1;
  animation: suite-bat 0.9s ease-in-out infinite;
}

#dialogue[data-fin="oui"] .dialogue-suite {
  width: 10px;
  height: 10px;
  border: 0;
  background: var(--or);
  rotate: 45deg;
}

@keyframes dialogue-apparait {
  from {
    opacity: 0;
    translate: 0 10px;
  }
}

@keyframes suite-bat {
  50% {
    translate: 0 3px;
  }
}

@media (prefers-reduced-motion: reduce) {
  #indice,
  #indice svg,
  #dialogue,
  #dialogue .dialogue-suite {
    animation: none !important;
  }
}

/* Joystick flottant : un anneau de 128 px (rayon 64) centré sous le pouce, et
   sa bille. Translucide, jamais cliquable. Il se dore quand on court. */
#stick {
  position: fixed;
  top: -64px;
  left: -64px;
  z-index: 11;
  width: 128px;
  height: 128px;
  border: 2px solid rgb(243 223 184 / 0.55);
  border-radius: 50%;
  background: rgb(243 223 184 / 0.12);
  pointer-events: none;
}

#stick[hidden] {
  display: none;
}

.stick-bille {
  position: absolute;
  top: 36px;
  left: 36px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgb(243 223 184 / 0.55);
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.35);
}

/* Étiquette de nom : posée par le jeu au-dessus de la tête de l'habitant. */
#nom {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 12;
  margin: -64px 0 0;
  padding: 3px 10px 4px;
  border: 1px solid rgb(255 208 138 / 0.45);
  border-radius: 6px;
  background: rgb(24 17 31 / 0.82);
  color: var(--or);
  font: 600 0.95rem/1.2 var(--police);
  letter-spacing: 0.04em;
  white-space: nowrap;
  pointer-events: none;
  translate: -50% 0;
}

#nom[hidden] {
  display: none;
}

/* --- Interface dorée (étape 2e) ---------------------------------------------
   Panneaux bleu nuit, filets d'or fins, losanges aux angles : le registre
   des RPG HD-2D, en CSS seulement (aucune image). */

:root {
  --nuit: rgb(16 15 32 / 0.9);
  --or-vif: #f3d08c;
  --or-fonce: #a8803e;
  --filet: linear-gradient(90deg, transparent, var(--or-vif) 18%, var(--or-vif) 82%, transparent);
}

/* Boîte de dialogue : double filet d'or, losanges aux quatre angles, nom sur
   un cartouche qui chevauche le bord. */
#dialogue {
  padding: 22px 26px 20px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: linear-gradient(180deg, rgb(26 24 50 / 0.94), rgb(14 13 28 / 0.94));
  box-shadow: inset 0 0 0 3px rgb(14 13 28 / 0.94), inset 0 0 0 4px rgb(243 208 140 / 0.55), 0 14px 40px rgb(0 0 0 / 0.55);
}

#dialogue::before,
#dialogue::after {
  content: "";
  position: absolute;
  top: -5px;
  width: 9px;
  height: 9px;
  background: var(--or-vif);
  rotate: 45deg;
  box-shadow: 0 0 6px rgb(243 208 140 / 0.6);
}

#dialogue::before {
  left: -5px;
}

#dialogue::after {
  right: -5px;
}

.dialogue-nom {
  position: absolute;
  top: -15px;
  left: 22px;
  margin: 0;
  padding: 4px 14px 5px 26px;
  border: 1px solid var(--or-fonce);
  border-radius: 3px;
  background: linear-gradient(180deg, #2a2650, #17152e);
  color: var(--or-vif);
  font-size: clamp(0.85rem, 0.55rem + 1.3vw, 1rem);
  letter-spacing: 0.12em;
}

/* Petit losange devant le nom. */
.dialogue-nom::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 10px;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  background: var(--or-vif);
  rotate: 45deg;
}

.dialogue-texte {
  margin-top: 6px;
}

/* Bandeau de lieu : le nom du quartier entre deux filets d'or, en haut. */
#lieu {
  position: fixed;
  top: calc(18px + env(safe-area-inset-top));
  left: 50%;
  z-index: 13;
  display: grid;
  justify-items: center;
  gap: 6px;
  width: min(520px, calc(100% - 32px));
  translate: -50% 0;
  pointer-events: none;
  text-align: center;
  animation: lieu-entre 0.7s ease-out both;
}

#lieu[hidden] {
  display: none;
}

#lieu.lieu-sortie {
  animation: lieu-sort 0.9s ease-in both;
}

.lieu-filet {
  width: 100%;
  height: 1px;
  background: var(--filet);
}

.lieu-nom {
  margin: 0;
  color: #fbf1dc;
  font: 500 clamp(1.25rem, 0.9rem + 2vw, 1.9rem) / 1.15 var(--police);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-shadow: 0 2px 10px rgb(0 0 0 / 0.8), 0 0 18px rgb(243 208 140 / 0.35);
}

@keyframes lieu-entre {
  from {
    opacity: 0;
    translate: -50% -8px;
  }
}

@keyframes lieu-sort {
  to {
    opacity: 0;
    translate: -50% -6px;
  }
}

/* Écran titre : le village vit derrière, assombri en bas et en haut ; au
   centre, la flamme grande, le titre doré, la contrée, le prénom, l'invitation.
   Version 1.3 : le village reste visible sur les bords, mais derrière les
   textes il est assombri et adouci (voile flou en ::before), comme un écran
   titre de RPG : les petits textes se lisent sur les pavés et les fanions. */
#titre {
  position: fixed;
  inset: 0;
  z-index: 25;
  display: grid;
  place-items: center;
  padding: calc(20px + env(safe-area-inset-top)) 16px calc(20px + env(safe-area-inset-bottom));
  background:
    radial-gradient(ellipse 72% 78% at 50% 48%, rgb(10 8 20 / 0.5), rgb(10 8 20 / 0.82) 80%),
    linear-gradient(180deg, rgb(10 8 20 / 0.6), transparent 30%, transparent 65%, rgb(10 8 20 / 0.8));
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  transition: opacity 0.65s ease;
}

/* Le voile : flou et un peu désaturé au centre, fondu vers les bords où le
   village reste net. Sous les textes, pas de ligne nette qui le traverse. */
#titre::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  -webkit-backdrop-filter: blur(6px) saturate(0.8);
  backdrop-filter: blur(6px) saturate(0.8);
  -webkit-mask-image: radial-gradient(ellipse 58% 64% at 50% 50%, #000 30%, transparent 100%);
  mask-image: radial-gradient(ellipse 58% 64% at 50% 50%, #000 30%, transparent 100%);
  pointer-events: none;
}

#titre[hidden] {
  display: none;
}

#titre.titre-fondu {
  opacity: 0;
  pointer-events: none;
}

.titre-cadre {
  display: grid;
  justify-items: center;
  gap: clamp(8px, 1.6vh, 16px);
  width: min(680px, 100%);
  text-align: center;
}

/* La flamme : aussi haute que le titre est large de deux lignes, jamais une
   vignette. */
.titre-flamme {
  width: auto;
  height: clamp(120px, 28vh, 250px);
  filter: drop-shadow(0 0 22px rgb(255 170 90 / 0.45));
  animation: titre-respire 4s ease-in-out infinite;
}

.titre-nom {
  margin: 0;
  background: linear-gradient(180deg, #fff3d2 10%, #f2c875 55%, #b88838 95%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font: 600 clamp(2.3rem, 1rem + 6.5vw, 5rem) / 1 var(--police);
  letter-spacing: 0.04em;
  filter: drop-shadow(0 2px 2px rgb(0 0 0 / 0.7)) drop-shadow(0 4px 16px rgb(0 0 0 / 0.8));
  text-wrap: balance;
}

/* Ornement sous le titre : deux filets et un losange. */
.titre-orne {
  display: flex;
  align-items: center;
  gap: 12px;
  width: min(420px, 80%);
}

.titre-orne span {
  flex: 1;
  height: 1px;
  background: var(--filet);
}

.titre-orne i {
  width: 9px;
  height: 9px;
  background: var(--or-vif);
  rotate: 45deg;
  box-shadow: 0 0 8px rgb(243 208 140 / 0.7);
}

/* Les textes : un halo sombre serré autour des lettres, puis une ombre
   large. Le premier détache les lettres du décor, la seconde les pose. */
.titre-contree {
  margin: 0;
  color: #f8ecd2;
  font: italic 500 clamp(1.05rem, 0.8rem + 1.2vw, 1.45rem) / 1.2 var(--police);
  letter-spacing: 0.08em;
  text-shadow: 0 0 3px rgb(0 0 0 / 0.95), 0 2px 10px rgb(0 0 0 / 0.85);
}

.titre-prenom {
  display: grid;
  gap: 6px;
  justify-items: center;
  margin-top: 6px;
  color: #efe3cb;
  font: 500 0.98rem/1.2 var(--police);
  text-shadow: 0 0 3px rgb(0 0 0 / 0.95), 0 2px 8px rgb(0 0 0 / 0.85);
  cursor: text;
}

.titre-prenom input {
  width: min(260px, 70vw);
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: rgb(14 13 28 / 0.8);
  color: #fff6e2;
  font: 500 1.1rem/1.2 var(--police);
  text-align: center;
  -webkit-user-select: text;
  user-select: text;
}

.titre-prenom input:focus {
  outline: 2px solid var(--or-vif);
  outline-offset: 2px;
}

.titre-commencer {
  margin: 10px 0 0;
  color: var(--or-vif);
  font: 600 clamp(0.95rem, 0.75rem + 0.7vw, 1.1rem) / 1.3 var(--police);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  text-shadow: 0 0 3px rgb(0 0 0 / 0.95), 0 2px 10px rgb(0 0 0 / 0.9);
  animation: titre-clignote 2.2s ease-in-out infinite;
}

.titre-nouvelle {
  min-height: 44px;
  padding: 6px 14px;
  border: 0;
  background: none;
  color: #e6d7b6;
  font: italic 500 0.95rem/1.2 var(--police);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-shadow: 0 0 3px rgb(0 0 0 / 0.95), 0 2px 8px rgb(0 0 0 / 0.85);
  cursor: var(--curseur-actif);
}

.titre-nouvelle[hidden] {
  display: none;
}

.titre-credits {
  display: grid;
  gap: 2px;
  margin: 8px 0 0;
  color: #e4d7bd;
  font: 500 0.92rem/1.35 var(--police);
  text-shadow: 0 0 3px rgb(0 0 0 / 0.95), 0 1px 8px rgb(0 0 0 / 0.9);
}

.titre-site {
  color: var(--or-vif);
  text-decoration: none;
}

.titre-site:hover,
.titre-site:focus-visible {
  text-decoration: underline;
}

@keyframes titre-respire {
  50% {
    filter: drop-shadow(0 0 30px rgb(255 170 90 / 0.65));
  }
}

@keyframes titre-clignote {
  50% {
    opacity: 0.6;
  }
}

/* Écran court (téléphone en paysage) : flamme et titre plus petits. */
@media (max-height: 480px) {
  .titre-flamme {
    height: 26vh;
  }

  .titre-nom {
    font-size: clamp(1.8rem, 6vh + 1rem, 3rem);
  }

  .titre-prenom {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .titre-flamme,
  .titre-commencer,
  #lieu {
    animation: none !important;
  }
}

/* Bouton de la musique : rond, filet d'or, en haut à droite. */
#son {
  position: fixed;
  top: calc(12px + env(safe-area-inset-top));
  right: calc(12px + env(safe-area-inset-right));
  z-index: 14;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--or-fonce);
  border-radius: 50%;
  background: var(--nuit);
  color: var(--or-vif);
  box-shadow: inset 0 0 0 2px rgb(14 13 28 / 0.9), inset 0 0 0 3px rgb(243 208 140 / 0.4), 0 4px 14px rgb(0 0 0 / 0.45);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

#son[hidden] {
  display: none;
}

#son .son-croix,
#son[data-coupe="oui"] .son-ondes {
  display: none;
}

#son[data-coupe="oui"] .son-croix {
  display: inline;
}

/* --- Quête (étape 3) ----------------------------------------------------------
   Les choix d'une question, le compteur de parchemins et le diplôme, dans le
   même registre : bleu nuit, filets d'or. */

/* Les trois choix : empilés, pleine largeur, au moins 46 px de haut pour le
   pouce. Le numéro rappelle les touches 1, 2, 3. */
.dialogue-choix {
  display: grid;
  gap: 8px;
  margin: 12px 0 2px;
  padding: 0;
  list-style: none;
}

.dialogue-choix[hidden] {
  display: none;
}

/* Pendant une question, la boîte épouse le texte (pas de lignes réservées)
   et la marque de suite disparaît : ce sont les choix qui font avancer. */
#dialogue[data-mode="question"] .dialogue-texte {
  min-height: 0;
}

#dialogue[data-mode="question"] .dialogue-suite {
  display: none;
}

.dialogue-choix button {
  position: relative;
  width: 100%;
  min-height: 46px;
  padding: 9px 14px 9px 46px;
  border: 1px solid rgb(168 128 62 / 0.75);
  border-radius: 3px;
  background: rgb(36 33 70 / 0.85);
  color: var(--texte);
  font: 500 clamp(1rem, 0.78rem + 1vw, 1.2rem) / 1.3 var(--police);
  text-align: left;
  text-wrap: pretty;
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  animation: choix-apparait 0.25s ease-out both;
}

.dialogue-choix li:nth-child(2) button {
  animation-delay: 0.06s;
}

.dialogue-choix li:nth-child(3) button {
  animation-delay: 0.12s;
}

.dialogue-choix button::before {
  content: attr(data-touche);
  position: absolute;
  top: 50%;
  left: 12px;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  margin-top: -12px;
  border: 1px solid var(--or-fonce);
  border-radius: 50%;
  color: var(--or-vif);
  font: 600 0.85rem/1 var(--police);
}

.dialogue-choix button.choisi,
.dialogue-choix button:focus-visible {
  border-color: var(--or-vif);
  outline: none;
  background: linear-gradient(90deg, rgb(243 208 140 / 0.24), rgb(36 33 70 / 0.88) 70%);
  box-shadow: inset 0 0 0 1px var(--or-vif), 0 0 12px rgb(243 208 140 / 0.25);
}

.dialogue-choix button.choisi::before {
  background: var(--or-vif);
  color: #17152e;
}

/* Un choix déjà essayé : grisé, barré, plus cliquable. */
.dialogue-choix button.ecarte {
  border-color: rgb(168 128 62 / 0.3);
  background: rgb(20 18 38 / 0.6);
  color: rgb(243 230 212 / 0.45);
  text-decoration: line-through;
  text-decoration-color: rgb(243 208 140 / 0.5);
  cursor: var(--curseur);
}

.dialogue-choix button.ecarte::before {
  opacity: 0.4;
}

@keyframes choix-apparait {
  from {
    opacity: 0;
    translate: 0 6px;
  }
}

/* Compteur de parchemins : une pilule en haut à gauche, un parchemin roulé par
   emplacement (corps et deux rouleaux, en CSS), vide puis doré. */
#parchemins {
  position: fixed;
  top: calc(12px + env(safe-area-inset-top));
  left: calc(12px + env(safe-area-inset-left));
  z-index: 14;
  pointer-events: none;
}

#parchemins[hidden] {
  display: none;
}

.parchemins-rangee {
  display: flex;
  margin: 0;
  font: inherit;
  cursor: var(--curseur-actif);
  pointer-events: auto;
  touch-action: manipulation;
  align-items: center;
  gap: 7px;
  width: max-content;
  height: 44px;
  padding: 0 14px;
  border: 1px solid var(--or-fonce);
  border-radius: 22px;
  background: var(--nuit);
  box-shadow: inset 0 0 0 2px rgb(14 13 28 / 0.9), inset 0 0 0 3px rgb(243 208 140 / 0.4), 0 4px 14px rgb(0 0 0 / 0.45);
}

.parchemin {
  position: relative;
  width: 15px;
  height: 20px;
  border: 1px solid rgb(168 128 62 / 0.6);
  border-radius: 1px;
  background: rgb(243 208 140 / 0.06);
}

.parchemin::before,
.parchemin::after {
  content: "";
  position: absolute;
  right: -3px;
  left: -3px;
  height: 4px;
  border: 1px solid rgb(168 128 62 / 0.6);
  border-radius: 3px;
  background: #17152e;
}

.parchemin::before {
  top: -3px;
}

.parchemin::after {
  bottom: -3px;
}

.parchemin.obtenu {
  border-color: #c9a45c;
  background:
    linear-gradient(transparent 40%, #a83228 40% 60%, transparent 60%),
    linear-gradient(90deg, #d4b780, #f6e8c4 50%, #d4b780);
  box-shadow: 0 0 9px rgb(243 208 140 / 0.5);
}

.parchemin.obtenu::before,
.parchemin.obtenu::after {
  border-color: #8a6630;
  background: linear-gradient(180deg, #f0d79c, #b38a48);
}

.parchemin.gagne {
  animation: parchemin-gagne 1.2s ease-out;
}

@keyframes parchemin-gagne {
  0% {
    scale: 2.1;
    box-shadow: 0 0 24px 8px rgb(255 224 160 / 0.95);
  }
  55% {
    scale: 1.15;
  }
}

/* L'annonce du parchemin gagné, sous le compteur. */
.parchemins-annonce {
  width: max-content;
  max-width: min(330px, calc(100vw - 24px));
  margin: 8px 0 0;
  padding: 8px 14px 9px;
  border: 1px solid var(--or-fonce);
  border-radius: 3px;
  background: var(--nuit);
  color: #fbf1dc;
  font: 500 1.05rem/1.3 var(--police);
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.45);
  animation: annonce-entre 0.4s ease-out both;
}

.parchemins-annonce::first-line {
  color: var(--or-vif);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.parchemins-annonce[hidden] {
  display: none;
}

.parchemins-annonce.parchemins-sortie {
  animation: annonce-sort 0.6s ease-in both;
}

@keyframes annonce-entre {
  from {
    opacity: 0;
    translate: -8px 0;
  }
}

@keyframes annonce-sort {
  to {
    opacity: 0;
    translate: -8px 0;
  }
}

/* Écran étroit : le bandeau de lieu passe sous le compteur. */
@media (max-width: 640px) {
  #lieu {
    top: calc(68px + env(safe-area-inset-top));
  }
}


/* Le diplôme : le village assombri derrière, la feuille au centre, les
   boutons dessous. */
#diplome {
  position: fixed;
  inset: 0;
  z-index: 17;
  display: grid;
  place-items: center;
  padding: calc(12px + env(safe-area-inset-top)) calc(12px + env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom)) calc(12px + env(safe-area-inset-left));
  background: rgb(10 8 18 / 0.74);
  animation: diplome-entre 0.5s ease-out both;
}

#diplome[hidden] {
  display: none;
}

.diplome-cadre {
  display: grid;
  justify-items: center;
  gap: 14px;
  width: 100%;
}

.diplome-toile {
  display: block;
  width: min(100%, 1100px, calc((var(--hauteur, 100vh) - 190px) * 1.416));
  height: auto;
  border-radius: 2px;
  box-shadow: 0 18px 50px rgb(0 0 0 / 0.65);
  animation: diplome-deroule 0.7s ease-out both;
}

.diplome-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: end;
  gap: 10px 16px;
}

.diplome-prenom {
  display: grid;
  gap: 5px;
  color: #e9dcc2;
  font: 500 0.9rem/1.2 var(--police);
}

.diplome-prenom input {
  width: min(240px, 80vw);
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: rgb(14 13 28 / 0.85);
  color: #fff6e2;
  font: 500 1.1rem/1.2 var(--police);
  -webkit-user-select: text;
  user-select: text;
}

.diplome-boutons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

.diplome-boutons button {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: var(--nuit);
  color: var(--or-vif);
  font: 600 1rem/1 var(--police);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

/* Le bouton principal : Partager quand le téléphone sait le faire, sinon
   Télécharger. */
.diplome-boutons .principal {
  border-color: var(--or-vif);
  background: linear-gradient(180deg, #f3d08c, #c9a45c);
  color: #17152e;
}

.diplome-boutons button[hidden] {
  display: none;
}

.diplome-prenom input:focus,
.diplome-boutons button:focus-visible {
  outline: 2px solid var(--or-vif);
  outline-offset: 2px;
}

@keyframes diplome-entre {
  from {
    opacity: 0;
  }
}

@keyframes diplome-deroule {
  from {
    opacity: 0;
    scale: 0.94;
    translate: 0 14px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dialogue-choix button,
  .parchemin.gagne,
  .parchemins-annonce,
  #diplome,
  .diplome-toile {
    animation: none !important;
  }
}

/* --- Étape 3b : grimoire, répliques, accroche ------------------------------- */

.parchemins-rangee:hover,
.parchemins-rangee:focus-visible {
  border-color: var(--or-vif);
  outline: none;
}

/* La troisième ligne de l'annonce : où relire le parchemin. */
.parchemins-annonce small {
  display: block;
  margin-top: 3px;
  color: #e9dcc2;
  font-size: 0.82rem;
  font-style: italic;
}

/* L'accroche, sous la contrée : ce qu'on vient faire ici, en une ligne. */
.titre-accroche {
  margin: 0;
  color: #f3e6d4;
  font: 500 clamp(0.95rem, 0.8rem + 0.7vw, 1.15rem) / 1.3 var(--police);
  letter-spacing: 0.06em;
  text-align: center;
  text-shadow: 0 2px 8px rgb(0 0 0 / 0.8);
}

/* Réplique d'un figurant : une bulle de parchemin, pointe vers le bas, posée
   par le jeu au-dessus de sa tête. */
#replique {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 12;
  width: max-content;
  max-width: min(260px, 70vw);
  margin: -58px 0 0;
  padding: 7px 12px 8px;
  border: 2px solid var(--encre);
  border-radius: 10px;
  background: var(--parchemin);
  color: var(--encre);
  font: 500 0.95rem/1.3 var(--police);
  text-wrap: pretty;
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.4);
  pointer-events: none;
  translate: -50% -100%;
  animation: replique-apparait 0.25s ease-out;
}

#replique::after {
  content: "";
  position: absolute;
  bottom: -8px;
  left: 50%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-right: 2px solid var(--encre);
  border-bottom: 2px solid var(--encre);
  background: var(--parchemin);
  rotate: 45deg;
}

#replique[hidden] {
  display: none;
}

@keyframes replique-apparait {
  from {
    opacity: 0;
    scale: 0.9;
  }
}

/* Le grimoire : un livre bleu nuit à filets d'or, une page de parchemin au
   centre. La page défile si la leçon est longue ; le reste de l'écran, non. */
#grimoire {
  position: fixed;
  inset: 0;
  z-index: 17;
  display: grid;
  place-items: center;
  padding: calc(12px + env(safe-area-inset-top)) calc(12px + env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom)) calc(12px + env(safe-area-inset-left));
  background: rgb(10 8 18 / 0.7);
  animation: diplome-entre 0.35s ease-out both;
}

#grimoire[hidden] {
  display: none;
}

.grimoire-livre {
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  gap: 12px;
  width: min(600px, 100%);
  max-height: calc(var(--hauteur, 100vh) - 24px);
  padding: 18px 18px 16px;
  border: 1px solid var(--or-fonce);
  border-radius: 6px;
  background: linear-gradient(180deg, rgb(26 24 50 / 0.97), rgb(14 13 28 / 0.97));
  box-shadow: inset 0 0 0 3px rgb(14 13 28 / 0.95), inset 0 0 0 4px rgb(243 208 140 / 0.5), 0 18px 50px rgb(0 0 0 / 0.6);
}

.grimoire-titre {
  margin: 0;
  color: var(--or-vif);
  font: 600 clamp(1rem, 0.8rem + 1vw, 1.2rem) / 1.2 var(--police);
  letter-spacing: 0.14em;
  text-align: center;
  text-transform: uppercase;
}

/* Les onglets : un petit parchemin par page (28 × 34 px), doré s'il est
   gagné. Le bouton autour fait 44 px de haut et se partage la largeur : une
   cible pour le pouce, le dessin reste petit. */
.grimoire-onglets {
  display: flex;
  justify-content: center;
  margin-inline: -8px;
}

.grimoire-onglet {
  position: relative;
  flex: 0 1 44px;
  min-width: 0;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

.grimoire-onglet::before {
  content: "";
  position: absolute;
  top: 5px;
  left: 50%;
  width: 28px;
  height: 34px;
  margin-left: -14px;
  border: 1px solid rgb(168 128 62 / 0.6);
  border-radius: 3px;
  background: rgb(243 208 140 / 0.05);
}

.grimoire-onglet.obtenu::before {
  background:
    linear-gradient(transparent 42%, #a83228 42% 58%, transparent 58%),
    linear-gradient(90deg, #d4b780, #f6e8c4 50%, #d4b780);
}

.grimoire-onglet[aria-current="page"]::before {
  border-color: var(--or-vif);
  box-shadow: 0 0 0 2px var(--or-vif), 0 0 10px rgb(243 208 140 / 0.5);
}

.grimoire-page {
  overflow-y: auto;
  padding: 18px 20px 20px;
  border-radius: 3px;
  background: radial-gradient(ellipse at 50% 40%, #f6ead0, #e6d3aa 75%, #d6be8c);
  color: var(--encre);
  box-shadow: inset 0 0 24px rgb(110 82 54 / 0.35);
  overscroll-behavior: contain;
  touch-action: pan-y;
  -webkit-user-select: text;
  user-select: text;
}

.grimoire-numero {
  margin: 0;
  color: #6e5236;
  font: 600 0.78rem/1.2 var(--police);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.grimoire-notion {
  margin: 4px 0 2px;
  font: 600 clamp(1.4rem, 1rem + 2vw, 1.9rem) / 1.15 var(--police);
}

.grimoire-maitre {
  margin: 0;
  color: #6e5236;
  font: italic 500 1rem/1.3 var(--police);
}

.grimoire-maitre:empty,
.grimoire-maxime:empty {
  display: none;
}

.grimoire-maxime {
  margin: 14px 0 12px;
  padding: 10px 0;
  border-top: 1px solid rgb(168 128 62 / 0.6);
  border-bottom: 1px solid rgb(168 128 62 / 0.6);
  color: #5a2320;
  font: 600 clamp(1.05rem, 0.9rem + 0.8vw, 1.25rem) / 1.35 var(--police);
  text-align: center;
  text-wrap: balance;
}

.grimoire-lecon p {
  margin: 0 0 10px;
  font: 500 clamp(1rem, 0.85rem + 0.6vw, 1.12rem) / 1.5 var(--police);
  text-wrap: pretty;
}

.grimoire-lecon .grimoire-vierge {
  margin-top: 16px;
  color: #6e5236;
  font-style: italic;
}

.grimoire-boutons {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 8px;
}

.grimoire-boutons button {
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: var(--nuit);
  color: var(--or-vif);
  font: 600 1rem/1 var(--police);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

.grimoire-boutons button:disabled {
  opacity: 0.35;
  cursor: var(--curseur);
}

.grimoire-precedente::before {
  content: "\2039\00a0";
}

.grimoire-suivante::after {
  content: "\00a0\203a";
}

.grimoire-onglet:focus-visible,
.grimoire-boutons button:focus-visible {
  outline: 2px solid var(--or-vif);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  #replique,
  #grimoire {
    animation: none !important;
  }
}

/* --- Étape 3c : minimap et carte ----------------------------------------- */

/* La minimap : en haut à droite, sous le bouton du son ; sur écran étroit,
   à gauche du bouton, plus petite. Le village fait 40 cases sur 30 : 4/3. */
#minimap {
  position: fixed;
  top: calc(64px + env(safe-area-inset-top));
  right: calc(12px + env(safe-area-inset-right));
  z-index: 14;
  width: 168px;
  padding: 4px;
  border: 1px solid var(--or-fonce);
  border-radius: 6px;
  background: var(--nuit);
  box-shadow: inset 0 0 0 2px rgb(14 13 28 / 0.9), inset 0 0 0 3px rgb(243 208 140 / 0.4), 0 4px 14px rgb(0 0 0 / 0.45);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

#minimap[hidden] {
  display: none;
}

#minimap canvas {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 3px;
}

#minimap:hover,
#minimap:focus-visible {
  border-color: var(--or-vif);
  outline: none;
}

@media (max-width: 640px) {
  #minimap {
    top: calc(12px + env(safe-area-inset-top));
    right: calc(64px + env(safe-area-inset-right));
    width: 88px;
    padding: 3px;
  }

  #lieu {
    top: calc(84px + env(safe-area-inset-top));
  }
}

/* La carte en grand, par-dessus le jeu. */
#carte {
  position: fixed;
  inset: 0;
  z-index: 17;
  display: grid;
  place-items: center;
  padding: calc(12px + env(safe-area-inset-top)) calc(12px + env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom)) calc(12px + env(safe-area-inset-left));
  background: rgb(10 8 18 / 0.7);
  animation: diplome-entre 0.3s ease-out both;
}

#carte[hidden] {
  display: none;
}

.carte-cadre {
  display: grid;
  justify-items: center;
  gap: 12px;
  width: min(760px, 100%);
  padding: 16px;
  border: 1px solid var(--or-fonce);
  border-radius: 6px;
  background: linear-gradient(180deg, rgb(26 24 50 / 0.97), rgb(14 13 28 / 0.97));
  box-shadow: inset 0 0 0 3px rgb(14 13 28 / 0.95), inset 0 0 0 4px rgb(243 208 140 / 0.5), 0 18px 50px rgb(0 0 0 / 0.6);
}

.carte-titre {
  margin: 0;
  color: var(--or-vif);
  font: 600 clamp(1rem, 0.8rem + 1vw, 1.2rem) / 1.2 var(--police);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.carte-toile {
  display: block;
  width: min(100%, calc((var(--hauteur, 100vh) - 200px) * 4 / 3));
  aspect-ratio: 4 / 3;
  border: 1px solid var(--or-fonce);
  border-radius: 3px;
  image-rendering: pixelated;
}

/* La carte illustrée (version 2.3) : une peinture, pas des cases. */
.carte-toile.carte-illustree,
#minimap canvas.carte-illustree {
  image-rendering: auto;
}

.carte-legende {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 18px;
  margin: 0;
  padding: 0;
  color: var(--texte);
  font: 500 0.95rem/1.2 var(--police);
  list-style: none;
}

.carte-legende li::before {
  content: "";
  display: inline-block;
  width: 11px;
  height: 11px;
  margin-right: 7px;
  border: 2px solid #1b1a2e;
  border-radius: 50%;
  vertical-align: -1px;
}

.carte-legende [data-repere="heros"]::before {
  border-radius: 2px;
  background: #fff6dc;
  rotate: 45deg;
}

.carte-legende [data-repere="guide"]::before {
  background: #8fd3ff;
}

.carte-legende [data-repere="quete"]::before {
  background: #ffd08a;
}

.carte-legende [data-repere="fait"]::before {
  background: #9a9488;
}

.carte-fermer {
  min-height: 44px;
  padding: 0 22px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: var(--nuit);
  color: var(--or-vif);
  font: 600 1rem/1 var(--police);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

.carte-fermer:focus-visible {
  outline: 2px solid var(--or-vif);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  #carte {
    animation: none !important;
  }
}

/* Le fondu au noir du passage d'une porte. */
#fondu {
  position: fixed;
  inset: 0;
  z-index: 16;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.24s ease;
}

#fondu.fondu-noir {
  opacity: 1;
}

#fondu[hidden] {
  display: none;
}

/* --- Étape 3c : Tokens et boutique ---------------------------------------- */

/* Compteur de parchemins et bourse sur une ligne ; sur écran étroit, la
   bourse passe dessous, plus petite. */
.parchemins-ligne {
  display: flex;
  align-items: center;
  gap: 8px;
}

#tokens {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  height: 44px;
  padding: 0 14px 0 10px;
  border: 1px solid var(--or-fonce);
  border-radius: 22px;
  background: var(--nuit);
  color: var(--or-vif);
  font: 600 1.05rem/1 var(--police);
  box-shadow: inset 0 0 0 2px rgb(14 13 28 / 0.9), inset 0 0 0 3px rgb(243 208 140 / 0.4), 0 4px 14px rgb(0 0 0 / 0.45);
}

/* La pièce : un disque d'or, un anneau gravé, un T au centre. */
.tokens-piece {
  position: relative;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff0c2, #e8b84c 45%, #a8803e 100%);
  box-shadow: inset 0 0 0 2px rgb(107 78 16 / 0.6), 0 0 6px rgb(243 208 140 / 0.45);
}

.tokens-piece::after {
  content: "T";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #6b4e10;
  font: 600 0.72rem/1 var(--police);
}

/* Le gain, qui monte et s'efface à droite de la bourse. */
.tokens-gain {
  position: absolute;
  left: 100%;
  top: 50%;
  margin-left: 6px;
  color: #ffe6a6;
  font: 600 1.05rem/1 var(--police);
  text-shadow: 0 2px 6px rgb(0 0 0 / 0.8);
  opacity: 0;
  pointer-events: none;
  translate: 0 -50%;
}

.tokens-gain.tokens-gagne {
  animation: tokens-gagne 1.6s ease-out both;
}

@keyframes tokens-gagne {
  0% {
    opacity: 0;
    translate: 0 -20%;
  }
  15% {
    opacity: 1;
    translate: 0 -50%;
  }
  70% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    translate: 0 -160%;
  }
}

@media (max-width: 640px) {
  .parchemins-ligne {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  #tokens {
    height: 32px;
    padding: 0 12px 0 8px;
    font-size: 0.95rem;
  }

  .tokens-piece {
    width: 16px;
    height: 16px;
  }

  #lieu {
    top: calc(104px + env(safe-area-inset-top));
  }
}

/* La boutique de Berthe : une liste de tenues dans un cadre doré. */
#boutique {
  position: fixed;
  inset: 0;
  z-index: 17;
  display: grid;
  place-items: center;
  padding: calc(12px + env(safe-area-inset-top)) calc(12px + env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom)) calc(12px + env(safe-area-inset-left));
  background: rgb(10 8 18 / 0.7);
  animation: diplome-entre 0.3s ease-out both;
}

#boutique[hidden] {
  display: none;
}

.boutique-cadre {
  display: grid;
  /* Titre, bourse, liste, bouton : seule la liste rapetisse (et défile) quand
     l'écran est court, le bouton Fermer reste visible. */
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  gap: 12px;
  width: min(560px, 100%);
  max-height: calc(var(--hauteur, 100vh) - 24px);
  padding: 18px;
  border: 1px solid var(--or-fonce);
  border-radius: 6px;
  background: linear-gradient(180deg, rgb(26 24 50 / 0.97), rgb(14 13 28 / 0.97));
  box-shadow: inset 0 0 0 3px rgb(14 13 28 / 0.95), inset 0 0 0 4px rgb(243 208 140 / 0.5), 0 18px 50px rgb(0 0 0 / 0.6);
}

.boutique-titre {
  margin: 0;
  color: var(--or-vif);
  font: 600 clamp(1rem, 0.8rem + 1vw, 1.2rem) / 1.2 var(--police);
  letter-spacing: 0.14em;
  text-align: center;
  text-transform: uppercase;
}

.boutique-bourse {
  margin: 0;
  color: var(--texte);
  font: 500 1rem/1.2 var(--police);
  text-align: center;
}

.boutique-liste {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
  overscroll-behavior: contain;
  touch-action: pan-y;
}

.boutique-tenue {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid rgb(168 128 62 / 0.6);
  border-radius: 4px;
  background: rgb(36 33 70 / 0.6);
}

.boutique-tenue[data-portee="oui"] {
  border-color: var(--or-vif);
  box-shadow: inset 0 0 0 1px var(--or-vif);
}

.boutique-echantillon {
  width: 40px;
  height: 40px;
  border: 2px solid #1b1a2e;
  border-radius: 50%;
}

.boutique-nom {
  margin: 0;
  color: var(--or-vif);
  font: 600 1.05rem/1.2 var(--police);
}

.boutique-description {
  margin: 2px 0 0;
  color: #e9dcc2;
  font: 500 0.92rem/1.3 var(--police);
}

.boutique-tenue button,
.boutique-fermer {
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: var(--nuit);
  color: var(--or-vif);
  font: 600 0.95rem/1.1 var(--police);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

.boutique-tenue button.principal {
  border-color: var(--or-vif);
  background: linear-gradient(180deg, #f3d08c, #c9a45c);
  color: #17152e;
}

.boutique-tenue button:disabled {
  opacity: 0.55;
  cursor: var(--curseur);
}

.boutique-fermer {
  justify-self: center;
  padding: 0 22px;
}

.boutique-tenue button:focus-visible,
.boutique-fermer:focus-visible {
  outline: 2px solid var(--or-vif);
  outline-offset: 2px;
}

@media (max-width: 480px) {
  .boutique-tenue {
    grid-template-columns: 36px 1fr;
  }

  .boutique-tenue button {
    grid-column: 1 / -1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tokens-gain.tokens-gagne,
  #boutique {
    animation: none !important;
  }
}

/* --- Étape 4 : tactile ---------------------------------------------------- */

/* Joystick poussé au-delà de 85 % : on court, l'anneau et la bille se dorent. */
#stick.stick-course {
  border-color: rgb(243 208 140 / 0.9);
  background: rgb(243 208 140 / 0.2);
  box-shadow: 0 0 16px rgb(243 208 140 / 0.4);
}

#stick.stick-course .stick-bille {
  background: rgb(243 208 140 / 0.85);
}

/* Bouton d'action : 74 px, en bas à droite sous le pouce libre, à gauche pour
   la main gauche. Seulement sur écran tactile (html[data-tactile], posé par
   src/core/guards.js) : au bureau, la touche E et la bulle suffisent. Au
   repos, une étincelle discrète ; un habitant à portée, il devient la bulle,
   sur fond de parchemin comme celle qui flotte au-dessus de sa tête. */
#action {
  position: fixed;
  right: calc(22px + env(safe-area-inset-right));
  bottom: calc(26px + env(safe-area-inset-bottom));
  z-index: 13;
  display: none;
  place-items: center;
  width: 74px;
  height: 74px;
  padding: 0;
  border: 1px solid var(--or-fonce);
  border-radius: 50%;
  background: var(--nuit);
  color: var(--or-vif);
  box-shadow: inset 0 0 0 3px rgb(14 13 28 / 0.9), inset 0 0 0 4px rgb(243 208 140 / 0.45), 0 6px 18px rgb(0 0 0 / 0.5);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  transition: scale 0.08s ease-out, opacity 0.2s ease;
}

[data-tactile] #action:not([hidden]) {
  display: grid;
}

[data-main="gauche"] #action {
  right: auto;
  left: calc(22px + env(safe-area-inset-left));
}

#action svg {
  width: 32px;
  height: 32px;
}

#action[data-mode="repos"] {
  opacity: 0.62;
}

#action .action-bulle,
#action[data-mode="parler"] .action-etincelle {
  display: none;
}

#action[data-mode="parler"] .action-bulle {
  display: block;
}

#action[data-mode="parler"] {
  border: 2px solid var(--encre);
  background: var(--parchemin);
  color: var(--encre);
  box-shadow: 0 0 0 3px rgb(243 208 140 / 0.35), 0 6px 18px rgb(0 0 0 / 0.5);
  animation: action-appelle 1.6s ease-in-out infinite;
}

#action:active {
  scale: 0.92;
}

@keyframes action-appelle {
  50% {
    box-shadow: 0 0 0 7px rgb(243 208 140 / 0.18), 0 6px 18px rgb(0 0 0 / 0.5);
  }
}

/* Le côté du joystick, sur l'écran titre : seulement sur écran tactile. */
.titre-commandes {
  display: none;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 6px 16px;
  border: 1px solid rgb(168 128 62 / 0.7);
  border-radius: 22px;
  background: rgb(14 13 28 / 0.7);
  color: #e9dcc2;
  font: 500 0.95rem/1.2 var(--police);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

[data-tactile] .titre-commandes {
  display: inline-flex;
}

.titre-commandes svg {
  color: var(--or-vif);
}

.titre-commandes:focus-visible {
  outline: 2px solid var(--or-vif);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  #action {
    animation: none !important;
  }
}

/* Sur téléphone, l'annonce d'un parchemin ou d'un coffre tombe là où passe
   le bandeau de lieu : tant qu'elle est affichée, le bandeau s'efface. */
@media (max-width: 640px), (max-height: 480px) {
  body:has(.parchemins-annonce:not([hidden])) #lieu {
    visibility: hidden;
  }
}

/* Téléphone court en portrait (petit écran, ou barres du navigateur
   affichées) : flamme et espacements resserrés, pour que le bas de l'écran
   titre reste visible avec « Nouvelle partie » et le côté du joystick.
   Écrans étroits seulement : un ordinateur portable garde sa grande flamme. */
@media (max-height: 720px) and (min-height: 481px) and (max-width: 640px) {
  .titre-cadre {
    gap: 6px;
  }

  .titre-flamme {
    height: clamp(120px, 24vh, 250px);
  }

  .titre-commencer {
    margin-top: 4px;
  }

  .titre-credits {
    margin-top: 2px;
  }
}

/* Écran large (ordinateur, tablette ou téléphone en paysage) : l'écran titre
   sur deux colonnes, la flamme grande à gauche, le titre et le reste à
   droite, comme l'image de partage. En une seule colonne, la flamme restait
   petite et l'écran débordait en bas sur un portable avec une sauvegarde. */
@media (orientation: landscape) and (min-width: 560px) {
  .titre-cadre {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: repeat(9, auto);
    align-content: center;
    column-gap: clamp(20px, 4vw, 64px);
    row-gap: 0;
    width: min(1100px, 100%);
  }

  .titre-cadre > * {
    grid-column: 2;
    margin-block: clamp(3px, 0.8vh, 7px);
  }

  .titre-cadre > .titre-flamme {
    grid-column: 1;
    grid-row: 1 / -1;
    align-self: center;
    height: min(64vh, 470px);
  }
}

/* Écran court (téléphone en paysage) : le HUD tient sur une ligne en haut,
   la minimap rapetisse à côté du son, le bandeau de lieu passe dessous, et la
   boîte de dialogue se compacte : deux lignes réservées au lieu de trois,
   les choix côte à côte plutôt qu'empilés, toujours hauts de 44 px. */
@media (max-height: 480px) {
  #minimap {
    top: calc(12px + env(safe-area-inset-top));
    right: calc(64px + env(safe-area-inset-right));
    width: 104px;
    padding: 3px;
  }

  #lieu {
    top: calc(64px + env(safe-area-inset-top));
    width: min(400px, calc(100% - 32px));
    gap: 4px;
  }

  #dialogue {
    bottom: calc(8px + env(safe-area-inset-bottom));
    width: min(820px, calc(100% - 24px - env(safe-area-inset-left) - env(safe-area-inset-right)));
    padding: 16px 20px 12px;
  }

  .dialogue-texte {
    min-height: 2.84em;
    font-size: 1.06rem;
  }

  .dialogue-choix {
    grid-auto-columns: 1fr;
    grid-auto-flow: column;
    gap: 8px;
    margin-top: 10px;
  }

  .dialogue-choix button {
    height: 100%;
    min-height: 44px;
    padding: 6px 10px 6px 38px;
    font-size: 0.98rem;
    line-height: 1.25;
  }

  .dialogue-choix button::before {
    left: 9px;
    width: 22px;
    height: 22px;
    margin-top: -11px;
  }

  .titre-commencer {
    margin-top: 8px;
  }

  .titre-credits {
    margin-top: 6px;
  }

  .titre-commandes {
    padding: 4px 14px;
  }

  /* Le diplôme à gauche, aussi grand que la hauteur le permet ; le prénom
     et les boutons à droite, empilés. Dessous, il ne faisait que 260 px. */
  .diplome-cadre {
    grid-template-columns: auto minmax(190px, 250px);
    justify-content: center;
    align-items: center;
    column-gap: 16px;
  }

  .diplome-toile {
    width: min(calc(100vw - 300px), calc((var(--hauteur, 100vh) - 24px) * 1.416));
  }

  .diplome-actions,
  .diplome-boutons {
    flex-direction: column;
    align-items: stretch;
  }

  .diplome-prenom input {
    width: 100%;
  }
}

/* --- Étape 5 : générique de fin et vignette de partage ------------------- */

/* Le générique : le village assombri derrière, les noms qui montent au
   centre, le remerciement qui s'arrête au milieu (src/game/credits.js). */
#generique {
  position: fixed;
  inset: 0;
  z-index: 18;
  overflow: hidden;
  background: rgb(8 7 16 / 0.9);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  animation: diplome-entre 0.8s ease-out both;
}

#generique[hidden] {
  display: none;
}

/* Les noms apparaissent et s'effacent dans un fondu, en haut et en bas :
   ils ne passent pas nets sous le rappel du bas. */
#generique::before,
#generique::after {
  content: "";
  position: fixed;
  right: 0;
  left: 0;
  z-index: 1;
  pointer-events: none;
}

#generique::before {
  top: 0;
  height: 12vh;
  background: linear-gradient(rgb(8 7 16), rgb(8 7 16 / 0));
}

#generique::after {
  bottom: 0;
  height: 24vh;
  background: linear-gradient(rgb(8 7 16 / 0), rgb(8 7 16) 65%);
}

.generique-defile {
  display: grid;
  justify-items: center;
  gap: clamp(30px, 6vh, 52px);
  padding: 0 calc(24px + env(safe-area-inset-right)) 0 calc(24px + env(safe-area-inset-left));
  text-align: center;
  will-change: transform;
}

.generique-titre {
  margin: 0;
  background: linear-gradient(180deg, #fff3d2 10%, #f2c875 55%, #b88838 95%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font: 600 clamp(2.1rem, 1rem + 5vw, 3.8rem) / 1.05 var(--police);
  letter-spacing: 0.04em;
  text-wrap: balance;
}

.generique-sous-titre {
  margin: calc(-1 * clamp(18px, 4vh, 36px)) 0 0;
  color: #f6e7c8;
  font: italic 500 clamp(1.1rem, 0.85rem + 1.2vw, 1.5rem) / 1.2 var(--police);
  letter-spacing: 0.08em;
}

.generique-bloc,
.generique-fin {
  display: grid;
  gap: 4px;
}

.generique-role {
  margin: 0 0 6px;
  color: var(--or-vif);
  font: 600 0.82rem / 1.3 var(--police);
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.generique-nom {
  margin: 0;
  color: var(--texte);
  font: 500 clamp(1.15rem, 0.95rem + 1vw, 1.5rem) / 1.35 var(--police);
}

.generique-note {
  margin: 4px 0 0;
  color: #cdbf9f;
  font: italic 500 clamp(0.95rem, 0.85rem + 0.4vw, 1.08rem) / 1.35 var(--police);
  text-wrap: balance;
}

.generique-merci {
  margin: 0;
  color: var(--or-vif);
  font: 600 clamp(1.7rem, 1rem + 3vw, 2.6rem) / 1.2 var(--police);
  text-shadow: 0 0 18px rgb(243 208 140 / 0.35);
}

.generique-site {
  margin: 6px 0 0;
  color: #e9dcc2;
  font: 500 1.05rem / 1.3 var(--police);
  letter-spacing: 0.04em;
}

/* Le rappel du bas : appuyer passe le générique, ou ramène au village. */
.generique-passer {
  position: fixed;
  z-index: 2;
  left: 50%;
  bottom: calc(14px + env(safe-area-inset-bottom));
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid rgb(168 128 62 / 0.7);
  border-radius: 22px;
  background: rgb(14 13 28 / 0.85);
  color: #e9dcc2;
  font: 500 0.95rem / 1 var(--police);
  white-space: nowrap;
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  translate: -50% 0;
}

.generique-passer:focus-visible {
  outline: 2px solid var(--or-vif);
  outline-offset: 2px;
}

/* Mouvement réduit : rien ne défile tout seul, le texte se lit d'un bloc et
   défile au doigt s'il dépasse l'écran. */
#generique.generique-fixe {
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;
  cursor: var(--curseur);
}

#generique.generique-fixe .generique-defile {
  padding-top: 48px;
  padding-bottom: 110px;
}

@media (prefers-reduced-motion: reduce) {
  #generique {
    animation: none !important;
  }
}

/* Mode vignette (?vignette) : l'écran titre recomposé pour l'image de
   partage des réseaux sociaux, en 1200 × 630, que capture outils/vignette.mjs.
   La flamme grande à gauche ; titre, contrée, accroche et signature à
   droite ; ni prénom, ni invitation, ni bouton. */
[data-vignette] :is(.titre-prenom, .titre-commencer, .titre-nouvelle, .titre-commandes) {
  display: none !important;
}

[data-vignette] .titre-cadre {
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: repeat(5, auto);
  align-content: center;
  column-gap: 64px;
  row-gap: 0;
  width: min(1100px, 100%);
}

[data-vignette] .titre-cadre > * {
  grid-column: 2;
  margin-block: 7px;
}

[data-vignette] .titre-cadre > .titre-flamme {
  grid-column: 1;
  grid-row: 1 / -1;
  align-self: center;
  height: 470px;
  animation: none;
  filter: drop-shadow(0 0 30px rgb(255 170 90 / 0.6));
}

[data-vignette] .titre-nom {
  font-size: 88px;
}

[data-vignette] .titre-orne {
  width: 72%;
}

[data-vignette] .titre-contree {
  font-size: 36px;
}

[data-vignette] .titre-accroche {
  font-size: 30px;
}

[data-vignette] .titre-credits {
  margin-top: 22px;
  font-size: 22px;
}

/* ---- Portrait de dialogue : l'illustration de qui parle, debout à gauche
   de la boîte, comme dans les RPG HD-2D récents. Un PNG à palette par
   habitant (assets/portraits/), préchargé après l'écran titre. ---- */
.dialogue-portrait {
  position: absolute;
  right: calc(100% + 14px);
  bottom: -2px;
  height: clamp(240px, 46vh, 460px);
  pointer-events: none;
}

.dialogue-portrait[hidden] {
  display: none;
}

/* Un halo sombre derrière le buste : il se détache du village. */
.dialogue-portrait::before {
  content: "";
  position: absolute;
  inset: -12% -30% -6%;
  z-index: -1;
  background: radial-gradient(ellipse at 50% 70%, rgb(10 8 20 / 0.72), rgb(10 8 20 / 0) 70%);
}

.dialogue-portrait img {
  display: block;
  width: auto;
  height: 100%;
  filter: drop-shadow(0 10px 22px rgb(0 0 0 / 0.55));
  animation: portrait-entre 0.28s ease-out;
}

@keyframes portrait-entre {
  from {
    opacity: 0;
    translate: -10px 8px;
  }
}

/* La boîte glisse vers la droite de la moitié du portrait : l'ensemble reste centré. */
#dialogue.avec-portrait {
  transform: translateX(calc(-50% + 130px));
}

@media (max-width: 1100px) {
  /* Pas de place à gauche : le portrait se tient sur le bord haut de la boîte,
     à gauche, et le cartouche du nom passe à droite. */
  #dialogue.avec-portrait {
    transform: translateX(-50%);
  }

  .dialogue-portrait {
    right: auto;
    left: -6px;
    bottom: calc(100% - 6px);
    height: clamp(150px, 30vh, 260px);
  }

  #dialogue.avec-portrait .dialogue-nom {
    left: auto;
    right: 22px;
  }
}

/* Paysage bas (téléphone couché) : la place manque, le portrait s'efface. */
@media (max-height: 480px) {
  .dialogue-portrait {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dialogue-portrait img {
    animation: none;
  }
}

/* ==== Version 1.5 : interface plus grande, ornements illustrés ===========
   Les ornements (assets/ui/) sont des dessins générés puis découpés par
   outils/decouper.mjs : coins de filigrane d'or, filet à losange, icônes du
   parchemin et du Token, parchemin du grimoire. Ils habillent la boîte de
   dialogue, les panneaux et le HUD, et tout est un peu plus grand qu'avant :
   lisible sur téléphone sans zoom. Ces règles viennent en dernier et
   l'emportent sur celles du dessus, à spécificité égale. */

:root {
  --coin: 68px; /* taille d'un coin d'ornement */
  --coin-debord: 12px; /* de combien il déborde du cadre */
}

/* Coins de filigrane : quatre copies du même dessin, retournées. Le dessin
   est fait pour l'angle haut gauche, ses deux bras partent vers la droite et
   vers le bas. */
.coins {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.coins span {
  position: absolute;
  width: var(--coin);
  height: var(--coin);
  background: url("assets/ui/coin.png") no-repeat center / contain;
  filter: drop-shadow(0 2px 3px rgb(0 0 0 / 0.6));
}

.coins span:nth-child(1) {
  top: calc(-1 * var(--coin-debord));
  left: calc(-1 * var(--coin-debord));
}

.coins span:nth-child(2) {
  top: calc(-1 * var(--coin-debord));
  right: calc(-1 * var(--coin-debord));
  scale: -1 1;
}

.coins span:nth-child(3) {
  bottom: calc(-1 * var(--coin-debord));
  left: calc(-1 * var(--coin-debord));
  scale: 1 -1;
}

.coins span:nth-child(4) {
  right: calc(-1 * var(--coin-debord));
  bottom: calc(-1 * var(--coin-debord));
  scale: -1 -1;
}

/* Les panneaux portent les coins : il leur faut un repère. */
.carte-cadre,
.boutique-cadre,
.grimoire-livre {
  position: relative;
}

/* Boîte de dialogue : plus large, texte plus grand ; les losanges d'angle
   d'avant laissent la place aux coins. */
#dialogue {
  width: min(780px, calc(100% - 28px - env(safe-area-inset-left) - env(safe-area-inset-right)));
  padding: 26px 30px 24px;
}

#dialogue::before,
#dialogue::after {
  display: none;
}

#dialogue .coins {
  --coin: 60px;
  --coin-debord: 11px;
}

.dialogue-nom {
  top: -17px;
  left: 30px;
  padding: 5px 16px 6px 30px;
  font-size: clamp(0.95rem, 0.6rem + 1.4vw, 1.1rem);
}

.dialogue-texte {
  min-height: 4.4em;
  font-size: clamp(1.14rem, 0.76rem + 1.6vw, 1.5rem);
}

.dialogue-choix button {
  min-height: 52px;
  font-size: clamp(1.02rem, 0.7rem + 1.3vw, 1.2rem);
}

/* Sur grand écran seulement : en dessous, le portrait est posé sur la boîte
   (règle plus haut) et la boîte reste centrée. */
@media (min-width: 1101px) {
  #dialogue.avec-portrait {
    transform: translateX(calc(-50% + 140px));
  }
}

/* Filet d'or à losange : sous le nom du lieu, sous le titre du jeu, sous les
   titres de panneaux. */
.lieu-filet {
  height: 16px;
  background: url("assets/ui/filet.png") no-repeat center / contain;
}

.titre-orne {
  height: 24px;
  background: url("assets/ui/filet.png") no-repeat center / contain;
}

.titre-orne span,
.titre-orne i {
  display: none;
}

.carte-titre,
.boutique-titre,
.grimoire-titre {
  padding-bottom: 20px;
  background: url("assets/ui/filet.png") no-repeat center bottom / auto 14px;
  font-size: clamp(1.1rem, 0.85rem + 1.1vw, 1.35rem);
}

/* Le grimoire s'écrit sur du vrai parchemin. */
.grimoire-page {
  background: url("assets/ui/parchemin.png") center / 512px repeat, #e6d3aa;
  box-shadow: inset 0 0 40px rgb(110 82 54 / 0.45);
}

/* HUD : pastilles plus hautes, icônes dessinées. */
.parchemins-rangee {
  gap: 8px;
  height: 52px;
  padding: 0 16px 0 12px;
  border-radius: 26px;
}

.parchemins-rangee::before {
  content: "";
  width: 38px;
  height: 30px;
  margin-right: 2px;
  background: url("assets/ui/icone-parchemin.png") no-repeat center / contain;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.6));
}

.parchemin {
  width: 17px;
  height: 23px;
}

#tokens {
  height: 52px;
  padding: 0 16px 0 10px;
  border-radius: 26px;
  font-size: 1.2rem;
}

.tokens-piece {
  width: 28px;
  height: 28px;
  border-radius: 0;
  background: url("assets/ui/icone-token.png") no-repeat center / contain;
  box-shadow: none;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.6));
}

.tokens-piece::after {
  content: none;
}

#son {
  width: 50px;
  height: 50px;
}

#minimap {
  top: calc(74px + env(safe-area-inset-top));
  width: 204px;
}

#action {
  width: 86px;
  height: 86px;
}

@media (max-width: 640px) {
  :root {
    --coin: 48px;
    --coin-debord: 9px;
  }

  #dialogue .coins {
    --coin: 44px;
    --coin-debord: 8px;
  }

  .parchemins-rangee {
    height: 48px;
  }

  #tokens {
    height: 46px;
    font-size: 1.1rem;
  }

  #minimap {
    width: 150px;
  }
}

/* Paysage bas : les coins prendraient la place du texte. */
@media (max-height: 480px) {
  .coins {
    display: none;
  }

  #dialogue {
    padding: 16px 20px 12px;
  }
}

/* Paysage bas : la minimap reste petite, le cartouche du nom ne la touche pas. */
@media (max-height: 480px) {
  #minimap {
    width: 118px;
  }
}

/* ==== Version 2.0 : la lande, le combat, la forge, la feuille ==============
   Les clartés dans le HUD, le bouton d'attaque des écrans tactiles, le menu
   Forger (dans la famille de la boutique) et la fiche d'apprenti. */

/* Les clartés : cinq losanges d'or, éteints quand ils sont perdus. */
#clartes {
  display: flex;
  gap: 7px;
  align-items: center;
  height: 40px;
  padding: 0 14px;
  border: 1px solid var(--or-fonce);
  border-radius: 20px;
  background: var(--nuit);
  box-shadow: inset 0 0 0 2px rgb(14 13 28 / 0.9), inset 0 0 0 3px rgb(243 208 140 / 0.4), 0 4px 14px rgb(0 0 0 / 0.45);
}

#clartes[hidden] {
  display: none;
}

.clarte {
  width: 13px;
  height: 13px;
  background: linear-gradient(135deg, #fff3c4, var(--or-vif) 45%, var(--or-fonce));
  rotate: 45deg;
  box-shadow: 0 0 6px rgb(243 208 140 / 0.55);
  transition: background 0.25s ease, box-shadow 0.25s ease, scale 0.25s ease;
}

.clarte.perdue {
  background: rgb(243 208 140 / 0.12);
  box-shadow: inset 0 0 0 1px rgb(168 128 62 / 0.6);
  scale: 0.8;
}

#clartes[data-alerte="oui"] .clarte:not(.perdue) {
  animation: clarte-alerte 0.8s ease-in-out infinite;
}

@keyframes clarte-alerte {
  50% {
    box-shadow: 0 0 12px rgb(255 120 90 / 0.9);
    background: linear-gradient(135deg, #ffd9c4, #ef6a58 45%, #a1262a);
  }
}

/* Le bouton livre du HUD : ouvre la feuille de personnage. */
.fiche-bouton {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  padding: 0;
  border: 1px solid var(--or-fonce);
  border-radius: 50%;
  background: var(--nuit) url("assets/ui/icone-livre.png") no-repeat center / 30px auto;
  box-shadow: inset 0 0 0 2px rgb(14 13 28 / 0.9), inset 0 0 0 3px rgb(243 208 140 / 0.4), 0 4px 14px rgb(0 0 0 / 0.45);
  cursor: var(--curseur-actif);
  pointer-events: auto;
  touch-action: manipulation;
}

.fiche-bouton[hidden] {
  display: none;
}

.fiche-bouton:hover,
.fiche-bouton:focus-visible {
  border-color: var(--or-vif);
  outline: none;
}

/* Le bouton d'attaque : une épée, au-dessus du bouton d'action, tactile seulement. */
#attaque {
  position: fixed;
  right: calc(26px + env(safe-area-inset-right));
  bottom: calc(126px + env(safe-area-inset-bottom));
  z-index: 13;
  display: none;
  width: 78px;
  height: 78px;
  padding: 0;
  border: 1px solid var(--or-fonce);
  border-radius: 50%;
  background: var(--nuit) url("assets/ui/icone-epee.png") no-repeat center / auto 46px;
  box-shadow: inset 0 0 0 3px rgb(14 13 28 / 0.9), inset 0 0 0 4px rgb(243 208 140 / 0.45), 0 6px 18px rgb(0 0 0 / 0.5);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  transition: scale 0.08s ease-out;
}

[data-tactile] #attaque:not([hidden]) {
  display: block;
}

[data-main="gauche"] #attaque {
  right: auto;
  left: calc(26px + env(safe-area-inset-left));
}

#attaque:active {
  scale: 0.9;
}

/* La forge et la feuille : des panneaux de la famille de la boutique. */
#forge,
#feuille {
  position: fixed;
  inset: 0;
  z-index: 24;
  display: grid;
  place-items: center;
  padding: 12px;
  background: rgb(8 6 16 / 0.62);
}

#forge[hidden],
#feuille[hidden] {
  display: none;
}

.forge-cadre,
.feuille-cadre {
  position: relative;
  display: grid;
  gap: 12px;
  width: min(560px, 100%);
  max-height: calc(var(--hauteur, 100vh) - 24px);
  padding: 18px;
  border: 1px solid var(--or-fonce);
  border-radius: 6px;
  background: linear-gradient(180deg, rgb(26 24 50 / 0.97), rgb(14 13 28 / 0.97));
  box-shadow: inset 0 0 0 3px rgb(14 13 28 / 0.95), inset 0 0 0 4px rgb(243 208 140 / 0.5), 0 18px 50px rgb(0 0 0 / 0.6);
  color: var(--texte);
}

.forge-cadre {
  grid-template-rows: auto auto minmax(0, 1fr) auto;
}

.forge-titre,
.feuille-titre {
  margin: 0;
  padding-bottom: 20px;
  color: var(--or-vif);
  font: 600 clamp(1.1rem, 0.85rem + 1.1vw, 1.35rem) / 1.2 var(--police);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  background: url("assets/ui/filet.png") no-repeat center bottom / auto 14px;
}

.forge-bourse {
  margin: 0;
  text-align: center;
  color: var(--or-vif);
  font: 600 1rem/1.3 var(--police);
}

.forge-liste {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
  overscroll-behavior: contain;
}

.forge-epee {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid rgb(168 128 62 / 0.45);
  border-radius: 4px;
  background: rgb(243 208 140 / 0.05);
}

.forge-epee[data-forgee="oui"] {
  border-color: var(--or-vif);
  background: rgb(243 208 140 / 0.12);
}

.forge-icone {
  width: 56px;
  height: 56px;
  background: url("assets/ui/icone-epee.png") no-repeat center / auto 50px;
  filter: grayscale(1) brightness(0.55);
}

.forge-epee[data-niveau="2"] .forge-icone {
  filter: grayscale(0.4) brightness(0.9);
}

.forge-epee[data-niveau="3"] .forge-icone,
.forge-epee[data-forgee="oui"] .forge-icone {
  filter: none;
}

.forge-nom {
  margin: 0;
  font: 600 1.05rem/1.25 var(--police);
}

.forge-description {
  margin: 2px 0 0;
  color: rgb(246 236 214 / 0.8);
  font: 500 0.92rem/1.35 var(--police);
}

.forge-epee button,
.forge-fermer,
.feuille-fermer {
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: rgb(243 208 140 / 0.08);
  color: var(--or-vif);
  font: 600 0.95rem/1.2 var(--police);
  cursor: var(--curseur-actif);
  touch-action: manipulation;
}

.forge-epee button.principal {
  background: linear-gradient(180deg, #f3d08c, #c9a24e);
  color: #2a1d10;
  border-color: #f3d08c;
}

.forge-epee button:disabled {
  opacity: 0.55;
  cursor: var(--curseur);
}

.forge-fermer,
.feuille-fermer {
  justify-self: center;
  min-width: 140px;
}

/* La feuille : le portrait dans le cadre rond, l'identité, les chiffres, les notions. */
.feuille-cadre {
  grid-template-rows: auto auto auto minmax(0, 1fr) auto;
  width: min(620px, 100%);
}

.feuille-tete {
  display: grid;
  grid-template-columns: 132px 1fr;
  gap: 16px;
  align-items: center;
}

.feuille-portrait {
  position: relative;
  width: 132px;
  height: 132px;
}

.feuille-portrait img {
  position: absolute;
  inset: 12px;
  width: calc(100% - 24px);
  height: calc(100% - 24px);
  object-fit: cover;
  object-position: 50% 12%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 40%, #3a3360, #17152e 75%);
}

.feuille-portrait::after {
  content: "";
  position: absolute;
  inset: -4px;
  background: url("assets/ui/cadre-rond.png") no-repeat center / contain;
  pointer-events: none;
}

.feuille-identite .feuille-titre {
  padding-bottom: 14px;
  text-align: left;
  background-position: left bottom;
}

.feuille-prenom {
  margin: 0;
  font: 600 clamp(1.3rem, 1rem + 1.4vw, 1.7rem) / 1.15 var(--police);
}

.feuille-sous-titre {
  margin: 2px 0 0;
  color: rgb(246 236 214 / 0.8);
  font: 500 0.95rem/1.3 var(--police);
}

.feuille-stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin: 0;
}

/* Les exploits (version 2.3) : six sceaux de cire, dorés une fois décrochés. */
.feuille-exploits-titre {
  margin: 4px 0 0;
  color: var(--or-vif);
  font: 600 0.85rem/1.2 var(--police);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.feuille-exploits {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.feuille-exploits li {
  display: grid;
  grid-template-columns: 34px 1fr;
  grid-template-rows: auto auto;
  column-gap: 8px;
  align-items: center;
  font: 500 0.82rem/1.2 var(--police);
}

.feuille-sceau {
  grid-row: 1 / 3;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 2px solid var(--or-fonce);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #ffe9a8, #c89a3a 60%, #8a6414);
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.4), inset 0 0 0 3px rgb(255 240 200 / 0.35);
  color: #4a2a08;
  font: 700 1rem/1 var(--police);
}

.feuille-exploit-nom {
  font-weight: 600;
}

.feuille-exploit-condition {
  color: var(--encre-douce, inherit);
  font-size: 0.74rem;
}

.feuille-exploits li[data-obtenu="non"] .feuille-sceau {
  border-color: rgb(120 110 100 / 0.5);
  background: radial-gradient(circle at 35% 30%, #d9d2c8, #9a948c 60%, #5e5852);
  box-shadow: none;
  color: rgb(40 30 30 / 0.45);
}

.feuille-exploits li[data-obtenu="non"] .feuille-exploit-nom,
.feuille-exploits li[data-obtenu="non"] .feuille-exploit-condition {
  opacity: 0.6;
}

.feuille-stat {
  display: grid;
  gap: 2px;
  padding: 8px 10px;
  border: 1px solid rgb(168 128 62 / 0.45);
  border-radius: 4px;
  background: rgb(243 208 140 / 0.05);
  text-align: center;
}

.feuille-stat dt {
  color: var(--or-vif);
  font: 600 0.72rem/1.2 var(--police);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.feuille-stat dd {
  margin: 0;
  font: 600 1.05rem/1.25 var(--police);
}

.feuille-notions-titre {
  margin: 4px 0 0;
  color: var(--or-vif);
  font: 600 0.85rem/1.2 var(--police);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.feuille-notions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
  margin: 0;
  padding: 0 0 0 1.4em;
  overflow-y: auto;
  font: 500 0.95rem/1.35 var(--police);
  overscroll-behavior: contain;
}

.feuille-notions li {
  display: flex;
  flex-wrap: wrap;
  gap: 0 8px;
  padding-right: 6px;
}

.feuille-etat {
  color: rgb(246 236 214 / 0.6);
  font-size: 0.82rem;
}

.feuille-notions li[data-etat="apprise"] .feuille-etat {
  color: var(--or-vif);
}

.feuille-notions li[data-etat="a-apprendre"] .feuille-notion {
  color: rgb(246 236 214 / 0.7);
}

@media (max-width: 640px) {
  .feuille-stats {
    grid-template-columns: repeat(2, 1fr);
  }

  .feuille-notions {
    grid-template-columns: 1fr;
  }

  .feuille-exploits {
    grid-template-columns: repeat(3, 1fr);
    gap: 4px 6px;
  }

  .feuille-exploits li {
    grid-template-columns: 26px 1fr;
    column-gap: 5px;
    font-size: 0.72rem;
  }

  .feuille-sceau {
    width: 26px;
    height: 26px;
    border-width: 1.5px;
    font-size: 0.8rem;
  }

  .feuille-exploit-condition {
    display: none;
  }

  .feuille-notions {
    min-height: 7.5rem;
  }

  .feuille-tete {
    grid-template-columns: 104px 1fr;
  }

  .feuille-portrait {
    width: 104px;
    height: 104px;
  }

  #clartes {
    height: 36px;
    padding: 0 12px;
  }

  .fiche-bouton {
    width: 48px;
    height: 48px;
  }
}

@media (max-height: 480px) {
  .feuille-tete {
    grid-template-columns: 80px 1fr;
  }

  .feuille-portrait {
    width: 80px;
    height: 80px;
  }

  #attaque {
    bottom: calc(100px + env(safe-area-inset-bottom));
    width: 64px;
    height: 64px;
  }
}

/* Téléphone : le HUD tient sur deux lignes (la rangée des parchemins et le
   bouton livre, puis les Tokens et les clartés), le bandeau de lieu dessous. */
@media (max-width: 640px) {
  .parchemins-ligne {
    flex-flow: row wrap;
    align-items: center;
    gap: 6px 8px;
    max-width: calc(100vw - 80px - env(safe-area-inset-left) - env(safe-area-inset-right));
  }

  #tokens,
  #clartes {
    height: 36px;
  }

  #lieu {
    top: calc(120px + env(safe-area-inset-top));
  }
}

/* ==== Version 2.1 : l'interface illustrée ==================================
   Les cadres, plaques et gemmes sont des dessins (assets/ui/, générés puis
   détourés par outils/detourer.mjs et découpés par outils/decouper.mjs), posés
   en bordure étirable (border-image) : les coins restent entiers, les filets
   s'étirent. La boîte de dialogue garde son cadre de nuit ; les menus passent
   sur parchemin, encre et sépia ; le HUD tient sur des plaques d'ivoire ; les
   clartés sont des gemmes. L'écran titre devient une page de parchemin avec
   l'illustration du voyageur et un menu. Une légende des touches apparaît
   sur ordinateur. Tout grandit d'un dixième. */

:root {
  --ivoire: #efe2c4;
  --sepia: #7a4a12;
  --encre-douce: rgb(42 29 46 / 0.72);
  --cadre-sombre: url("assets/ui/cadre-sombre.png") 110 fill;
  --cadre-parchemin: url("assets/ui/cadre-parchemin.png") 110 fill;
  --plaque: url("assets/ui/bouton.png") 0 95 fill;
}

/* --- Les plaques d'ivoire : une bordure étirable aux deux bouts seulement. */
.parchemins-rangee,
#tokens,
#clartes,
.titre-menu button,
.dialogue-nom,
.forge-epee button,
.forge-fermer,
.feuille-fermer,
.boutique-tenue button,
.boutique-fermer,
.carte-fermer,
.grimoire-boutons button,
.diplome-boutons button,
.generique-passer {
  border: 0 solid transparent;
  border-width: 0 30px;
  border-image: var(--plaque) / 0 30px stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--encre);
  filter: drop-shadow(0 3px 6px rgb(0 0 0 / 0.4));
}

/* --- La boîte de dialogue : le cadre de nuit, le nom sur une plaque. ------- */
#dialogue {
  width: min(840px, calc(100% - 28px - env(safe-area-inset-left) - env(safe-area-inset-right)));
  padding: 6px 12px 10px;
  border: 48px solid transparent;
  border-image: var(--cadre-sombre) / 48px stretch;
  border-radius: 0;
  background: none;
  box-shadow: 0 18px 46px rgb(0 0 0 / 0.55);
}

#dialogue .coins {
  display: none;
}

.dialogue-nom {
  top: -36px;
  left: 28px;
  padding: 6px 22px 7px;
  font-size: clamp(0.98rem, 0.6rem + 1.4vw, 1.12rem);
  letter-spacing: 0.1em;
}

.dialogue-nom::before {
  display: none;
}

.dialogue-texte {
  margin-top: 2px;
  min-height: 4.4em;
  padding-right: 20px;
  font-size: clamp(1.2rem, 0.8rem + 1.7vw, 1.6rem);
}

.dialogue-suite {
  right: 4px;
  bottom: 2px;
}

.dialogue-choix button {
  min-height: 56px;
  font-size: clamp(1.08rem, 0.74rem + 1.4vw, 1.3rem);
}

@media (min-width: 1101px) {
  #dialogue.avec-portrait {
    transform: translateX(calc(-50% + 150px));
  }
}

/* --- Les menus : parchemin, encre et sépia. -------------------------------- */
.carte-cadre,
.boutique-cadre,
.grimoire-livre,
.forge-cadre,
.feuille-cadre {
  padding: 4px 10px 8px;
  border: 54px solid transparent;
  border-image: var(--cadre-parchemin) / 54px stretch;
  border-radius: 0;
  background: none;
  box-shadow: 0 22px 54px rgb(0 0 0 / 0.55);
  color: var(--encre);
}

.carte-cadre .coins,
.boutique-cadre .coins,
.grimoire-livre .coins,
.forge-cadre .coins,
.feuille-cadre .coins {
  display: none;
}

.carte-titre,
.boutique-titre,
.grimoire-titre,
.forge-titre,
.feuille-titre {
  color: var(--sepia);
  font-size: clamp(1.2rem, 0.9rem + 1.2vw, 1.5rem);
}

.forge-bourse,
.boutique-bourse,
.feuille-stat dt,
.feuille-notions-titre,
.grimoire-numero,
.grimoire-maitre {
  color: var(--sepia);
}

.forge-epee,
.boutique-tenue,
.feuille-stat {
  border-color: rgb(122 74 18 / 0.35);
  background: rgb(255 250 238 / 0.6);
}

.forge-epee[data-forgee="oui"],
.boutique-tenue[data-portee="oui"] {
  border-color: var(--or-fonce);
  background: rgb(243 208 140 / 0.35);
}

.forge-nom,
.boutique-nom,
.feuille-prenom,
.feuille-stat dd,
.feuille-notion,
.carte-legende {
  color: var(--encre);
}

.forge-nom,
.boutique-nom {
  font-size: 1.15rem;
}

.forge-description,
.boutique-description,
.feuille-sous-titre,
.feuille-etat {
  color: var(--encre-douce);
  font-size: 1rem;
}

.feuille-notions {
  font-size: 1.05rem;
}

.feuille-notions li[data-etat="apprise"] .feuille-etat {
  color: var(--sepia);
}

.feuille-notions li[data-etat="a-apprendre"] .feuille-notion {
  color: rgb(42 29 46 / 0.55);
}

.forge-epee button,
.forge-fermer,
.feuille-fermer,
.boutique-tenue button,
.boutique-fermer,
.carte-fermer,
.grimoire-boutons button,
.diplome-boutons button {
  min-height: 48px;
  padding: 8px 10px;
  font: 600 1.02rem/1.2 var(--police);
  letter-spacing: 0.04em;
}

.forge-epee button.principal,
.boutique-tenue button.principal,
.diplome-boutons .principal {
  color: var(--encre);
  filter: drop-shadow(0 0 9px rgb(243 208 140 / 0.95)) drop-shadow(0 3px 6px rgb(0 0 0 / 0.4));
}

.forge-epee button:disabled,
.boutique-tenue button:disabled,
.grimoire-boutons button:disabled {
  opacity: 0.5;
}

.forge-epee button:focus-visible,
.forge-fermer:focus-visible,
.feuille-fermer:focus-visible,
.boutique-tenue button:focus-visible,
.boutique-fermer:focus-visible,
.carte-fermer:focus-visible,
.grimoire-boutons button:focus-visible,
.titre-menu button:focus-visible {
  outline: 2px solid var(--sepia);
  outline-offset: 2px;
}

.grimoire-onglet::before {
  border-color: rgb(122 74 18 / 0.5);
  background: rgb(122 74 18 / 0.08);
}

.grimoire-onglet[aria-current="page"]::before {
  box-shadow: 0 0 0 2px var(--sepia);
}

/* --- Le HUD : plaques d'ivoire, icônes dessinées, gemmes de clarté. -------- */
.parchemins-rangee,
#tokens,
#clartes {
  height: 58px;
  padding: 0 4px;
  font-size: 1.3rem;
}

.parchemins-rangee {
  gap: 8px;
}

.parchemins-rangee::before {
  width: 40px;
  height: 32px;
}

.parchemin {
  width: 19px;
  height: 25px;
  border-color: rgb(122 74 18 / 0.5);
  background: rgb(122 74 18 / 0.08);
}

.parchemin::before,
.parchemin::after {
  border-color: rgb(122 74 18 / 0.5);
  background: #e9d8b3;
}

.parchemins-rangee:hover,
.parchemins-rangee:focus-visible {
  filter: drop-shadow(0 0 8px rgb(243 208 140 / 0.9));
  outline: none;
}

#tokens .tokens-montant {
  color: var(--encre);
}

.tokens-piece {
  width: 30px;
  height: 30px;
}

#clartes {
  gap: 4px;
}

.clarte {
  width: 20px;
  height: 28px;
  background: url("assets/ui/clarte.png") no-repeat center / contain;
  rotate: 0deg;
  box-shadow: none;
  filter: drop-shadow(0 0 5px rgb(255 220 140 / 0.7));
}

.clarte.perdue {
  background-image: url("assets/ui/clarte-eteinte.png");
  box-shadow: none;
  scale: 1;
  filter: none;
  opacity: 0.8;
}

#clartes[data-alerte="oui"] .clarte:not(.perdue) {
  animation: clarte-alerte-2 0.8s ease-in-out infinite;
}

@keyframes clarte-alerte-2 {
  50% {
    filter: drop-shadow(0 0 10px rgb(255 120 90 / 1)) brightness(1.25);
  }
}

/* Les boutons ronds (livre du HUD, son) : ivoire dans l'anneau d'or. */
.fiche-bouton,
#son {
  position: relative;
  width: 58px;
  height: 58px;
  border: 0;
  background: radial-gradient(circle at 50% 40%, #f8ecd4, #e2cc9f 70%);
  box-shadow: 0 4px 10px rgb(0 0 0 / 0.45);
  color: var(--encre);
  overflow: visible;
}

.fiche-bouton {
  background: url("assets/ui/icone-livre.png") no-repeat center / 32px auto, radial-gradient(circle at 50% 40%, #f8ecd4, #e2cc9f 70%);
}

.fiche-bouton::after,
#son::after {
  content: "";
  position: absolute;
  inset: -7px;
  background: url("assets/ui/cadre-rond.png") no-repeat center / contain;
  pointer-events: none;
}

#son {
  position: fixed;
  width: 54px;
  height: 54px;
}

.fiche-bouton:hover,
.fiche-bouton:focus-visible,
#son:hover,
#son:focus-visible {
  filter: drop-shadow(0 0 8px rgb(243 208 140 / 0.9));
  outline: none;
}

/* L'annonce (parchemin gagné, coffre) : un petit cadre de nuit. */
.parchemins-annonce {
  padding: 2px 8px 4px;
  border: 30px solid transparent;
  border-image: var(--cadre-sombre) / 30px stretch;
  border-radius: 0;
  background: none;
  box-shadow: 0 8px 22px rgb(0 0 0 / 0.5);
  font-size: 1.1rem;
}

/* Les boutons tactiles : ivoire dans l'anneau d'or, l'étincelle ou la bulle en encre. */
#action,
#attaque {
  border: 0;
  background: radial-gradient(circle at 50% 40%, #f8ecd4, #dcc69a 72%);
  color: var(--encre);
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.5);
}

#attaque {
  width: 84px;
  height: 84px;
  background: url("assets/ui/icone-epee.png") no-repeat center / auto 50px, radial-gradient(circle at 50% 40%, #f8ecd4, #dcc69a 72%);
}

#action::after,
#attaque::after {
  content: "";
  position: absolute;
  inset: -9px;
  background: url("assets/ui/cadre-rond.png") no-repeat center / contain;
  pointer-events: none;
}

#action[data-mode="parler"] {
  border: 0;
  background: radial-gradient(circle at 50% 40%, #fff6e2, #f3d08c 75%);
  box-shadow: 0 0 0 3px rgb(243 208 140 / 0.35), 0 6px 18px rgb(0 0 0 / 0.5);
}

#action[data-mode="repos"] {
  opacity: 0.8;
}

/* --- La légende des touches, sur ordinateur. ------------------------------- */
#touches {
  position: fixed;
  left: calc(14px + env(safe-area-inset-left));
  bottom: calc(14px + env(safe-area-inset-bottom));
  z-index: 11;
  display: none;
  padding: 2px 6px 4px;
  border: 34px solid transparent;
  border-image: var(--cadre-sombre) / 34px stretch;
  color: var(--texte);
  font: 500 0.95rem/1.3 var(--police);
  box-shadow: 0 10px 28px rgb(0 0 0 / 0.5);
  pointer-events: none;
  transition: opacity 0.25s ease;
}

@media (hover: hover) and (pointer: fine) {
  #touches:not([hidden]) {
    display: block;
  }
}

#touches[data-efface="oui"] {
  opacity: 0;
}

.touches-titre {
  margin: 0 0 8px;
  color: var(--or-vif);
  font: 600 0.8rem/1.2 var(--police);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.touches-liste {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.touches-liste li {
  display: grid;
  grid-template-columns: 106px 1fr;
  align-items: center;
  gap: 12px;
}

.touches-liste li[hidden] {
  display: none;
}

.touches-touches {
  display: flex;
  gap: 3px;
}

.touches-touches kbd {
  display: inline-grid;
  place-items: center;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border: 1px solid var(--or-fonce);
  border-bottom-width: 3px;
  border-radius: 4px;
  background: linear-gradient(180deg, #f8e9c9, #dcc08a);
  color: var(--encre);
  font: 600 0.8rem/1 var(--police);
  white-space: nowrap;
}

.touches-action {
  color: #efe3cb;
  white-space: nowrap;
}

/* --- L'écran titre : une page de parchemin, l'illustration, le menu. ------- */
#titre {
  padding: calc(16px + env(safe-area-inset-top)) 16px calc(16px + env(safe-area-inset-bottom));
  background:
    radial-gradient(ellipse 85% 75% at 50% 42%, rgb(255 250 238 / 0.9), rgb(255 250 238 / 0) 70%),
    linear-gradient(180deg, #f2e6cc, #e9d8b3 60%, #d9c39a);
  cursor: var(--curseur);
}

#titre::before {
  display: none;
}

.titre-cadre {
  gap: clamp(6px, 1.4vh, 14px);
  width: min(1100px, 100%);
}

.titre-illustration {
  width: auto;
  height: clamp(170px, 34vh, 360px);
  filter: drop-shadow(0 16px 26px rgb(90 55 20 / 0.28));
  animation: titre-flotte 5s ease-in-out infinite;
}

@keyframes titre-flotte {
  50% {
    translate: 0 -6px;
  }
}

.titre-texte {
  display: grid;
  justify-items: center;
  gap: clamp(6px, 1.2vh, 12px);
  text-align: center;
}

.titre-nom {
  background: none;
  color: #2b1b22;
  filter: none;
  text-shadow: 0 1px 0 #fff8e6, 0 3px 0 rgb(122 74 18 / 0.18);
  font-size: clamp(2.2rem, 1rem + 6vw, 4.6rem);
}

.titre-orne {
  width: min(380px, 80%);
}

.titre-contree {
  color: var(--sepia);
  text-shadow: none;
}

.titre-accroche {
  color: #4d3b33;
  text-shadow: none;
}

.titre-menu {
  display: grid;
  gap: 10px;
  margin-top: 6px;
}

.titre-menu button {
  min-width: 280px;
  min-height: 56px;
  margin: 0;
  padding: 10px 14px;
  border-width: 0 40px;
  border-image: var(--plaque) / 0 40px stretch;
  font: 600 clamp(1.1rem, 0.9rem + 0.8vw, 1.3rem) / 1.2 var(--police);
  letter-spacing: 0.08em;
  text-transform: none;
  text-decoration: none;
  text-shadow: none;
  cursor: var(--curseur-actif);
  touch-action: manipulation;
  animation: none;
  transition: scale 0.15s ease, filter 0.15s ease;
}

.titre-menu button.choisi,
.titre-menu button:hover {
  filter: brightness(1.08) drop-shadow(0 3px 6px rgb(0 0 0 / 0.35));
}

.titre-menu button[hidden] {
  display: none;
}

.titre-prenom {
  margin-top: 4px;
  color: #4d3b33;
  text-shadow: none;
}

.titre-prenom input {
  border-color: var(--sepia);
  background: #fff8e8;
  color: var(--encre);
}

.titre-prenom input:focus {
  outline-color: var(--sepia);
}

.titre-commandes {
  border-color: rgb(122 74 18 / 0.6);
  background: rgb(255 248 232 / 0.7);
  color: var(--encre);
}

.titre-credits {
  color: #5a463a;
  text-shadow: none;
}

.titre-site {
  color: var(--sepia);
}

/* Écran large : l'illustration à gauche, grande, le texte et le menu à droite. */
@media (orientation: landscape) and (min-width: 560px) {
  .titre-cadre {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto;
    align-items: center;
    column-gap: clamp(20px, 4vw, 56px);
  }

  .titre-cadre > .titre-illustration {
    grid-column: 1;
    grid-row: 1;
    height: min(80vh, 640px);
    margin: 0;
  }

  .titre-cadre > .titre-texte {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
  }
}

/* Écran court (téléphone en paysage) : tout plus petit. */
@media (max-height: 480px) {
  .titre-illustration {
    height: 36vh;
  }

  .titre-cadre > .titre-illustration {
    height: 78vh;
  }

  .titre-menu button {
    min-width: 220px;
    min-height: 44px;
    padding: 6px 10px;
  }

  .titre-nom {
    font-size: clamp(1.7rem, 5.5vh + 0.9rem, 2.8rem);
  }
}

/* L'image de partage : l'illustration grande à gauche, le titre à droite. */
[data-vignette] .titre-cadre {
  grid-template-rows: auto;
}

[data-vignette] .titre-cadre > .titre-illustration {
  grid-column: 1;
  grid-row: 1;
  height: 560px;
  animation: none;
}

[data-vignette] .titre-cadre > .titre-texte {
  grid-column: 2;
  grid-row: 1;
}

[data-vignette] .titre-menu {
  display: none;
}

/* Téléphone : cadres et plaques plus fins, HUD sur deux lignes. */
@media (max-width: 640px) {
  #dialogue {
    border-width: 32px;
    border-image-width: 32px;
    padding: 4px 6px 8px;
  }

  .dialogue-nom {
    top: -30px;
    left: 10px;
  }

  .carte-cadre,
  .boutique-cadre,
  .grimoire-livre,
  .forge-cadre,
  .feuille-cadre {
    border-width: 38px;
    border-image-width: 38px;
    padding: 2px 4px 6px;
  }

  .parchemins-rangee,
  #tokens,
  #clartes {
    height: 50px;
    border-width: 0 24px;
    border-image-width: 0 24px;
    font-size: 1.15rem;
  }

  .fiche-bouton {
    width: 50px;
    height: 50px;
  }

  .clarte {
    width: 17px;
    height: 24px;
  }

  #lieu {
    top: calc(126px + env(safe-area-inset-top));
  }
}

/* Paysage bas : les grands cadres prendraient la place du texte. */
@media (max-height: 480px) {
  #dialogue {
    border-width: 22px;
    border-image-width: 22px;
    padding: 2px 6px 4px;
  }

  .dialogue-nom {
    top: -26px;
  }

  .carte-cadre,
  .boutique-cadre,
  .grimoire-livre,
  .forge-cadre,
  .feuille-cadre {
    border-width: 28px;
    border-image-width: 28px;
  }

  #touches {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .titre-illustration {
    animation: none;
  }
}

/* Les panneaux sur parchemin : plus larges, le cadre prenant sa part ; les
   petits boutons gardent des bouts de plaque plus courts et une seule ligne. */
.forge-cadre,
.boutique-cadre {
  width: min(680px, 100%);
}

.feuille-cadre {
  width: min(760px, 100%);
}

.grimoire-livre {
  width: min(720px, 100%);
}

.carte-cadre {
  width: min(860px, 100%);
}

.forge-epee button,
.forge-fermer,
.feuille-fermer,
.boutique-tenue button,
.boutique-fermer,
.carte-fermer,
.grimoire-boutons button,
.diplome-boutons button,
.generique-passer {
  padding: 8px 4px;
  border-width: 0 22px;
  border-image-width: 0 22px;
  white-space: nowrap;
}

.forge-epee,
.boutique-tenue {
  gap: 14px;
  padding: 12px 14px;
}

.forge-fermer,
.feuille-fermer,
.boutique-fermer,
.carte-fermer {
  min-width: 170px;
}

/* ==== Version 2.3 : la légende repliable, la minimap au-dessus du son =========
   La touche T replie la légende des touches sur son seul titre (elle prenait
   un coin d'écran). En haut à droite, la minimap passe au-dessus et le bouton
   du son se range dessous, à toutes les tailles d'écran. */

#touches[data-replie="oui"] .touches-liste {
  display: none;
}

#touches[data-replie="oui"] {
  padding-bottom: 6px;
}

#touches[data-replie="oui"] .touches-titre {
  margin-bottom: 0;
}

#minimap {
  top: calc(12px + env(safe-area-inset-top));
  right: calc(12px + env(safe-area-inset-right));
}

#son {
  top: calc(192px + env(safe-area-inset-top));
}

@media (max-width: 640px) {
  #minimap {
    right: calc(12px + env(safe-area-inset-right));
  }

  #son {
    top: calc(150px + env(safe-area-inset-top));
  }
}

@media (max-height: 480px) {
  #minimap {
    right: calc(12px + env(safe-area-inset-right));
  }

  #son {
    top: calc(122px + env(safe-area-inset-top));
  }
}

/* ==== Version 2.5 : le dialogue sans boîte ====================================
   Comme dans les RPG en HD-2D : plus de cadre. Le nom, puis le texte, posés
   sur un voile sombre fondu, dans le tiers haut de l'écran (au-dessus des
   personnages qui parlent) ; le portrait en grand, debout dans le coin bas
   gauche. Pendant la conversation, deux bandes sombres et douces ferment le
   haut et le bas de l'écran. Ce bloc annule les cadres des versions
   précédentes, déclarés plus haut. */

#dialogue,
#dialogue.avec-portrait {
  top: calc(17vh + env(safe-area-inset-top));
  right: 0;
  bottom: auto;
  left: 0;
  display: grid;
  grid-template-columns: 1fr minmax(0, 720px) 1fr;
  width: auto;
  padding: 3.2vh max(24px, env(safe-area-inset-right)) 3.6vh max(24px, env(safe-area-inset-left));
  border: 0;
  border-image: none;
  border-radius: 0;
  background: radial-gradient(ellipse 52% 64% at 50% 50%, rgb(5 4 12 / 0.9), rgb(5 4 12 / 0.74) 45%, rgb(5 4 12 / 0) 80%);
  box-shadow: none;
  filter: none;
  transform: none;
  animation: dialogue-fond 0.25s ease-out;
}

/* Le portrait occupe la gauche : le texte se décale vers la droite. */
#dialogue.avec-portrait {
  grid-template-columns: minmax(min(30vw, 470px), 1fr) minmax(0, 700px) 1fr;
  background: radial-gradient(ellipse 46% 64% at 58% 50%, rgb(5 4 12 / 0.9), rgb(5 4 12 / 0.74) 45%, rgb(5 4 12 / 0) 80%);
}

/* Les deux règles ci-dessus ont la même force que #dialogue[hidden], déclarée
   plus haut, et passent après elle : sans ce rappel, la conversation finie,
   le voile, le nom et le texte restaient à l'écran. */
#dialogue[hidden] {
  display: none;
}

#dialogue > * {
  grid-column: 2;
}

/* Les deux bandes de cinéma, fondues, qui assombrissent aussi l'interface. */
#dialogue::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  display: block;
  width: auto;
  height: auto;
  background:
    linear-gradient(180deg, rgb(3 2 8 / 0.82), rgb(3 2 8 / 0) 20%, rgb(3 2 8 / 0) 76%, rgb(3 2 8 / 0.85)),
    radial-gradient(ellipse 85% 75% at 50% 50%, rgb(3 2 8 / 0.08), rgb(3 2 8 / 0.5));
  box-shadow: none;
  rotate: none;
  pointer-events: none;
}

#dialogue::after,
#dialogue .coins {
  display: none;
}

#dialogue .dialogue-nom,
#dialogue.avec-portrait .dialogue-nom {
  position: static;
  margin: 0 0 0.45em;
  padding: 0;
  border: 0;
  border-image: none;
  background: none;
  filter: none;
  color: #f1e2c4;
  font: 500 clamp(0.98rem, 0.75rem + 0.9vw, 1.2rem) / 1.2 var(--police);
  letter-spacing: 0.02em;
  text-transform: none;
  text-shadow: 0 1px 4px rgb(0 0 0 / 0.9);
}

#dialogue .dialogue-texte {
  min-height: 2.9em;
  margin: 0;
  padding: 0 0 0 1.1em;
  color: #fbf6ec;
  font: 500 clamp(1.18rem, 0.8rem + 1.45vw, 1.7rem) / 1.45 var(--police);
  text-shadow: 0 1px 3px rgb(0 0 0 / 0.95), 0 0 14px rgb(0 0 0 / 0.6);
}

/* La marque de suite : un petit triangle blanc qui bat, sous la fin du texte. */
#dialogue .dialogue-suite {
  position: static;
  justify-self: end;
  margin-top: 0.2em;
  border: 7px solid transparent;
  border-top: 10px solid #fbf6ec;
  border-bottom: 0;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.9));
}

#dialogue[data-fin="oui"] .dialogue-suite {
  background: #fbf6ec;
}

/* Les choix : des lignes de texte, un filet d'or devant celui qu'on vise. */
#dialogue .dialogue-choix {
  margin-top: 0.7em;
  padding-left: 1.1em;
}

#dialogue .dialogue-choix button {
  min-height: 46px;
  border: 0;
  border-left: 2px solid transparent;
  border-radius: 0;
  background: linear-gradient(90deg, rgb(5 4 12 / 0.55), rgb(5 4 12 / 0) 85%);
  box-shadow: none;
  color: #f3e9d6;
  font-size: clamp(1.02rem, 0.82rem + 0.9vw, 1.35rem);
  text-shadow: 0 1px 3px rgb(0 0 0 / 0.9);
}

#dialogue .dialogue-choix button.choisi,
#dialogue .dialogue-choix button:focus-visible {
  border-left-color: var(--or-vif);
  background: linear-gradient(90deg, rgb(243 208 140 / 0.22), rgb(5 4 12 / 0) 85%);
  box-shadow: none;
  color: #fffaf0;
}

/* Le portrait : debout dans le coin bas gauche, aussi grand que l'écran le permet. */
#dialogue .dialogue-portrait {
  position: fixed;
  right: auto;
  bottom: 0;
  left: max(1.5vw, env(safe-area-inset-left));
  z-index: -1;
  height: min(76vh, 780px);
}

#dialogue .dialogue-portrait::before {
  inset: 10% -25% -4%;
  background: radial-gradient(ellipse at 50% 65%, rgb(5 4 12 / 0.7), rgb(5 4 12 / 0) 70%);
}

@keyframes dialogue-fond {
  from {
    opacity: 0;
  }
}

/* Téléphone en portrait : le texte sur toute la largeur, au tiers haut ; le
   portrait plus petit, en bas à gauche, sous le texte. */
@media (max-width: 760px) {
  #dialogue,
  #dialogue.avec-portrait {
    top: calc(205px + env(safe-area-inset-top));
    grid-template-columns: 0 minmax(0, 1fr) 0;
    padding: 22px 18px 26px;
    background: radial-gradient(ellipse 85% 70% at 50% 50%, rgb(5 4 12 / 0.82), rgb(5 4 12 / 0.6) 50%, rgb(5 4 12 / 0) 85%);
  }

  #dialogue .dialogue-texte {
    padding-left: 0;
    font-size: 1.12rem;
  }

  #dialogue .dialogue-choix {
    padding-left: 0;
  }

  #dialogue .dialogue-portrait {
    left: 0;
    height: min(44vh, 400px);
  }
}

/* Paysage bas (téléphone couché) : le texte en haut, le portrait petit à gauche. */
@media (max-height: 480px) {
  #dialogue,
  #dialogue.avec-portrait {
    top: calc(58px + env(safe-area-inset-top));
    padding: 10px 18px 12px;
  }

  #dialogue.avec-portrait {
    grid-template-columns: 24vw minmax(0, 1fr) 0.3fr;
  }

  #dialogue .dialogue-portrait {
    display: block;
    height: 72vh;
  }

  #dialogue .dialogue-texte {
    min-height: 2.6em;
    font-size: 1.05rem;
  }

  #dialogue .dialogue-choix {
    margin-top: 0.4em;
  }

  #dialogue .dialogue-choix button {
    min-height: 40px;
    font-size: 0.98rem;
  }
}

@media (max-height: 480px) and (max-width: 760px) {
  #dialogue .dialogue-portrait {
    display: none;
  }
}

/* --- Version 2.6 : bandeaux, annonces, chiffres de dégâts, lieu courant. --- */

/* Le bandeau de lieu descend vers le centre de l'écran : en haut, il passait
   sous les pastilles et la minimap sur un écran de portable. */
#lieu {
  top: 30vh;
}

/* Les annonces (parchemin, Token, coffre, exploit) quittent le coin des
   pastilles pour le milieu du bord gauche, où rien ne les couvre. */
.parchemins-annonce {
  position: fixed;
  left: calc(16px + env(safe-area-inset-left));
  top: 42vh;
  z-index: 13;
  margin: 0;
}

@media (max-width: 640px), (max-height: 480px) {
  body:has(.parchemins-annonce:not([hidden])) #lieu {
    visibility: visible;
  }
}

/* Le lieu où l'on est : sous la minimap, au-dessus du bouton du son. */
#endroit {
  position: fixed;
  top: calc(224px + env(safe-area-inset-top));
  right: calc(12px + env(safe-area-inset-right));
  z-index: 13;
  width: 204px;
  margin: 0;
  padding: 7px 12px 8px;
  border: 1px solid var(--or-fonce);
  border-radius: 4px;
  background: rgb(14 13 28 / 0.86);
  box-shadow: inset 0 0 0 2px rgb(14 13 28 / 0.9), inset 0 0 0 3px rgb(243 208 140 / 0.35), 0 4px 14px rgb(0 0 0 / 0.45);
  color: #fbf1dc;
  font: 500 0.95rem/1.25 var(--police);
  text-align: right;
  pointer-events: none;
}

#endroit[hidden] {
  display: none;
}

.endroit-monde {
  display: block;
  color: var(--or-vif);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.endroit-lieu {
  display: block;
  margin-top: 2px;
}

.endroit-lieu:empty {
  display: none;
}

#endroit:has(.endroit-lieu:empty) .endroit-monde {
  color: #fbf1dc;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: none;
}

@media (max-width: 640px) {
  #endroit {
    top: calc(160px + env(safe-area-inset-top));
    width: 150px;
    padding: 5px 9px 6px;
    font-size: 0.82rem;
  }
}

/* Avec le lieu courant sous la minimap, le bouton du son descend d'autant. */
#son {
  top: calc(296px + env(safe-area-inset-top));
}

@media (max-width: 640px) {
  #son {
    top: calc(222px + env(safe-area-inset-top));
  }
}

/* Les chiffres de dégâts (src/game/damage.js), posés sur le canvas. */
#degats {
  position: fixed;
  inset: 0;
  z-index: 12;
  overflow: hidden;
  pointer-events: none;
}

.degat {
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  justify-items: center;
  color: #fff3d6;
  font: 700 1.5rem/1 var(--police);
  text-shadow: 0 0 2px #2a1308, 0 2px 0 #2a1308, 0 -2px 0 #2a1308, 2px 0 0 #2a1308, -2px 0 0 #2a1308, 0 3px 10px rgb(0 0 0 / 0.7);
  translate: -50% -100%;
  will-change: transform, opacity;
}

.degat-critique {
  color: var(--or-vif);
  font-size: 2.1rem;
}

.degat small {
  margin-top: 2px;
  color: #fff3d6;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.degat-recu {
  color: #ff7a6a;
}

/* Le dernier choix d'une question, « Au revoir » : en retrait, sans numéro. */
.dialogue-choix button.sortie {
  opacity: 0.8;
  font-style: italic;
}

/* Le « double fond » des cadres illustrés : box-shadow dessine un rectangle
   autour de la boîte entière, qui dépassait du filet doré en haut et en bas
   (les coins du cadre sont transparents). drop-shadow suit le dessin. */
.carte-cadre,
.boutique-cadre,
.grimoire-livre,
.forge-cadre,
.feuille-cadre {
  box-shadow: none;
  filter: drop-shadow(0 16px 22px rgb(0 0 0 / 0.5));
}

#touches {
  box-shadow: none;
  filter: drop-shadow(0 8px 14px rgb(0 0 0 / 0.5));
}

/* Sans minimap (la lande, une pièce), le lieu courant monte sous les pastilles. */
body:has(#minimap[hidden]) #endroit {
  top: calc(74px + env(safe-area-inset-top));
}

body:has(#minimap[hidden]) #son {
  top: calc(146px + env(safe-area-inset-top));
}

/* --- Version 2.6 : l'écran titre sur l'illustration. ----------------------- */

/* La page : le papier de l'illustration prolongé sur tout l'écran. */
#titre {
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 0;
  padding: 0;
  background: #f7f4ee;
  overflow: hidden auto;
}

/* L'illustration, entière, aussi grande que l'écran le permet (16 : 9). */
.titre-scene {
  position: relative;
  display: block;
  width: min(100vw, 177.7vh);
  margin: 0;
}

/* L'image et son cache, dans la même boîte : le cache suit l'image seule. */
.titre-image {
  position: relative;
  width: 100%;
  aspect-ratio: 1672 / 941;
}

.titre-image > .titre-illustration {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  filter: none;
  animation: none;
}

/* Le cache : du papier fondu sur la partie dessinée que le HTML remplace
   (bouton, champ du prénom, signature), en pourcentages de l'image. */
.titre-cache {
  position: absolute;
  left: 67.5%;
  top: 58%;
  width: 26.5%;
  height: 37%;
  background: #f7f4ee;
  box-shadow: 0 0 28px 22px #f7f4ee;
  border-radius: 20px;
}

/* Le texte : hors de l'image, dessous, centré (écran étroit ou court). */
.titre-scene > .titre-texte {
  display: grid;
  justify-items: center;
  gap: 10px;
  width: min(100%, 420px);
  margin: 10px auto 16px;
  padding: 0 16px;
  text-align: center;
}

.titre-invisible {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.titre-scene .titre-menu {
  display: grid;
  gap: 8px;
  margin: 0;
}

.titre-scene .titre-menu button {
  min-width: 260px;
  min-height: 54px;
}

.titre-scene .titre-prenom {
  display: grid;
  gap: 4px;
  width: 100%;
  margin: 0;
  color: #4d3b33;
  font: 500 0.95rem/1.3 var(--police);
  text-align: center;
}

.titre-scene .titre-prenom input {
  width: 100%;
  min-height: 44px;
  padding: 6px 12px;
  border: 1px solid rgb(122 74 18 / 0.55);
  border-radius: 8px;
  background: #fffdf8;
  color: var(--encre);
  font: 500 1.05rem/1.2 var(--police);
  text-align: center;
}

.titre-scene .titre-credits {
  display: grid;
  gap: 2px;
  margin: 6px 0 0;
  padding-top: 10px;
  border-top: 1px solid rgb(122 74 18 / 0.35);
  color: #5a463a;
  font: 500 0.88rem/1.35 var(--police);
  text-align: center;
  text-shadow: none;
}

.titre-scene .titre-site {
  color: var(--sepia);
  text-decoration: underline;
  text-underline-offset: 3px;
  pointer-events: auto;
}

.titre-droits {
  font-size: 0.78rem;
  opacity: 0.75;
}

/* Écran large : le texte prend la place des éléments dessinés, dans l'image. */
@media (orientation: landscape) and (min-width: 900px) and (min-height: 540px) {
  #titre {
    place-items: center;
  }

  .titre-scene > .titre-texte {
    position: absolute;
    left: 67.5%;
    top: 59%;
    width: 26.5%;
    margin: 0;
    padding: 0;
    gap: clamp(6px, 1.2vh, 12px);
    font-size: clamp(0.8rem, 1.1vw, 1.1rem);
  }

  .titre-scene .titre-menu button {
    min-width: 100%;
    min-height: clamp(40px, 5.2vh, 58px);
    font-size: clamp(0.95rem, 1.25vw, 1.35rem);
  }

  .titre-scene .titre-prenom {
    font-size: clamp(0.78rem, 1vw, 0.98rem);
  }

  .titre-scene .titre-prenom input {
    min-height: clamp(34px, 4.4vh, 46px);
    font-size: clamp(0.9rem, 1.1vw, 1.1rem);
  }

  .titre-scene .titre-credits {
    font-size: clamp(0.72rem, 0.95vw, 0.95rem);
  }

  .titre-droits {
    font-size: clamp(0.64rem, 0.8vw, 0.8rem);
  }
}

/* L'image de partage (?vignette, outils/vignette.mjs) : l'illustration seule. */
[data-vignette] .titre-scene {
  width: 100vw;
}

[data-vignette] .titre-scene > .titre-texte {
  display: none;
}

/* --- Version 2.8 : le curseur du jeu et le retour des boutons. ------------ */

/* Un gantelet d'acier qui pointe (assets/ui/curseur.png, 32 px, et
   curseur-2x.png pour les écrans à haute densité, fabriqués par
   outils/curseur.mjs depuis un dessin généré puis détouré), le point chaud au
   bout de l'index. La première ligne sert aux navigateurs sans image-set(). */
:root {
  --curseur: image-set(url("assets/ui/curseur.png") 1x, url("assets/ui/curseur-2x.png") 2x) 2 1, auto;
  --curseur-actif: image-set(url("assets/ui/curseur-actif.png") 1x, url("assets/ui/curseur-actif-2x.png") 2x) 2 1, pointer;
}

@supports not (cursor: image-set(url("assets/ui/curseur.png") 1x) 1 1, auto) {
  :root {
    --curseur: url("assets/ui/curseur.png") 2 1, auto;
    --curseur-actif: url("assets/ui/curseur-actif.png") 2 1, pointer;
  }
}

html,
body,
#scene,
input {
  cursor: var(--curseur);
}

/* Sur ce qui se clique, le même gantelet avec un éclat d'or : ici, et dans
   chaque règle du fichier qui disait « pointer » (« default » reprend le
   gantelet nu). */
button,
a,
label,
[role="button"] {
  cursor: var(--curseur-actif);
}

/* Au survol d'un bouton de menu : il s'éclaire un peu, sans grandir ni
   scintiller (version 2.9 : l'étincelle et l'agrandissement de la 2.8 faisaient
   interface générique ; la sélection garde ses propres styles, plus haut). */
.dialogue-choix button,
.titre-menu button,
#boutique button,
#forge button,
#grimoire button,
#feuille button,
#carte button,
#diplome button {
  position: relative;
  transition: filter 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.dialogue-choix button:not(.ecarte):hover,
#boutique button:not(:disabled):hover,
#forge button:not(:disabled):hover,
#grimoire button:not(:disabled):hover,
#feuille button:not(:disabled):hover,
#carte button:not(:disabled):hover,
#diplome button:not(:disabled):hover {
  filter: brightness(1.12);
}

/* --- Version 2.9 : les titres et les étiquettes retrouvent la casse du livre.
   Les capitales espacées partout (titres de panneaux, petites étiquettes au-
   dessus des chiffres) faisaient tableau de bord ; seuls le bandeau de lieu,
   le « Nouvelle partie » qui clignote, les rôles du générique et la mention
   des coups critiques gardent leurs capitales. ------------------------------ */
.grimoire-titre,
.carte-titre,
.boutique-titre,
.forge-titre,
.feuille-titre {
  font-size: clamp(1.25rem, 1rem + 1.2vw, 1.6rem);
  letter-spacing: 0;
  text-transform: none;
}

.dialogue-nom,
.touches-titre,
.endroit-monde {
  letter-spacing: 0;
  text-transform: none;
}

.dialogue-nom {
  font-size: clamp(1rem, 0.65rem + 1.6vw, 1.15rem);
}

.touches-titre {
  font-size: 0.95rem;
}

.endroit-monde {
  font-size: 0.82rem;
  font-weight: 500;
  color: rgb(246 236 214 / 0.7);
}

/* Les petites étiquettes : en italique discret plutôt qu'en capitales. */
.grimoire-numero,
.feuille-exploits-titre,
.feuille-notions-titre,
.feuille-stat dt {
  font-style: italic;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

.grimoire-numero {
  font-size: 0.95rem;
}

.feuille-exploits-titre,
.feuille-notions-titre {
  font-size: 1rem;
  color: #6e5236;
}

/* Les chiffres de la fiche : une liste à points de conduite, comme un
   registre, plutôt que cinq tuiles encadrées. */
.feuille-stats {
  grid-template-columns: 1fr 1fr;
  gap: 4px 28px;
}

.feuille-stat {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 2px 0;
  border: 0;
  border-radius: 0;
  background: none;
  text-align: left;
}

.feuille-stat dt {
  display: flex;
  flex: 1;
  align-items: baseline;
  font-size: 0.95rem;
  color: #6e5236;
}

.feuille-stat dt::after {
  content: "";
  flex: 1;
  margin: 0 2px 0.3em 8px;
  border-bottom: 1px dotted rgb(110 82 54 / 0.55);
}

.feuille-stat dd {
  color: var(--encre);
  font-size: 1rem;
}

/* Les exploits : un petit sceau de cire sans lettre, le nom, la condition à la
   suite, sur deux colonnes. */
.feuille-exploits {
  grid-template-columns: 1fr 1fr;
  gap: 4px 20px;
}

.feuille-exploits li {
  display: block;
  padding-left: 22px;
  text-indent: -22px;
  font-size: 0.92rem;
  line-height: 1.3;
}

.feuille-sceau {
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-right: 6px;
  vertical-align: -1px;
  text-indent: 0;
  border-width: 1px;
  background: radial-gradient(circle at 35% 30%, #d9544a, #8a1f1a 65%, #5a1210);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4), inset 0 0 0 2px rgb(255 200 180 / 0.25);
  font-size: 0;
}

.feuille-exploit-condition::before {
  content: ", ";
}

.feuille-exploit-condition {
  font-size: 0.92rem;
}

.feuille-exploits li[data-obtenu="non"] .feuille-sceau {
  border-color: rgb(120 110 100 / 0.5);
  background: radial-gradient(circle at 35% 30%, #8a8378, #55504a 65%, #35312c);
}

@media (max-width: 640px) {
  .feuille-stats,
  .feuille-exploits {
    grid-template-columns: 1fr;
  }

  .feuille-exploits li {
    grid-template-columns: 14px 1fr;
    font-size: 0.85rem;
  }
}

/* Les boutons du grimoire : les mots seuls, sans chevrons. */
.grimoire-precedente::before,
.grimoire-suivante::after {
  content: none;
}

/* --- Version 2.9 : l'iris des portes. ---------------------------------------- */

/* Le noir se referme en cercle sur le héros qui passe la porte, puis se
   rouvre de la même façon de l'autre côté, comme dans les vieux jeux de rôle. */
#fondu {
  opacity: 1;
  clip-path: circle(0 at var(--iris-x, 50%) var(--iris-y, 50%));
  transition: clip-path 0.24s ease-in;
}

#fondu.fondu-noir {
  clip-path: circle(160% at var(--iris-x, 50%) var(--iris-y, 50%));
  transition-timing-function: ease-out;
}

@media (prefers-reduced-motion: reduce) {
  #fondu {
    opacity: 0;
    clip-path: none;
    transition: opacity 0.24s ease;
  }

  #fondu.fondu-noir {
    opacity: 1;
    clip-path: none;
  }
}
