/* RunRunFar — site web. Palette reprise de RunRunFar/DesignSystem/Theme.swift */
:root {
  --rust: #E0301E;
  --rust-dark: #8E1B10;
  --rust-light: #F4573F;
  --parchment: #E9D5B9;
  --parchment-deep: #D8C09A;
  --wood: #C89B5E;
  --wood-dark: #8C6334;
  --ink: #1C1712;
  --ink-soft: #584A3A;
  --defend: #2E6E4F;
  --explore: #2A5F8F;
  --zombie: #6C8F3A;
  --night: #14202B;
  --night-2: #1B2B38;
  --cream: #F6EBDA;

  --display: "Bangers", "Impact", "Arial Black", sans-serif;
  --condensed: "Barlow Condensed", "Arial Narrow", sans-serif;
  --body: "Barlow", system-ui, -apple-system, "Segoe UI", sans-serif;

  --radius: 12px;
  --border: 3px solid var(--ink);
  --shadow: 0 5px 0 var(--ink);
  --wrap: 1120px;
  --gutter: 16px;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 84px; }
body {
  margin: 0;
  font-family: var(--body);
  font-weight: 500;
  font-size: 17px;
  line-height: 1.55;
  color: var(--cream);
  background: var(--night);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
button { font: inherit; }
/* Tous les boutons du site sont dessines : aucun n'a besoin du rendu natif.
   Sans ca la WebView Android pose son propre fond et son propre relief, et
   fait clignoter un gris au toucher — c'est ce qui donnait au jeu l'air d'un
   formulaire web plutot que d'une interface de jeu. */
button, .btn {
  appearance: none; -webkit-appearance: none;
  -webkit-tap-highlight-color: transparent;
}
h1, h2, h3 { margin: 0; line-height: 1.05; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.muted { color: #9AA7B2; }
.on-dark { color: var(--cream); }
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }
[hidden] { display: none !important; }

/* ---------- Boutons ---------- */
.btn {
  --bg: var(--rust);
  display: inline-flex; align-items: center; justify-content: center; gap: .55em;
  padding: .55em 1.1em;
  border: var(--border); border-radius: 10px;
  background: var(--bg); color: #fff;
  font-family: var(--display); font-size: 1.15rem; letter-spacing: .04em;
  text-decoration: none; text-transform: uppercase;
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: transform .08s ease, box-shadow .08s ease, filter .15s;
  text-shadow: 0 2px 0 rgba(0,0,0,.35);
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--ink); }
.btn:focus-visible { outline: 3px solid #FFD27A; outline-offset: 3px; }
.btn-rust { background: linear-gradient(180deg, var(--rust-light), var(--rust) 55%, #C4261A); }
.btn-wood { background: linear-gradient(180deg, #D9AE72, var(--wood) 55%, var(--wood-dark)); color: var(--ink); text-shadow: 0 1px 0 rgba(255,255,255,.35); }
.btn-lg { font-size: 1.6rem; padding: .45em 1.2em; transform: skew(-4deg); }
.btn-lg:active { transform: skew(-4deg) translateY(4px); }
.btn-sm { font-size: 1.05rem; padding: .35em .9em; box-shadow: 0 3px 0 var(--ink); }
.btn-block { width: 100%; }
.btn-ghost { background: transparent; border-color: transparent; box-shadow: none; font-family: var(--body); font-weight: 700; text-transform: none; letter-spacing: 0; font-size: 1rem; text-shadow: none; padding: .45em .7em; color: var(--cream); }
.btn-ghost:hover { background: rgba(255,255,255,.08); }
.btn-ghost:active { transform: none; box-shadow: none; }
.btn-ghost-dark { background: transparent; color: var(--ink); box-shadow: none; border-color: var(--ink-soft); font-family: var(--body); font-weight: 700; text-transform: none; letter-spacing: 0; font-size: 1rem; text-shadow: none; }
.link { background: none; border: 0; padding: 0; color: var(--rust); font-weight: 700; text-decoration: underline; cursor: pointer; }

/* Petit coureur blanc, comme sur les boutons de l'app */
.runner {
  width: 1.05em; height: 1.05em; flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M13.5 5.5a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM9.8 8.9 7 23h2.1l1.8-8 2.1 2v6h2v-7.5l-2.1-2 .6-3A7.3 7.3 0 0 0 19 13v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1L6 8.3V13h2V9.6l1.8-.7'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M13.5 5.5a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM9.8 8.9 7 23h2.1l1.8-8 2.1 2v6h2v-7.5l-2.1-2 .6-3A7.3 7.3 0 0 0 19 13v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1L6 8.3V13h2V9.6l1.8-.7'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ---------- Barre du haut ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 12px;
  padding: 8px var(--gutter);
  background: rgba(20, 32, 43, .92);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-bottom: 3px solid var(--ink);
}
.topbar-logo img { height: 44px; width: auto; }
.topbar-nav { display: flex; gap: 4px; margin-left: auto; }
.topbar-nav a { text-decoration: none; font-weight: 700; padding: .4em .7em; border-radius: 8px; }
.topbar-nav a:hover { background: rgba(255,255,255,.08); }
.topbar-auth { display: flex; align-items: center; gap: 6px; }
.avatar { font-size: 1.1em; }
@media (max-width: 720px) {
  .topbar-nav { display: none; }
  .topbar-auth { margin-left: auto; }
  .topbar-logo img { height: 36px; }
  .topbar-auth .btn-ghost { padding: .45em .5em; }
}

/* ---------- Hero ---------- */
.hero { position: relative; min-height: min(88vh, 820px); display: grid; place-items: center; overflow: hidden; border-bottom: 3px solid var(--ink); }
.hero-bg {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(20,32,43,.15) 0%, rgba(20,32,43,.05) 40%, rgba(20,32,43,.85) 100%),
    url("/assets/img/fond.jpg") center 30% / cover no-repeat;
  background:
    linear-gradient(180deg, rgba(20,32,43,.15) 0%, rgba(20,32,43,.05) 40%, rgba(20,32,43,.85) 100%),
    image-set(url("/assets/img/fond.webp") type("image/webp"), url("/assets/img/fond.jpg") type("image/jpeg")) center 30% / cover no-repeat;
}
.hero-bg-fixed { position: fixed; z-index: -1; filter: saturate(.8) brightness(.45); }
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 55% 45% at 50% 52%, rgba(10,16,22,.62), transparent 75%);
}
.hero-inner { z-index: 1; position: relative; text-align: center; padding: 64px var(--gutter) 80px; max-width: 900px; }
.hero-logo { width: min(760px, 100%); margin: 0 auto; filter: drop-shadow(0 8px 12px rgba(0,0,0,.55)); }
.hero-tagline {
  margin: 12px 0 28px;
  font-family: var(--display); font-size: clamp(1.8rem, 4.8vw, 3rem); letter-spacing: .03em;
  color: #fff;
  -webkit-text-stroke: 1px var(--ink);
  text-shadow: 0 3px 0 var(--ink), 0 0 20px rgba(0,0,0,.85);
  transform: skew(-4deg);
}
.hero-tagline span { color: #FF5A40; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 16px; justify-content: center; }

/* ---------- Panneaux parchemin + pancarte bois ---------- */
.panel { border: var(--border); border-radius: var(--radius); box-shadow: 0 6px 0 var(--ink); }
/* Le parchemin du JEU, partout sur le site (même recette que
   `.jeu-app .panneau` dans jeu.css) : cadre aux bords déchirés en neuf
   tranches, texture répétée sur un ::before rentré de 4 px sous la
   déchirure, ombre en `drop-shadow` pour qu'elle suive la déchirure.
   Deux règles, payées dans le jeu :
   - JAMAIS d'`overflow` sur un parchemin déchiré : la texture vit sous la
     bordure, hors de la boîte de remplissage, et `overflow` la rogne ;
   - le ::before est pris : un dessin dans un parchemin passe par ::after.
   Ce qui défile (fenêtres, fiche de la carte) ou ce qui est petit (champs,
   tuiles posées sur un parchemin) prend `--parchemin-texture` seule, sur son
   cadre d'encre habituel : voir plus bas. */
:root { --parchemin-texture: url("/assets/img/jeu/parchemin-texture.webp") 0 0 / 190px auto repeat; }
.parchment,
.city-card,
.trouvaille {
  position: relative; z-index: 0;
  color: var(--ink);
  background: none;
  border: 21px solid transparent;
  border-image: url("/assets/img/jeu/parchemin-cadre.webp") 63 / 21px / 0 stretch;
  border-radius: 0; box-shadow: none;
  filter: drop-shadow(0 6px 9px rgba(0,0,0,.45));
}
.parchment::before,
.city-card::before,
.trouvaille::before {
  content: ""; position: absolute; inset: -17px; z-index: -1; border-radius: 10px;
  background: var(--parchemin-texture);
}
/* Ce qui défile garde son cadre d'encre et prend la texture seule. */
.modal-card,
.modal-card.parchment,
.map-panel.parchment {
  background: var(--parchemin-texture);
  border: 4px solid var(--ink); border-radius: 16px;
  box-shadow: 0 8px 0 var(--ink); filter: none;
}
.map-panel.parchment { border-width: 3px; border-radius: var(--radius); box-shadow: 0 5px 0 var(--ink); }
.modal-card.parchment::before,
.map-panel.parchment::before { content: none; }
.sign {
  display: flex; justify-content: center; margin: 0 auto 32px;
  font-family: var(--display); font-weight: 400; letter-spacing: .04em;
  font-size: clamp(1.9rem, 5vw, 2.8rem); color: var(--ink);
}
.sign span {
  position: relative; display: inline-block;
  padding: .18em 1.1em .1em;
  background:
    repeating-linear-gradient(0deg, transparent 0 9px, rgba(90,55,20,.18) 9px 11px),
    linear-gradient(180deg, #DDB177, var(--wood) 50%, #A87A42);
  border: var(--border); border-radius: 8px;
  box-shadow: 0 5px 0 var(--ink), inset 0 2px 0 rgba(255,255,255,.35);
  transform: rotate(-1.2deg);
  text-align: center;
}
.sign span::before, .sign span::after {
  content: ""; position: absolute; top: 50%; width: 9px; height: 9px; margin-top: -4px;
  border-radius: 50%; background: #3C3F44; box-shadow: inset 0 -2px 0 #000, 0 0 0 2px var(--ink);
}
.sign span::before { left: 10px; } .sign span::after { right: 10px; }

/* ---------- Histoire : sept panneaux illustrés ----------
   Chaque <p> de `.pitch-cartes` est un panneau. On ne peut PAS en faire une
   grille ni une boîte flex : le texte y est en ligne (<b>, <img>, <span> au
   milieu des mots) et chaque morceau deviendrait une cellule. Le panneau
   reste donc un bloc ; le dessin est un pseudo-élément posé en absolu dans la
   marge que le texte lui laisse, et le titre est le premier <b>, mis en bloc.
   Les dessins ont leurs bords fondus dans l'image même : le fond des panneaux
   reprend la couleur sur laquelle ils ont été peints, sinon le fondu se voit. */
.pitch { padding: 64px 0 76px; background: linear-gradient(180deg, var(--night), var(--night-2)); }
.pitch .sign { margin-bottom: 30px; }
/* Deux colonnes : les panneaux à gauche, l'illustration de la ville à droite,
   qui reste en vue pendant qu'on lit (sticky, sous la barre du haut). Le bloc
   est plus large que les autres sections pour que les panneaux gardent leur
   dessin à côté du texte. Le crayon de l'admin est en `absolute` : il ne
   prend pas de case dans la grille. */
.pitch > .wrap {
  max-width: 1280px;
  display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: 20px 36px; align-items: start;
}
.pitch > .wrap > .sign { grid-column: 1 / -1; }
.pitch-cartes { display: grid; gap: 20px; min-width: 0; }
.pitch-art { margin: 0; position: sticky; top: 92px; }
.pitch-art img {
  display: block; width: 100%; height: auto;
  border: var(--border); border-radius: var(--radius);
  box-shadow: 0 6px 0 var(--ink), 0 18px 36px rgba(0,0,0,.4);
  transform: rotate(1.5deg);
}
.pitch-cartes > p {
  --art: none;
  position: relative;
  margin: 0; min-height: 200px;
  padding: 8px 14px 8px 37%;
  color: var(--ink); font-size: 1.08rem; line-height: 1.55;
}
.pitch-cartes > p.pitch-carte::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: calc(37% - 20px);
  background: var(--art) center / contain no-repeat;
}
.pitch-cartes > p > b:first-child {
  display: block; margin-bottom: .4em;
  font-family: var(--display); font-weight: 400; letter-spacing: .035em;
  font-size: clamp(1.5rem, 2.7vw, 1.95rem); line-height: 1.04;
  color: #B21F17; text-shadow: 0 2px 0 rgba(255,255,255,.45);
}
.pitch-cartes > p:nth-child(1) { --art: url(/assets/img/accueil/coureur.webp?v=5047bb57); padding: 14px 47% 14px 14px; }
.pitch-cartes > p:nth-child(1)::after { left: auto; right: 0; width: 46%; background-size: cover; background-position: left center; }
.pitch-cartes > p:nth-child(1) > b:first-child { font-size: clamp(1.7rem, 3.1vw, 2.2rem); }
.pitch-cartes > p:nth-child(2) { --art: url(/assets/img/accueil/commune.webp?v=7771cfd1); }
/* Deux dessins : le panneau du dimanche à gauche, la horde à droite. Le
   ::before est pris par la texture du parchemin, les deux tiennent donc sur
   le même ::after, étalé sur tout le panneau. */
.pitch-cartes > p:nth-child(3) { padding-right: 25%; }
.pitch-cartes > p:nth-child(3)::after {
  width: auto; right: 0;
  background:
    url(/assets/img/accueil/dimanche.webp?v=9f49cb71) left center / calc(37% - 20px) auto no-repeat,
    url(/assets/img/accueil/horde.webp?v=df71c28e) right center / 23% 100% no-repeat;
}
.pitch-cartes > p:nth-child(4) { --art: url(/assets/img/accueil/tresor.webp?v=fb4fb9f4); }
.pitch-cartes > p:nth-child(5) { --art: url(/assets/img/accueil/deux-sens.webp?v=3353e273); padding-left: 46%; }
.pitch-cartes > p:nth-child(5)::after { width: calc(46% - 20px); }
.pitch-cartes > p:nth-child(6) { --art: url(/assets/img/accueil/fleau.webp?v=0b329cdc); }
.pitch-cartes .vo2 { color: var(--defend); }
.horde { color: var(--rust-dark); }

/* Le bandeau de la mission. Le ruban est dessiné sur ::before (découpé en
   queue d'aronde par clip-path) et non sur le <p> lui-même : un clip-path
   sur le <p> rognerait le billet épinglé, qui déborde du ruban. */
.pitch-cartes > p.pitch-mission {
  position: relative; isolation: isolate;
  min-height: 0; margin: 14px 0 6px;
  padding: 26px 214px 26px 118px;
  text-align: center; color: #FCEBC0; font-size: 1rem;
}
.pitch-cartes > p.pitch-mission::before {
  content: ""; position: absolute; left: -8px; right: -8px; top: 0; bottom: 0; z-index: -1;
  background:
    repeating-linear-gradient(100deg, transparent 0 22px, rgba(0,0,0,.05) 22px 26px),
    linear-gradient(180deg, #D7362A, #B5221A 55%, #8E160F);
  clip-path: polygon(0 0, 100% 0, calc(100% - 28px) 50%, 100% 100%, 0 100%, 28px 50%);
  box-shadow: inset 0 3px 0 rgba(255,255,255,.18), inset 0 -6px 0 rgba(0,0,0,.25);
}
.pitch-cartes > p.pitch-mission::after {
  content: ""; position: absolute; left: 26px; top: 50%; width: 86px; height: 64px; margin-top: -32px;
  background: url(/assets/img/accueil/basket.webp?v=be7e5bc8) center / contain no-repeat;
  transform: rotate(-8deg);
}
.pitch-cartes > p.pitch-mission > b:first-child {
  margin: 0; color: #FCE6A0;
  font-size: clamp(1.6rem, 2.6vw, 2.15rem); line-height: 1.08;
  text-shadow: 0 3px 0 rgba(60,8,4,.85), 0 0 1px #3C0804;
}
.pitch-mission > span {
  position: absolute; right: 4px; top: 50%; width: 180px;
  padding: 16px 18px 14px;
  transform: translateY(-50%) rotate(-4deg);
  font-family: "Caveat", "Segoe Print", "Bradley Hand", cursive; font-weight: 700;
  font-size: 1.45rem; line-height: 1.1; color: var(--ink); text-align: center;
  background: url("/assets/img/jeu/parchemin-texture.webp") 0 0 / 190px auto repeat;
  border: 2px solid #6B4A25; border-radius: 4px 10px 6px 12px;
  box-shadow: 0 5px 0 rgba(0,0,0,.45), 0 10px 18px rgba(0,0,0,.35);
}
.pitch-mission > span::before {
  content: ""; position: absolute; left: 50%; top: 7px; width: 10px; height: 10px; margin-left: -5px;
  border-radius: 50%; background: #3C3F44; box-shadow: inset 0 -2px 0 #000, 0 0 0 2px var(--ink);
}

/* Sous 1080 px, deux colonnes rendraient les panneaux trop étroits : une
   seule, et l'illustration après la mission. */
@media (max-width: 1080px) {
  .pitch > .wrap { grid-template-columns: minmax(0, 1fr); }
  .pitch-cartes { max-width: 1000px; width: 100%; margin: 0 auto; }
  .pitch-art { position: static; max-width: 460px; width: 100%; margin: 24px auto 0; }
}
@media (max-width: 760px) {
  .pitch { padding: 48px 0 56px; }
  .pitch-cartes { gap: 18px; }
  .pitch-cartes > p.pitch-carte,
  .pitch-cartes > p.pitch-carte:nth-child(n) {
    min-height: 0; padding: 180px 4px 4px; font-size: 1.02rem;
  }
  .pitch-cartes > p.pitch-carte::after,
  .pitch-cartes > p.pitch-carte:nth-child(n)::after {
    left: 0; right: 0; top: 0; bottom: auto; width: auto; height: 170px;
    background: var(--art) center / contain no-repeat;
  }
  .pitch-cartes > p.pitch-carte:nth-child(1)::after { background-size: cover; }
  /* Sur un téléphone, le dimanche n'a que son panneau : pas la place de la horde. */
  .pitch-cartes > p.pitch-carte:nth-child(3) { --art: url(/assets/img/accueil/dimanche.webp?v=9f49cb71); }
  /* Le dessin des deux coureurs est trois fois plus large que haut. */
  .pitch-cartes > p.pitch-carte:nth-child(5) { padding-top: 122px; }
  .pitch-cartes > p.pitch-carte:nth-child(5)::after { height: 112px; }
  .pitch-cartes > p.pitch-mission { padding: 26px 30px 24px 30px; margin-top: 8px; }
  .pitch-cartes > p.pitch-mission::before { left: -6px; right: -6px; }
  .pitch-cartes > p.pitch-mission::after { display: none; }
  .pitch-mission > span {
    position: relative; display: block; right: auto; top: auto;
    width: auto; max-width: 240px; margin: 18px auto -46px;
    transform: rotate(-3deg);
  }
  .pitch-cartes > p.pitch-mission { margin-bottom: 52px; }
}

/* ---------- Le parchemin du jeu, sur les zones claires de l'accueil ----------
   La même recette que `.jeu-app .panneau` (jeu.css) : cadre aux bords
   déchirés en neuf tranches, texture répétée sur un ::before rentré de 4 px
   sous la déchirure. Deux règles payées dans le jeu, et qui valent ici :
   - JAMAIS d'`overflow` sur un parchemin : la texture vit sous la bordure,
     hors de la boîte de remplissage, et `overflow` la rogne (liseré sombre) ;
   - le ::before est pris : un dessin dans un parchemin passe par ::after.
   L'ombre est un `filter: drop-shadow` : une `box-shadow` suivrait le
   rectangle, pas la déchirure. */
.pitch-cartes > p.pitch-carte,
.rules .rule,
.verite .verite-texte,
.verite .med-chiffre {
  position: relative; z-index: 0;
  background: none;
  border: 21px solid transparent;
  border-image: url("/assets/img/jeu/parchemin-cadre.webp") 63 / 21px / 0 stretch;
  border-radius: 0; box-shadow: none;
  filter: drop-shadow(0 6px 9px rgba(0,0,0,.45));
}
.pitch-cartes > p.pitch-carte::before,
.rules .rule::before,
.verite .verite-texte::before,
.verite .med-chiffre::before {
  content: ""; position: absolute; inset: -17px; z-index: -1; border-radius: 10px;
  background: url("/assets/img/jeu/parchemin-texture.webp") 0 0 / 190px auto repeat;
}

/* ---------- Règles ---------- */
.rules { padding: 72px 0; background: var(--night-2); }
.rules-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 18px; counter-reset: r; }
/* Six règles : deux rangées de trois plutôt qu'une carte orpheline. */
@media (min-width: 760px) { .rules-list { grid-template-columns: repeat(3, 1fr); } }
.rule {
  counter-increment: r;
  position: relative;
  padding: 26px 20px 22px;
  border: var(--border); border-radius: var(--radius); box-shadow: 0 6px 0 var(--ink);
  background: linear-gradient(180deg, var(--parchment), var(--parchment-deep));
  color: var(--ink);
}
.rule::after {
  content: counter(r); position: absolute; top: -16px; right: 14px;
  width: 36px; height: 36px; display: grid; place-items: center;
  font-family: var(--display); font-size: 1.3rem; color: #fff;
  background: var(--rust); border: var(--border); border-radius: 50%;
}
/* Dans le parchemin, la bordure déchirée fait déjà 21 px de marge. */
.rules .rule { padding: 8px 6px 6px; }
.rules .rule::after { top: -34px; right: -8px; }
/* L'embleme et le titre sont centres, le texte reste justifie en dessous :
   l'embleme seul, cale a gauche au-dessus d'un titre court, pendait dans
   le vide de la carte. */
.rule-icon { font-size: 2.3rem; line-height: 1; display: block; margin-bottom: 10px; text-align: center; }
.rule h3 { font-family: var(--display); font-weight: 400; font-size: 1.7rem; letter-spacing: .04em; text-transform: uppercase; margin-bottom: 8px; color: var(--rust-dark); text-align: center; }
/* Une regle est faite de blocs : des paragraphes et des listes a puces
   (`gabaritBlocs`). D'ou une marge entre eux — et aucune sous le dernier,
   sinon la carte prend du vide en bas. Les puces ne sont pas justifiees :
   une ligne de trois mots etiree bord a bord est illisible. */
.rule p { margin: 0 0 .7em; font-size: 1rem; }
.rule ul { margin: 0 0 .7em; padding-left: 1.15em; font-size: 1rem; }
.rule li { margin: 0 0 .3em; }
.rule p:last-child, .rule ul:last-child, .rule li:last-child { margin-bottom: 0; }

/* Le petit tableau d'un gabarit (« | 1 km | Usé »). Serre : il remplace une
   liste a puces qui mangeait un demi-ecran pour dix mots. `width: auto` et
   non 100 % — deux colonnes de trois mots etirees sur toute la carte sont
   plus difficiles a lire que collees a gauche. */
.gab-tableau { width: auto; margin: 0 0 .7em; border-collapse: collapse; font-size: .95rem; }
.gab-tableau td { padding: .12em .9em .12em 0; vertical-align: baseline; white-space: nowrap; }
.gab-tableau .gab-cle { font-weight: 800; font-variant-numeric: tabular-nums; color: var(--rust-dark); }
/* COUCHÉ : les clés en rangée du haut, les libellés en dessous. Cinq paliers
   tiennent alors sur deux lignes au lieu de cinq — et comme la grille étire
   les trois cartes à la hauteur de la plus haute, c'est tout le rang qui
   raccourcit. Les colonnes se partagent la largeur à parts égales
   (`table-layout: fixed`), et les libellés longs ont le droit de se replier :
   sans quoi « Exceptionnel » déborderait du parchemin sur un téléphone. */
.gab-tableau.est-couche { width: 100%; table-layout: fixed; font-size: .88rem; }
.gab-tableau.est-couche td { padding: .1em .5em .1em 0; white-space: normal; overflow-wrap: anywhere; hyphens: auto; }
.gab-tableau.est-couche td:last-child { padding-right: 0; }
.rule .gab-tableau:last-child { margin-bottom: 0; }

.motto { padding: 44px var(--gutter); text-align: center; background: var(--rust); border-block: 3px solid var(--ink); }
.motto p {
  margin: 0 auto; max-width: 980px;
  font-family: var(--condensed); font-style: italic; font-weight: 800;
  font-size: clamp(1.35rem, 3.2vw, 2rem); line-height: 1.25; color: #fff;
  text-shadow: 0 2px 0 var(--ink);
}
.motto span { color: var(--ink); text-shadow: none; }

/* ---------- Champs (façon maquette : bloc rouge + parchemin) ---------- */
.field {
  display: flex; align-items: stretch; min-height: 50px;
  background: var(--parchemin-texture);
  border: var(--border); border-radius: 10px; overflow: hidden;
  color: var(--ink);
}
.field:focus-within { outline: 3px solid #FFD27A; outline-offset: 1px; }
.field-icon {
  flex: none; width: 50px; display: grid; place-items: center; font-size: 1.2rem;
  background: linear-gradient(180deg, var(--rust-light), var(--rust));
  border-right: var(--border);
}
.field input, .field select {
  flex: 1; min-width: 0; border: 0; background: transparent; padding: 0 14px;
  font: 600 1rem var(--body); color: var(--ink);
}
.field input::placeholder { color: #7C6A55; }
.field input:focus, .field select:focus { outline: none; }
.field select { appearance: none; -webkit-appearance: none; cursor: pointer; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%231C1712' stroke-width='2.5'/%3E%3C/svg%3E") right 14px center no-repeat; padding-right: 38px; }
.field-eye { flex: none; border: 0; background: none; padding: 0 14px; cursor: pointer; font-size: 1.1rem; color: var(--ink-soft); }
.field-hint { margin: 4px 4px 0; font-size: .82rem; color: var(--ink-soft); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ---------- Villes ---------- */
.cities { padding: 72px 0; background: linear-gradient(180deg, var(--night-2), var(--night)); }
.cities-toolbar { display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center; margin-bottom: 22px; }
.field-search { flex: 1 1 320px; max-width: 520px; }
.field-search .field-icon { background: linear-gradient(180deg, #D9AE72, var(--wood)); }
.cities-count { margin: 0; color: #B9C4CD; font-weight: 600; }
.city-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.city-card {
  display: flex; flex-direction: column; gap: 12px;
  padding: 2px 4px; text-decoration: none;
  transition: transform .12s ease;
}
.city-card:hover { transform: translateY(-3px) rotate(-.4deg); }
.city-card:focus-visible { outline: 3px solid #FFD27A; outline-offset: 3px; }
.city-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
/* Une rangee, comme le titre d'une page de ville : en flux normal, la coupe
   est une image en ligne, et sur un telephone un nom long la repoussait
   seule sur la ligne du dessus. En rangee, c'est le nom qui se replie. */
.city-name { font-family: var(--display); font-weight: 400; font-size: 1.6rem; letter-spacing: .03em; line-height: 1;
  display: flex; align-items: center; }
/* La coupe des trois premieres. Une seule image, trois teintes : l'or est
   celui du dessin, l'argent lui retire sa couleur, le bronze la tire vers le
   cuivre et l'assombrit. */
.city-coupe {
  width: 1.2em; height: 1.2em; margin-right: 6px; flex: none;
  object-fit: contain;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.45));
}
.city-coupe.est-2 { filter: grayscale(.82) brightness(1.18) drop-shadow(0 1px 1px rgba(0,0,0,.45)); }
.city-coupe.est-3 { filter: hue-rotate(-20deg) saturate(1.25) brightness(.78) drop-shadow(0 1px 1px rgba(0,0,0,.45)); }
/* Devant le titre d'une page de ville : a la taille du titre. Le calage est
   celui de la rangee (`.city-hero h1` en flex), d'ou ni marge ni
   `vertical-align` ici — et `flex: none` pour qu'un nom tres long ne la
   comprime pas. */
.city-coupe-titre { width: .82em; height: .82em; flex: none; }

/* Le rang dans la grille de l'accueil : discret, mais il dit pourquoi la
   liste est dans cet ordre-la. NE PAS l'appeler `.city-rang` : ce nom est
   deja celui du bandeau de rang de la page d'une ville, plus bas dans cette
   feuille, et les deux regles s'appliqueraient l'une a l'autre. */
.city-rang-num {
  display: inline-block; min-width: 1.6em; margin-right: 6px; flex: none;
  font-family: var(--condensed); font-weight: 800; font-size: .82em;
  color: var(--rust-dark);
}
.city-cp { font-size: .85rem; color: var(--ink-soft); font-weight: 600; }
.city-level { flex: none; font-family: var(--display); font-size: 1.05rem; letter-spacing: .04em; color: #fff; background: var(--defend); border: 2px solid var(--ink); border-radius: 8px; padding: .1em .5em; }
.city-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0; }
.city-stats div { background: rgba(255,255,255,.35); border: 2px solid rgba(28,23,18,.2); border-radius: 8px; padding: 6px 4px; text-align: center; }
.city-stats dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); font-weight: 700; }
.city-stats dd { margin: 0; font-weight: 800; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.threat { display: grid; gap: 4px; }
.threat-label { display: flex; justify-content: space-between; font-size: .82rem; font-weight: 700; }
.threat-bar { height: 12px; border: 2px solid var(--ink); border-radius: 6px; background: rgba(28,23,18,.15); overflow: hidden; }
.threat-bar i { display: block; height: 100%; background: var(--zombie); }
.threat[data-level="mid"] .threat-bar i { background: #D68A1C; }
.threat[data-level="high"] .threat-bar i { background: var(--rust); }
.threat[data-level="high"] .threat-label b { color: var(--rust-dark); }
.city-attack { font-size: .85rem; color: var(--ink-soft); font-weight: 600; }
.cities-note { margin: 26px 0 0; color: #B9C4CD; text-align: center; }
.empty { grid-column: 1 / -1; text-align: center; padding: 30px; color: #B9C4CD; }

/* ---------- Carte ---------- */
.map { padding: 72px 0 88px; background: var(--night); }
.map-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin-bottom: 16px; }
.map-status { margin: 0; color: #B9C4CD; font-weight: 600; }
.map-status strong { color: var(--parchment); }
.map-frame {
  position: relative; overflow: hidden;
  height: min(72vh, 640px); min-height: 420px;
  border: var(--border); border-radius: var(--radius); box-shadow: 0 6px 0 var(--ink);
  background: #CBB994;
}
.map-canvas { position: absolute; inset: 0; background: #CBB994; font-family: var(--body); }
/* Tuiles teintées parchemin, pour rester dans l'univers du jeu */
.map-canvas .leaflet-tile-pane { filter: sepia(.45) saturate(.85) contrast(.95); }
.map-canvas .leaflet-control-attribution { font-size: 10px; background: rgba(233,213,185,.85); }
.map-canvas .leaflet-control-zoom a { color: var(--ink); background: var(--parchment); border-color: var(--ink); font-weight: 800; }
.map-canvas .leaflet-bar { border: 2px solid var(--ink); box-shadow: 0 3px 0 var(--ink); }

/* Repère de ville : un écusson avec son niveau */
.pin-wrap { background: none; border: 0; }
.pin {
  --c: var(--zombie);
  display: grid; place-items: center;
  width: 34px; height: 38px;
  font-family: var(--display); font-size: 17px; color: #fff; line-height: 1;
  background: var(--c);
  border: 3px solid var(--ink);
  border-radius: 8px 8px 50% 50% / 8px 8px 60% 60%;
  box-shadow: 0 3px 0 var(--ink);
  text-shadow: 0 1px 0 var(--ink);
  transition: transform .12s ease;
  cursor: pointer;
}
.pin[data-level="low"] { --c: var(--defend); }
.pin[data-level="mid"] { --c: #D68A1C; }
.pin[data-level="high"] { --c: var(--rust); }
.pin-wrap:hover .pin, .pin.is-active { transform: scale(1.18) translateY(-3px); }
.pin.is-active { outline: 3px solid #FFD27A; outline-offset: 2px; }
.pin-label {
  position: absolute; left: 50%; top: 42px; transform: translateX(-50%);
  white-space: nowrap; padding: 1px 7px; border-radius: 6px;
  font: 800 12px var(--body); color: var(--ink);
  background: rgba(233,213,185,.95); border: 2px solid var(--ink);
  pointer-events: none;
}
.me-dot { display: block; width: 18px; height: 18px; border-radius: 50%; background: #2F80ED; border: 3px solid #fff; box-shadow: 0 0 0 2px var(--ink), 0 0 0 10px rgba(47,128,237,.25); }

.map-panel {
  position: absolute; z-index: 500; top: 12px; right: 12px; bottom: 26px;
  width: min(360px, calc(100% - 24px)); overflow: auto;
  padding: 18px 18px 16px;
  border: var(--border); border-radius: var(--radius); box-shadow: 0 5px 0 var(--ink);
  color: var(--ink);
}
.map-panel h3 { font-family: var(--display); font-weight: 400; font-size: 2rem; letter-spacing: .03em; line-height: 1; padding-right: 36px; }
.map-panel .modal-close { top: 10px; right: 10px; }
.panel-meta { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; margin: 6px 0 12px; font-size: .9rem; font-weight: 700; color: var(--ink-soft); }
.panel-meta .city-level { font-size: .95rem; }
.panel-here { margin: 0 0 12px; padding: 6px 10px; border-radius: 8px; background: rgba(47,128,237,.14); border: 2px solid #2F80ED; font-weight: 700; font-size: .9rem; }
.panel-block { margin-top: 14px; }
.panel-block h4 { margin: 0 0 8px; font-family: var(--display); font-weight: 400; font-size: 1.35rem; letter-spacing: .04em; color: var(--rust-dark); display: flex; justify-content: space-between; align-items: baseline; }
.panel-block h4 small { font-family: var(--body); font-weight: 700; font-size: .8rem; color: var(--ink-soft); letter-spacing: 0; }
.bld { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.bld li { display: grid; grid-template-columns: 1.7em 1fr auto; gap: 2px 8px; align-items: center; padding: 7px 9px; border-radius: 8px; background: rgba(255,255,255,.4); border: 2px solid rgba(28,23,18,.18); }
.bld li.is-empty { background: rgba(28,23,18,.06); border-style: dashed; }
.bld li.is-empty .bld-name, .bld li.is-empty .bld-ico { opacity: .55; }
.bld-ico { grid-row: span 2; font-size: 1.25rem; text-align: center; }
.bld-name { font-weight: 800; font-size: .95rem; }
.bld-state { font-weight: 800; font-size: .8rem; padding: .1em .5em; border-radius: 6px; color: #fff; background: var(--defend); border: 2px solid var(--ink); white-space: nowrap; }
.bld li.is-empty .bld-state { background: #8A7D6C; }
.bld-state.is-max { background: #B8860B; }
.bld-bar { grid-column: 2 / 4; display: flex; align-items: center; gap: 8px; font-size: .78rem; color: var(--ink-soft); font-weight: 600; }
.bld-bar .pips { flex: none; }
.bld-bar .pips i { width: 6px; height: 10px; }
.panel-actions { margin-top: 16px; }
.panel-loading { color: var(--ink-soft); font-weight: 600; }

.map-legend { list-style: none; display: flex; flex-wrap: wrap; gap: 8px 20px; justify-content: center; margin: 16px 0 0; padding: 0; color: #B9C4CD; font-weight: 600; font-size: .92rem; }
.map-legend li { display: flex; align-items: center; gap: 8px; }
.map-legend .dot { width: 14px; height: 14px; border-radius: 4px; border: 2px solid var(--ink); background: var(--zombie); }
.map-legend .dot[data-level="low"] { background: var(--defend); }
.map-legend .dot[data-level="mid"] { background: #D68A1C; }
.map-legend .dot[data-level="high"] { background: var(--rust); }
.map-legend .ring { width: 16px; height: 16px; border-radius: 50%; border: 2px dashed var(--parchment); }

@media (max-width: 720px) {
  .map-frame { height: 78vh; min-height: 480px; }
  .map-panel { top: auto; left: 8px; right: 8px; bottom: 8px; width: auto; max-height: 62%; }
}

/* ---------- Pied ---------- */
.footer { padding: 36px 0; background: #0E171F; border-top: 3px solid var(--ink); text-align: center; }
.footer-inner img { width: 200px; margin: 0 auto 10px; }
.footer p { margin: 4px 0; }

/* ---------- Modales ---------- */
.modal { padding: 0; border: 0; background: transparent; max-width: calc(100vw - 24px); width: 460px; max-height: calc(100dvh - 24px); overflow: visible; }
.modal::backdrop { background: rgba(8, 12, 16, .72); backdrop-filter: blur(3px); }
.modal[open] { animation: pop .18s ease-out; }
@keyframes pop { from { transform: scale(.94); opacity: 0; } to { transform: none; opacity: 1; } }
.modal-card {
  position: relative; display: grid; gap: 10px;
  max-height: calc(100dvh - 24px); overflow: auto;
  padding: 28px 24px 22px;
  color: var(--ink);
}
.modal-card .sign { margin-bottom: 0; font-size: 2.2rem; }
/* ---------------------------------------------------------------------------
   Les textes de la page d'accueil, modifiables sur place
   Le crayon ne se voit que pour un administrateur : c'est le JavaScript qui
   le pose, la feuille de style ne fait que l'habiller.
   --------------------------------------------------------------------------- */
.texte-modifiable { position: relative; }
.texte-crayon {
  position: absolute; top: -10px; right: -10px; z-index: 3;
  width: 34px; height: 34px; padding: 0; line-height: 1;
  font-size: 1rem; cursor: pointer;
  border: 2px solid var(--ink); border-radius: 999px;
  background: var(--parchment, #F3E4C3);
  box-shadow: 0 2px 0 rgba(0,0,0,.35);
  opacity: .55; transition: opacity .12s ease, transform .12s ease;
}
.texte-crayon:hover, .texte-crayon:focus-visible { opacity: 1; transform: scale(1.08); }
/* Sur une pancarte `.sign`, le crayon se pose a cote du bois, pas dessus. */
.sign.texte-modifiable .texte-crayon { top: 50%; right: -42px; margin-top: -17px; }
.modal-texte .modal-card { max-width: 680px; }
.modal-texte textarea { width: 100%; font: inherit; font-size: .95rem; line-height: 1.5; resize: vertical; }
.modal-texte code { font-size: .85em; background: rgba(0,0,0,.07); padding: 0 .25em; border-radius: 4px; }
.modal-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

.modal-sub { margin: 0 0 8px; text-align: center; font-family: var(--condensed); font-style: italic; font-weight: 800; text-transform: uppercase; font-size: 1.1rem; }
.modal-close { position: absolute; top: 8px; right: 10px; width: 36px; height: 36px; border: 0; background: none; font-size: 1.2rem; cursor: pointer; color: var(--ink-soft); border-radius: 50%; }
.modal-close:hover { background: rgba(0,0,0,.08); }
.modal-card .btn-lg { margin-top: 8px; transform: none; font-size: 1.5rem; }
.modal-card .btn-lg:active { transform: translateY(4px); }
.modal-switch { margin: 6px 0 0; text-align: center; font-size: .95rem; }
.form-error { margin: 2px 0 0; padding: 8px 12px; border-radius: 8px; background: rgba(224,48,30,.14); border: 2px solid var(--rust-dark); color: var(--rust-dark); font-weight: 700; font-size: .95rem; }
.form-ok { margin: 0; padding: 8px 12px; border-radius: 8px; background: rgba(46,110,79,.15); border: 2px solid var(--defend); color: var(--defend); font-weight: 700; }
.btn[aria-busy="true"] { opacity: .7; pointer-events: none; }
@media (max-width: 420px) { .field-row { grid-template-columns: 1fr; } .modal-card { padding: 26px 16px 18px; } }

.account-actions { display: grid; gap: 10px; margin-top: 8px; }
.kv { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 0; }
.kv div { background: rgba(255,255,255,.35); border: 2px solid rgba(28,23,18,.2); border-radius: 8px; padding: 8px 10px; }
.kv dt { font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); font-weight: 700; }
.kv dd { margin: 0; font-weight: 800; font-size: 1.15rem; font-variant-numeric: tabular-nums; }

/* ---------- Page ville ---------- */
.city-page { position: relative; padding: 28px 0 72px; min-height: 70vh; }
.back { display: inline-block; margin-bottom: 18px; font-weight: 700; text-decoration: none; color: var(--parchment); }
.back:hover { text-decoration: underline; }
.city-hero { padding: 26px 28px; margin-bottom: 22px; }
.city-hero h1 { font-family: var(--display); font-weight: 400; font-size: clamp(2.4rem, 7vw, 3.8rem); letter-spacing: .03em;
  /* Une rangee, pas une ligne de texte : sans cela la coupe passait a la
     ligne AU-DESSUS du nom des que celui-ci etait long. En rangee, c'est le
     nom qui se replie — la coupe reste a sa gauche. */
  display: flex; align-items: center; gap: .14em; }
.city-hero h1 > span { min-width: 0; }
.city-hero .city-cp { font-size: 1rem; }
.city-hero-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 14px; align-items: flex-start; }
.city-sections { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 22px; }
.city-section { padding: 22px 24px; }
.city-section h2 { font-family: var(--display); font-weight: 400; font-size: 1.7rem; letter-spacing: .04em; margin-bottom: 12px; color: var(--rust-dark); }
.buildings { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.buildings li { display: grid; grid-template-columns: 1.6em 1fr auto; gap: 8px; align-items: center; font-weight: 700; }
.pips { display: flex; gap: 2px; }
.pips i { width: 7px; height: 14px; border-radius: 2px; background: rgba(28,23,18,.18); }
.pips i.on { background: var(--defend); }
.runners-list { margin: 0; padding: 0; list-style: none; counter-reset: rk; display: grid; gap: 6px; }
.runners-list li { counter-increment: rk; display: flex; justify-content: space-between; gap: 10px; padding: 6px 10px; background: rgba(255,255,255,.35); border-radius: 8px; font-weight: 700; }
.runners-list li::before { content: counter(rk) "."; color: var(--ink-soft); margin-right: 6px; }
.runners-list li span:first-child { margin-right: auto; }

/* Les bornes de la semaine en cours, au-dessus du classement. */
.wk-bornes { margin: -6px 0 10px; font-weight: 700; color: var(--ink-soft); font-size: .9rem; }

/* --- Interface d'administration --- */
.admin-body { background: #14202B; }
.admin-main { max-width: 1100px; margin: 0 auto; padding: 24px 18px 60px; }
.admin-badge {
  font-weight: 800; color: #F1E4C8; letter-spacing: .03em;
  background: rgba(255,255,255,.1); padding: 6px 12px; border-radius: 999px;
}

/* Le menu : des onglets qui restent lisibles sur fond sombre. */
.admin-menu { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.admin-onglet {
  font-family: inherit; font-size: .95rem; font-weight: 800;
  color: #C9D4DE; background: rgba(255,255,255,.07);
  border: 2px solid rgba(255,255,255,.14); border-radius: 999px;
  padding: 9px 16px; cursor: pointer;
}
.admin-onglet:hover { background: rgba(255,255,255,.14); color: #fff; }
.admin-onglet.est-actif { background: var(--rust); border-color: var(--rust-dark); color: #fff; }

.admin-entete { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.admin-entete h1 {
  font-family: var(--display); font-weight: 400; font-size: 2rem;
  letter-spacing: .04em; color: #F1E4C8; margin: 0;
}

/* L'etiquette dit franchement ou en est la page. Mieux vaut une maquette
   annoncee qu'un ecran qui a l'air fini et ne fait rien. */
.admin-etiquette {
  font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: #14202B; background: #D68A1C; padding: 3px 9px; border-radius: 999px;
  white-space: nowrap;
}
.admin-etiquette.est-prete { background: var(--defend); color: #fff; }

.admin-panneau { padding: 20px 22px; }
.admin-panneau h2 {
  font-family: var(--display); font-weight: 400; font-size: 1.5rem;
  letter-spacing: .04em; color: var(--rust-dark); margin: 0 0 12px;
}
.admin-panneau p { margin: 0 0 10px; line-height: 1.55; }
.admin-panneau code {
  background: rgba(28,23,18,.1); padding: 1px 5px; border-radius: 4px; font-size: .9em;
}
.admin-note {
  margin-top: 14px !important; padding: 10px 12px;
  background: rgba(28,23,18,.07); border-left: 4px solid var(--rust);
  border-radius: 0 6px 6px 0; font-size: .92rem;
}

.admin-cartes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px; margin-top: 18px;
}
.admin-carte {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  text-align: left; font-family: inherit; cursor: pointer;
  padding: 16px 18px; border-radius: 12px;
  background: rgba(255,255,255,.07); border: 2px solid rgba(255,255,255,.14);
}
.admin-carte:hover { background: rgba(255,255,255,.13); border-color: var(--rust); }
.admin-carte-titre { font-family: var(--display); font-size: 1.25rem; letter-spacing: .03em; color: #F1E4C8; }
.admin-carte-resume { font-size: .9rem; color: #B7C3CE; line-height: 1.45; }

@media (max-width: 560px) {
  .admin-entete h1 { font-size: 1.6rem; }
  .admin-onglet { font-size: .85rem; padding: 8px 12px; }
}

/* --- Editeur de canevas de ville --- */
.admin-aide { color: #B7C3CE; font-size: .92rem; line-height: 1.5; margin: 0 0 14px; max-width: 70ch; }

.cv-barre {
  display: flex; flex-wrap: wrap; gap: 18px; align-items: center;
  padding: 10px 0; color: #C9D4DE; font-size: .88rem; font-weight: 700;
}
.cv-groupe { display: flex; gap: 10px; align-items: center; }
.cv-groupe label { display: flex; gap: 6px; align-items: center; }
.cv-groupe select, .cv-groupe input[type=range] {
  font: inherit; padding: 4px 6px; border-radius: 6px;
  border: 2px solid rgba(255,255,255,.2); background: #1D2B38; color: #F1E4C8;
}
.cv-valeur { color: #8FA0AF; font-variant-numeric: tabular-nums; }
.cv-compte { color: var(--defend); }
.cv-compte.est-court { color: var(--rust); }
.cv-jaune { color: #F1C40F; }
.cv-bleu { color: #5DADE2; }
.cv-violet { color: #A569BD; }
.cv-vert { color: #2ECC71; }
.cv-etat { color: #8FA0AF; font-weight: 600; }

/* La scene garde le rapport du decor : 853 x 1844. Sans cette contrainte, les
   emplacements exprimes en pourcentage se decaleraient d'un ecran a l'autre. */
/* Les reglages a gauche, la ville a droite. Ils etaient au-dessus et
   au-dessous : il fallait quitter l'image des yeux pour changer un niveau,
   et la place a cote d'elle restait noire. */
.cv-atelier { display: flex; gap: 20px; align-items: flex-start; }
.cv-cote { flex: 0 0 300px; display: flex; flex-direction: column; gap: 2px; }
.cv-cote .cv-barre { flex-direction: column; align-items: stretch; gap: 12px; }
.cv-cote .cv-groupe { justify-content: space-between; flex-wrap: wrap; }
.cv-cote .cv-groupe .btn { flex: 1 1 auto; }
.cv-cote .cv-groupe select { flex: 0 0 auto; }
.cv-cote .cv-compte, .cv-cote .cv-alerte { width: 100%; }

.cv-scene {
  position: relative; width: 100%; max-width: 520px; margin: 0;
  aspect-ratio: 853 / 1844; border-radius: 10px; overflow: hidden;
  background: #0E1720; touch-action: none; user-select: none;
}
.cv-fond { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* Le plan au sol, rappele en pointilles : c'est le domaine ou un emplacement
   a un sens. En dehors, le batiment flotterait au-dessus de la muraille. */
.cv-arene {
  position: absolute; border: 2px dashed rgba(255,255,255,.45);
  border-radius: 50%; pointer-events: none;
}

.cv-point {
  position: absolute; transform: translate(-50%, -50%);
  border-radius: 50%; cursor: grab;
  display: flex; align-items: center; justify-content: center;
  font-size: .7rem; font-weight: 800; color: #14202B;
  border: 2px solid rgba(0,0,0,.55);
}
.cv-batiments { background: #F1C40F; }
.cv-decors { background: #5DADE2; }
.cv-persos { background: #A569BD; }
/* Un trajet de marcheur : A plein, B cerclé, un trait entre les deux. */
.cv-marcheurs { background: #2ECC71; z-index: 4; }
.cv-marcheurs.est-b { background: #14202B; color: #2ECC71; border-color: #2ECC71; }
.cv-trait { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.cv-trait line { stroke: #2ECC71; stroke-width: 2; stroke-dasharray: 5 4; opacity: .8; }
.cv-trait.est-actif line { stroke: #fff; opacity: 1; }
.cv-point.est-actif { outline: 3px solid #fff; z-index: 5; }
.cv-point.est-trop { background: #E8743B; box-shadow: 0 0 0 3px rgba(232,116,59,.45); }

/* La croix de suppression, accrochee a l'epaule de chaque point. Elle est
   toujours visible : chercher d'abord a selectionner un point pour le
   supprimer ensuite, personne ne le devine. */
.cv-retire {
  position: absolute; z-index: 6;
  transform: translate(6px, -22px);
  width: 18px; height: 18px; padding: 0; line-height: 16px;
  border-radius: 50%; border: 2px solid rgba(0,0,0,.55);
  background: #C0392B; color: #fff; font-size: .8rem; font-weight: 800;
  cursor: pointer;
}
.cv-retire:hover { background: #E74C3C; }
.cv-alerte { color: var(--rust); font-weight: 800; }

/* En apercu, le marqueur devient le batiment lui-meme, pose par sa base. */
.cv-sprite {
  position: absolute; transform: translate(-50%, -100%);
  background-repeat: no-repeat; cursor: grab;
}
.cv-sprite.est-actif { outline: 2px dashed #fff; z-index: 5; }

/* Les quatre onglets de muraille : chacun son jeu d'emplacements. */
.cv-onglets { flex-wrap: wrap; gap: 6px; }
.cv-onglet { display: flex; flex-direction: column; align-items: center; line-height: 1.15; }
.cv-onglet small { font-size: .72em; font-weight: 600; opacity: .7; }
.cv-onglet.est-court { border-color: var(--rust); color: var(--rust); }

/* --- L'inventaire des dessins, sous l'editeur --- */
.cv-planche { margin-top: 28px; color: #C9D4DE; }
.cv-planche h2 { margin: 0 0 6px; font-size: 1.1rem; }
.cv-planche h3 {
  margin: 22px 0 8px; font-size: .95rem; color: #F1E4C8;
  border-bottom: 1px solid rgba(255,255,255,.12); padding-bottom: 4px;
}
.cv-rangee {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,.07);
}
.cv-nom { flex: 0 0 190px; display: flex; flex-direction: column; gap: 2px; }
.cv-nom b { color: #F1E4C8; font-size: .92rem; text-transform: capitalize; }
.cv-nom code { color: #8FA0AF; font-size: .74rem; word-break: break-all; }

/* Les etats se suivent, et debordent en defilement plutot qu'en retour a la
   ligne : une evolution lue de gauche a droite se lit d'un coup d'oeil. */
.cv-suite {
  flex: 1 1 auto; display: flex; gap: 10px; align-items: flex-end;
  overflow-x: auto; padding-bottom: 4px;
}
.cv-case { margin: 0; flex: 0 0 auto; text-align: center; }
.cv-case .cv-vue {
  height: 86px; background-repeat: no-repeat; background-size: contain;
  border-radius: 4px;
}
.cv-case.est-fond .cv-vue { height: 110px; border: 1px solid rgba(255,255,255,.15); }

/* Un marcheur sur place, au rythme du jeu (DUREE_PAS et DUREE_ARRET dans
   ville-rendu.js) : la marche fait defiler les cases 1 a 8 de sa rangee,
   l'arret les cases 9 a 12. Sur 26 colonnes, la case c est a c x 4 %. */
.cv-anime-marche { animation: cv-marche 1.75s steps(8) infinite; }
.cv-anime-arret { animation: cv-souffle 2.4s steps(4) infinite; }
@keyframes cv-marche { from { background-position-x: 0%; } to { background-position-x: 32%; } }
@keyframes cv-souffle { from { background-position-x: 32%; } to { background-position-x: 48%; } }
.cv-separe { flex: 0 0 1px; align-self: stretch; background: rgba(255,255,255,.12); margin: 0 4px; }
.cv-telecharger { flex: 0 0 auto; align-self: center; }
.cv-case figcaption {
  margin-top: 4px; font-size: .68rem; color: #8FA0AF;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Sous 860 px, la colonne ne tient plus a cote de la ville : on revient a
   l'empilement, les reglages au-dessus. */
@media (max-width: 860px) {
  .cv-atelier { flex-direction: column; }
  .cv-cote { flex: none; width: 100%; }
  .cv-cote .cv-barre { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .cv-scene { margin: 0 auto; }
}

@media (max-width: 560px) {
  .cv-barre { gap: 10px; font-size: .8rem; }
  .cv-rangee { flex-direction: column; gap: 6px; }
  .cv-nom { flex: none; }
}

/* --- Version, dans le pied de page --- */
.version {
  font-variant-numeric: tabular-nums;
  opacity: .75;
  cursor: help;
}
/* Site et API déposés séparément : quand les deux ne disent pas la même chose,
   ça se voit, sinon on cherche longtemps. */
.version[data-desaccord] {
  opacity: 1;
  font-weight: 800;
  color: #D68A1C;
}

/* --- Import d'une activité depuis « Mon espace » --- */
.import-run {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 2px dashed rgba(28,23,18,.25);
}
.import-run h3 {
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.3rem;
  letter-spacing: .04em;
  color: var(--rust-dark);
  margin: 0 0 6px;
}
.import-hint { font-size: .85rem; color: var(--ink-soft); margin: 0 0 12px; line-height: 1.45; }
.import-run .kv { margin: 12px 0; }
.import-apercu .import-fichier {
  margin: 0;
  font-weight: 800;
  font-size: .85rem;
  color: var(--ink-soft);
  word-break: break-all;
}
/* La date est longue : on la laisse tenir sur deux lignes plutôt que déborder. */
.import-quand { font-size: .95rem !important; line-height: 1.3; }
.import-ok {
  margin: 12px 0 0;
  padding: 10px 12px;
  background: rgba(46,110,79,.14);
  border: 2px solid rgba(46,110,79,.4);
  border-radius: 8px;
  font-weight: 700;
}
.import-ok .vo2 { vertical-align: -2px; }
.import-detail { margin: 6px 0 0; font-size: .9rem; color: var(--ink-soft); }


/* L'historique : une ligne par semaine, la plus recente en haut. */
.week-history { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.week-history li {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  background: rgba(255,255,255,.35);
  border-radius: 8px;
  font-weight: 700;
  font-size: .92rem;
}
.week-history .wk-quand { color: var(--ink-soft); }
.week-history .wk-km,
.week-history .wk-vo2 { font-variant-numeric: tabular-nums; }
.week-history .wk-issue,
.wk-issue-ligne .wk-issue {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: .8rem;
  color: #fff;
  white-space: nowrap;
}
.week-history .wk-issue[data-level="ok"],
.wk-issue-ligne .wk-issue[data-level="ok"]   { background: #2E6E4F; }
.week-history .wk-issue[data-level="calm"],
.wk-issue-ligne .wk-issue[data-level="calm"] { background: #6C8F3A; }
.week-history .wk-issue[data-level="mid"],
.wk-issue-ligne .wk-issue[data-level="mid"]  { background: #D68A1C; }
.week-history .wk-issue[data-level="high"],
.wk-issue-ligne .wk-issue[data-level="high"] { background: #E0301E; }

@media (max-width: 480px) {
  .week-history li { grid-template-columns: 1fr auto; row-gap: 4px; }
  .week-history .wk-quand { grid-column: 1 / -1; }
}
.versus { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; text-align: center; margin-bottom: 12px; }
.versus b { display: block; font-family: var(--display); font-weight: 400; font-size: 2.2rem; letter-spacing: .03em; line-height: 1; }
.versus .def b { color: var(--defend); } .versus .hor b { color: var(--rust-dark); }
.versus small { font-weight: 700; text-transform: uppercase; font-size: .75rem; letter-spacing: .05em; color: var(--ink-soft); }
.versus .vs { font-family: var(--display); font-size: 1.5rem; }
.map-canvas.hide-labels .pin-label { display: none; }
.btn[aria-busy="true"] { cursor: progress; }
/* ---------- Le choix de la ville a l'inscription ---------- */
.city-choices { display: grid; gap: 6px; margin: -4px 0 4px; }
.city-choice {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  text-align: left; width: 100%; cursor: pointer;
  padding: 8px 12px; border-radius: 8px;
  border: 2px solid rgba(28,23,18,.18); background: rgba(255,255,255,.6);
  font: inherit; color: var(--ink);
}
.city-choice:hover, .city-choice:focus-visible {
  border-color: var(--rust); background: #fff;
}
.city-choice-nom { font-weight: 800; }
.city-choice-detail { font-size: .8rem; color: var(--ink-soft); }
.city-chosen, .city-vide { margin: 0; font-size: .9rem; color: var(--ink-soft); }
.city-chosen b { color: var(--ink); }

/* Le champ de commune et son bouton « Ma commune » sur la meme ligne. Le champ
   prend ce qui reste ; le bouton ne se laisse pas couper son texte. Sous 380 px
   ils passent l'un au-dessus de l'autre plutot que de s'ecraser. */
.field-with-action { display: flex; gap: 8px; align-items: stretch; }
.field-with-action .field { flex: 1 1 auto; min-width: 0; }
.field-with-action .btn { flex: 0 0 auto; white-space: nowrap; padding-inline: 14px; }
@media (max-width: 380px) {
  .field-with-action { flex-direction: column; }
}

/* ---------- Admin : les réglages du jeu ---------- */
/* Une ligne par réglage : le libellé et son explication à gauche, le champ à
   droite, les bornes en dessous. Sur téléphone tout passe l'un sous l'autre —
   quatre-vingt-six lignes serrées sur 375 px seraient illisibles. */
.rg-groupe { margin-bottom: 14px; }
.rg-chapeau { margin: -4px 0 12px; font-size: .9rem; color: var(--ink-soft); }

.rg-ligne {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "libelle champ" "bornes champ";
  gap: 2px 14px; align-items: start;
  padding: 9px 0; border-top: 1px solid rgba(28,23,18,.12);
}
.rg-ligne:first-of-type { border-top: 0; }
.rg-libelle { grid-area: libelle; display: grid; gap: 2px; cursor: pointer; }
.rg-nom { font-weight: 700; }
.rg-aide { font-size: .85rem; color: var(--ink-soft); line-height: 1.35; }
.rg-bornes { grid-area: bornes; font-size: .78rem; color: var(--ink-soft); }
.rg-champ { grid-area: champ; display: flex; align-items: center; gap: 6px; }
.rg-champ input {
  width: 8.5ch; padding: 5px 8px; text-align: right;
  font: 700 1rem var(--body); color: var(--ink);
  border: 2px solid rgba(28,23,18,.25); border-radius: 7px; background: rgba(255,255,255,.75);
}
.rg-champ input:focus-visible { border-color: var(--rust); outline: none; background: #fff; }
.rg-unite { font-size: .82rem; color: var(--ink-soft); min-width: 5.5ch; }

/* Une ligne qui s'écarte de l'origine se signale, et propose d'y revenir. */
.rg-ligne.est-change .rg-nom::after {
  content: " ●"; color: var(--rust); font-size: .7em; vertical-align: super;
}
.rg-ligne.est-refuse { background: rgba(178,58,38,.10); border-radius: 8px; }
.rg-retour {
  font: 700 .78rem var(--body); color: var(--ink-soft); cursor: pointer;
  padding: 3px 7px; border-radius: 6px;
  border: 2px solid rgba(28,23,18,.2); background: rgba(255,255,255,.6);
}
.rg-retour:hover, .rg-retour:focus-visible { border-color: var(--rust); color: var(--ink); }

/* Ce qui découle des réglages : jamais saisi, toujours visible. */
.rg-deduits-liste {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px; margin: 0;
}
.rg-deduit { margin: 0; }
.rg-deduit dt { font-size: .82rem; color: var(--ink-soft); }
.rg-deduit dd { margin: 0; font: 800 1.5rem var(--titre, inherit); color: var(--ink); }
.rg-deduit p { margin: 2px 0 0; font-size: .78rem; color: var(--ink-soft); line-height: 1.3; }

/* La barre d'enregistrement suit le bas de l'écran : à quatre-vingt-six
   réglages, un bouton en pied de page se perd. */
.rg-barre {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding: 10px 14px; border-radius: 12px;
  background: rgba(20,32,43,.94); border: 2px solid rgba(255,255,255,.12);
  backdrop-filter: blur(6px);
}
.rg-compte { flex: 1 1 auto; font-weight: 700; color: #E9D5B9; }
.rg-barre.est-actif { border-color: var(--rust); }
.rg-barre:not(.est-actif) [data-rg="enregistrer"] { opacity: .5; pointer-events: none; }

@media (max-width: 560px) {
  .rg-ligne { grid-template-columns: 1fr; grid-template-areas: "libelle" "champ" "bornes"; }
  .rg-champ { justify-content: flex-start; }
}

/* ---------- Admin : les textes des règles ---------- */
/* Le gabarit au-dessus, son rendu en dessous : on écrit la phrase à trous et
   on la voit telle que le joueur la lira, à la frappe. Sans cet aperçu, un
   gabarit se relit de travers. */
.tx-bloc {
  padding: 12px 0; border-top: 1px solid rgba(28,23,18,.12);
}
.tx-bloc:first-of-type { border-top: 0; }
.tx-tete { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.tx-icone { font-size: 1.3rem; line-height: 1; }
.tx-titre, .tx-corps {
  width: 100%; padding: 6px 9px;
  font: 600 .95rem var(--body); color: var(--ink);
  border: 2px solid rgba(28,23,18,.25); border-radius: 7px; background: rgba(255,255,255,.75);
}
.tx-titre { font-weight: 800; }
.tx-corps { display: block; resize: vertical; line-height: 1.45; }
.tx-titre:focus-visible, .tx-corps:focus-visible {
  border-color: var(--rust); outline: none; background: #fff;
}
.tx-apercu {
  margin: 6px 0 0; padding: 8px 10px; border-radius: 7px;
  background: rgba(28,23,18,.06); border-left: 3px solid var(--rust);
  font-size: .9rem; line-height: 1.45; color: var(--ink);
}
.tx-bloc.est-change .tx-titre { border-color: var(--rust); }
.tx-bloc.est-refuse { background: rgba(178,58,38,.10); border-radius: 8px; }

/* La liste des trous : longue, donc repliée. On l'ouvre quand on cherche le
   nom exact d'un réglage, pas avant. */
.tx-trous { margin-top: 10px; font-size: .85rem; }
.tx-trous summary { cursor: pointer; font-weight: 700; color: var(--ink-soft); }
.tx-trous ul {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 2px 14px; margin: 8px 0 0; padding: 0; list-style: none;
  max-height: 260px; overflow-y: auto;
}
.tx-trous code { font-size: .8rem; color: var(--rust-dark, var(--rust)); }

/* ---------- Les communes infestees ---------- */
/* Dix ruines sur une planche de cinq par deux. Chaque dessin est pose au bas de
   sa case : c'est le socle qui doit tomber sur le point de la carte, pas le
   milieu de l'image. `background-position` compte en intervalles, pas en cases —
   d'ou les 25 % par colonne et les 100 % par ligne. */
.ruine {
  display: block;
  aspect-ratio: 400 / 257;
  background-image: url(/assets/img/villes-zombies.webp);
  background-size: 500% 200%;
  background-repeat: no-repeat;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .55));
}
.pin-ruine .ruine { width: 72px; }
.ruine-moyenne { width: 100%; max-width: 260px; margin: 0 auto 6px; }
.ruine-grande  { width: 100%; }

/* Le marqueur de carte : la ruine remplace l'ecusson de niveau. Le nom se pose
   sous elle, comme pour les autres villes. */
.pin-ruine { width: 72px; }
.pin-ruine .pin-label { top: 46px; }
.pin-ruine .ruine.is-active { filter: drop-shadow(0 0 6px var(--rust)) drop-shadow(0 2px 3px rgba(0, 0, 0, .6)); }

/* La page d'une commune infestee : la ruine a la place du dessin de ville. */
.ville-ruine { display: grid; justify-items: center; gap: 10px; }
.ruine-mot {
  margin: 0; text-align: center;
  font-family: var(--titre, inherit); font-size: 1.05rem; color: var(--ink-soft);
}
.panel-ruine { margin: -4px 0 2px; }
.city-infested {
  font-weight: 800; color: #fff;
  background: var(--rust); border-radius: 999px; padding: 2px 10px;
}
.panel-infested { color: var(--ink-soft); }

/* ---------- Le numero de version ---------- */
/* En haut a gauche, au-dessus de tout, sur chaque page. Discret au repos,
   lisible quand on le cherche : c'est la premiere chose qu'on demande quand
   quelque chose ne va pas. Il ne prend pas de place dans le flux, donc il ne
   deplace rien nulle part. */
.rrf-build {
  order: -1;                      /* tout a gauche, avant le logo */
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11px; font-weight: 700; letter-spacing: .02em; line-height: 1;
  color: rgba(255,255,255,.55);
  background: rgba(255,255,255,.07);
  padding: 4px 8px; border-radius: 999px;
  white-space: nowrap; user-select: none;
}
@media (max-width: 560px) { .rrf-build { font-size: 10px; padding: 3px 6px; } }

/* ---------- La ville dessinee ---------- */
/* Le decor fait 853 x 1844 : trois fois plus haut que large. Tel quel, il
   ferait un panneau interminable. On le montre donc par une fenetre plus
   calme, recentree sur l'enceinte — le sol est a 44,6 % de la hauteur de
   l'image, et c'est lui qu'on veut au milieu. */
.ville-vue {
  position: relative; width: 100%; aspect-ratio: 5 / 4;
  overflow: hidden; border-radius: 10px; border: var(--border);
  background: #0E1720;
}
.ville-cadre {
  position: absolute; top: 0; left: 0; width: 100%;
  aspect-ratio: 853 / 1844;
  transform: translateY(-26.1%);
}
.ville-cadre .rv-fond { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* Le rempart decoupe du fond, repose par-dessus les batiments du fond : il a
   exactement le cadre du fond, donc rien a calculer. Il ne prend aucun
   toucher, sinon il volerait les clics des batiments qu'il recouvre a moitie. */
.ville-cadre .rv-mur {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  pointer-events: none;
}
.ville-cadre .rv-piece {
  position: absolute; transform: translate(-50%, -100%);
  background-repeat: no-repeat;
}
.ville-note { margin: 10px 0 0; font-size: .95rem; color: var(--ink-soft); }

.city-territory { margin-top: 22px; }
.city-territory p { margin: 0 0 12px; }
.territory-map { height: 380px; border: var(--border); border-radius: 10px; overflow: hidden; }
.territory-map .leaflet-tile-pane { filter: sepia(.45) saturate(.85) contrast(.95); }
.territory-map .leaflet-control-attribution { font-size: 10px; }

/* ---------- Icônes maison ---------- */
/* La goutte de VO₂ remplace le mot dans le texte : elle porte déjà les lettres. */
img.vo2 {
  display: inline-block; width: auto; height: 2em;
  vertical-align: -0.62em; margin: -0.2em .05em;
  filter: drop-shadow(0 1px 0 rgba(28,23,18,.35));
}
dt img.vo2 { height: 1.7em; vertical-align: -0.6em; }
.bld-bar img.vo2 { height: 1.6em; vertical-align: -0.55em; }
img.runner-ico { display: inline-block; width: auto; height: 1.3em; vertical-align: -0.3em; }
.rule-icon img.runner-lg { height: 3rem; margin: -.2rem 0; }
.avatar img.runner-ico { height: 1.5em; vertical-align: -0.4em; }
.bld-ico img.runner-ico { height: 1.4rem; }
.bld-next { white-space: nowrap; }
.bld-bar { flex-wrap: wrap; }
.bld-stock { flex-basis: 100%; font-size: .85rem; font-weight: 700; color: var(--ink-soft); }
.bld-stock.is-plein { color: #8E1B10; }

/* ---------------------------------------------------------------------------
   Les villes sur la carte
   Même grammaire que l'onglet Carte de l'application : un halo de la couleur
   de la menace porte l'information avant le texte, la vignette se pose au sol,
   le nom et le pourcentage n'apparaissent qu'une fois assez zoomé.
   --------------------------------------------------------------------------- */
/* La taille suit le zoom. `--pin` est posé sur la carte par site.js (un demi
   au zoom 7, un à partir du 11) et tout en hérite : une seule variable, et pas
   une ligne de JavaScript qui touche à une vignette. L'origine est le point
   d'ancrage du marqueur (55, 62 dans la boîte de 110 × 92) : la vignette
   rapetisse donc sans quitter sa ville. */
.cpin {
  position: relative; display: block; width: 110px; height: 66px;
  cursor: pointer; transition: transform .18s ease;
  transform: scale(var(--pin, 1)); transform-origin: 50% 62px;
}
.cpin-halo {
  position: absolute; left: 50%; top: 52%; transform: translate(-50%, -50%);
  width: 92px; height: 56px; border-radius: 50%;
  background: radial-gradient(closest-side, var(--halo) 0%, color-mix(in srgb, var(--halo) 45%, transparent) 55%, transparent 100%);
  filter: blur(2px);
}
.cpin::after { /* l'ombre au sol : sans elle la vignette flotte */
  content: ""; position: absolute; left: 50%; bottom: -2px; transform: translateX(-50%);
  width: 50px; height: 14px; border-radius: 50%;
  background: rgba(0, 0, 0, .3); filter: blur(3px);
}
.crest {
  position: relative; display: block; width: 86px; height: 66px; margin: 0 auto;
  background-image: url(/assets/img/crests.webp);
  background-size: 500% 300%; background-repeat: no-repeat;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .45));
}
.cpin .ruine { position: relative; margin: 0 auto; width: 84px; }
.cpin.is-active { transform: scale(calc(var(--pin, 1) * 1.12)) translateY(-3px); z-index: 3; }
/* Une ruine ne doit pas voler la vedette a une ville qui tient : 55 %, comme
   dans l'application. Deux exceptions, les memes qu'elle : la ruine touchee,
   et la ville du joueur meme infestee — on ne rapetisse pas chez soi. */
.cpin.est-infestee:not(.is-active):not(.is-mine) { transform: scale(calc(var(--pin, 1) * .55)); }
.cpin.is-active .crest, .cpin.is-active .ruine { filter: drop-shadow(0 0 6px var(--halo)) drop-shadow(0 2px 3px rgba(0, 0, 0, .6)); }
.cpin-mine {
  position: absolute; left: 6px; bottom: 6px;
  width: 24px; height: 24px; display: grid; place-items: center;
  font-size: 12px; line-height: 1;
  background: #1878C4; border: 2px solid #fff; border-radius: 50%;
  box-shadow: 0 2px 3px rgba(0, 0, 0, .45);
}
.cpin-mine img.runner-ico { height: 13px; vertical-align: 0; }
.pin-wrap .pin-label {
  position: static; display: block; transform: none; margin: 2px auto 0;
  width: max-content; max-width: 120px; overflow: hidden; text-overflow: ellipsis;
  padding: 2px 8px; border-radius: 999px;
  font: 800 12px var(--body); color: #fff;
  background: rgba(28, 23, 18, .88); border: 1px solid rgba(255, 255, 255, .28);
}
.pin-badge {
  display: block; width: max-content; margin: 3px auto 0;
  padding: 1px 7px; border-radius: 999px;
  font: 800 11px var(--body); color: #fff;
  background: var(--c, var(--zombie)); border: 1px solid rgba(0, 0, 0, .35);
}
.pin-badge.is-infested { background: var(--rust-dark); }
.pin-badge.is-shelter { background: #1878C4; }
.map-canvas.hide-labels .pin-badge { display: none; }
/* Le nom ne bouge pas quand la vignette rapetisse : l'echelle a pour origine
   le point d'ancrage, la vignette retrecit donc vers le haut et son pied reste
   ou il est. Une marge qui « rattrape » la difference ferait passer
   l'etiquette par-dessus le blason — essaye, c'est laid.
   Sur une ruine reduite, la pastille « Infestee » ne s'affiche pas du tout :
   en petit, une ruine se reconnait sans legende. */
.cpin.est-infestee:not(.is-active):not(.is-mine) ~ .pin-badge { display: none; }
.map-canvas.hide-ruin-labels .cpin.est-infestee:not(.is-active):not(.is-mine) ~ .pin-label { display: none; }

/* La fiche d'une ville */
.panel-head { display: flex; align-items: flex-start; gap: 12px; padding-right: 30px; }
.crest-fiche { width: 74px; height: 58px; flex: none; }
.ruine-fiche { width: 84px; flex: none; }
.tag-mine {
  padding: 1px 7px; border-radius: 999px; font-size: .72rem; font-weight: 800;
  color: #fff; background: #1878C4;
}
.menace { margin-top: 12px; display: grid; gap: 5px; }
.menace-head { display: flex; justify-content: space-between; align-items: center; font-weight: 700; font-size: .92rem; }
.menace-head b { color: #fff; background: var(--c); border: 2px solid var(--ink); border-radius: 999px; padding: 0 .6em; font-size: .82rem; }
.menace-bar { height: 13px; border: 2px solid var(--ink); border-radius: 7px; background: rgba(28, 23, 18, .15); overflow: hidden; }
.menace-bar i { display: block; height: 100%; background: var(--c); }
.menace-pct { font: 800 .95rem var(--body); font-variant-numeric: tabular-nums; }
.menace-forecast, .menace-when { margin: 0; font-size: .85rem; color: var(--ink-soft); font-weight: 600; }
/* Une voisine sur la carte du territoire : presente, mais elle ne doit pas
   voler la vedette a la commune dont on lit la page. */
.pin-voisine { opacity: .82; transform: scale(.86); transform-origin: 50% 62px; }
.pin-voisine:hover { opacity: 1; transform: scale(.96); }
/* Une commune infestee n'a pas d'assaut a annoncer : elle a des passages. */
.menace-infestee .pstats { grid-template-columns: repeat(3, 1fr); }
.pstats-passages { margin-top: 8px; }

.pstats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 12px 0 0; }
.pstats div { text-align: center; background: rgba(255, 255, 255, .35); border: 2px solid rgba(28, 23, 18, .2); border-radius: 8px; padding: 6px 2px; }
.pstats dt { font-size: .68rem; font-weight: 700; color: var(--ink-soft); white-space: nowrap; }
.pstats dt img.runner-ico { height: 1em; vertical-align: -0.15em; }
.pstats dd { margin: 0; font-family: var(--display); font-weight: 400; font-size: 1.25rem; letter-spacing: .02em; }
.panel-note { margin: 10px 0 0; font-size: .85rem; color: var(--ink-soft); font-weight: 600; }

/* La légende reprend les quatre états que le serveur qualifie. */
.map-legend .dot[data-s="calm"] { background: #3F9A63; }
.map-legend .dot[data-s="pressed"] { background: #E08A22; }
.map-legend .dot[data-s="critical"] { background: #D93B26; }
.map-legend .dot[data-s="grace"] { background: #3BA7E8; }
.map-panel .panel-head h3 { font-size: 1.6rem; line-height: 1.05; }
.pin-wrap .pin-label { max-width: 150px; }

/* Le décor semé entre les villes : il est là pour le paysage, il ne réagit
   à rien et ne doit jamais attraper un clic destiné à une ville. */
.decor-wrap { pointer-events: none; background: none; border: 0; }
.decor { display: block; width: auto; filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .35)); }

/* Les communes infestées, dans leur propre section sous les villes tenues. */
.sign-infestees { margin-top: 52px; }
.cities-intro { max-width: 640px; margin: -14px auto 22px; text-align: center; color: #B9C4CD; }
/* Une commune infestée : le même parchemin, assombri et rougi. La teinte se
   pose sur la texture (::before), jamais sur la carte : un fond sur la carte
   remplirait aussi la bordure déchirée et dessinerait un rectangle autour. */
.city-card.is-infested::before {
  background:
    linear-gradient(180deg, rgba(120, 45, 20, .10), rgba(70, 30, 10, .22)),
    var(--parchemin-texture);
}
.city-card.is-infested .city-name { color: var(--rust-dark); }
.city-infested {
  flex: none; padding: .12em .6em; border-radius: 999px;
  font-size: .78rem; font-weight: 800; color: #fff;
  background: var(--rust-dark); border: 2px solid var(--ink);
}
.ruine-carte { width: 100%; max-width: 190px; margin: 2px auto; }

/* Les communes infestées arrivent 12 par 12 : la page garde sa taille et on
   tourne les pages avec les chevrons. Le [hidden] doit passer devant le flex,
   sinon la barre reste visible quand il n'y a qu'une seule page. */
.grid-pages { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 22px 0 0; }
.grid-pages[hidden] { display: none; }
.grid-pages .btn { font-size: 1.5rem; line-height: 1; padding: .05em .55em; }
.grid-pages .btn:disabled { opacity: .4; cursor: default; filter: none; transform: none; }
.grid-pages-etat { margin: 0; color: #B9C4CD; font-weight: 600; font-variant-numeric: tabular-nums; text-align: center; }

/* ---------------------------------------------------------------------------
   La page d'une commune infestée : pas de ville à montrer, une ruine et une
   place à prendre.
   --------------------------------------------------------------------------- */
.ruine-hero {
  display: grid; grid-template-columns: minmax(200px, 340px) 1fr; gap: 24px;
  align-items: center; padding: 8px 10px; margin-bottom: 22px;
}
.ruine-hero-art { display: grid; place-items: center; }
.ruine-page { width: 100%; max-width: 340px; }
.ruine-hero-mots h1 {
  font-family: var(--display); font-weight: 400; letter-spacing: .03em;
  font-size: clamp(2.2rem, 6vw, 3.4rem); margin: 6px 0 2px;
}
.ruine-hero-mots .city-infested { display: inline-block; }
.ruine-hero-mots .ruine-mot {
  margin: 12px 0 0; font-size: 1.05rem; color: var(--ink);
  font-style: normal; text-align: left;
}
.ruine-cta {
  margin-top: 18px; padding-top: 16px;
  border-top: 2px dashed rgba(28, 23, 18, .25);
}
.ruine-cta-note { margin: 8px 0 0; font-size: .9rem; color: var(--ink-soft); font-weight: 600; }
.horde-jauge { margin-bottom: 12px; }
.horde-jauge .menace-head b { background: var(--rust-dark); }
.bld-chantiers li { grid-template-columns: 1.7em 1fr auto; }
.bld-chantiers .bld-next { font-weight: 800; color: var(--ink); font-size: .95rem; }
@media (max-width: 720px) {
  .ruine-hero { grid-template-columns: 1fr; text-align: center; padding: 20px 18px; }
  .ruine-hero-mots .ruine-mot { text-align: left; }
}

/* ---------- Pages légales (mentions, confidentialité, CGU) ---------- */
.legal { padding: 110px 0 56px; }
.legal-wrap { max-width: 780px; }
.legal-title { font-family: var(--display); font-weight: 400; letter-spacing: .03em; font-size: clamp(2rem, 6vw, 3rem); color: var(--cream); }
.legal-date { margin: 6px 0 28px; color: #9AA7B2; font-size: .9rem; }
.legal .legal-lead { padding: 16px 18px; border: var(--border); border-radius: var(--radius); background: var(--parchemin-texture); color: var(--ink); box-shadow: var(--shadow); }
.legal h2 { margin: 34px 0 10px; font-family: var(--display); font-weight: 400; letter-spacing: .03em; font-size: 1.55rem; color: var(--rust-light); }
.legal p, .legal li { color: #DCD2C4; }
.legal a { color: #FFD27A; }
.legal ul { padding-left: 1.2em; }
.legal ol { padding-left: 1.4em; }
.legal li { margin: 4px 0; }
.legal-table { overflow-x: auto; margin: 8px 0 12px; }
.legal table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: .93rem; }
.legal th, .legal td { padding: 10px 12px; border-bottom: 1px solid #2E4050; text-align: left; vertical-align: top; }
.legal th { color: var(--cream); font-weight: 800; background: var(--night-2); }
/* Sur téléphone, le tableau devient une pile de fiches : pas de défilement horizontal. */
@media (max-width: 640px) {
  .legal table { min-width: 0; }
  .legal thead { display: none; }
  .legal tr { display: block; padding: 12px 0; border-bottom: 1px solid #2E4050; }
  .legal td { display: block; padding: 3px 0; border: 0; }
  .legal td:nth-child(2)::before { content: "À quoi elles servent — "; color: #9AA7B2; }
  .legal td:nth-child(3)::before { content: "Base légale — "; color: #9AA7B2; }
}
.footer-links a { color: inherit; }
.footer-links { font-size: .92rem; }

/* Case à cocher de l'inscription (CGU, âge) */
.check { display: flex; gap: 10px; align-items: flex-start; margin: 4px 2px; color: var(--ink); font-size: .9rem; line-height: 1.4; cursor: pointer; }
.check input { flex: none; width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--rust); }
.check a { color: var(--rust-dark); font-weight: 700; }

/* ---------- Admin : utilisateurs ---------- */
.us-barre { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.us-compte { margin: 0 !important; color: var(--ink); }
.us-filtre { flex: 1 1 260px; max-width: 360px; padding: 9px 12px; border: 2px solid var(--ink-soft); border-radius: 8px; background: rgba(255,255,255,.6); font: inherit; color: var(--ink); }
.us-filtre:focus-visible { outline: none; border-color: var(--rust); background: #fff; }
.us-ok { margin: 0 0 10px !important; padding: 8px 12px; border-radius: 8px; background: rgba(46,110,79,.15); color: var(--defend); font-weight: 700; }
.us-table-cadre { overflow-x: auto; }
.us-table { width: 100%; min-width: 820px; border-collapse: collapse; font-size: .92rem; color: var(--ink); }
.us-table th { text-align: left; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); padding: 6px 8px; border-bottom: 2px solid var(--ink-soft); white-space: nowrap; }
.us-table td { padding: 9px 8px; border-bottom: 1px solid rgba(88,74,58,.25); vertical-align: top; }
.us-table tr.est-en-suppression td { background: rgba(178,58,38,.10); }
.us-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.us-sous { font-size: .8rem; color: var(--ink-soft); }
.us-mail { overflow-wrap: anywhere; min-width: 170px; }
.hg-libres { width: 100%; margin: 4px 0 6px; padding: 8px 10px; border: 2px solid var(--ink); border-radius: 10px; background: #fff; font: inherit; font-size: .95rem; }
/* Fiche d'un joueur (admin) */
.us-lien { color: inherit; text-decoration: none; border-bottom: 2px dotted rgba(28,23,18,.35); }
.us-lien:hover { border-bottom-color: var(--rust); }
.fi-retour { display: inline-block; margin-bottom: 4px; color: #fff; font-weight: 700; text-decoration: none; padding: 6px 14px; border: 2px solid rgba(255,255,255,.55); border-radius: 999px; }
.fi-retour:hover { background: rgba(255,255,255,.1); }
.fi-entete { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.fi-entete h2 { margin: 0 0 4px; font-size: 1.5rem; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.fi-entete p { margin: 2px 0; }
.fi-qui { flex: 1 1 320px; min-width: 0; overflow-wrap: anywhere; }
.fi-avatar { width: 84px; height: 84px; border-radius: 50%; border: 3px solid var(--ink); object-fit: cover; background: var(--parchment-deep); flex: none; }
.fi-initiales { display: grid; place-items: center; font-weight: 900; font-size: 1.8rem; color: var(--ink); }
.fi-tuiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(150px, 45%), 1fr)); gap: 10px; margin: 14px 0; }
.fi-tuile { display: grid; gap: 2px; padding: 12px 14px; border-radius: 12px; background: var(--parchemin-texture); border: 3px solid var(--ink); color: var(--ink); }
.fi-tuile-titre { font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.fi-tuile b { font-size: 1.45rem; line-height: 1.1; }
.fi-tuile span:last-child:not(.fi-tuile-titre) { font-size: .8rem; color: var(--ink-soft); }
.fi-barres { display: flex; align-items: flex-end; gap: 2px; height: 120px; padding: 6px 0; border-bottom: 2px solid rgba(28,23,18,.3); }
.fi-barre { flex: 1; display: flex; flex-direction: column-reverse; height: 100%; position: relative; min-width: 3px; }
.fi-barre i { display: block; width: 100%; }
.fi-ville { background: #3f8f4e; border-radius: 0 0 2px 2px; }
.fi-dehors { background: #d9822b; border-radius: 2px 2px 0 0; }
.fi-pas { position: absolute; bottom: 2px; left: 50%; width: 5px !important; height: 5px; border-radius: 50%; background: var(--ink-soft); transform: translateX(-50%); }
.fi-axe { display: flex; justify-content: space-between; font-size: .75rem; color: var(--ink-soft); }
.fi-pt { display: inline-block; width: 10px; height: 10px; border-radius: 2px; vertical-align: middle; }
.fi-pt-ville { background: #3f8f4e; } .fi-pt-dehors { background: #d9822b; }
.fi-colonnes { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; margin: 14px 0; }
.fi-colonnes h3, .admin-panneau > h3 { margin: 0 0 8px; }
.fi-colonnes h3 + * { margin-bottom: 12px; }
.fi-table { min-width: 0; }
.fi-table td { padding: 5px 6px; }
.fi-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.fi-jour { padding: 10px 0; border-top: 1px solid rgba(28,23,18,.18); }
.fi-jour header { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.fi-jour header b::first-letter { text-transform: uppercase; }
.fi-ligne { display: grid; grid-template-columns: 26px 1fr; gap: 6px; padding: 4px 0; }
.fi-ligne > div { display: grid; gap: 2px; min-width: 0; }
.fi-icone { font-size: 1.1rem; line-height: 1.4; }
.fi-villes { display: flex; flex-wrap: wrap; gap: 4px; }
.fi-objets { display: flex !important; flex-wrap: wrap; gap: 10px; }
.fi-objet { display: flex; gap: 6px; align-items: center; }
.fi-objet > span { display: grid; line-height: 1.2; font-size: .9rem; }
.fi-alerte { color: var(--rust-dark); }
.us-objets { display: block; margin-top: 4px; padding: 2px 8px; border: 2px solid var(--ink); border-radius: 999px; background: var(--parchment); color: var(--ink); font: inherit; font-size: .78rem; cursor: pointer; white-space: nowrap; }
.us-objets:hover { background: var(--parchment-deep); }
.us-objets-modale { width: 640px; }
.us-objets-titre { margin: 6px 0 2px; font-family: var(--condensed); font-style: italic; text-transform: uppercase; font-size: 1rem; }
.us-objets-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 12px; }
.us-objet { margin: 0; display: grid; justify-items: center; gap: 6px; text-align: center; }
.us-objet-cadre { position: relative; }
.us-objet-reste { position: absolute; z-index: 3; left: 50%; bottom: 6px; transform: translateX(-50%); padding: 1px 7px; border-radius: 999px; background: rgba(8, 12, 16, .78); color: #fff; font-size: .72rem; font-weight: 700; white-space: nowrap; }
.us-objet figcaption { display: grid; gap: 1px; font-size: .78rem; line-height: 1.25; }
.us-objet figcaption span { color: var(--ink-soft); }
.us-action { text-align: right; white-space: nowrap; }
.us-muet { color: var(--ink-soft); }
.us-vide { text-align: center; color: var(--ink-soft); padding: 18px !important; }
.us-tag { display: inline-block; margin-left: 6px; padding: 0 6px; border-radius: 99px; font-size: .7rem; font-weight: 800; text-transform: uppercase; background: var(--ink-soft); color: #fff; vertical-align: 1px; }
.us-tag-admin { background: var(--explore); }
.us-tag-banni { background: var(--rust-dark); }
.us-confirmer { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: flex-end; white-space: normal; }
.us-confirmer label { font-size: .82rem; color: var(--ink); text-align: right; }
.us-confirmer input { display: block; margin-top: 4px; margin-left: auto; width: 150px; padding: 6px 8px; border: 2px solid var(--rust); border-radius: 6px; font: inherit; }

/* ---------- Mot de passe oublié ---------- */
.mdp-panneau { padding: 22px; margin-top: 8px; color: var(--ink); }
.mdp-panneau form { display: grid; gap: 10px; }
.mdp-texte { margin: 0 0 4px; color: var(--ink) !important; }
.mdp-ok { margin: 0 0 12px; padding: 12px 14px; border-radius: 8px; background: rgba(46,110,79,.15); color: var(--defend) !important; font-weight: 700; }
.legal .mdp-panneau .form-error { margin: 0 0 12px; color: var(--rust-dark); }
.legal .mdp-panneau .field-hint { color: var(--ink-soft); margin-top: -4px; }
.modal-oubli { margin: -4px 2px 8px; text-align: right; font-size: .9rem; }
.modal-oubli a { color: var(--rust-dark); font-weight: 700; }
.legal a.btn { color: #fff; }

/* ---------- Bouton Connexion (barre du haut) ---------- */
.btn-connexion {
  display: inline-flex; align-items: center; gap: .45em;
  padding: .4em .85em; border: 2px solid rgba(246,235,218,.55); border-radius: 10px;
  background: rgba(255,255,255,.06); color: var(--cream);
  font-family: var(--body); font-weight: 800; font-size: 1rem; text-transform: none; letter-spacing: 0;
  box-shadow: none; cursor: pointer;
}
.btn-connexion:hover, .btn-connexion:focus-visible { background: rgba(255,255,255,.14); border-color: var(--cream); }
.icone-connexion { flex: none; }
@media (max-width: 480px) {
  /* Sur un petit écran : l'icône seule, mais une vraie cible de 44 px. */
  .btn-connexion { padding: 0; width: 44px; height: 44px; justify-content: center; }
  .btn-connexion-texte { display: none; }
}

/* Lien « Déjà un compte ? Se connecter » sous les boutons de l'accueil */
.hero-connexion { margin: 14px 0 0; font-weight: 700; color: var(--cream); text-shadow: 0 2px 6px rgba(0,0,0,.6); }
.hero-connexion a { display: inline-flex; align-items: center; gap: .3em; margin-left: .3em; color: #FFD27A; }
.hero-connexion .icone-connexion { width: 18px; height: 18px; }
@media (max-width: 480px) {
  /* La barre tenait à peine : badge, logo, connexion et inscription sur 390 px
     débordaient de ~35 px et faisaient défiler la page de côté. */
  .topbar-auth .btn-rust.btn-sm { font-size: .95rem; padding: .35em .6em; }
  .topbar-logo img { height: 30px; }
  .topbar { gap: 8px; }
}

/* ---------- Admin : messagerie ---------- */
.admin-pastille { display: inline-block; min-width: 1.5em; margin-left: 4px; padding: 0 .45em; border-radius: 99px; background: #F4C430; color: var(--ink); font-size: .78rem; font-weight: 800; line-height: 1.5; text-align: center; }
.msg-grille { display: grid; grid-template-columns: minmax(240px, 340px) 1fr; gap: 16px; align-items: start; }
.msg-liste, .msg-fil { padding: 12px; color: var(--ink); }
.msg-liste { display: grid; gap: 6px; max-height: 70vh; overflow-y: auto; }
.msg-conv { display: grid; gap: 2px; width: 100%; padding: 10px 12px; border: 2px solid transparent; border-radius: 10px; background: rgba(255,255,255,.45); text-align: left; cursor: pointer; font: inherit; color: var(--ink); }
.msg-conv:hover { border-color: var(--ink-soft); }
.msg-conv.est-ouverte { border-color: var(--rust); background: rgba(255,255,255,.75); }
.msg-conv.est-non-lue .msg-apercu { font-weight: 800; color: var(--ink); }
.msg-conv-tete { display: flex; align-items: center; gap: 6px; }
.msg-date { margin-left: auto; font-size: .78rem; color: var(--ink-soft); }
.msg-apercu { font-size: .88rem; color: var(--ink-soft); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.msg-ville { font-size: .75rem; color: var(--ink-soft); }
.msg-vide { color: var(--ink-soft); margin: 8px; }
.msg-fil-tete { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; padding: 4px 6px 10px; border-bottom: 2px solid rgba(88,74,58,.3); font-size: .92rem; }
.msg-fil-tete a { margin-left: auto; color: var(--rust-dark); font-weight: 700; }
.msg-bulles { display: flex; flex-direction: column; gap: 10px; max-height: 52vh; overflow-y: auto; padding: 12px 4px; }
.msg-bulle { max-width: 78%; padding: 9px 12px; border-radius: 14px; }
.msg-bulle p { margin: 0 0 4px !important; line-height: 1.45; overflow-wrap: anywhere; }
.msg-joueur { align-self: flex-start; background: #fff; border: 2px solid rgba(88,74,58,.35); border-bottom-left-radius: 4px; }
.msg-equipe { align-self: flex-end; background: var(--defend); color: #fff; border-bottom-right-radius: 4px; }
.msg-meta { display: block; font-size: .74rem; opacity: .75; }
.msg-contexte { font-family: ui-monospace, Menlo, monospace; }
.vf-bloc { display: grid; gap: 6px; margin: 6px 0 4px; padding: 8px 10px; border: 2px dashed rgba(88,74,58,.4); border-radius: 10px; background: rgba(255,248,230,.7); font-size: .88rem; }
.vf-bloc .vf-mot { width: 100%; padding: 6px 9px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; background: #fff; }
.vf-boutons { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; }
.vf-boutons a, .vf-bloc a { color: var(--rust-dark); font-weight: 700; }
.vf-validee, .vf-refusee { display: block; }
.vf-validee { border-style: solid; border-color: rgba(60,120,60,.5); }
/* Le bouton « annuler la validation » et son erreur, dans un bloc deja
   decide. `:not([hidden])` est indispensable : sans lui, la regle `display`
   l'emporte sur le `hidden` du navigateur et le message s'afficherait vide en
   permanence. */
.vf-validee button, .vf-refusee button { margin-left: 4px; }
.vf-validee .form-error:not([hidden]) { display: block; margin-top: 6px; }
.vf-refusee { border-style: solid; border-color: rgba(150,60,40,.5); }
.vf-raisons { margin: 4px 0; padding-left: 18px; font-size: .88rem; }
.msg-repondre { display: grid; gap: 8px; padding-top: 10px; border-top: 2px solid rgba(88,74,58,.3); }
.msg-repondre textarea { width: 100%; padding: 10px 12px; border: 2px solid var(--ink-soft); border-radius: 10px; font: inherit; resize: vertical; background: rgba(255,255,255,.8); }
.msg-repondre textarea:focus-visible { outline: none; border-color: var(--rust); background: #fff; }
.msg-repondre .btn { justify-self: end; }
@media (max-width: 760px) { .msg-grille { grid-template-columns: 1fr; } .msg-liste { max-height: 40vh; } }

/* ---------- Admin : versions ---------- */
.vs-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px 16px; margin-top: 6px; color: var(--ink); }
.vs-form label { display: grid; gap: 4px; font-weight: 700; font-size: .9rem; }
.vs-form input { padding: 8px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; background: rgba(255,255,255,.7); }
.vs-form input:focus-visible { outline: none; border-color: var(--rust); background: #fff; }
.vs-large { grid-column: 1 / -1; }
.vs-actions { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; }
.vs-form .form-error, .vs-form .us-ok { grid-column: 1 / -1; }
.vs-aide { font-weight: 500; font-size: .8rem; color: var(--ink-soft); }
/* Notifications push (admin) */
.ps-test { margin: 14px 0 6px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* A qui envoyer le test : un telephone de test n'est pas connecte sur le
   compte admin, et c'est pourtant lui qu'on veut faire sonner. */
.ps-test select {
  padding: 5px 8px; border: 2px solid var(--ink-soft); border-radius: 8px;
  font: inherit; font-size: .88rem; background: #fffdf8; color: var(--ink);
}
.ps-form { grid-template-columns: 1fr 1fr; margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(88,74,58,.3); }
.ps-form select, .ps-form textarea { padding: 8px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; font-weight: 500;
  background: rgba(255,255,255,.7); width: 100%; min-width: 0; box-sizing: border-box; }
.ps-form textarea { resize: vertical; min-height: 76px; }
.ps-form select:focus-visible, .ps-form textarea:focus-visible { outline: none; border-color: var(--rust); background: #fff; }
.ps-form input { width: 100%; min-width: 0; box-sizing: border-box; }
.admin-panneau .ps-titre { margin: 30px 0 8px; color: var(--ink); }
@media (max-width: 700px) { .ps-form { grid-template-columns: 1fr; } }
.vs-proposition { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; background: rgba(244,196,48,.25); border: 2px solid #C99A12; color: var(--ink); }
.vs-repartition { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; color: var(--ink); }
.vs-repartition li { padding: 8px 12px; border-radius: 8px; background: rgba(255,255,255,.5); }
.vs-repartition li.est-en-retard { background: rgba(224,48,30,.12); }
/* La provenance, devant le build : iOS et la coque Android partagent le meme
   compteur, le numero seul ne dit donc pas de quelle application il s'agit. */
.vs-plateforme {
  display: inline-block; margin-right: 8px; padding: 1px 8px;
  border-radius: 999px; font-size: .78rem; font-weight: 800;
  color: #fff; background: #6b7280; vertical-align: 1px;
}
.vs-plateforme.est-ios     { background: #1f2937; }
.vs-plateforme.est-android { background: #2f7d32; }
.vs-plateforme.est-web     { background: #8a6a3a; }
/* Zonage (admin) */
.zn-barre { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 10px; }
.zn-barre select, .zn-barre input[type=search] { padding: 8px 10px; border: 2px solid var(--ink); border-radius: 10px; background: #fff; font: inherit; }
.zn-cherche { position: relative; flex: 1 1 240px; }
.zn-cherche input { width: 100%; box-sizing: border-box; }
.zn-resultats { position: absolute; z-index: 1000; left: 0; right: 0; top: 100%; margin: 4px 0 0; padding: 4px; list-style: none; background: #fff8ec; border-radius: 8px; box-shadow: 0 6px 16px rgba(0,0,0,.25); max-height: 280px; overflow: auto; }
.zn-resultats button { all: unset; display: block; width: 100%; box-sizing: border-box; padding: 6px 8px; cursor: pointer; border-radius: 6px; }
.zn-resultats button:hover { background: #f1e1c9; }
.zn-case { display: inline-flex; gap: 4px; align-items: center; font-weight: 700; color: var(--ink); }
.zn-carte { height: min(72vh, 760px); border: 3px solid var(--ink); border-radius: 12px; overflow: hidden; background: #dfe7ea; }
.zn-attente { padding: 20px; color: var(--ink-soft); }
.cv { margin: 10px 0 4px; padding: 10px 12px; background: #fffaf0; border: 2px solid var(--ink); border-radius: 12px; }
.cv figcaption { font-weight: 700; color: var(--ink); display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; }
.cv-legende { font-weight: 500; font-size: .85em; color: #5b4a3a; }
.cv-legende i { display: inline-block; width: 16px; height: 0; vertical-align: middle; margin: 0 3px 0 8px; border-top: 2px solid; }
.cv-legende .cv-brute { border-color: #1d4ed8; }
.cv-legende .cv-ajustee { border-color: #c2410c; border-top-style: dashed; }
.cv-legende .cv-seuil { border-color: #7a6a5a; border-top-style: dotted; }
.cv-legende .cv-zone { height: 10px; border: 0; background: rgba(217, 59, 38, .14); }
.cv svg { width: 100%; height: auto; display: block; font: 11px system-ui, sans-serif; fill: #5b4a3a; }
.cv .cv-grille { stroke: rgba(65, 42, 20, .12); }
.cv .cv-axe { stroke: rgba(65, 42, 20, .4); }
.cv .cv-unite { font-weight: 700; }
.cv .cv-lent { fill: rgba(217, 59, 38, .12); }
.cv .cv-ligne-seuil { stroke: #7a6a5a; stroke-dasharray: 2 4; stroke-width: 1.5; }
.cv .cv-l-brute { fill: none; stroke: #1d4ed8; stroke-width: 2; stroke-linejoin: round; }
.cv .cv-l-ajustee { fill: none; stroke: #c2410c; stroke-width: 1.5; stroke-dasharray: 5 3; opacity: .9; }
.cv .cv-curseur { stroke: var(--ink); stroke-width: 1; }
.cv-info { margin: 4px 0 0; font-size: .9em; color: var(--ink); min-height: 1.3em; }
.src-barre { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; }
.src-defile { overflow-x: auto; }
.src-campagnes { font-size: .85em; font-weight: 400; }
.src-campagnes summary { cursor: pointer; color: #5b4a3a; }
.src-fabrique { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px 12px; }
.src-fabrique label { display: flex; flex-direction: column; gap: 3px; font-weight: 600; }
.src-lien { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px; }
.src-lien code { word-break: break-all; background: #fff; padding: 4px 8px; border-radius: 6px; border: 1px solid rgba(65, 42, 20, .25); }
.zn-etat, .zn-sortie { margin: 8px 0 2px; color: var(--ink); font-weight: 600; }
.zn-nom { background: rgba(255,255,255,.75); border: 0; box-shadow: none; font-size: 11px; font-weight: 700; padding: 0 3px; }
.fg-barre { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; margin: 8px 0 12px; }
.fg-barre .us-filtre { flex: 1 1 260px; max-width: 420px; }
.fg-forge h2 { margin: 0 0 10px; display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.us-objet figcaption a { color: inherit; }
.fi-carte-modale { width: min(1100px, 96vw); }
.fi-carte-modale .modal-card { padding: 18px 18px 14px; }
.fi-carte { height: min(70vh, 640px); border: 3px solid var(--ink); border-radius: 12px; overflow: hidden; background: #dfe7ea; }
.fi-carte-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 4px; }
.tx-section { margin: 22px 0 4px; font-size: 1.15rem; }
.vs-noms { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.vs-nom { text-decoration: none; cursor: pointer; }
.us-tri { all: unset; cursor: pointer; font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit; white-space: nowrap; }
.us-tri:hover, .us-tri.est-actif { color: var(--ink); }
.us-tri span { opacity: .7; }
.us-tri:focus-visible { outline: 2px solid var(--rust); outline-offset: 2px; border-radius: 3px; }

/* ---------- Admin : modération ---------- */
.admin-pastille.est-alerte { background: var(--rust); color: #fff; }
.mod-carte { padding: 16px 18px; margin-bottom: 12px; color: var(--ink); }
.mod-carte.est-masque { border-style: dashed; }
.mod-tete { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; }
.mod-compte { margin-left: auto; font-weight: 800; color: var(--rust-dark); }
.mod-contexte { margin: 10px 0 0; padding: 8px 12px; border-left: 3px solid rgba(88,74,58,.35); font-size: .86rem; color: var(--ink-soft); }
.mod-contexte p { margin: 2px 0 !important; }
.mod-texte { margin: 10px 0; padding: 10px 14px; border-radius: 10px; background: #fff; border: 2px solid var(--rust); font-size: 1rem; overflow-wrap: anywhere; }
.mod-actions, .mod-muet { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.mod-muet { font-size: .85rem; color: var(--ink-soft); }
.mod-muets { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; color: var(--ink); }
.mod-muets li { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.us-strava { display: inline-block; padding: 1px 8px; border-radius: 99px; background: #FC4C02; color: #fff !important; font-size: .78rem; font-weight: 800; text-decoration: none; }
.us-strava:hover { filter: brightness(1.1); }
.us-liaison { margin-bottom: 4px; white-space: nowrap; }
.us-montre { display: inline-block; padding: 1px 8px; border-radius: 99px; color: #fff; font-size: .78rem; font-weight: 800; background: #555; }
.us-montre-garmin { background: #007CC3; }
.us-montre-suunto { background: #1A1A1A; }
.us-liaison-x { margin-left: 4px; width: 20px; height: 20px; padding: 0; border: 1px solid rgba(0,0,0,.25); border-radius: 50%;
  background: transparent; color: var(--ink-soft); font: 700 14px/1 sans-serif; cursor: pointer; vertical-align: middle; }
.us-liaison-x:hover { background: #B3261E; border-color: #B3261E; color: #fff; }
.us-liaison-x:disabled { opacity: .4; cursor: wait; }

/* ---------- Admin : objets ---------- */
.admin-entete .btn { margin-left: auto; }

/* Smileys zombies du chat (admin) */
.emo-zombie { width: 1.35em; height: 1.35em; vertical-align: -0.3em; }
.emo-zombie.est-seul { width: 48px; height: 48px; }

/* ---------- Reliques (admin) ---------- */
.rq-outils { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; margin: 0 0 12px; }
.rq-outils label { display: grid; gap: 4px; color: #fff; font-weight: 700; font-size: .85rem; }
.rq-outils select, .rq-outils input[type=search] { padding: 8px 10px; border-radius: 10px; border: 2px solid var(--ink); background: var(--parchment, #e9d5b9); font: inherit; }
.rq-outils input[type=search] { flex: 1; min-width: 180px; }
.rq-stats { margin: 0 0 10px; }
.rq-pages { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 4px 0 10px; font-weight: 700; color: var(--ink); }
.rq-liste { list-style: none; margin: 0; padding: 0; }
.rq-liste > li { border-bottom: 1px solid rgba(28,23,18,.15); padding: 8px 0; }
/* Les trois objets d'une même relique : même fond, même filet à gauche. */
.rq-liste > li.rq-en-relique { background: var(--hg-teinte); border-left: 6px solid color-mix(in srgb, var(--hg-teinte) 55%, #1c1712); padding-left: 10px; padding-right: 8px; border-radius: 6px; margin: 2px 0; }
.rq-ligne { display: flex; align-items: center; gap: 12px; }
.rq-ville { flex: 1; display: grid; gap: 1px; min-width: 0; color: var(--ink); }
.rq-nom { font-size: .9rem; }
.rq-sans .rq-nom em { color: var(--ink-soft); }
.rq-droite { display: flex; align-items: center; gap: 8px; }
.us-tag.rq-attente { background: #8e1b10; color: #fff; }
.rq-form { display: grid; grid-template-columns: auto 1fr; gap: 16px; margin: 10px 0 4px; padding: 12px; border-radius: 12px; background: rgba(28,23,18,.06); color: var(--ink); }
.rq-champs { display: grid; gap: 8px; }
.rq-champs label { display: grid; gap: 4px; font-weight: 700; font-size: .88rem; }
.rq-champs input:not([type=file]) { padding: 8px 10px; border-radius: 8px; border: 2px solid var(--ink); font: inherit; }
.rq-etats { display: grid; grid-template-columns: repeat(5, auto); gap: 8px; align-content: start; }
.rq-etats figure { margin: 0; text-align: center; font-size: .72rem; font-weight: 700; }
@media (max-width: 720px) { .rq-form { grid-template-columns: 1fr; } }

/* Les cinq cadres d'état, posés par-dessus la même image. */
.rq-cadre { position: relative; display: inline-grid; place-items: center; flex: none; border-radius: 16px;
  padding: 5px; box-sizing: border-box; overflow: hidden; }
.rq-cadre img { width: 100%; height: 100%; object-fit: contain; position: relative; z-index: 1; }
.rq-cadre .rq-vide { font-weight: 900; font-size: 1.4rem; color: rgba(255,255,255,.8); }
.rq-n1 { background: radial-gradient(circle, #5a4636, #2e231a); border: 3px solid #6b4a2b; }
.rq-n1 img { filter: sepia(.45) saturate(.75) brightness(.92); }
.rq-n2 { background: radial-gradient(circle, #6e4a2c, #3a2617); border: 3px solid #c07a3e; box-shadow: 0 0 0 1px #5a3518; }
.rq-n3 { background: radial-gradient(circle, #43505e, #1d252e); border: 3px solid #c9d1d9; box-shadow: 0 0 8px rgba(120,180,255,.6); }
.rq-n4 { background: radial-gradient(circle, #4a2f6b, #1f1330); border: 3px solid #a66bf0; box-shadow: 0 0 10px rgba(166,107,240,.75); }
.rq-n5 { background: radial-gradient(circle, #6b5418, #2a1f06); border: 3px solid #f2c94c; box-shadow: 0 0 14px rgba(242,201,76,.9); }
.rq-n5::after { content: ''; position: absolute; inset: -50%; z-index: 2; pointer-events: none;
  background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,.55) 50%, transparent 60%);
  animation: rq-reflet 2.6s ease-in-out infinite; }
@keyframes rq-reflet { from { transform: translateX(-60%); } to { transform: translateX(60%); } }

/* Le champ parrain : coche verte si le joueur existe, croix rouge sinon. */
.parrain-etat { flex: none; align-self: center; padding-right: 12px; min-width: 1.6em; text-align: center; font-weight: 900; font-size: 1.1em; }
.parrain-etat.oui { color: #2e9e5b; }
.parrain-etat.non { color: #d93b26; }
.parrain-etat.attente { color: #8a7a66; }

/* Télécharger l'app : iPhone (TestFlight) et Android (bientôt). */
.telecharger { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin: 22px 0 0; }
.dl-btn {
  display: inline-flex; align-items: center; gap: 10px; min-width: 190px;
  padding: 9px 18px; border-radius: 12px; border: 2px solid #fff;
  background: #111; color: #fff; text-decoration: none; text-align: left;
  box-shadow: 0 4px 12px rgba(0,0,0,.45); transition: transform .12s ease, background .12s ease;
}
.dl-btn span { display: flex; flex-direction: column; font-weight: 800; font-size: 1.25rem; line-height: 1.05; }
.dl-btn small { font-weight: 600; font-size: .72rem; opacity: .85; letter-spacing: .02em; }
a.dl-btn:hover, a.dl-btn:focus-visible { transform: translateY(-2px); background: #000; }
.dl-bientot { opacity: .55; cursor: default; border-style: dashed; }
.telecharger-aide { margin: 10px auto 0; max-width: 34em; font-size: .85rem; color: var(--cream); text-shadow: 0 2px 6px rgba(0,0,0,.6); }
.telecharger-aide strong { color: #FFD27A; }

/* Page Telecharger : le meme bouton que l'accueil, en plus grand, avec la
   version et la taille a cote plutot qu'en dessous — c'est ce qu'on regarde
   avant de toucher. */
.dl-bloc { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 22px; margin: 20px 0 4px; }
.dl-bloc .dl-btn { min-width: 240px; padding: 13px 22px; }
.dl-meta { margin: 0; color: #9AA7B2; font-size: .9rem; line-height: 1.55; }
.legal code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em; color: var(--cream); }
/* L'empreinte de signature : 32 octets qui doivent pouvoir se comparer au
   caractere pres, donc jamais coupes ailleurs qu'entre deux groupes. */
/* La mise a jour de la coque Android (site.js, majCoque).
   Le bandeau se pose au-dessus de la barre d'onglets du jeu ; la version
   bloquante prend tout l'ecran et capte les touchers, puisqu'il n'y a plus
   rien a faire tant que la mise a jour n'est pas installee.
   `pointer-events` : le conteneur du bandeau laisse passer les touchers a
   cote de la boite, sinon il couvrirait la largeur de l'ecran pour rien. */
.maj-coque {
  position: fixed; left: 0; right: 0; z-index: 9000; pointer-events: none;
  bottom: calc(96px + env(safe-area-inset-bottom));
  display: flex; justify-content: center; padding: 0 12px;
}
.maj-coque.est-bloquant {
  inset: 0; bottom: 0; align-items: center; padding: 24px;
  background: rgba(10, 16, 22, .92); pointer-events: auto;
}
.maj-coque-boite {
  pointer-events: auto; width: 100%; max-width: 420px; padding: 16px 18px;
  border: 3px solid var(--ink, #1c1712); border-radius: 14px;
  background: var(--parchment, #f0dfbb); color: var(--ink, #1c1712);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .5);
}
.maj-coque-titre {
  margin: 0 0 6px; font-family: var(--condensed); font-weight: 800;
  text-transform: uppercase; font-size: 1.15rem;
}
.maj-coque-mot { margin: 0 0 12px; font-size: .95rem; line-height: 1.45; }
.maj-coque .btn-block { display: block; text-align: center; text-decoration: none; }
.maj-coque-plus-tard {
  display: block; width: 100%; margin: 8px 0 0; padding: 6px; border: 0;
  background: none; color: var(--ink-soft, #6b5a45); font: inherit;
  font-size: .9rem; text-decoration: underline; cursor: pointer;
}

/* La classification PEGI. La pastille est au style du site et PAS au style de
   la marque PEGI : la note est un fait qu'on peut ecrire, le logo est une
   marque qui se telecharge sur pegi.info et ne se redessine pas. */
.pegi { display: flex; align-items: flex-start; gap: 14px; }
.pegi-note {
  flex: none; display: grid; place-items: center; width: 46px; height: 46px;
  border: 2px solid var(--cream); border-radius: 10px;
  font-family: var(--display); font-size: 1.9rem; line-height: 1;
  color: var(--cream); background: var(--night-2);
}
/* La meme note, en une ligne sous les boutons de l'accueil : fond sombre, donc
   les memes couleurs que `.telecharger-aide` autour. */
.pegi-mini { width: 30px; height: 30px; border-width: 2px; border-radius: 7px; font-size: 1.15rem; }
.telecharger-pegi {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin: 16px auto 0; font-size: .85rem; color: var(--cream);
  text-shadow: 0 2px 6px rgba(0,0,0,.6);
}
.telecharger-pegi a { color: #FFD27A; }

/* La dernière mise à jour du jeu, sous la note PEGI (initMaj, admin → MAJ).
   Une bannière (le porte-voix du Hourra), puis un parchemin déchiré comme
   les autres du site (`.parchment`) : badges de catégorie à gauche, date à
   droite derrière son calendrier, titre, trois lignes, « Voir plus ».
   `pre-line` garde les retours à la ligne écrits dans l'admin. */
.maj-accueil { max-width: 560px; margin: 18px auto 0; text-align: left; }
/* Le titre : le porte-voix et deux lignes, posés sur le décor de la page,
   sans cadre ni image de fond. */
.maj-banniere {
  position: relative; display: flex; align-items: center; gap: 10px;
  margin: 0 6px 4px; padding: 6px 14px 6px 92px; min-height: 58px;
  color: var(--cream); text-shadow: 0 2px 6px rgba(0,0,0,.75);
}
.maj-porte-voix { position: absolute; left: 6px; bottom: 2px; width: 82px; height: auto;
  filter: drop-shadow(0 4px 5px rgba(0,0,0,.5)); transform: rotate(-6deg); }
.maj-banniere b { display: block; font-family: var(--display); font-weight: 400; font-size: 1.6rem; line-height: 1; letter-spacing: .02em; }
.maj-banniere span { display: block; font-size: .8rem; font-weight: 700; color: #DCE4EA; }
.maj-parchemin { padding: 6px 4px 2px; }
.maj-tete { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 6px; }
.maj-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.maj-cat-badge { height: 28px; width: auto; display: block; }
.maj-badge { padding: 2px 9px; border-radius: 99px; background: var(--rust); color: #fff; font-weight: 900;
  text-transform: uppercase; letter-spacing: .03em; font-size: .7rem; }
/* La date tout à droite, derrière son petit onglet de calendrier. */
.maj-date { flex: none; display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px 3px 4px;
  border: 1.5px solid rgba(65,42,20,.35); border-radius: 99px; background: rgba(255,255,255,.35);
  font-size: .76rem; font-weight: 800; color: var(--ink-soft); white-space: nowrap; }
.maj-date span { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%;
  background: var(--ink); font-size: .7rem; }
/* Le titre en Barlow droit, pas dans la police d'affiche : en capitales
   italiques (Bangers), une phrase entière devenait illisible. Les règles
   `h3` du site (capitales, police d'affiche) sont neutralisées une à une. */
.maj-accueil .maj-titre {
  margin: 2px 0 4px; font-family: var(--body); font-style: normal; font-weight: 800;
  font-size: 1.02rem; line-height: 1.3; letter-spacing: 0; text-transform: none; text-align: left;
  color: var(--rust-dark);
}
.maj-texte {
  margin: 0; white-space: pre-line; font-size: .9rem; font-weight: 600; line-height: 1.45; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.maj-accueil.est-ouverte .maj-texte, .maj-texte.est-entier { display: block; -webkit-line-clamp: unset; overflow: visible; }
.maj-ancienne { margin-top: 12px; padding-top: 10px; border-top: 1.5px dashed rgba(65,42,20,.3); }
.maj-ancienne .maj-cat-badge { height: 24px; }
.maj-pagination { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin: 12px 0 0; padding-top: 8px; border-top: 1.5px dashed rgba(65,42,20,.3); font-size: .8rem; font-weight: 800; }
.maj-pagination button { padding: 4px 10px; border: 1.5px solid var(--ink-soft); border-radius: 99px;
  background: rgba(255,255,255,.55); color: var(--ink); font: inherit; cursor: pointer; }
.maj-pagination button:disabled { opacity: .35; cursor: default; }
.maj-numero { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.maj-plus { margin: 6px 0 0; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .85rem; font-weight: 800; color: var(--rust-dark); text-decoration: underline; }

.dl-empreinte {
  display: block; margin: 6px 0 0; padding: 10px 12px;
  border: 1px solid #2E4050; border-radius: 8px; background: var(--night-2);
  color: #DCD2C4; font-size: .78rem; line-height: 1.7; word-break: break-all;
}

/* Admin → Reliques : les cinq icônes d'objet mystérieux. */
.rq-mysteres { margin-top: 18px; }
.rq-mysteres h2 { margin: 0 0 4px; }
.rq-mysteres-liste { list-style: none; display: flex; flex-wrap: wrap; gap: 14px; margin: 12px 0 0; padding: 0; }
.rq-mysteres-liste li { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 96px;
  font-size: .8rem; font-weight: 700; text-align: center; color: var(--ink); }

/* Admin → Héritages : trois reliques, un triptyque. */
.hg-trio { display: flex; flex-wrap: wrap; gap: 6px 12px; margin: 4px 0; font-size: .85rem; }
.hg-trio > span { display: inline-flex; align-items: center; gap: 6px; }
.hg-libre { font-style: italic; opacity: .6; border: 1px dashed currentColor; border-radius: 8px; padding: 2px 8px; }
.hg-places { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; margin: 6px 0; }
.hg-place { position: relative; display: flex; flex-direction: column; gap: 4px; padding: 8px; border: 2px dashed rgba(0,0,0,.25); border-radius: 10px; }
.hg-place.est-prise { flex-direction: row; align-items: center; border-style: solid; border-color: #c07a3e; }
.hg-place.est-prise > div { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.hg-resultats { list-style: none; margin: 4px 0 0; padding: 0; max-height: 240px; overflow: auto; background: #fff8ec; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,.2); }
.hg-resultats button { display: flex; align-items: center; gap: 6px; width: 100%; padding: 6px 8px; border: 0; background: none; text-align: left; cursor: pointer; font: inherit; }
.hg-res-texte { display: grid; gap: 1px; min-width: 0; line-height: 1.2; }
.hg-res-texte .vs-aide { font-style: italic; }
.hg-resultats button:hover:not(:disabled) { background: #f1e1c9; }
.hg-resultats button:disabled { opacity: .5; cursor: not-allowed; }
.hg-tag { background: #6b3fa0; color: #fff; }
.hg-tag-lien { border: 0; font-family: inherit; line-height: inherit; cursor: pointer; }
.hg-tag-lien:hover { background: #8150c0; text-decoration: underline; }
.hg-cible { outline: 3px solid #8150c0; outline-offset: 2px; transition: outline-color .6s; }

/* Admin → Reliques : onglets, et le temps qui reste pour créer une relique trouvée. */
.rq-onglets { display: flex; flex-wrap: wrap; gap: 6px; }
.rq-onglet { padding: 6px 12px; border-radius: 99px; border: 2px solid rgba(255,255,255,.35); background: transparent;
  color: var(--cream, #f4e8d4); font: inherit; font-weight: 700; font-size: .85rem; cursor: pointer; }
.rq-onglet:hover { border-color: #fff; }
.rq-onglet.est-actif, [data-rq-ici].est-actif { background: var(--rust, #e0301e); border-color: var(--rust, #e0301e); color: #fff; }
.rq-echeance { display: block; margin-top: 2px; font-size: .8rem; font-weight: 700; color: #8a5a10; }
.rq-echeance.est-retard { color: #c62d1a; }
.rq-outils [data-rq-ici]:not(.est-actif) { color: var(--cream, #f4e8d4); border-color: rgba(255,255,255,.35); background: transparent; }

/* Inscription : le portrait à gauche du pseudo, la grille pour en changer, et l'appel aux iPhone. */
.field-avatar { display: flex; align-items: stretch; gap: 10px; }
.field-avatar .field { flex: 1; min-width: 0; }
.avatar-choix { position: relative; flex: none; width: 54px; height: 54px; padding: 0; border: 3px solid var(--ink, #1c1712);
  border-radius: 50%; background: var(--rust, #e0301e); cursor: pointer; overflow: visible; }
/* Une <img> est en ligne par defaut : elle se pose sur la ligne de base, et
   le creux reserve aux jambages la decalait vers le haut dans son rond. D'ou
   `display: block` et un centrage absolu, qui ne depend plus de la typographie. */
.avatar-choix img {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: block; width: 112%; height: 112%; object-fit: contain;
}
.avatar-stylo { position: absolute; right: -6px; bottom: -6px; width: 22px; height: 22px; display: grid; place-items: center;
  border-radius: 50%; background: var(--ink, #1c1712); color: #fff; font-size: 12px; border: 2px solid #fff; }
.avatar-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 6px; max-height: 220px; overflow: auto;
  margin: 6px 0; padding: 8px; border-radius: 10px; background: rgba(0,0,0,.08); }
.avatar-pick { padding: 2px; border: 2px solid transparent; border-radius: 50%; background: none; cursor: pointer; }
.avatar-pick img { width: 100%; aspect-ratio: 1; object-fit: contain; display: block; }
.avatar-pick.est-choisi { border-color: var(--rust, #e0301e); }
.modal-iphone { margin: 0 0 12px; padding: 8px 12px; border-radius: 10px; background: rgba(0,0,0,.08); text-align: center; font-size: .9rem; }
.modal-iphone a { font-weight: 800; color: var(--rust-dark, #8e1b10); }
.avatar .avatar-img { width: 1.6em; height: 1.6em; object-fit: contain; vertical-align: -0.45em; }
/* La colonne de la fenêtre ne s'élargit jamais pour son contenu (sinon, sur téléphone, le formulaire débordait à droite). */
.modal-card { grid-template-columns: minmax(0, 1fr); }

/* Rare (n3) et Exceptionnel (n4) scintillent aussi, plus discrètement que le
   Légendaire : un passage, puis une pause (comme dans l'app). */
.rq-n3::after, .rq-n4::after { content: ''; position: absolute; inset: -50%; z-index: 2; pointer-events: none;
  background: linear-gradient(115deg, transparent 42%, rgba(255,255,255,.45) 50%, transparent 58%);
  transform: translateX(-60%); }
.rq-n3::after { animation: rq-scintille 5.4s ease-in-out infinite; }
.rq-n4::after { animation: rq-scintille 3.6s ease-in-out infinite; }
@keyframes rq-scintille {
  0% { transform: translateX(-60%); }
  30%, 100% { transform: translateX(60%); }
}
@media (prefers-reduced-motion: reduce) {
  .rq-n3::after, .rq-n4::after, .rq-n5::after { animation: none; display: none; }
}

/* --- Lab : Claude cherche des objets et des triptyques --------------------- */
.lab-moteurs { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px; margin-bottom: 14px; }
.lab-moteur { position: relative; display: grid; gap: 4px; padding: 12px 14px; border: 3px solid rgba(28,23,18,.25); border-radius: 12px;
  background: rgba(255,255,255,.35); color: var(--ink); cursor: pointer; }
.lab-moteur input { position: absolute; opacity: 0; pointer-events: none; }
.lab-moteur.est-choisi { border-color: var(--rust-dark); background: rgba(224,48,30,.08); box-shadow: 0 3px 0 var(--ink); }
.lab-prix { font-size: 1.25rem; font-weight: 800; }
.lab-prix small { font-size: .75rem; font-weight: 600; color: var(--ink-soft); }
.lab-dispo { color: var(--defend); }
.lab-indispo, .lab-retard { color: var(--rust-dark); }
.lab-reglages { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin-bottom: 12px; color: var(--ink); }
.lab-reglages input { width: 70px; padding: 4px 6px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; }
.lab-choix { display: grid; grid-template-columns: 1fr minmax(240px, 380px); gap: 12px; align-items: start; margin-bottom: 10px; }
.lab-puces { display: flex; flex-wrap: wrap; gap: 6px; min-height: 36px; align-items: center; }
.lab-puce { display: inline-flex; align-items: center; gap: 4px; padding: 4px 6px 4px 12px; border-radius: 99px; background: var(--ink); color: var(--parchment); font-weight: 700; }
.lab-puce button { border: 0; background: none; color: inherit; cursor: pointer; font-size: .9rem; }
.lab-cherche { position: relative; }
.lab-cherche input { width: 100%; padding: 8px 10px; border: 2px solid var(--ink); border-radius: 10px; font: inherit; }
.lab-cherche .hg-resultats { position: absolute; z-index: 5; left: 0; right: 0; }
.lab-lancer { flex-wrap: wrap; margin: 6px 0 12px; }
.lab-lancer input[type=number] { width: 60px; padding: 4px 6px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; }
.lab-relier { display: inline-flex; gap: 6px; align-items: center; color: var(--ink); font-weight: 700; }
.lab-relier.est-off { opacity: .45; }
.lab-ou { color: var(--ink-soft); }
.lab-batch { flex-basis: 100%; margin: 6px 0 0; }
.lab-sous-titre { margin: 8px 0 6px; color: var(--ink); }
.lab-villes { max-height: 340px; overflow: auto; border: 2px solid rgba(28,23,18,.2); border-radius: 10px; background: rgba(255,255,255,.25); }
.lab-liste { list-style: none; margin: 0; padding: 0; }
.lab-liste li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding: 7px 10px; border-bottom: 1px solid rgba(88,74,58,.2); color: var(--ink); }
.lab-liste li.est-choisie { background: rgba(224,48,30,.10); }
.lab-liste label { display: inline-flex; gap: 8px; align-items: center; cursor: pointer; }
.lab-badge { display: inline-block; padding: 2px 9px; border-radius: 99px; font-size: .78rem; font-weight: 800; border: 0; background: #ddd; color: var(--ink); cursor: default; white-space: nowrap; }
button.lab-badge { cursor: pointer; }
.lab-b-attente { background: #d9d2c4; }
.lab-b-cours { background: #f3c74c; }
.lab-b-relire { background: #e0301e; color: #fff; }
.lab-b-ok { background: #2e6e4f; color: #fff; }
.lab-b-non { background: #8b8072; color: #fff; }
.lab-b-echec { background: #5b1d14; color: #fff; }
.lab-table { min-width: 900px; }
.lab-table tr.est-ouverte td { background: rgba(224,48,30,.08); }
/* La roue, a cote du titre « Nouvelle demande » : l'editeur du prompt est en
   bas de page, et on n'y pense pas au moment ou l'on en aurait besoin —
   c'est-a-dire juste avant de lancer une recherche. */
.lab-roue {
  border: 0; background: none; cursor: pointer; padding: 0 0 0 6px;
  font-size: 1.1rem; line-height: 1; vertical-align: baseline;
  filter: grayscale(.35); transition: transform .15s ease, filter .15s ease;
}
.lab-roue:hover, .lab-roue:focus-visible { transform: rotate(45deg); filter: none; }
/* Le pseudo de qui attend l'objet, juste apres le nom de la ville. */
.lab-trouveur {
  flex: none; padding: .05em .5em; border-radius: 999px;
  font-size: .78rem; font-weight: 800; color: var(--rust-dark);
  background: rgba(224,48,30,.1); border: 1px solid rgba(224,48,30,.25);
}
.lab-prompt summary, .lab-requete summary { cursor: pointer; list-style: none; }
.lab-prompt summary h2, .lab-requete summary h2 { display: inline; }
/* La requete envoyee : un texte qu'on lit, pas qu'on edite. `pre-wrap` garde
   les sauts de ligne du serveur sans imposer de defilement horizontal, et la
   hauteur est bornee — le message fait 200 lignes quand le voisinage est
   dense. */
.lab-requete-texte {
  margin: 10px 0 0; padding: 10px 12px; max-height: 60vh; overflow: auto;
  white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: ui-monospace, Menlo, monospace; font-size: .78rem; line-height: 1.5;
  color: var(--ink); background: #fffdf8;
  border: 2px solid var(--ink-soft); border-radius: 8px;
}
.lab-prompt textarea, .lab-champ textarea, .lab-champ input { width: 100%; padding: 8px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; font-size: .92rem; background: #fffdf8; color: var(--ink); }
.lab-prompt textarea { font-family: ui-monospace, Menlo, monospace; font-size: .8rem; margin: 8px 0; }
.lab-prop { border: 4px solid var(--rust-dark); }
.lab-prop h3 { margin: 16px 0 8px; color: var(--ink); }
.lab-prop-tete { display: flex; justify-content: space-between; gap: 12px; align-items: start; }
.lab-champ { display: grid; gap: 4px; margin-bottom: 10px; color: var(--ink); font-weight: 700; font-size: .9rem; }
.lab-champ > span { display: flex; justify-content: space-between; gap: 8px; }
.lab-champ [readonly] { background: rgba(255,255,255,.4); }
.lab-compte { font-weight: 600; font-size: .78rem; color: var(--ink-soft); }
.lab-compte.est-trop { color: var(--rust-dark); font-weight: 800; }
.lab-objets { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.lab-objet { padding: 12px; border-radius: 12px; background: rgba(28,23,18,.06); }
.lab-objet-tete { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-bottom: 8px; color: var(--ink); }
.lab-insee { width: 74px; padding: 3px 6px; border: 2px solid var(--ink-soft); border-radius: 6px; font: inherit; font-size: .85rem; }
.lab-existant { display: flex; gap: 8px; align-items: center; color: var(--ink); }
.lab-sans, .lab-incertain { color: var(--ink); }
.lab-incertain { padding: 8px 12px; border-radius: 8px; background: rgba(243,199,76,.3); }
.lab-sources { margin: 0 0 10px; padding-left: 20px; color: var(--ink); font-size: .9rem; line-height: 1.5; }
.lab-problemes ul { margin: 6px 0 0; padding-left: 20px; }
.lab-brut pre { white-space: pre-wrap; max-height: 300px; overflow: auto; font-size: .78rem; background: rgba(255,255,255,.5); padding: 10px; border-radius: 8px; color: var(--ink); }
@media (max-width: 700px) { .lab-choix { grid-template-columns: 1fr; } }
.lab-compte { white-space: nowrap; }
.lab-prop .vs-actions { flex-wrap: wrap; }
.lab-prop .vs-actions .btn { white-space: nowrap; }
.lab-bloc { margin: 14px 0; padding: 12px 14px 4px; border: 3px solid rgba(28,23,18,.25); border-radius: 14px; background: rgba(255,255,255,.18); }
.lab-bloc h3 { margin: 0 0 10px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lab-bloc.est-valide { border-color: #2e6e4f; background: rgba(46,110,79,.08); }
.lab-bloc.est-ecarte { opacity: .55; }
.lab-bloc-actions { margin: 10px 0 8px; }
.lab-tag { padding: 1px 8px; border-radius: 99px; font-size: .72rem; font-weight: 800; background: rgba(46,110,79,.18); color: #2e6e4f; }
.lab-tag-hors { background: rgba(243,199,76,.35); color: #6b4e00; }
.lab-resume { color: var(--ink); }
.lab-existant span { flex: 1; }

/* Fiche joueur : ses messages */
.fi-msg-barre { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px; }
.fi-msg-onglet { color: var(--ink); border-color: rgba(28,23,18,.3); }
.fi-msg-onglet.est-actif { background: var(--ink); color: var(--parchment); }
.fi-msg-barre select { padding: 5px 8px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; }
.fi-msgs { list-style: none; margin: 0; padding: 0; max-height: 560px; overflow: auto; display: grid; gap: 8px; }
.fi-msg { padding: 8px 12px; border-radius: 10px; background: rgba(255,255,255,.35); border-left: 4px solid var(--ink-soft); color: var(--ink); }
.fi-msg.est-envoye { border-left-color: var(--rust-dark); }
.fi-msg.est-recu { border-left-color: #2e6e4f; background: rgba(46,110,79,.08); }
.fi-msg-tete { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; font-size: .88rem; }
.fi-msg-texte { margin-top: 4px; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.45; }
.fi-msg-texte .emo-zombie { height: 1.4em; vertical-align: -.3em; }
.fi-msg-pied { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; align-items: center; }
.fi-msg-tag { padding: 1px 8px; border-radius: 99px; font-size: .72rem; font-weight: 800; background: rgba(28,23,18,.1); }
.fi-msg-tag.est-masque { background: #8b8072; color: #fff; }
.fi-msg-tag.est-signale { background: #e0301e; color: #fff; }
.fi-msg-texte .emo-zombie { display: inline; }
.us-objet.est-doublon { opacity: .6; }

/* Journal des requêtes */
.jr-barre { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; }
.jr-tuiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 14px; }
.jr-heures { display: flex; align-items: flex-end; gap: 2px; height: 120px; padding: 4px; border-bottom: 2px solid var(--ink-soft); }
.jr-heure { flex: 1; height: 100%; display: flex; align-items: flex-end; min-width: 3px; }
.jr-heure i { display: block; width: 100%; background: #2e6e4f; border-radius: 2px 2px 0 0; }
.jr-heure i.est-lente { background: #e08a1e; }
.jr-heure i.est-erreur { background: #e0301e; }
.jr-php { white-space: pre-wrap; max-height: 360px; overflow: auto; font-size: .76rem; background: rgba(255,255,255,.5); padding: 10px; border-radius: 8px; color: var(--ink); }
.jr-axe { display: flex; justify-content: space-between; font-size: .75rem; color: var(--ink-soft); margin-top: 4px; }

/* Le menu en icônes, chacune avec son nom en dessous. */
.admin-menu { gap: 8px; }
.admin-menu .admin-onglet { position: relative; padding: 6px 4px 5px; border-radius: 14px; line-height: 1.1;
  display: flex; flex-direction: column; align-items: center; gap: 4px; width: 88px; }
.admin-onglet-icone { width: 46px; height: 46px; display: block; filter: drop-shadow(0 2px 2px rgba(0,0,0,.45)); transition: transform .12s ease; }
.admin-onglet:hover .admin-onglet-icone { transform: translateY(-2px) scale(1.06); }
.admin-onglet.est-actif .admin-onglet-icone { transform: scale(1.08); }
/* Une page dont le dessin n'existe pas encore : l'emoji de secours tient la
   place de l'icone, pour que le menu ne se deforme pas. */
.admin-onglet-icone.est-sans-image { display: grid; place-items: center; font-size: 1.7rem; filter: none; }
.admin-onglet-titre { display: block; max-width: 100%; font-size: .66rem; font-weight: 800; text-align: center;
  color: #E6D7BA; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-onglet.est-actif .admin-onglet-titre, .admin-onglet:hover .admin-onglet-titre { color: #fff; }
.admin-menu .admin-pastille { position: absolute; top: -6px; right: -6px; margin: 0; line-height: 1.5; box-shadow: 0 0 0 2px #17202A; }
@media (max-width: 600px) { .admin-onglet-icone { width: 36px; height: 36px; } .admin-menu .admin-onglet { width: 72px; } .admin-onglet-titre { font-size: .58rem; } }
.champ-prompt > span, .lab-champ > span { display: flex; align-items: center; gap: 8px; }
.champ-prompt textarea { width: 100%; padding: 8px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; font-size: .9rem; background: #fffdf8; color: var(--ink); }
.champ-prompt [data-copier], .lab-champ [data-copier] { padding: .15em .6em; font-size: .8rem; box-shadow: none; }
.lab-compte { margin-left: auto; }
.lab-cherche-ville { margin: 0 0 10px; } .lab-cherche-ville input { font-size: .88rem; }
.lab-piste { display: grid; gap: 4px; margin: 6px 0 4px; color: var(--ink); font-weight: 700; } .lab-piste textarea { width: 100%; padding: 8px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; font-weight: 500; background: #fffdf8; }
/* « Créer à la main » : le JSON collé d'une autre IA, en police fixe. */
.lab-import textarea { width: 100%; margin: 8px 0 4px; padding: 8px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: 500 .82rem/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; background: #fffdf8; color: var(--ink); resize: vertical; }
/* Un objet de triptyque : un clic ouvre sa fiche dans la page Objets. */
.hg-vers-objet { display: inline-flex; align-items: center; gap: 6px; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; border-radius: 8px; }
.hg-vers-objet:hover strong, .hg-vers-objet:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.hg-place.est-prise > .hg-vers-objet { flex: 1; min-width: 0; gap: 10px; }
.hg-place.est-prise > .hg-vers-objet > div { display: flex; flex-direction: column; min-width: 0; }

/* Lab : déposer les images avant ou après la validation */
.lab-depot { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; padding: 8px; border: 2px dashed rgba(28,23,18,.35); border-radius: 12px; cursor: pointer; background: rgba(255,255,255,.25); }
.lab-depot .rq-cadre { flex: none; }
.lab-depot.est-survol { border-color: var(--rust); background: rgba(224,48,30,.12); }
.lab-depot.est-envoi { opacity: .5; pointer-events: none; }
.lab-depot.a-image { border-style: solid; border-color: rgba(46,110,79,.6); }
.lab-relique-image { display: grid; gap: 4px; margin-bottom: 6px; }
.lab-existant { display: block; }
.lab-table td:last-child { white-space: nowrap; }
.lab-corbeille { margin-left: 6px; padding: 4px 8px; border: 2px solid transparent; border-radius: 8px; background: none; cursor: pointer; font-size: 1.05rem; line-height: 1; opacity: .6; }
.lab-corbeille:hover { opacity: 1; border-color: var(--rust-dark); background: rgba(224,48,30,.1); }
.lab-carte { height: 340px; margin: 12px 0 4px; border-radius: 12px; border: 2px solid var(--ink-soft); overflow: hidden; } .lab-carte .leaflet-tooltip { font-weight: 800; }
/* Présence dans la liste des joueurs */
.us-presence { display: inline-block; width: 10px; height: 10px; margin-right: 7px; border-radius: 50%; vertical-align: 1px; box-shadow: 0 0 0 2px rgba(255,255,255,.7); }
.us-presence.est-present { background: #2e9e5b; }
.us-presence.est-recent { background: #e08a1e; }
.us-presence.est-absent { background: #c0281b; }
.hg-carte { grid-column: 1 / -1; }
/* Le rapport Strava tenait deja sur plusieurs lignes ; les six regles aussi
   depuis qu'elles sont ecrites en paragraphes et en puces. L'apercu garde donc
   les sauts de ligne partout — sans quoi dix lignes s'affichaient en un seul
   pave, et on ne pouvait pas relire ce qu'on venait d'ecrire. */
.tx-apercu { white-space: pre-line; }
/* Lab : le bouton « Copier les 4 prompts d'images », tout en haut du triptyque. */
.lab-copier-tous { display: flex; justify-content: flex-end; margin-bottom: 6px; }
/* Message passager de l'admin (ex. faux damier retiré d'une image). */
.admin-toast { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 9999;
  padding: 10px 16px; border-radius: 10px; background: rgba(23,32,42,.95); color: #fff;
  font-weight: 700; box-shadow: 0 6px 18px rgba(0,0,0,.35); }
/* Un objet montré pour lui-même (pages Objets, Reliques, Lab) : l'image telle
   quelle, sans le cadre ni la teinte d'un état. */
.rq-n0 { background: rgba(255,255,255,.35); border: 1px solid rgba(28,23,18,.18); }

/* Changer la ville d'un joueur (admin, fiche) */
.cv-carte { max-width: 520px; display: grid; gap: 10px; }
.cv-carte h3 { margin: 0; }
.cv-recherche, #cv-mot { width: 100%; padding: 8px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; background: #fff; }
.cv-resultats { display: grid; gap: 4px; max-height: 40vh; overflow-y: auto; }
.cv-ville { text-align: left; padding: 7px 10px; border: 1.5px solid rgba(88,74,58,.35); border-radius: 8px; background: rgba(255,255,255,.7); font: inherit; cursor: pointer; }
.cv-ville:hover:not(:disabled) { border-color: var(--rust); background: #fff; }
.cv-ville:disabled { opacity: .5; cursor: default; }
.cv-choix { display: grid; gap: 8px; padding-top: 8px; border-top: 2px solid rgba(88,74,58,.3); }
.cv-choix .btn { justify-self: end; }

/* Message à tous les joueurs (admin, Messagerie) */
.df-panneau { margin-bottom: 14px; }
.df-panneau summary { cursor: pointer; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.df-form { display: grid; gap: 8px; margin-top: 10px; }
.df-form textarea { width: 100%; padding: 10px 12px; border: 2px solid var(--ink-soft); border-radius: 10px; font: inherit; resize: vertical; background: rgba(255,255,255,.8); }
.df-form .btn { justify-self: end; }
.df-case { font-size: .9rem; display: flex; gap: 6px; align-items: center; }
.df-ligne { padding: 8px 0; border-top: 1px solid rgba(88,74,58,.25); }
.df-ligne p { margin: 4px 0 0; white-space: pre-wrap; }
.nl-criteres { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 10px 14px; }
.nl-criteres label { display: grid; gap: 4px; font-size: .85rem; font-weight: 700; }
.nl-criteres select, .nl-criteres input, .nl-form > input { padding: 7px 9px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; font-weight: 400; background: rgba(255,255,255,.8); min-width: 0; }
.nl-ligne { display: flex; gap: 6px; align-items: center; font-weight: 400; }
.nl-ligne select { flex: 1 1 0; width: auto; min-width: 0; }
.nl-ligne input { flex: 0 0 64px; width: 64px; }
.nl-ligne input:disabled { opacity: .45; }
.nl-compte { margin: 2px 0; }
.nl-exemples summary { cursor: pointer; font-size: .85rem; }
.nl-exemples p { font-size: .85rem; }
.nl-boutons .btn-ghost { color: var(--ink); border: 2px solid var(--ink-soft); background: rgba(255,255,255,.55); }
.nl-boutons { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
.nl-campagne .btn { margin-left: 8px; }
.nl-texte { white-space: pre-wrap; font-size: .9rem; }


/* Journal, onglet « Activité du jour » : la journée horodatée. */
.jr-onglets { margin: 0 0 14px; }
.jr-onglets .rq-onglet { color: #E6D7BA; border-color: rgba(255,255,255,.25); background: rgba(255,255,255,.06); }
.jr-onglets .rq-onglet.est-actif { color: #fff; background: var(--rust); border-color: var(--rust-dark); }
.act-date { padding: 4px 8px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; background: #fffdf8; color: var(--ink); }
.act-titre { color: var(--ink); text-transform: capitalize; }
.act-filtres { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 12px 0; }
.act-puce { font: inherit; font-size: .8rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; border: 2px solid var(--ink-soft);
  background: #fffdf8; color: var(--ink); cursor: pointer; }
.act-puce.est-actif { background: var(--rust); border-color: var(--rust-dark); color: #fff; }
.act-cherche { flex: 1; min-width: 180px; padding: 5px 10px; border: 2px solid var(--ink-soft); border-radius: 8px; font: inherit; background: #fffdf8; }
.act-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.act-ligne { display: grid; grid-template-columns: 70px 26px 1fr; gap: 6px; align-items: baseline; padding: 5px 6px; border-radius: 6px; color: var(--ink); font-size: .88rem; }
.act-ligne:nth-child(odd) { background: rgba(255,255,255,.4); }
.act-ligne time { font-family: ui-monospace, monospace; font-size: .8rem; color: var(--ink-soft); }
.act-ligne a { color: inherit; }
.act-pillage, .act-signalement { background: rgba(217,59,38,.10) !important; }
.act-objet .act-texte b { color: var(--rust-dark); }

.rq-decouvertes { margin-top: 14px; }

/* Journal → Santé */
.sn-note { margin-top: 8px; }
.sn-titre { margin: 0; }
.sn-jauge { height: 18px; border: 3px solid var(--ink); border-radius: 99px; background: rgba(255,255,255,.5); overflow: hidden; }
.sn-jauge i { display: block; height: 100%; background: #2e6e4f; }
.sn-jauge i.est-lente { background: #e08a1e; }
.sn-jauge i.est-erreur { background: #e0301e; }
.sn-jauge-texte { margin: 6px 0 12px; }
.sn-controles { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }
.sn-controle { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; border-radius: 10px; background: rgba(255,255,255,.45); }
.sn-pastille { flex: none; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; font-weight: 900; color: #fff; background: #8b8072; }
.sn-controle.est-ok .sn-pastille { background: #2e6e4f; }
.sn-controle.est-rate .sn-pastille { background: #e0301e; }

/* Admin, notifications : qui les a activées, qui non (l'une sous l'autre). */
.ps-qui { display: grid; gap: 4px; }
.ps-qui > div { min-width: 0; overflow-x: auto; }

/* Admin › Statistiques, « Aujourd'hui » : sur un écran étroit, seulement le
   joueur et son nombre d'ouvertures (le tableau débordait sur le côté). */
@media (max-width: 640px) {
  .st-jour .st-large { display: none; }
  .us-table.st-jour, .us-table.st-jours { min-width: 0; width: 100%; }
  .us-table.st-jours th, .us-table.st-jours td { padding-left: 4px; padding-right: 4px; }
  .us-table.st-jours th { font-size: .68rem; letter-spacing: 0; }
}

/* Admin › Joueurs : l'appareil sur lequel il joue, devant le pseudo. */
.us-plateforme { display: inline-block; width: 16px; height: 16px; margin: 0 6px 0 2px; vertical-align: -2px; }
.us-plateforme.est-vide { opacity: 0; }

.us-appareils { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 0 0 10px; }
.us-appareil { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-weight: 700; color: var(--ink);
  padding: 4px 10px 4px 6px; border: 2px solid rgba(65, 42, 20, .3); border-radius: 999px; background: rgba(255, 255, 255, .35); }
.us-appareil input { margin: 0; accent-color: var(--rust); }
.us-appareil.est-decoche { opacity: .5; }
.us-appareil.est-decoche img { filter: grayscale(1); }

/* Lab : une ville choisie qui est déjà dans un triptyque. */
.lab-puce.est-en-triptyque { background: #B3261E; }
.lab-deja { flex-basis: 100%; margin-top: 4px; color: #8A1C14; font-size: .92rem; }
.lab-deja p { margin: 2px 0; }
.lab-deja-ville { color: #B3261E; }

/* ---------------------------------------------------------------------------
   15. « Pourquoi ce jeu existe » (medicale.html)
   Une variante de l'accueil : meme decor, meme hero, mais elle plaide au lieu
   de raconter. Chaque chiffre porte sa source — une page qui parle de sante et
   cite mal ne vaut rien.
   --------------------------------------------------------------------------- */
.med-hero { min-height: min(78vh, 700px); }
.med-titre {
  margin: 0 0 6px;
  font-family: var(--display); font-weight: 400; letter-spacing: .03em;
  font-size: clamp(2.1rem, 7vw, 4rem); line-height: 1.02;
  color: var(--cream); text-shadow: 0 4px 0 rgba(0,0,0,.6);
}
.med-hero .hero-tagline { margin-bottom: 18px; }
.med-chapo {
  max-width: 44em; margin: 0 auto 26px;
  font-size: clamp(1rem, 2.4vw, 1.18rem); font-weight: 600; line-height: 1.55;
  color: #E7DDCE; text-shadow: 0 2px 6px rgba(0,0,0,.85);
}
.med-chapo strong { color: #FFD27A; }

.med-section { padding: 64px 0; background: var(--night-2); }
.med-section-sombre { background: linear-gradient(180deg, var(--night), var(--night-2)); }
.med-intro {
  max-width: 48em; margin: 0 auto 26px; text-align: center;
  font-size: 1.05rem; font-weight: 600; color: #DCD2C4;
}

/* Les quatre chiffres du constat : un parchemin chacun, le nombre d'abord. */
.med-chiffres {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 18px;
}
.med-chiffre { padding: 20px 20px 16px; display: grid; align-content: start; gap: 8px; }
.med-chiffre b {
  font-family: var(--display); font-weight: 400; letter-spacing: .02em;
  font-size: clamp(2.2rem, 6vw, 2.9rem); line-height: 1; color: var(--rust-dark);
}
.med-chiffre p { margin: 0; font-size: .98rem; line-height: 1.45; color: var(--ink); }
.med-chiffre small { font-size: .78rem; font-weight: 700; font-style: italic; color: var(--ink-soft); }

.med-texte { max-width: 54em; margin: 0 auto; padding: 26px 28px; color: var(--ink); }
.med-texte p { margin: 0 0 1em; line-height: 1.55; }
.med-texte p:last-child { margin-bottom: 0; }
.med-texte .lead { font-size: 1.28rem; font-weight: 800; color: var(--rust-dark); }
.med-texte .warning {
  margin: 0; font-family: var(--condensed); font-style: italic; font-weight: 800;
  font-size: 1.3rem; color: var(--rust-dark);
}
.med-nuance {
  padding: 14px 16px; border-left: 4px solid var(--rust);
  border-radius: 0 8px 8px 0; background: rgba(0,0,0,.05); font-size: .97rem;
}

.med-promesse { max-width: 54em; margin: 0 auto 18px; padding: 24px 28px; color: var(--ink); }
.med-promesse:last-child { margin-bottom: 0; }
.med-promesse h3 {
  display: flex; align-items: center; gap: 10px; margin: 0 0 12px;
  font-family: var(--display); font-weight: 400; letter-spacing: .03em;
  font-size: clamp(1.3rem, 3.6vw, 1.75rem); line-height: 1.1; color: var(--rust-dark);
}
.med-promesse-ico { font-size: 1.5rem; font-style: normal; }
.med-promesse p { margin: 0 0 1em; line-height: 1.55; }
/* L'aveu : ce que les etudes ne disent PAS. C'est ce bloc qui rend le reste
   croyable, donc il se voit autant que les chiffres. */
.med-honnete {
  margin-bottom: 0; padding: 14px 16px; border-radius: 8px;
  background: rgba(0,0,0,.06); font-size: .95rem;
}
.med-honnete b { color: var(--rust-dark); }

.med-fin { max-width: 780px; }
.med-fin .hero-cta { margin-bottom: 28px; }
.med-avertissement {
  max-width: 54em; margin: 0 auto 34px; padding: 14px 16px;
  border: 2px dashed #3C5265; border-radius: var(--radius);
  font-size: .92rem; line-height: 1.5; color: #C7BCAD;
}
.med-avertissement b { color: var(--cream); }
.med-sign-sources { margin-top: 10px; }
.med-sources { margin: 0; padding-left: 1.3em; color: #C7BCAD; font-size: .9rem; }
.med-sources li { margin: 8px 0; line-height: 1.45; }
.med-sources a { color: #FFD27A; }

@media (max-width: 680px) {
  .med-section { padding: 44px 0; }
  .med-texte, .med-promesse { padding: 20px 18px; }
}

/* ---------------------------------------------------------------------------
   16. L'accueil avoue (index.html, section « Alors pourquoi des zombies ? »)
   La page raconte une invasion pendant cinq ecrans, puis elle dit la verite.
   L'aveu N'EST PAS un repentir : c'est l'argument de vente. Les chiffres sont
   vrais, les zombies non, et c'est exactement le propos. Les cartes des
   chiffres reutilisent `.med-chiffres` de medicale.html — un seul dessin.
   --------------------------------------------------------------------------- */
.hero-verite {
  max-width: 32em; margin: -16px auto 26px;
  font-family: var(--condensed); font-style: italic; font-weight: 800;
  font-size: clamp(1.05rem, 3vw, 1.5rem); line-height: 1.25;
  color: #E7DDCE; text-shadow: 0 2px 6px rgba(0,0,0,.9);
}
.hero-verite strong { color: #FF5A40; }

.verite { padding: 72px 0 0; background: var(--night-2); }
.verite-texte { max-width: 54em; margin: 0 auto 36px; padding: 26px 28px; color: var(--ink); }
.verite-texte p { margin: 0 0 1em; line-height: 1.55; }
.verite-texte p:last-child { margin-bottom: 0; }
.verite-texte .lead { font-size: 1.3rem; font-weight: 800; color: var(--rust-dark); }
.verite-marche {
  padding: 14px 16px; border-left: 4px solid var(--rust);
  border-radius: 0 8px 8px 0; background: rgba(0,0,0,.06);
}
/* La meme pancarte, en plus petit : elle annonce un bloc, pas une section.
   Les rivets de `.sign span` sont poses a 10 px des bords : a cette taille le
   texte tenait sur une ligne et leur passait dessus. On elargit la reserve
   laterale pour qu'il revienne a la ligne avant de les atteindre. */
.sign-mini { font-size: clamp(1.15rem, 3.4vw, 1.6rem); margin-bottom: 22px; }
.sign-mini span { padding-left: 1.75em; padding-right: 1.75em; }
.verite-pointe {
  max-width: 40em; margin: 20px auto 0; text-align: center;
  font-family: var(--condensed); font-style: italic; font-weight: 800;
  font-size: clamp(1.05rem, 2.8vw, 1.35rem); color: #DCD2C4;
}
/* Le bandeau de l'aveu. Volontairement sombre : la devise juste au-dessus est
   rouge, deux bandes de la meme couleur se seraient annulees. */
.verite-aveu {
  margin: 48px 0 0; padding: 40px var(--gutter);
  background: var(--ink); border-block: 3px solid var(--rust);
  text-align: center; color: var(--cream);
  font-family: var(--condensed); font-style: italic; font-weight: 800;
  font-size: clamp(1.15rem, 3.4vw, 1.9rem); line-height: 1.3;
}
.verite-aveu span { color: var(--rust-light); }
.verite-pied { padding-top: 28px; padding-bottom: 48px; text-align: center; }

/* L'accueil seulement (`.verite`) : medicale.html garde ses tuiles telles
   quelles. Le grand parchemin porte le coureur à droite, les quatre chiffres
   leur emblème en tête — tous sur ::after, le ::before étant la texture. */
.verite .verite-texte {
  max-width: 1080px; min-height: 380px;
  padding: 10px 41% 12px 18px;
}
.verite .verite-texte::after {
  content: ""; position: absolute; right: -6px; top: -6px; bottom: -6px; width: 40%;
  background: url(/assets/img/accueil/verite-coureur.webp?v=c6dcd597) left center / cover no-repeat;
}
.verite .verite-texte .lead {
  margin-bottom: .45em;
  font-size: clamp(1.6rem, 3vw, 2.15rem); line-height: 1.1; font-weight: 800; color: #B21F17;
}
.verite .verite-texte p { font-size: 1.06rem; }
.verite .verite-marche {
  position: relative; margin-top: 1.3em;
  padding: 16px 18px 16px 76px;
  border: 2px solid rgba(107,74,37,.4); border-left: 0; border-radius: 0 8px 8px 0;
  background: rgba(255,246,224,.38);
  box-shadow: 0 4px 10px rgba(60,35,10,.18), inset 0 1px 0 rgba(255,255,255,.5);
}
/* Le signet rouge et sa basket, accrochés au bord gauche de l'encart. */
.verite .verite-marche::before {
  content: ""; position: absolute; left: 12px; top: -8px; width: 48px; height: 96px;
  background:
    url(/assets/img/accueil/basket.webp?v=be7e5bc8) center 40% / 38px auto no-repeat,
    linear-gradient(180deg, #D7362A, #A81D15);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 84%, 0 100%);
  filter: drop-shadow(0 3px 2px rgba(0,0,0,.35));
}
.verite .verite-marche strong { color: #B21F17; font-weight: 800; font-size: 1.12em; }

.verite .med-chiffres { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; }
.verite .med-chiffre {
  padding: 104px 4px 6px; gap: 8px; text-align: center;
  grid-template-rows: auto 1fr auto;
}
.verite .med-chiffre::after {
  content: ""; position: absolute; left: 50%; top: -4px; width: 150px; height: 104px; margin-left: -75px;
  background: var(--embleme) center / contain no-repeat;
}
.verite .med-chiffre:nth-child(1) { --embleme: url(/assets/img/accueil/chiffre-monde.webp?v=a036b9e1); }
.verite .med-chiffre:nth-child(2) { --embleme: url(/assets/img/accueil/chiffre-tombe.webp?v=adda8fd6); }
.verite .med-chiffre:nth-child(3) { --embleme: url(/assets/img/accueil/chiffre-reveil.webp?v=dc862379); }
.verite .med-chiffre:nth-child(4) { --embleme: url(/assets/img/accueil/chiffre-sante.webp?v=df39812f); }
.verite .med-chiffre b { font-size: clamp(2.4rem, 5vw, 3rem); color: #8E1B10; text-shadow: 0 2px 0 rgba(255,255,255,.4); }
.verite .med-chiffre p { text-align: center; hyphens: manual; -webkit-hyphens: manual; }
.verite .med-chiffre small {
  justify-self: center; margin-top: 4px; padding: 3px 14px;
  border: 1px solid rgba(107,74,37,.35); border-radius: 4px;
  background: rgba(140,99,52,.16);
}

@media (max-width: 760px) {
  .verite { padding-top: 48px; }
  .verite .verite-texte { min-height: 0; padding: 236px 4px 6px; }
  .verite .verite-texte::after { left: -6px; right: -6px; top: -6px; bottom: auto; width: auto; height: 236px; background-position: center 30%; }
  /* Justifié sur une colonne si étroite, le texte se creusait de trous. */
  .verite .verite-texte .verite-marche { padding-left: 68px; text-align: left; hyphens: manual; -webkit-hyphens: manual; }
}

/* Les deux tresors du classement, cites dans le texte de l'accueil : la meme
   pastille que dans le jeu — 🏺 une relique (un triptyque reuni), ⚱ un objet
   rapporte d'une commune. `font-style: normal` en ceinture : les polices
   d'emoji n'ont pas de face italique, et le navigateur en fabrique une en
   cisaillant le glyphe. */
.tresor { font-style: normal; font-weight: 400; font-size: .95em; line-height: 1; }

/* Une ville sous bouclier : barre pleine, mais verte — elle est protegee, pas
   perdue. Meme gabarit que les trois niveaux de menace, pour que la grille
   garde des cartes de meme hauteur. */
.threat[data-level="shield"] .threat-bar i { background: var(--defend); }
.threat[data-level="shield"] .threat-label b { color: #1C4A33; }

/* ---------------------------------------------------------------------------
   17. Les dernieres trouvailles (index.html, sous la carte)
   Ce que le jeu produit vraiment, avec le nom de qui l'a rapporte. Le cadre
   de chaque tuile porte l'etat de l'objet — meme palette que la Forge, de
   l'Use (rouille) au Legendaire (or).
   --------------------------------------------------------------------------- */
.trouvailles { padding: 64px 0; background: var(--night-2); }
.trouvailles-intro {
  max-width: 44em; margin: 0 auto 26px; text-align: center;
  font-size: 1rem; font-weight: 600; color: #DCD2C4;
}
.trouvailles-liste {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 14px;
}
.trouvaille {
  display: flex; align-items: center; gap: 12px;
  padding: 0 4px;
}
.trouvaille-tuile {
  flex: none; width: 60px; height: 60px; display: grid; place-items: center;
  border: 2px solid var(--cadre, #6b4a2b); border-radius: 10px;
  background: rgba(0,0,0,.12); overflow: hidden;
}
.trouvaille-tuile img { width: 100%; height: 100%; object-fit: contain; }
.trouvaille-tuile i { font-style: normal; font-size: 1.6rem; opacity: .5; }
/* Les cinq etats de la Forge, memes teintes que `.rq-n1` a `.rq-n5` du jeu. */
.trouvaille[data-n="1"] { --cadre: #6b4a2b; }
.trouvaille[data-n="2"] { --cadre: #c07a3e; }
.trouvaille[data-n="3"] { --cadre: #c9d1d9; }
.trouvaille[data-n="4"] { --cadre: #a66bf0; }
.trouvaille[data-n="5"] { --cadre: #f2c94c; }
.trouvaille-dit { display: grid; gap: 2px; min-width: 0; color: var(--ink); }
.trouvaille-dit > b {
  font-family: var(--display); font-weight: 400; letter-spacing: .02em;
  font-size: 1.15rem; line-height: 1.12; color: var(--rust-dark);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.trouvaille-dit small { font-size: .78rem; font-weight: 600; color: var(--ink-soft); }
.trouvaille-dit small b { color: var(--ink); font-weight: 800; }
.trouvaille-dit small.trouvaille-etat { font-weight: 800; color: var(--ink); }

/* ---------------------------------------------------------------------------
   18. La fiche publique d'une commune (ville.html)
   Son rang, son palmares, ses triptyques, et ses semaines une par une.
   Les tuiles d'objets reprennent `.trouvaille` de l'accueil — un seul dessin.
   --------------------------------------------------------------------------- */
.city-rang, .city-palmares {
  margin: 12px 0 0; padding: 10px 12px; border-radius: 10px;
  background: rgba(0,0,0,.06); font-size: .92rem; line-height: 1.45; color: var(--ink);
}
.city-rang b, .city-palmares b { color: var(--rust-dark); }
.city-rang sup { font-size: .62em; }
.city-sous-titre {
  margin: 18px 0 8px; font-family: var(--display); font-weight: 400;
  letter-spacing: .03em; font-size: 1.3rem; color: var(--rust-dark);
}

/* Les triptyques reunis : la tuile, le nom, l'etat. Le cadre porte l'etat,
   comme dans la Forge. */
.triptyques { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.triptyques li { display: flex; align-items: center; gap: 12px; }
.triptyque-tuile {
  flex: none; width: 54px; height: 54px; display: grid; place-items: center;
  border: 3px solid var(--cadre, #6b4a2b); border-radius: 10px;
  background: rgba(0,0,0,.12); overflow: hidden;
}
.triptyque-tuile img { width: 100%; height: 100%; object-fit: contain; }
.triptyque-tuile i { font-style: normal; font-size: 1.4rem; opacity: .55; }
.triptyques li[data-n="1"] { --cadre: #6b4a2b; }
.triptyques li[data-n="2"] { --cadre: #c07a3e; }
.triptyques li[data-n="3"] { --cadre: #c9d1d9; }
.triptyques li[data-n="4"] { --cadre: #a66bf0; }
.triptyques li[data-n="5"] { --cadre: #f2c94c; }
.triptyques b { display: block; font-size: 1rem; color: var(--ink); }
.triptyques small { font-size: .8rem; font-weight: 700; color: var(--ink-soft); }

/* Les semaines passees, une a la fois : deux chevrons et un cadre. Le tableau
   d'avant les alignait toutes, et une ville qui joue depuis trois mois
   deroulait quinze lignes que personne ne lisait. */
.wk-pager { display: grid; gap: 10px; }
.wk-nav { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.wk-nav .wk-quand { margin: 0; font-weight: 800; font-size: .95rem; color: var(--ink); text-align: center; }
.wk-nav .btn[disabled] { opacity: .4; cursor: default; }
.wk-carte {
  padding: 12px 14px; border: var(--border); border-radius: var(--radius);
  background: rgba(0,0,0,.05);
}
.wk-chiffres { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.wk-chiffres dt { font-size: .72rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-soft); }
.wk-chiffres dd { margin: 2px 0 0; font-family: var(--display); font-weight: 400;
  font-size: 1.5rem; line-height: 1; color: var(--ink); }
.wk-issue-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 12px 0 0; }
.wk-issue-ligne small { font-size: .8rem; font-weight: 600; color: var(--ink-soft); }
.wk-compte { margin: 0; text-align: center; font-size: .78rem; font-weight: 700; color: var(--ink-soft); }

/* ---------------------------------------------------------------------------
   19. Le tableau de bord de l'administration
   Quatre rangees, chacune repondant a une question : combien, qui joue, ou en
   est le monde, et qu'est-ce qui attend une decision.
   --------------------------------------------------------------------------- */
.admin-chiffres {
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-bottom: 4px;
}
.admin-sous-titre {
  margin: 20px 0 8px;
  font-family: var(--display); font-weight: 400; letter-spacing: .03em;
  font-size: 1.2rem; color: var(--rust-dark);
}
/* Un chiffre qui demande une action. A zero il reste neutre : une bonne
   nouvelle ne doit pas crier aussi fort qu'un probleme. */
.admin-chiffres .est-alerte {
  border-color: var(--rust); background: rgba(224,48,30,.1);
}
.admin-chiffres .est-alerte dd { color: var(--rust-dark); }
/* Une tuile qui mene a sa page. Ce n'est pas un <button> : un <dl> n'accepte
   que des <div> de <dt>/<dd>, le clavier est donc gere en JS. */
.admin-chiffres .est-cliquable { cursor: pointer; transition: transform .1s ease, box-shadow .1s ease; }
.admin-chiffres .est-cliquable:hover,
.admin-chiffres .est-cliquable:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 2px 0 rgba(88,74,58,.35);
  border-color: var(--rust);
}
.admin-chiffres .est-cliquable dt::after { content: ' ›'; color: var(--rust-dark); font-weight: 900; }
.admin-note b { color: var(--ink); }

/* ---------- Justification des panneaux de prose ----------
   Les paragraphes longs des panneaux parchemin sont justifies : le bord droit
   en dents de scie sautait aux yeux dans ces cadres etroits. On n'y touche
   que pour de la prose (pas les tuiles de chiffres : trop étroites dans
   leur parchemin, la justification y creusait des trous) : pas les titres, pas les boutons, pas les tuiles de
   chiffres ni les devises, qui restent centres.
   hyphens: auto est indispensable ici. Justifier sans cesure etire les
   espaces entre les mots et creuse des rivieres blanches dans la colonne ;
   la cesure rend la main au navigateur. Elle n'agit que si la langue est
   declaree, et les pages du site portent bien <html lang="fr">. */
.rule > p:not(.a-icone),
.verite-texte p,
.med-texte p {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* Admin → Tests */
.ts-table td { vertical-align: top; }
.ts-table tr.ts-rate td { background: rgba(224,48,30,.08); }
.ts-url { font-size: .76rem; color: var(--ink-soft); word-break: break-all; }
.ts-plier { margin-top: 12px; }
.ts-plier > summary { cursor: pointer; font-weight: 700; color: var(--ink); padding: 4px 0; }
.ts-ecartes { margin: 8px 0 0; padding-left: 18px; color: var(--ink); font-size: .9rem; }
.ts-ecartes li { margin: 3px 0; }

/* Le parchemin déchiré porte déjà 21 px de bordure : les panneaux qui
   avaient leur propre marge intérieure la reprennent d'autant, sinon le
   texte flotte au milieu d'un grand vide. Deux classes : `.parchment` seule
   ne battrait pas la règle propre de chaque panneau, écrite plus haut. */
.parchment.city-hero { padding: 6px 8px; }
.parchment.city-section { padding: 2px 4px; }
.parchment.admin-panneau { padding: 2px 4px; }
.parchment.mdp-panneau { padding: 2px 2px; }
.parchment.med-texte { padding: 6px 8px; }
.parchment.med-promesse { padding: 4px 8px; }
@media (max-width: 680px) {
  .parchment.city-hero, .parchment.med-texte, .parchment.med-promesse { padding: 2px 0; }
}
/* « Ma commune » est un bouton fantôme, écrit en crème pour la barre du
   haut : posé sur le parchemin de l'inscription, il ne se lisait plus. */
.modal-card .field-with-action .btn-ghost { color: var(--rust-dark); }

/* ---------- Les dessins de l'histoire, placés comme sur le croquis ----------
   Les dessins restent DANS le parchemin, sauf la Terre, qui déborde vers le
   haut (pas sur le côté). Ils passent derrière le texte (z-index -1 dans le
   panneau, au-dessus de la texture qui vient avant eux) : la horde du
   dimanche est un fond à droite du paragraphe, et le texte mord un peu
   dessus, comme sur le croquis. */
.pitch-cartes > p.pitch-carte::after { z-index: -1; }
@media (min-width: 761px) {
  /* De la place à gauche pour la Terre, qui déborde un peu de ce côté. */
  .pitch-cartes { gap: 30px; padding-left: 14px; }
  .pitch-cartes > p.pitch-carte::after { left: -6px; top: -8px; bottom: -8px; width: calc(37% - 6px); }
  /* Le coureur, grand, la tête qui dépasse du parchemin en haut. */
  .pitch-cartes > p.pitch-carte:nth-child(1)::after {
    left: auto; right: -12px; top: -44px; bottom: -16px; width: 55%;
    background-size: contain; background-position: right bottom;
  }
  /* Le panneau à gauche, la horde en fond à droite, sur toute la hauteur. */
  .pitch-cartes > p.pitch-carte:nth-child(3) { padding-right: 29%; }
  /* La horde (horde-coin.webp : déjà fondue à droite et en bas) est collée
     dans le coin bas-droit, jusqu'au bord de la texture (-17 px). */
  .pitch-cartes > p.pitch-carte:nth-child(3)::after {
    left: -6px; right: -17px; top: -14px; bottom: -17px; width: auto;
    background:
      url(/assets/img/accueil/dimanche.webp?v=9f49cb71) left 6px center / 33% auto no-repeat,
      url(/assets/img/accueil/horde-coin.webp?v=7a564a92) right bottom / 36% auto no-repeat;
  }
  .pitch-cartes > p.pitch-carte:nth-child(5)::after { width: calc(46% - 8px); }
  /* La Terre déborde vers le haut, et seulement vers le haut. */
  .pitch-cartes > p.pitch-carte:nth-child(6) { margin-top: 16px; }
  /* La Terre, grande et centrée dans sa place : elle déborde un peu à gauche et en haut. */
  .pitch-cartes > p.pitch-carte:nth-child(6)::after { left: -40px; top: -46px; bottom: -14px; width: calc(37% + 30px); background-position: center; }
}
@media (max-width: 760px) {
  .pitch-cartes { gap: 30px; }
  .pitch-cartes > p.pitch-carte:nth-child(n)::after { top: -8px; left: -4px; right: -4px; height: 180px; }
  .pitch-cartes > p.pitch-carte:nth-child(5)::after { height: 120px; }
  .pitch-cartes > p.pitch-carte:nth-child(6)::after { top: -44px; height: 216px; }
  /* Le coureur : entier (contain, pas cover, qui lui coupait la tête), posé
     en bas de sa place, la tête qui dépasse du parchemin comme sur ordinateur. */
  .pitch-cartes > p.pitch-carte:nth-child(1) { margin-top: 40px; padding-top: 172px; }
  .pitch-cartes > p.pitch-carte:nth-child(1)::after {
    top: -58px; height: 228px; left: -10px; right: -10px;
    background-size: contain; background-position: center bottom;
  }
}

/* ---------- Les règles, d'après la maquette « Les règles sont simples » ----------
   L'habillage est posé par `habillerRegles()` (site.js) sur le texte du
   serveur : dessin en tête, une icône par ligne (--ico), tons du dimanche. */
.rules .rule { padding: 4px 6px 6px; }
.rules .rule-icon { margin: -6px 0 2px; }
.rules .rule-dessin { display: block; width: 100%; max-width: 250px; height: 112px; margin: 0 auto; object-fit: contain; filter: drop-shadow(0 4px 4px rgba(60,30,10,.25)); }
.rules .rule h3 { font-size: clamp(1.6rem, 2.4vw, 2rem); color: #B21F17; text-shadow: 0 2px 0 rgba(255,255,255,.45); margin-bottom: 6px; }
.rules .rule p, .rules .rule ul { font-size: .95rem; line-height: 1.42; }
.rules .rule > p:first-of-type { text-align: left; hyphens: manual; -webkit-hyphens: manual; }
/* Le numéro : le rond rouge dessiné, plus le cercle CSS. */
.rules .rule::after {
  top: -38px; right: -12px; width: 50px; height: 50px;
  background: url(/assets/img/regles/pastille.webp?v=a9f7bef8) center / contain no-repeat;
  border: 0; font-size: 1.65rem; text-shadow: 0 2px 0 rgba(0,0,0,.45);
}
.rules .rule ul { padding-left: 0; list-style: none; }
.rules .rule ul > li:not(.a-icone) { list-style: disc; margin-left: 1.15em; }
/* Une ligne à icône : l'icône dans la marge gauche, le texte à côté. */
.rules .rule .a-icone {
  position: relative; min-height: 36px;
  padding-left: 46px; margin-bottom: .6em;
  text-align: left; hyphens: manual; -webkit-hyphens: manual;
}
.rules .rule .a-icone::before {
  content: ""; position: absolute; left: 0; top: 0; width: 36px; height: 36px;
  background: var(--ico) center / contain no-repeat;
}
/* Les tons : les issues du dimanche, l'encart d'alerte, l'encart final. */
.rules .rule .a-icone[class*="ton-"] { padding: 7px 10px 7px 50px; border-radius: 8px; margin-bottom: 6px; }
.rules .rule .a-icone[class*="ton-"]::before { left: 8px; top: 50%; margin-top: -16px; width: 32px; height: 32px; }
.rules .rule .ton-vert   { background: rgba(120, 165, 60, .26); }
.rules .rule .ton-jaune  { background: rgba(240, 190, 70, .30); }
.rules .rule .ton-orange { background: rgba(240, 150, 70, .24); }
.rules .rule .ton-rouge  { background: rgba(214, 50, 42, .34); }
.rules .rule .ton-alerte { background: rgba(224, 48, 30, .14); border: 1px solid rgba(178, 31, 23, .3); margin-top: .8em; }
.rules .rule .ton-encart { background: rgba(255, 246, 224, .45); border: 1px solid rgba(107, 74, 37, .35); font-size: .88rem; margin-top: .8em; }
/* Les chiffres en gras : surlignés, comme sur la maquette. */
.rules .rule b.pastille {
  padding: 0 .3em; border-radius: 4px;
  background: rgba(240, 190, 90, .5);
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
/* Les cinq paliers d'objets : un petit tableau en cases, l'objet au milieu. */
.rules .rule .gab-tableau.est-couche {
  width: 100%; table-layout: fixed; margin: 4px 0 10px;
  border: 1px solid rgba(107, 74, 37, .35); border-radius: 8px; border-collapse: separate; border-spacing: 0;
  background: rgba(255, 246, 224, .4); font-size: .8rem;
}
.rules .rule .gab-tableau.est-couche td { padding: 6px 2px 4px; text-align: center; white-space: normal; border-left: 1px solid rgba(107, 74, 37, .2); }
.rules .rule .gab-tableau.est-couche td:first-child { border-left: 0; }
.rules .rule .gab-tableau.est-couche tr + tr td { padding-top: 0; font-weight: 700; }
.rules .rule .rule-objet { display: block; width: 34px; height: 30px; margin: 0 auto 2px; object-fit: contain; }

/* ---------- Le choix de la langue (lang.js) ----------
   Deux drapeaux dessinés en SVG : les drapeaux en emoji ne s'affichent pas
   sous Windows (on y lit « FR » et « GB »). */
.langue { display: flex; align-items: center; gap: 6px; flex: none; }
.langue-choix {
  display: block; width: 26px; height: 18px; border-radius: 3px; overflow: hidden;
  opacity: .5; box-shadow: 0 0 0 1px rgba(255,255,255,.35);
  transition: opacity .12s ease, transform .12s ease;
}
.langue-choix svg { display: block; width: 100%; height: 100%; }
.langue-choix:hover, .langue-choix:focus-visible { opacity: 1; transform: translateY(-1px); }
.langue-choix.est-active { opacity: 1; box-shadow: 0 0 0 2px var(--cream); }
@media (max-width: 720px) { .langue { margin-left: auto; } }
/* Les noms de rareté sont plus longs en anglais (« Exceptional ») : la
   rangée du bas se serre un peu pour qu'aucun ne se coupe en deux. */
.rules .rule .gab-tableau.est-couche tr + tr td { font-size: .7rem; letter-spacing: -.01em; overflow-wrap: normal; hyphens: manual; }
.legal-note { font-size: .92rem; opacity: .85; }

/* La barre de l'administration : le bouton de la page où l'on est, enfoncé. */
.topbar-auth .btn.est-ici { box-shadow: inset 0 2px 4px rgba(0,0,0,.35); transform: none; opacity: .9; cursor: default; }
.admin-badge { display: inline-flex; align-items: center; gap: 8px; }
.admin-sortir {
  display: grid; place-items: center; width: 22px; height: 22px; padding: 0;
  border: 0; border-radius: 50%; cursor: pointer;
  font: inherit; font-size: .75rem; line-height: 1;
  color: #F1E4C8; background: rgba(255,255,255,.14);
}
.admin-sortir:hover, .admin-sortir:focus-visible { background: var(--rust); color: #fff; }
/* Sur un téléphone, le pseudo s'efface ; la croix reste. */
@media (max-width: 720px) { .admin-body #admin-qui { display: none; } }

/* ---------- Les chiffres du jeu, au-dessus de « Se connecter » ---------- */
.hero-chiffres {
  display: inline-flex; align-items: stretch; margin: 18px auto 0; padding: 0;
  background: rgba(12, 18, 24, .72);
  border: 2px solid #C89B5E; border-radius: 12px;
  box-shadow: 0 4px 0 rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.08);
  backdrop-filter: blur(2px);
}
.hero-chiffres > div { display: flex; flex-direction: column-reverse; align-items: center; padding: 8px 20px 7px; }
.hero-chiffres > div + div { border-left: 1px dashed rgba(200, 155, 94, .6); }
.hero-chiffres dd {
  margin: 0; font-family: var(--display); font-size: clamp(1.5rem, 3vw, 1.9rem); line-height: 1;
  letter-spacing: .03em; color: #FFD27A; text-shadow: 0 2px 0 rgba(0,0,0,.6);
}
/* « 3 571 km » : l'unite colle au nombre, en plus petit ; l'etiquette
   dessous n'a plus a la porter. */
.hero-chiffres dd small { margin-left: .14em; font-size: .55em; letter-spacing: .02em; }
.hero-chiffres dt { margin-top: 3px; font-size: .78rem; font-weight: 700; color: #E9DCC6; text-transform: uppercase; letter-spacing: .05em; }
.hero-chiffres + .hero-connexion { margin-top: 12px; }
@media (max-width: 420px) { .hero-chiffres > div { padding: 7px 12px 6px; } .hero-chiffres dt { font-size: .68rem; } }

/* ---------- Le compte, en haut à droite : portrait, pseudo, croix ----------
   Partout pareil (site.js sur l'accueil et la page d'une ville, barre.js
   ailleurs). La croix déconnecte. */
.compte-pill { display: inline-flex; align-items: center; gap: 2px; padding-right: 6px; border-radius: 999px; background: rgba(255,255,255,.06); }
.compte-pill .btn-ghost { padding-right: .35em; }
.compte-sortir {
  display: grid; place-items: center; flex: none; width: 22px; height: 22px; padding: 0;
  border: 0; border-radius: 50%; cursor: pointer;
  font: inherit; font-size: .72rem; font-weight: 800; line-height: 1;
  color: #F1E4C8; background: rgba(255,255,255,.14);
}
.compte-sortir:hover, .compte-sortir:focus-visible { background: var(--rust); color: #fff; }
.topbar-auth a.btn { text-decoration: none; }
@media (max-width: 720px) { .compte-pill .btn-ghost > span:not(.avatar) { display: none; } }


/* --- Admin, page MAJ ------------------------------------------------------- */
.maj-bloc .maj-titre { width: 100%; box-sizing: border-box; padding: .5em .7em; font: inherit; font-weight: 700;
  border: 2px solid var(--ink-soft); border-radius: 8px; background: rgba(255,255,255,.7); }
.maj-bloc .maj-texte { width: 100%; box-sizing: border-box; }
/* Les cinq badges de catégorie, à cocher : un badge non coché est pâli. */
.maj-cats { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
.maj-cat { cursor: pointer; }
.maj-cat input { position: absolute; opacity: 0; pointer-events: none; }
.maj-cat img { display: block; height: 38px; width: auto; filter: grayscale(1) opacity(.45); transition: filter .15s, transform .15s; }
.maj-cat input:checked + img { filter: none; transform: scale(1.04); }
.maj-cat input:focus-visible + img { outline: 3px solid var(--rust); outline-offset: 2px; border-radius: 99px; }
