/* ma-boite-a-livres — feuille unique, mobile d'abord, budget 3G.
   Direction : fiche de bibliothèque. Papier froid, encre violette d'école
   (le violet des tampons et des porte-plumes), dates en "tampon dateur"
   monospace. Aucune police web : pile système. */

:root {
  --papier:   #FCFBF8;
  --encre:    #221E33;
  --encre-2:  #6B6577;
  --tampon:   #5A3FA0;   /* encre violette d'école */
  --tampon-f: #47327F;
  --regle:    #E4E1D8;   /* hairlines, comme les lignes d'une fiche */
  --estompe:  #8B8677;
  --alerte:   #8A5A1F;
  --valide:   #2E7D46;   /* checks verts de l'encadré « gains » (23/08/2026) */
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--papier);
  color: var(--encre);
  font: 17px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

main { max-width: 640px; margin: 0 auto; padding: 0 20px 40px; }

/* ---- entête / pied ---- */
.entete {
  max-width: 640px; margin: 0 auto; padding: 14px 20px;
  border-bottom: 1px solid var(--regle);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
/* Une seule ligne : les noms de boîte longs s'élident (22/08/2026). */
.entete-texte { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.entete-icones { flex-shrink: 0; display: flex; gap: 10px; }
.entete-icone img { width: 28px; height: auto; display: block; }
.entete-icone-login img { width: 23px; }   /* login seul en 23 px (Leo 23/08) */
/* Pastille rouge : nouveaux messages dans la discussion (23/08/2026). */
.entete-icone-nonlu { position: relative; }
.entete-icone-nonlu::after {
  content: ''; position: absolute; top: -2px; right: -3px;
  width: 9px; height: 9px; border-radius: 50%;
  background: #C63A2F; border: 1.5px solid var(--papier);
}
/* Guide « ajouter à l'écran d'accueil » (Leo 11/09/2026) : <details> dans
   l'en-tête, summary = pictogramme (SVG en currentColor), panneau en popup
   CSS pure — même mécanique que les popups « gains ». Toujours cibler
   `> summary` : un summary descendant du panneau n'est pas concerné. */
.installer > summary.installer-apercu {
  list-style: none; cursor: pointer; display: block; color: var(--encre);
}
.installer > summary.installer-apercu::-webkit-details-marker { display: none; }
.ico-installer { width: 28px; height: 28px; display: block; }
.installer[open]::before {
  content: ''; position: fixed; inset: 0;
  background: rgba(20, 17, 30, 0.55); z-index: 40;
}
.installer[open] > summary.installer-apercu { position: relative; z-index: 41; }
.installer-popup {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 41; width: min(92vw, 420px); max-height: 86vh; overflow-y: auto;
  background: var(--papier); border: 1px solid var(--regle); border-radius: 6px;
  padding: 18px; box-shadow: 0 8px 40px rgba(20, 17, 30, 0.35);
  white-space: normal; text-align: left; font-weight: 400;
}
.installer-popup h3 { margin: 0 0 8px; padding-right: 36px; font-size: 18px; }
.installer-popup p { margin: 0 0 14px; font-size: 15px; }
.installer-plateforme + .installer-plateforme { border-top: 1px solid var(--regle); margin-top: 12px; padding-top: 12px; }
.installer-plateforme h4 { margin: 0 0 6px; font-size: 16px; }
.installer-appareil { color: var(--tampon); font-weight: 400; font-size: 14px; }
.installer-etapes { margin: 0; padding-left: 22px; font-size: 15px; }
.installer-etapes li + li { margin-top: 4px; }
/* Bandeau « installer » (Leo 12/09/2026) : sous l'en-tête, rendu hidden
   par le serveur et révélé par boite.js selon l'appareil. Boutons compacts
   (le .bouton par défaut est pleine largeur). */
.installer-bandeau {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin: 12px 0 0; padding: 10px 12px;
  border: 1px solid var(--tampon); border-radius: 6px; background: #fff;
}
.installer-bandeau-ico { flex-shrink: 0; display: block; }
.installer-bandeau-ico .ico-installer { width: 34px; height: 34px; }
.installer-bandeau-texte { flex: 1 1 180px; min-width: 0; font-size: 15px; line-height: 1.35; }
.installer-bandeau-boutons { display: flex; gap: 8px; margin-left: auto; }
.installer-bandeau .bouton { width: auto; padding: 8px 14px; font-size: 15px; white-space: nowrap; }
.installer-guide-bouton { margin-top: 12px; }
/* `.bouton` pose display:block, qui l'emporte sur l'attribut hidden du
   navigateur : le bouton « Installer » ne doit exister que quand boite.js
   le révèle (événement Chrome), jamais sur iPhone. */
.installer-action[hidden], .installer-bandeau[hidden] { display: none; }
.marque {
  color: var(--encre); text-decoration: none;
  font-weight: 800; letter-spacing: -0.02em; font-size: 17px;
}
.pied {
  max-width: 640px; margin: 24px auto 0; padding: 16px 20px 32px;
  border-top: 1px solid var(--regle);
  display: flex; gap: 18px; flex-wrap: wrap;
}
.pied a { color: var(--encre-2); font-size: 14px; text-decoration: none; }
.pied a:hover { color: var(--tampon); }

/* ---- page boîte ---- */
h1 {
  font-size: 30px; line-height: 1.15; font-weight: 800;
  letter-spacing: -0.02em; margin: 26px 0 2px;
}
.commune { margin: 0 0 14px; color: var(--encre-2); font-size: 16px; }

h2 {
  font-size: 13px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--encre-2); margin: 30px 0 10px;
}

/* Le tampon dateur : la signature de la page. Jamais « présent »,
   toujours une date d'observation, encrée comme au guichet. */
.tampon {
  display: inline-block;
  font-family: var(--mono); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--tampon); border: 2px solid var(--tampon);
  border-radius: 3px; padding: 4px 10px; margin: 2px 0 6px;
}
.tampon-perimee, .tampon-jamais { color: var(--estompe); border-color: var(--estompe); }

.flash {
  border-left: 3px solid var(--tampon);
  padding: 8px 12px; margin: 14px 0; font-size: 15px;
  background: #F3F0FA;
}

.photo-etagere { margin: 18px 0 0; }
.photo-etagere img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--regle); border-radius: 4px;
}

/* ---- inventaire : les lignes de la fiche ---- */
.items { list-style: none; margin: 0; padding: 0; }
.item {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 12px 0;
  border-bottom: 1px solid var(--regle);
}
.item-texte { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.item-titre { font-weight: 600; }
.item-auteur { color: var(--encre-2); font-size: 15px; }
.item-type {
  font-size: 12px; color: var(--encre-2); text-transform: uppercase;
  letter-spacing: 0.06em;
}
.item-vu { font-family: var(--mono); font-size: 12.5px; color: var(--tampon); margin-top: 3px; }

.item-grise .item-titre, .item-grise .item-auteur { color: var(--estompe); }
.item-grise .item-vu { color: var(--estompe); }

.item-apercu { color: var(--encre); text-decoration: underline dotted; text-underline-offset: 3px; }
.item-apercu:hover { color: var(--tampon); }
.carrousel-photo figcaption a { text-decoration: underline dotted; text-underline-offset: 2px; }
.deja-inscrit { text-align: left; }
.deja-inscrit a { color: var(--tampon); }
.connexion { margin-top: 20px; }
.connexion summary { display: inline; }
.connexion .form-email { margin-top: 10px; max-width: 420px; }
.item-couverture {
  flex-shrink: 0; height: 64px; width: auto; align-self: center;
  border: 1px solid var(--regle); border-radius: 3px;
}
.item-actions { flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.item-prise summary { list-style: none; }
.item-prise summary::-webkit-details-marker { display: none; }
.prise-choix { display: flex; flex-direction: column; align-items: flex-end; }
.lien-discret {
  background: none; border: none; padding: 6px 0; cursor: pointer;
  color: var(--encre-2); font-size: 13px; text-decoration: underline;
  text-underline-offset: 2px; font-family: inherit;
}
.lien-discret:hover { color: var(--tampon); }

/* Chevron uniforme des dépliants texte (22/08/2026) : marqueur natif masqué,
   ▸ dessiné qui pivote à l'ouverture. Les summaries-boutons restent nus. */
summary.lien-discret { list-style: none; }
summary.lien-discret::-webkit-details-marker { display: none; }
summary.lien-discret::before, .pourquoi > summary::before { content: '▸ '; }
details[open] > summary.lien-discret::before,
.pourquoi[open] > summary::before { content: '▾ '; }

.vide { color: var(--encre-2); }

/* ---- actions ---- */
.actions { margin-top: 26px; }

.bouton {
  display: block; width: 100%; text-align: center;
  padding: 15px 16px; border-radius: 4px; border: 1.5px solid var(--encre);
  background: transparent; color: var(--encre);
  font: 600 17px/1.2 system-ui, sans-serif;
  text-decoration: none; cursor: pointer;
}
.bouton-primaire { background: var(--tampon); border-color: var(--tampon); color: #fff; }
.bouton-primaire:hover, .bouton-primaire:focus { background: var(--tampon-f); border-color: var(--tampon-f); }
.sous-action { margin: 8px 0 0; font-size: 14px; color: var(--encre-2); text-align: center; }

.form-email label {
  display: block; font-size: 13px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--encre-2); margin-bottom: 6px;
}
.form-email input {
  display: block; width: 100%; padding: 13px 12px; margin-bottom: 10px;
  font: 17px/1.2 system-ui, sans-serif;
  border: 1.5px solid var(--regle); border-radius: 4px;
  background: #fff; color: var(--encre);
}
.form-email input:focus { outline: 2px solid var(--tampon); outline-offset: 1px; border-color: var(--tampon); }
/* Radios et checkbox : exemptées du bloc pleine largeur ci-dessus (Leo
   31/08/2026) — étirées à 100 %, la coche se dessinait seule, CENTRÉE sur sa
   ligne, séparée de son libellé. Ici elles restent en ligne avec le texte. */
.form-email input[type="radio"], .form-email input[type="checkbox"] {
  display: inline-block; width: auto; margin: 0 6px 0 0; vertical-align: -1px;
}

.repli { margin-top: 18px; }
.repli summary { cursor: pointer; color: var(--tampon); font-weight: 600; }
.repli[open] summary { margin-bottom: 12px; }

/* ---- page boîte simplifiée (19-20/08/2026) ---- */
.marque-detail { color: var(--encre-2); font-size: 15px; }
.logo-boite {
  display: block; width: min(100%, 340px); height: auto; margin: 18px auto 4px;
}
/* Image posée par une mairie (027) : ce qu'elle montre et ses proportions sont
   inconnus du code — on borne les DEUX côtés, sans quoi une image carrée
   occuperait 340 px de haut. */
.logo-mairie { width: auto; max-width: min(100%, 340px); max-height: 150px; }
.service { margin: 0 0 14px; color: var(--encre-2); font-size: 16px; text-align: center; }

/* Boutons sur deux lignes centrées (20/08/2026). */
.bouton-2l { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 11px 10px; }
.bouton-2l small { font-size: 13px; font-weight: 400; opacity: 0.85; }

/* Rangée duo : Annoncer un livre | Ranger ou photographier (30/08/2026).
   Chaque cellule empile la phrase de gains puis son bouton ; les boutons
   s'étirent à la même hauteur, quelle que soit la longueur des libellés. */
.rangee-duo { display: flex; gap: 10px; margin-top: 14px; align-items: stretch; }
.rangee-duo .duo-cell { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rangee-duo .bouton { flex: 1; margin: 0; }
.photo-etagere figcaption.tampon { margin-top: 8px; }

/* Vitrine (Leo 30/08/2026) : la photo d'ensemble + le rayon animé — il
   remplace le carrousel horizontal des couvertures. */
.vitrine { display: flex; gap: 10px; align-items: stretch; justify-content: center; margin: 0 0 6px; }
.vitrine-photo { margin: 0; min-width: 0; position: relative; }
.vitrine-photo img {
  height: 240px; width: auto; max-width: 100%; display: block;
  border: 1px solid var(--regle); border-radius: 4px;
}
/* Légende en bandeau SUR la photo (décision Leo 20/08/2026) : blanc quasi
   opaque, texte noir — plus rien n'est écrit sous les photos. */
.vitrine-photo figcaption.bandeau {
  position: absolute; left: 1px; right: 1px; bottom: 1px;
  background: rgba(255, 255, 255, 0.88); color: #000;
  font-size: 12.5px; padding: 4px 8px; border-radius: 0 0 4px 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.vitrine-photo figcaption.bandeau a {
  color: #000; text-decoration: underline dotted; text-underline-offset: 2px;
}

/* Le rayon : des étagères de couvertures qui défilent de bas en haut, en CSS
   pur — deux copies de la bande pour une boucle sans couture. L'invitation
   reprend le bandeau blanc des photos. */
/* Largeur adaptative (Leo 31/08/2026) : le rayon occupe l'espace restant à
   côté de la photo — borné pour rester une colonne, jamais un mur. */
.rayon { margin: 0; flex: 1 1 112px; min-width: 100px; max-width: 240px; }
.rayon-apercu {
  position: relative; display: block; height: 240px; overflow: hidden;
  border: 1px solid var(--regle); border-radius: 4px; background: var(--papier);
  cursor: pointer; list-style: none;
}
.rayon-apercu::-webkit-details-marker { display: none; }
.rayon-defile { height: 100%; overflow: hidden; }
.rayon-bande { animation: rayon-monte 16s linear infinite; }
.rayon-apercu:hover .rayon-bande { animation-play-state: paused; }
.rayon-fixe .rayon-bande { animation: none; }
@keyframes rayon-monte {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }
}
.rayon-etagere {
  display: flex; align-items: flex-end; justify-content: center; gap: 7px;
  padding: 8px 6px 0; border-bottom: 3px solid var(--regle);
}
/* Les couvertures suivent la largeur de la bande (moitié moins l'espacement),
   plafonnées — la hauteur découle du ratio de chaque couverture. */
.rayon-etagere img {
  width: calc(50% - 10px); max-width: 88px; height: auto; display: block;
  border: 1px solid var(--regle); border-radius: 2px;
}
.rayon-invite {
  position: absolute; left: 1px; right: 1px; bottom: 1px;
  background: rgba(255, 255, 255, 0.88); color: #000; text-align: center;
  font-size: 12px; font-weight: 600; padding: 4px 4px; border-radius: 0 0 4px 4px;
}
/* Popover pleine page : même mécanique <details> en surimpression CSS que
   les popups « gains » (boite.js ajoute clic-fond et Échap). */
.rayon[open]::before {
  content: ''; position: fixed; inset: 0;
  background: rgba(20, 17, 30, 0.55); z-index: 40;
}
.rayon[open] > summary.rayon-apercu { position: relative; z-index: 41; }
.rayon-popover {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 41; width: min(94vw, 560px); max-height: 86vh;
  display: flex; flex-direction: column;
  background: var(--papier); border: 1px solid var(--regle); border-radius: 6px;
  padding: 18px; box-shadow: 0 8px 40px rgba(20, 17, 30, 0.35);
}
.rayon-popover h3 { margin: 0 0 12px; padding-right: 36px; font-size: 18px; }
/* Croix de fermeture du popover : confort JS (hidden levé par boite.js). */
.rayon-popover .popover-fermer,
.installer-popup .popover-fermer {
  position: absolute; top: 8px; right: 8px;
  background: transparent; border: none; color: var(--encre);
  font: 700 26px/1 system-ui, sans-serif; cursor: pointer;
  width: 36px; height: 36px; border-radius: 50%;
}
.rayon-popover .popover-fermer:hover,
.installer-popup .popover-fermer:hover { background: var(--regle); }
/* C'est la GRILLE qui défile, pas le popover : le titre et la croix restent
   épinglés en haut (une croix en absolute dans un conteneur scrollable
   partirait avec le contenu). */
.rayon-grille {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
  overflow-y: auto; min-height: 0;
}
.rayon-grille img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--regle); border-radius: 3px;
}
/* Page « toutes les vues » : défilement vertical, une vue par figure. */
.photos-page > * + * { margin-top: 18px; }
.photo-vue { margin: 0; position: relative; }
.photo-vue img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--regle); border-radius: 4px;
}
.photo-vue .bandeau {
  position: absolute; left: 1px; right: 1px; bottom: 1px;
  background: rgba(255, 255, 255, 0.88); color: #000;
  font-size: 12.5px; padding: 4px 8px; border-radius: 0 0 4px 4px;
}

/* Légende en texte normal, pas de tampon ici (décision Leo 19/08/2026). */
.photo-legende { margin: 4px 0 0; font-size: 15px; color: var(--encre-2); }
.photo-legende a { color: var(--tampon); }
.maj-photo { margin-top: 22px; }
.pourquoi { display: inline-block; }
.pourquoi summary {
  list-style: none; cursor: pointer; color: var(--tampon);
  font-size: 13.5px; text-decoration: underline dotted; text-underline-offset: 2px;
}
.pourquoi summary::-webkit-details-marker { display: none; }
.pourquoi[open] { display: block; }
.pourquoi p {
  margin: 6px 0 0; font-size: 14px; color: var(--encre-2);
  border-left: 3px solid var(--regle); padding: 4px 10px;
}
.service a { color: var(--tampon); }
.classement-anonyme { color: var(--estompe); font-style: italic; }
/* Tout en bas, sous le pied : « Service approuvé et soutenu par » + logo,
   sur une seule ligne (21/08/2026). */
.pied-mairie {
  max-width: 640px; margin: 0 auto; padding: 0 20px 28px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 13.5px; color: var(--encre-2);
}
.pied-mairie img { max-height: 40px; width: auto; vertical-align: middle; }
.pied-mairie a { color: var(--encre-2); }

/* ---- récompenses clarifiée (19/08/2026) ---- */
.recompenses-solde {
  font-size: 19px; font-weight: 700; color: var(--tampon); margin: 14px 0 4px;
}
/* Étapes en pastilles numérotées, ligne courte + sous-ligne (23/08/2026). */
.recompenses-etapes { list-style: none; counter-reset: etape; margin: 10px 0 20px; padding: 0; }
.recompenses-etapes li {
  counter-increment: etape; display: flex; gap: 10px; align-items: flex-start;
  padding: 5px 0; color: var(--encre);
}
.recompenses-etapes li::before {
  content: counter(etape); flex: 0 0 22px; height: 22px; border-radius: 50%;
  background: var(--tampon); color: #fff;
  font: 700 12.5px/22px var(--mono); text-align: center;
}
.etape-sous { display: block; font-size: 13px; color: var(--encre-2); margin-top: 1px; }
/* Icône récompense en ligne — remplace le mot « point » (23/08/2026). */
.ico-reward { width: 17px; height: 17px; vertical-align: -3px; }
/* Image cadeau de la 4e étape (Leo 02/09/2026) : 50 % plus grande que
   l'icône récompense, marges verticales négatives = elle DÉBORDE de sa
   ligne au lieu de repousser celle du dessus (les marges d'une image
   inline comptent dans la hauteur de ligne, en négatif aussi). */
.ico-cadeau { width: 36px; height: 36px; margin: -10px 0; }
/* Libellés de récompenses sans gras sur la page publique (Leo 02/09/2026) —
   .item-titre reste à 600 partout ailleurs (inventaire, /c, admin). */
.recompense-commercant .item-titre { font-weight: normal; }

/* Coup de cœur (Leo 26/08/2026) : l'icône remplace le mot « cœur » dans les
   libellés, exactement comme reward.png remplace « point ». */
/* SVG inline : `fill="currentColor"` suit la couleur du texte. Violet sur le
   papier, blanc sur le bouton primaire — une image au violet figé y était
   invisible (fond identique). Les lignes grisées l'estompent avec le reste. */
.ico-coeur { width: 16px; height: 15px; vertical-align: -2px; color: var(--tampon); }
.bouton-primaire .ico-coeur { color: #fff; }
.ico-argent { width: 16px; height: 16px; vertical-align: -3px; color: var(--tampon); }
/* Icône livre incorporée aux libellés de boutons : elle suit la couleur du
   texte, donc blanche sur le bouton primaire et encre ailleurs. */
.ico-livre { width: 17px; height: 17px; vertical-align: -3px; }

/* Bandeau de soutien : mairie et commerçants réunis sous une phrase. Les
   logos gardent leurs proportions et se replient sur les petits écrans. */
.soutiens { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--regle); }
.soutiens-phrase { margin: 0 0 10px; text-align: center; font-size: 15px; color: var(--encre-2); }
.soutiens-logos {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 14px;
}
.soutiens-logos img { height: 38px; width: auto; max-width: 130px; object-fit: contain; }
/* Taille adaptée au nombre de logos (Leo 31/08/2026) : jusqu'à 3, grands ;
   jusqu'à 6, moyens ; au-delà, la taille d'origine. Classe posée par la vue. */
.soutiens-peu img { height: 72px; max-width: 220px; }
.soutiens-quelques img { height: 52px; max-width: 170px; }
.soutiens-logos a { color: var(--encre-2); text-decoration: none; }

/* Classement : la ligne du visiteur, repérable sans rien révéler des autres. */
.classement-moi { background: #F2EEFA; }
.classement-moi td { font-weight: 600; }
.classement-vous { color: var(--tampon); font-weight: 400; font-size: 13px; }

/* Points : l'icône est RÉPÉTÉE, jamais « 2x » (Leo 27/08/2026). Les icônes
   se serrent légèrement pour qu'une valeur à 5 reste lisible sur mobile. */
.pts { display: inline-flex; align-items: center; gap: 1px; white-space: nowrap; }
.pts .ico-reward { width: 15px; height: 15px; vertical-align: -2px; }

/* Phrase de gains « {ico} à gagner ! » AU-DESSUS des boutons d'action
   (Leo 30/08/2026) — elle remplace la pastille absolue du 27/08, pour la
   même raison d'origine : posée SUR le bouton primaire, l'icône récompense
   se noyait dans le violet du fond (image à couleur figée, la page ne peut
   pas la reteindre). Calée à droite, comme l'était la pastille. */
.pts-gagner {
  display: flex; justify-content: flex-end; align-items: center; gap: 1px;
  font-size: 13px; color: var(--encre-2); white-space: nowrap;
  margin: 0 2px 3px 0;
}
.pts-gagner .ico-reward { width: 15px; height: 15px; }
.gains-liste .pts { gap: 0; }

/* Pages de choix (30/08/2026) : « Attention coup de cœur ! » et « De l'ordre
   et une liste à jour ! » — une pile d'options, phrase de gains puis bouton. */
.choix-intro { margin: 18px 0 0; text-align: left; font-size: 16px; }
.choix-actions { display: flex; flex-direction: column; gap: 20px; margin-top: 16px; }
.choix-option .bouton { margin: 0; }
.titre-coeur .ico-coeur { width: 26px; height: 24px; vertical-align: -3px; }

/* Parrainage : le QR doit rester scannable — fond blanc franc, marge propre,
   et une taille bornée pour ne pas déborder sur un petit écran. */
.parrainage-promesse { text-align: center; font-size: 17px; margin: 16px 0; }
.parrainage-qr {
  max-width: 260px; margin: 0 auto; padding: 12px;
  background: #fff; border: 1px solid var(--regle); border-radius: 4px;
}
.parrainage-qr svg { display: block; width: 100%; height: auto; }
.parrainage-lien {
  text-align: center; font-size: 13px; word-break: break-all;
  color: var(--encre-2); margin: 4px 0 0;
}
.parrainage-note { margin-top: 18px; }

/* Mot de la mairie, sous la phrase d'accueil de la boîte. */
.message-mairie {
  margin: 6px 0 0; text-align: center; font-size: 15px;
  color: var(--encre-2); font-style: italic;
}
/* Espace mairie : le mot de passe généré doit être lisible à voix haute. */
.mairie-identifiants { text-align: center; line-height: 1.7; }
.mairie-mdp { font-size: 20px; letter-spacing: 0.08em; }
.mairie-bareme td { vertical-align: middle; }
.mairie-points { width: 70px; font: inherit; padding: 4px 6px;
  border: 1px solid var(--regle); border-radius: 4px; background: var(--papier); color: var(--encre); }
.item-marque-coeur .ico-coeur, .item-grise .item-marque-coeur .ico-coeur { color: inherit; }
.item-marque-coeur {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start;
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--tampon); margin-bottom: 2px;
}
.item-coeur { border-left: 3px solid var(--tampon); padding-left: 10px; }
.item-mot {
  margin-top: 4px; font-style: italic; color: var(--encre-2);
  font-size: 14px; quotes: '\00AB\00A0' '\00A0\00BB';
}
.item-grise .item-marque-coeur, .item-grise .item-mot { color: var(--estompe); }
/* Présentation vocale d'un coup de cœur (30/08/2026) : lecteur natif, compact. */
.item-audio { display: block; margin-top: 6px; width: 100%; max-width: 320px; height: 36px; }
/* Le mot du déposant : champ ordinaire, révélé avec le bouton de clôture. */
.coeur-mot { border: 0; padding: 0; margin: 18px 0 0; }
.coeur-mot legend { font-weight: 600; padding: 0; }
.coeur-mot textarea {
  width: 100%; box-sizing: border-box; font: inherit; padding: 8px;
  border: 1px solid var(--regle); border-radius: 4px; background: var(--papier);
  color: var(--encre); resize: vertical;
}
.moderation-mot { display: inline-block; margin-top: 4px; font-style: italic; }
.recompense-commercant h2 { margin-bottom: 2px; }
.recompense-enseigne { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin: 22px 0 4px; }
/* L'enseigne est l'identité du bloc : pas le style « libellé de section »
   du h2 global (13 px capitales grises — 22/08/2026). */
.recompense-enseigne h2 {
  margin: 0; font-size: 19px; font-weight: 700; color: var(--encre);
  text-transform: none; letter-spacing: normal;
}
.recompense-logo { display: block; max-height: 64px; width: auto; }
.recompense-adresse { margin: 0; }
.recompense-adresse a { color: var(--encre-2); text-decoration: none; }
.recompense-adresse a:hover { color: var(--tampon); text-decoration: underline; }
.pin { width: 14px; height: auto; vertical-align: -2px; margin-right: 4px; }
.admin-logo-apercu { display: block; max-height: 48px; width: auto; margin-bottom: 6px; }
.admin-supprimer { color: var(--alerte) !important; }
.admin-carte { height: 340px; border: 1.5px solid var(--regle); border-radius: 4px; }
.contact-corps { font: 16px/1.5 system-ui, sans-serif; }
.recompense-indispo { color: var(--estompe); font-size: 13.5px; text-align: right; }
.recompense-bouton { width: auto; padding: 9px 14px; font-size: 15px; }
.actions-trio { display: flex; flex-direction: column; gap: 4px; }
.actions-trio .bouton { margin-top: 14px; }
/* Les phrases de gains espacent elles-mêmes les boutons de l'actions-trio ;
   dans la rangée duo, la cellule reprend la main (sinon le 14 px du trio se
   cumulerait avec le margin-top de la rangée). */
.actions-trio .pts-gagner { margin-top: 14px; }
.duo-cell .pts-gagner { margin-top: 0; }
.duo-cell .bouton { margin-top: 0; }
.actions-trio .sous-action { margin: 6px 0 0; text-align: center; }
.abonner { margin: 0; }
/* .repli summary teint le texte en violet : sur le bouton primaire (fond
   violet), le libellé doit rester blanc. */
/* > : seul le bouton violet DIRECT est blanc — les dépliants imbriqués
   (« Je m'inscris » / « J'ai déjà un compte », boutons neutres) restent
   en encre (blanc sur blanc sinon — bug signalé par Leo le 21/08). */
.abonner > summary { list-style: none; text-align: center; color: #fff; }
.abonner > summary:hover, .abonner > summary:focus { color: #fff; }
.abonner summary::-webkit-details-marker { display: none; }
.abo-option > summary { color: var(--encre); }
.abo-option > summary:hover { color: var(--tampon); }
.abonner[open] summary { margin-bottom: 0; }
.abonner .form-email { margin-top: 12px; }
/* Étape intermédiaire : deux options empilées, boutons neutres. */
.abo-option { margin-top: 10px; }
.abo-option > summary { list-style: none; text-align: center; }
.abo-option > summary::-webkit-details-marker { display: none; }
.abo-option[open] > summary { border-color: var(--tampon); color: var(--tampon); }
.isbn-bloc { margin-top: 22px; }

.lien-secondaire {
  display: inline-block; margin-top: 14px;
  color: var(--tampon); font-weight: 600; text-decoration: none;
}
.lien-secondaire:hover { text-decoration: underline; }

.actions-secondaires {
  display: flex; gap: 20px; flex-wrap: wrap;
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--regle);
}
.actions-secondaires a { color: var(--encre-2); font-size: 15px; text-decoration: underline; text-underline-offset: 2px; }
.actions-secondaires a:hover { color: var(--tampon); }

/* ---- voisines / listes de boîtes ---- */
.voisines ul { list-style: none; margin: 0; padding: 0; }
.voisines li { padding: 11px 0; border-bottom: 1px solid var(--regle); }
.voisines a { color: var(--encre); font-weight: 600; text-decoration: none; }
.voisines a:hover { color: var(--tampon); }
.voisine-meta { display: block; font-size: 14px; color: var(--encre-2); margin-top: 2px; }
.mono { font-family: var(--mono); font-size: 13px; }

/* ---- accueil (refonte 21/08/2026) ---- */
.accueil > * + * { margin-top: 26px; }
.accueil-date { font-size: 13px; color: var(--encre-2); margin: 0 0 10px; text-align: center; }
.stats-grille { display: flex; gap: 12px; }
.stat {
  flex: 1; text-align: center; padding: 14px 8px;
  border: 1px solid var(--regle); border-radius: 4px; background: #fff;
}
.stat-n { display: block; font: 700 28px/1.1 var(--mono); color: var(--tampon); }
.stat-l { display: block; font-size: 13px; color: var(--encre-2); margin-top: 3px; }
.stat-c { display: block; font-size: 12px; color: var(--estompe); margin-top: 4px; font-family: var(--mono); }

.accueil-profils { display: flex; flex-direction: column; gap: 14px; }
.profil { border-left: 3px solid var(--tampon); padding: 2px 0 2px 14px; }
.profil h2 { margin: 0 0 4px; }
.profil p { margin: 0; font-size: 15px; color: var(--encre); }

.accueil-exemple h2 { margin-bottom: 10px; }
/* Photo à 30 %, texte à droite (Leo 21/08/2026) ; fond papier, sans carte ni
   bordure, bouton « Découvrir » sous le texte (Leo 22/08/2026). */
.exemple-carte { display: flex; align-items: flex-start; gap: 14px; color: var(--encre); }
.exemple-carte img {
  width: 30%; flex: 0 0 30%; height: auto; display: block;
  border: 1px solid var(--regle); border-radius: 4px;
}
.exemple-texte p { margin: 0 0 12px; font-size: 15px; }
.exemple-bouton { max-width: 300px; }
.accueil-appel {
  max-width: 420px; margin: 22px auto 10px; text-align: center;
  font-size: 15px; color: var(--encre-2);
}
.accueil-contact { max-width: 340px; margin-left: auto; margin-right: auto; }

/* ---- statiques / messages ---- */
.baseline { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; margin: 30px 0 8px; line-height: 1.3; }
.comment p { color: var(--encre); }
.zone { color: var(--encre-2); font-size: 15px; text-align: center; }
.statique p { color: var(--encre); }
/* Carte des alentours (Leo 31/08/2026) : la HAUTEUR est posée par
   alentours-carte.js — sans JS, aucun cadre vide n'apparaît. */
#carte-alentours { border: 1px solid var(--regle); border-radius: 4px; margin: 0 0 14px; }
/* Avis « en cours de rédaction » des pages statiques (Leo 31/08/2026). */
.statique-avis {
  border: 1px solid var(--regle); border-left: 3px solid var(--tampon);
  border-radius: 4px; padding: 10px 12px; font-size: 14.5px; color: var(--encre-2);
}
.message h1 { font-size: 24px; }

/* ---- pipeline photo (tranche 2) ---- */
/* Pages dépôt / prendre / discussion : respiration verticale (20/08). */
#photo-app { margin-top: 22px; }
#photo-app > * + * { margin-top: 22px; }
.discussion > * + * { margin-top: 16px; }
.discussion h1 { margin-bottom: 2px; }
.prises { display: flex; flex-direction: column; gap: 4px; }
.prises .sous-action { margin: 8px 0 2px; }
.prises .bouton { margin: 0; }
.bouton-fichier { position: relative; overflow: hidden; }
.bouton-fichier input[type="file"] {
  position: absolute; inset: 0; opacity: 0; cursor: pointer; font-size: 0;
}
/* État d'envoi : texte normal, court — pas de tampon majuscules (20/08). */
.envoi-etat { margin: 0 0 6px; font-size: 15px; color: var(--encre); }
.progression {
  height: 14px; margin: 14px 0 8px;
  border: 1.5px solid var(--tampon); border-radius: 4px;
  background: #fff; overflow: hidden;
}
.progression-barre {
  height: 100%; width: 0; background: var(--tampon);
  transition: width 0.4s ease;
}

/* ---- administration / modération (tranche 3) ---- */
.admin-table { width: 100%; border-collapse: collapse; font-size: 15px; }
.admin-table td { padding: 8px 6px; border-bottom: 1px solid var(--regle); vertical-align: top; }
.admin-table a { color: var(--tampon); margin-right: 8px; }
.admin-inactive td { color: var(--estompe); }
.admin-textarea {
  display: block; width: 100%; padding: 10px; margin-bottom: 10px;
  font: 13px/1.5 var(--mono); border: 1.5px solid var(--regle); border-radius: 4px;
  background: #fff; color: var(--encre);
}
.admin-select {
  display: block; width: 100%; padding: 12px; margin-bottom: 10px;
  font: 17px/1.2 system-ui, sans-serif;
  border: 1.5px solid var(--regle); border-radius: 4px; background: #fff;
}
.admin-nav a { margin-right: 4px; }
.admin-actions-cellule form { display: inline-block; margin-right: 6px; }

.signaler-types { border: 1px solid var(--regle); border-radius: 4px; padding: 12px 14px; margin: 0 0 14px; }
.signaler-types legend { font-weight: 600; padding: 0 4px; }
.signaler-choix { display: block; padding: 7px 0; cursor: pointer; }

.moderation-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; }
.moderation-photo { margin: 0; }
.moderation-photo img { width: 100%; height: auto; border: 1px solid var(--regle); border-radius: 4px; }
.moderation-photo figcaption { font-size: 13px; color: var(--encre-2); margin: 4px 0; }
.moderation-clore { margin-top: 24px; }

.voucher-encours { border: 2px solid var(--tampon); border-radius: 4px; padding: 14px 16px; margin: 18px 0; }
.voucher-code { font-size: 34px; font-weight: 700; letter-spacing: 0.25em; color: var(--tampon); margin: 6px 0; }
.commercant-code { text-transform: uppercase; letter-spacing: 0.2em; font-size: 22px; }
.commercant-recredit input[type="file"] { display: block; font-size: 13px; margin: 4px 0; }
/* « Max. [N] gagnant(s) par [période] » sur une seule ligne. */
.offre-quota { display: flex; align-items: center; gap: 8px; }
.offre-quota label { margin: 0; }
.offre-quota input { width: 72px; margin: 0; }
.offre-quota-periode { width: auto; margin: 0; }
.admin-inline { display: inline-block; }

.planche-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px; }
.planche-carte { margin: 0; text-align: center; border: 1px solid var(--regle); border-radius: 4px; padding: 14px; }
.planche-qr svg { width: 180px; height: 180px; }
.planche-url { font-size: 12px; margin: 6px 0 0; }
@media print {
  .entete, .pied, .planche-cacher-impression { display: none !important; }
  .planche-carte { break-inside: avoid; border: 1px solid #000; }
  main { max-width: none; }
}

/* ---- discussion par boîte (20/08/2026) ---- */
.discussion-fil {
  max-height: 55vh; overflow-y: auto; padding: 6px 2px;
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--regle); border-radius: 4px; padding: 12px;
  background: #fff;
}
.bulle {
  max-width: 82%; align-self: flex-start;
  background: #F3F0FA; border-radius: 10px 10px 10px 3px;
  padding: 7px 11px; font-size: 15px;
}
.bulle-moi {
  align-self: flex-end; background: var(--tampon); color: #fff;
  border-radius: 10px 10px 3px 10px;
}
.bulle-pseudo { display: block; font-size: 12px; font-weight: 700; opacity: 0.75; }
.bulle-moi .bulle-pseudo { color: #fff; }
.bulle-texte { display: block; word-wrap: break-word; }
.bulle-heure { display: block; font-size: 10.5px; opacity: 0.6; text-align: right; margin-top: 2px; }
.discussion-form { display: flex; gap: 8px; margin-top: 12px; }
.discussion-form input {
  flex: 1; padding: 12px; font: 16px/1.2 system-ui, sans-serif;
  border: 1.5px solid var(--regle); border-radius: 4px; background: #fff; color: var(--encre);
}
.discussion-form input:focus { outline: 2px solid var(--tampon); outline-offset: 1px; }
.discussion-envoyer { width: auto; padding: 12px 18px; }

/* ---- visionneuse plein écran (21/08/2026) ---- */
.visionneuse {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(20, 17, 30, 0.94);
  display: flex; align-items: center; justify-content: center;
}
.visionneuse[hidden] { display: none; }
.visionneuse img {
  max-width: 97vw; max-height: 92vh; width: auto; height: auto;
  border-radius: 4px; box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);
}
.visionneuse-fermer, .visionneuse-nav {
  position: absolute; z-index: 51;
  background: rgba(252, 251, 248, 0.14); border: none; color: #fff;
  font: 700 30px/1 system-ui, sans-serif; cursor: pointer;
  width: 48px; height: 48px; border-radius: 50%;
}
.visionneuse-fermer:hover, .visionneuse-nav:hover { background: rgba(252, 251, 248, 0.3); }
.visionneuse-fermer { top: 10px; right: 10px; }
/* Flèches SUR l'image (semi-transparentes), plus d'espace perdu autour. */
.visionneuse-prec { left: 4px; top: 50%; transform: translateY(-50%); background: rgba(20, 17, 30, 0.45); }
.visionneuse-suiv { right: 4px; top: 50%; transform: translateY(-50%); background: rgba(20, 17, 30, 0.45); }
.visionneuse-legende {
  position: absolute; left: 0; right: 0; bottom: 16px;
  text-align: center; color: #fff; font-size: 15px; margin: 0; padding: 0 60px;
}

/* ---- encadré « comment gagner » (23/08/2026) ---- */
/* ---- jauge de la boîte et défi (029) ----
   Arc SVG inline : le cadran commence AU PLANCHER, il n'a donc pas de zone
   rouge et l'aiguille n'a pas à être bridée. Couleurs explicites sur l'arc —
   une teinte figée héritée serait invisible selon le fond. */
/* En-tête avec jauge (029) : elle REMPLACE le logo du service — la main, le
   téléphone et la flèche ont été retirés le 15/09/2026 (Leo). Il ne reste que
   le cadran entre un petit et un gros cadeau, qui dispose donc de toute la
   largeur : tailles revues à la hausse. */
.entete-jauge {
  display: flex; align-items: center; justify-content: center;
  gap: 6px; margin: 16px auto 2px;
}
.jauge-cadeaux { display: flex; align-items: center; gap: 4px; }
.jauge-cadeau { width: auto; }
/* Le petit cadeau est retourné en miroir (Leo 15/09/2026) : les deux
   cadeaux regardent ainsi vers le cadran. */
.jauge-cadeau-petit { height: 28px; transform: scaleX(-1); }
.jauge-cadeau-grand { height: 58px; }
/* Centrage (Leo 15/09/2026) : les deux cadeaux n'ont pas la même largeur,
   le cadran était donc tiré vers la gauche. Même emplacement de 58 px des
   deux côtés, image calée CONTRE le cadran — le petit est retourné en miroir,
   son « left » tombe donc à droite à l'écran. */
.jauge-cadeau-petit, .jauge-cadeau-grand {
  width: 58px; object-fit: contain; object-position: left center;
}
/* « continuons ! » : lien stylé en bouton violet, dans le fil de la phrase. */
.jauge-suite {
  display: inline-block; padding: 2px 10px; border-radius: 4px;
  background: var(--tampon, #5A3FA0); color: #fff; font-weight: 600;
  text-decoration: none;
}
.jauge-suite:hover, .jauge-suite:focus-visible { background: #4A3386; color: #fff; }
/* Cible du bouton : un peu d'air au-dessus, et un défilement doux sauf si
   le visiteur a demandé moins d'animations. */
#participer { scroll-margin-top: 16px; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
.entete-jauge .jauge-cadran { width: 160px; height: auto; margin: 0; }
/* Dans l'en-tête, le cadran est déjà dessiné : il ne reste que la phrase et
   le défi, sans encadré. */
.jauge-nue { border: 0; background: none; padding: 0; margin: 2px 0 10px; }

/* Marge du bas portée de 4 à 20 px (Leo 15/09/2026) : l'encart touchait le
   bloc suivant. NB : cette règle, placée APRÈS .jauge-nue et de même
   spécificité, l'emporte sur elle — l'encart de l'en-tête garde donc son
   cadre blanc, ce qui est l'aspect validé. */
.jauge {
  margin: 12px 0 20px; border: 1px solid var(--regle); border-radius: 4px;
  padding: 14px 16px 12px; background: #fff; text-align: center;
}
/* Centrage DÉTERMINISTE : marge auto sur un bloc, sans dépendre d'un
   text-align hérité. */
.jauge-cadran { display: block; margin: 0 auto; }
/* Miniature dans le fil d'un titre : même arc, même aiguille, sans les
   chiffres — illisibles à cette taille. Règle APRÈS .jauge-cadran, dont elle
   doit renverser le display. */
.jauge-cadran-mini {
  display: inline-block; width: auto; height: 2em;
  vertical-align: -0.55em; margin: 0 .12em;
}
.jauge-nombre {
  font: 700 24px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  fill: var(--encre, #221E33);
}
/* Bornes : des <text> DANS le SVG, calés sur les extrémités de l'arc. */
.jauge-borne { font: 500 12px/1 var(--mono); fill: var(--encre-2, #6B6577); }
.ico-jauge { height: .78em; width: auto; vertical-align: -.06em; }
.jauge-phrase { margin: 4px 0 0; font-size: 15px; }
/* Le cœur de fin de phrase est ROUGE : la teinte vit ici, le SVG reste en
   currentColor. */
.jauge-coeur .ico-coeur { color: #C0392B; }
/* « une boîte à livres vivante et appréciée » : la chute de la phrase, à la
   taille du reste (Leo 15/09/2026 — le 1.2em a été retiré), en demi-gras. */
.jauge-grand { font-weight: 600; }
.jauge-defi { margin: 8px 0 0; font-size: 15px; color: var(--tampon); font-weight: 600; }
.jauge-plein { color: var(--valide); }

/* ---- sondage de commune (028) ----
   Même boîte blanche que l'encadré « gains » : c'est un encadré de la page,
   jamais un passage obligé. Les deux échappatoires sont côte à côte et
   visuellement secondaires — mais ce sont de vrais boutons, pas des liens
   décoratifs : tout le parcours marche sans JS. */
.sondage {
  margin-top: 22px; border: 1px solid var(--regle); border-radius: 4px;
  padding: 12px 16px 16px; background: #fff;
}
.sondage-titre { margin: 0 0 4px; }
.sondage-intro { margin: 0 0 6px; font-style: italic; color: var(--encre-2); }
.sondage-aide { margin: 0 0 12px; font-size: 14px; color: var(--encre-2); }
.sondage-question {
  border: 0; border-top: 1px solid var(--regle); margin: 0; padding: 10px 0 4px;
}
.sondage-question legend { font-size: 14px; font-weight: 600; padding: 0; }
.sondage-question .signaler-choix { display: block; padding: 3px 0; }
.sondage-libre {
  width: 100%; font: inherit; padding: 6px 8px; border: 1px solid var(--regle);
  border-radius: 4px; background: var(--papier); color: var(--encre);
}
.sondage-echappatoires { display: flex; gap: 10px; margin-top: 8px; }
.sondage-echappatoires .bouton { flex: 1; font-size: 14px; }
/* Réponses libres côté mairie : du texte écrit par des visiteurs. */
.sondage-libres { margin: 6px 0 0; padding-left: 18px; font-size: 14px; }
/* Avertissement sous la question libre, dans /mairie. */
.avertissement { color: #8A3324; }

.gains {
  margin-top: 22px; border: 1px solid var(--regle); border-radius: 4px;
  padding: 12px 16px 4px; background: #fff;
}
.gains-titre { margin: 0 0 4px; }
.gains-liste { list-style: none; margin: 0; padding: 0; }
.gain-ligne {
  display: flex; align-items: center; gap: 8px; padding: 9px 0;
  font-size: 15px; border-bottom: 1px solid var(--regle);
}
.gains-liste > li:last-child .gain-ligne { border-bottom: none; }
summary.gain-ligne { cursor: pointer; list-style: none; }
summary.gain-ligne::-webkit-details-marker { display: none; }
.gain-check { color: var(--valide); font-weight: 700; }
.gain-libelle { min-width: 0; }
.gain-pts {
  margin-left: auto; white-space: nowrap;
  color: var(--tampon); font-weight: 600; font-size: 14px;
}
/* Popup en CSS pur : le <details> ouvert pose un fond assombri (::before)
   et son panneau en surimpression ; le summary reste au-dessus (re-clic =
   fermeture sans JS ; boite.js ajoute clic-fond et Échap). */
.gain[open]::before {
  content: ''; position: fixed; inset: 0;
  background: rgba(20, 17, 30, 0.55); z-index: 40;
}
.gain[open] > summary.gain-ligne {
  position: relative; z-index: 41; background: var(--papier);
  border-radius: 4px; padding-left: 6px; padding-right: 6px;
}
.gain-popup {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 41; width: min(92vw, 400px); max-height: 80vh; overflow-y: auto;
  background: var(--papier); border: 1px solid var(--regle); border-radius: 6px;
  padding: 18px; box-shadow: 0 8px 40px rgba(20, 17, 30, 0.35);
}
.gain-popup h3 { margin: 0 0 8px; font-size: 18px; }
.gain-popup p { margin: 0 0 14px; font-size: 15px; }

/* ---- paramètres du compte (23/08/2026) ---- */
.parametres-note { text-align: left; margin: 0 0 8px; }
.parametres-alerte .bouton { margin-top: 8px; }
a.parametres-supprimer { color: var(--alerte); }
.bouton.parametres-supprimer {
  color: var(--alerte); border-color: var(--alerte); background: transparent;
}

/* ---- petits écrans (22/08/2026) ---- */
@media (max-width: 480px) {
  /* Encart exemple empilé : la photo à 30 % devenait un timbre-poste. */
  .exemple-carte { flex-direction: column; }
  .exemple-carte img { width: 100%; flex: none; }
  .exemple-bouton { max-width: none; }
  /* Stats : les trois tuiles restent en rangée, chiffres resserrés. */
  .stat { padding: 10px 4px; }
  .stat-n { font-size: 22px; }
}

/* ---- sélection des BD par la mairie (032) ----
   Quatre candidats par emplacement : l'album proposé et ses trois remplaçants.
   Tout tient en HTML : des boutons radio dans un formulaire, aucun JS requis.
   Couleurs avec REPLI — une variable non résolue rendrait l'écran illisible. */
.selection { max-width: 960px; margin: 0 auto; }
.selection-intro { color: var(--encre-2, #6B6577); }
.selection-date {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 12px; letter-spacing: 0.04em; color: var(--encre-2, #6B6577);
}
.selection-alerte, .selection-valide, .selection-ok {
  border-radius: 4px; padding: 12px 14px; margin: 14px 0;
}
.selection-alerte { border: 1px solid #C0392B; background: #FDF3F2; color: #7B241C; }
.selection-alerte ul { margin: 8px 0 0; padding-left: 20px; }
.selection-valide, .selection-ok { border: 1px solid var(--vert, #2E7D46); background: #F1F8F3; }

.sel-emplacement { border: 0; border-top: 1px solid var(--filet, #E4E1D8); margin: 0; padding: 18px 0 8px; }
.sel-emplacement legend {
  font-weight: 700; font-size: 15.5px;
  color: var(--tampon, #5A3FA0); padding: 0;
}
.sel-aide { margin: 5px 0 0; font-size: 13px; color: var(--encre-2, #6B6577); }
.sel-candidats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 12px; }
.sel-candidat {
  display: flex; flex-direction: column; gap: 4px; cursor: pointer;
  border: 1px solid var(--filet, #E4E1D8); border-radius: 4px; padding: 8px;
  background: var(--papier, #FCFBF8);
}
.sel-candidat:has(input:checked) { border-color: var(--tampon, #5A3FA0); border-width: 2px; padding: 7px; }
.sel-candidat input { margin: 0 0 4px; accent-color: var(--tampon, #5A3FA0); }
.sel-vignette { position: relative; display: block; }
.sel-vignette img {
  display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: contain;
  background: #EFEDE7; border-radius: 2px;
}
.sel-sans-image { display: block; width: 100%; aspect-ratio: 3 / 4; background: #EFEDE7; border-radius: 2px; }
.sel-badge {
  position: absolute; top: 4px; left: 4px; background: var(--tampon, #5A3FA0); color: #fff;
  font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 2px;
}
.sel-titre { font-weight: 600; font-size: 13.5px; line-height: 1.25; }
.sel-meta, .sel-etat { font-size: 12px; color: var(--encre-2, #6B6577); }
.sel-absent { opacity: 0.5; cursor: not-allowed; }

/* Barre d'action collée en bas : le lot est long, les boutons doivent rester
   sous la main. L'encoche du téléphone s'ajoute au rembourrage, jamais à 0. */
.selection-barre {
  position: sticky; bottom: 0; display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; background: var(--papier, #FCFBF8);
  border-top: 1px solid var(--filet, #E4E1D8);
  padding: 12px 0 calc(12px + env(safe-area-inset-bottom, 0px));
}
.selection-compte { flex: 1; font-size: 13px; color: var(--encre-2, #6B6577); }
/* `.bouton` est pleine largeur dans tout le site : dans la barre, les deux
   actions doivent tenir côte à côte, sans quoi elles s'empilent. */
.selection-barre .bouton { width: auto; display: inline-flex; align-items: center; justify-content: center; }
/* Sans cette ligne, le `display: inline-flex` ci-dessus l'emporterait sur le
   display:none du navigateur et le bouton masqué resterait visible. Piège
   rencontré deux fois en production. */
.selection-barre .bouton[hidden] { display: none; }
.selection-note { font-size: 13px; color: var(--encre-2, #6B6577); margin-top: 18px; }

/* Loupe et visionneuse : révélées par selection.js. `[hidden]` est répété
   explicitement — une règle d'auteur qui pose `display` l'emporte sinon sur le
   display:none du navigateur, et l'élément masqué s'affiche quand même. */
.sel-loupe {
  position: absolute; right: 4px; bottom: 4px;
  background: rgba(252, 251, 248, 0.92); border: 1px solid var(--filet, #E4E1D8);
  border-radius: 3px; font-size: 11px; padding: 2px 7px; cursor: pointer;
  color: var(--encre, #221E33);
}
.sel-loupe[hidden] { display: none; }
.sel-fige { overflow: hidden; }

.sel-visionneuse {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(20, 18, 28, 0.94);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: calc(16px + env(safe-area-inset-top, 0px)) 16px
                     calc(16px + env(safe-area-inset-bottom, 0px));
}
.sel-visionneuse[hidden] { display: none; }
.sel-visionneuse-titre { color: #fff; font-weight: 600; margin: 0; text-align: center; }
.sel-visionneuse-image { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 0; }
.sel-visionneuse-image img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 3px; }
.sel-fermer {
  position: absolute; top: calc(10px + env(safe-area-inset-top, 0px)); right: 12px;
  width: 38px; height: 38px; border-radius: 50%; border: 0;
  background: rgba(255, 255, 255, 0.9); font-size: 22px; line-height: 1; cursor: pointer;
}
.sel-onglets { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.sel-onglet {
  border: 1px solid rgba(255, 255, 255, 0.5); background: transparent; color: #fff;
  border-radius: 999px; padding: 6px 14px; font-size: 13px; cursor: pointer;
}
.sel-onglet.actif { background: #fff; color: var(--encre, #221E33); border-color: #fff; }

.sel-auto {
  position: sticky; bottom: 0; margin: 0; text-align: right;
  font-size: 13px; color: var(--vert, #2E7D46);
}
.sel-auto[hidden] { display: none; }

.sel-auto-info { margin: 18px 0 0; font-size: 13.5px; color: var(--vert, #2E7D46); }
.sel-auto-info[hidden] { display: none; }
/* L'avertissement de validation : appuyé sans être alarmant — la validation
   est irréversible et lance une livraison, mais ce n'est pas une erreur. */
.sel-avert {
  margin: 6px 0 0; padding: 10px 12px; font-size: 13.5px;
  border-left: 3px solid var(--tampon, #5A3FA0);
  background: var(--papier-2, #F6F4EF); border-radius: 0 3px 3px 0;
}

@media (max-width: 640px) {
  .sel-candidats { grid-template-columns: repeat(2, 1fr); }
  .selection-barre .bouton { flex: 1; }
}

/* ---- LE MUR DU LOT (032, 18/09/2026) ----
   Remplace la grille « un emplacement = quatre radios » : à quatorze
   récompenses, celle-ci empilait 56 vignettes. Les règles .sel-emplacement et
   .sel-candidats ci-dessus ne sont plus employées — laissées en place plutôt
   que retirées à l'aveugle, comme le veut le projet. */
.sel-etat { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 18px 0 12px; }
.sel-etat b { font-size: 13.5px; }
.sel-jauge { flex: 1; min-width: 150px; height: 7px; border-radius: 99px; background: var(--filet, #E4E1D8); overflow: hidden; }
.sel-jauge i { display: block; height: 100%; background: var(--tampon, #5A3FA0); }
.sel-etat-detail { font-size: 13px; color: var(--encre-2, #6B6577); }

/* auto-fill et non six colonnes fixes : à trois récompenses, une grille figée
   tassait les cartes en timbres-poste dans un coin. Le padding du haut laisse
   la place à la pastille numérotée, qui déborde de 7 px. */
.sel-mur {
  display: grid; gap: 12px; padding-top: 10px;
  grid-template-columns: repeat(auto-fill, minmax(155px, 1fr));
}
.sel-carte {
  position: relative; display: flex; flex-direction: column; gap: 5px;
  border: 1px solid var(--filet, #E4E1D8); border-radius: 4px; padding: 7px;
  background: #fff; text-decoration: none; color: inherit; cursor: pointer;
}
.sel-carte:hover, .sel-carte:focus-visible { border-color: var(--tampon, #5A3FA0); }
.sel-carte-modifiee { border-color: var(--tampon, #5A3FA0); border-width: 2px; padding: 6px; }
.sel-carte img { width: 100%; aspect-ratio: 3 / 4; object-fit: contain; background: #EFEDE7; border-radius: 2px; }
.sel-num {
  position: absolute; top: -7px; left: -7px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--encre, #221E33); color: #fff; text-align: center;
  font: 600 11px/22px ui-monospace, Menlo, monospace;
}
.sel-carte-titre { font-size: 12.5px; font-weight: 600; line-height: 1.25; }
.sel-carte-chg {
  font: 10px/1 ui-monospace, Menlo, monospace; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--tampon, #5A3FA0);
}
.sel-carte-chg[hidden] { display: none; }

/* Barre fixe : l'avertissement y est AVEC le bouton, pour qu'on ne puisse plus
   valider sans l'avoir sous les yeux — il défilait hors champ auparavant. */
.sel-barre {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  background: var(--papier, #FCFBF8); border-top: 1px solid var(--filet, #E4E1D8);
  padding: 12px 18px calc(12px + env(safe-area-inset-bottom, 0px));
}
.sel-barre-in { max-width: 1000px; margin: 0 auto; display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.sel-barre .sel-avert {
  flex: 1; min-width: 260px; margin: 0; font-size: 12.5px; color: var(--encre-2, #6B6577);
  border-left: 3px solid var(--tampon, #5A3FA0); padding: 0 0 0 10px; background: none; border-radius: 0;
}
.sel-barre .sel-auto-info { margin: 0; font-size: 12.5px; color: var(--vert, #2E7D46); }
.sel-barre form { margin: 0; }
.sel-barre .bouton { width: auto; }

.sel-fenetre {
  position: fixed; inset: 0; z-index: 50; background: rgba(20, 18, 28, 0.55);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.sel-fenetre[hidden] { display: none; }
.sel-fen {
  position: relative; background: var(--papier, #FCFBF8); border-radius: 6px;
  max-width: 940px; width: 100%; max-height: 92vh; overflow: auto; padding: 22px;
}
.sel-fen-titre { margin: 0 0 3px; font-size: 19px; }
.sel-fen-intro { margin: 0 0 16px; font-size: 13.5px; color: var(--encre-2, #6B6577); }
.sel-fen-cands { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.sel-cand {
  display: flex; flex-direction: column; gap: 7px; background: #fff;
  border: 1px solid var(--filet, #E4E1D8); border-radius: 4px; padding: 9px;
}
.sel-cand-retenu { border: 2px solid var(--tampon, #5A3FA0); padding: 8px; }
.sel-cand img { width: 100%; aspect-ratio: 3 / 4; object-fit: contain; background: #EFEDE7; border-radius: 2px; }
.sel-cand-badge {
  margin: 0; align-self: flex-start; background: var(--tampon, #5A3FA0); color: #fff;
  font: 10px/1 ui-monospace, Menlo, monospace; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 3px 7px; border-radius: 2px;
}
.sel-cand-titre { margin: 0; font-size: 12.5px; font-weight: 600; line-height: 1.25; }
.sel-cand-meta { margin: 0; font-size: 11.5px; color: var(--encre-2, #6B6577); }
.sel-cand .bouton { margin-top: auto; width: 100%; }
.sel-vues-liens { display: flex; gap: 5px; flex-wrap: wrap; margin: 0; }
.sel-vues-liens a, .sel-vues-liens button {
  /* `font: 10.5px inherit` était INVALIDE — le raccourci exige une famille
     réelle, et le navigateur jetait la déclaration entière : les pilules
     s'affichaient en taille normale et débordaient. */
  font-size: 10.5px; font-family: inherit; line-height: 1.4;
  border: 1px solid var(--filet, #E4E1D8); background: #fff;
  color: var(--encre-2, #6B6577); border-radius: 99px; padding: 2px 8px; cursor: pointer; text-decoration: none;
}
.sel-retour { margin: 0 0 10px; font-size: 13.5px; }

/* Visionneuse plein écran (032) : la grande image pèse ~200 Ko, d'où le témoin
   d'attente — sans lui, on clique et rien ne bouge pendant deux secondes. Il
   est dessiné en CSS : un pictogramme à télécharger aurait le défaut qu'il est
   censé masquer. */
.sel-plein {
  position: fixed; inset: 0; z-index: 60; background: rgba(18, 16, 24, 0.95);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  padding: calc(18px + env(safe-area-inset-top, 0px)) 18px calc(18px + env(safe-area-inset-bottom, 0px));
}
.sel-plein[hidden] { display: none; }
.sel-plein-titre { margin: 0; color: #fff; font-weight: 600; text-align: center; }
.sel-plein-image {
  position: relative; flex: 1; min-height: 0; width: 100%;
  display: flex; align-items: center; justify-content: center;
}
.sel-plein-image img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 3px; }
.sel-plein-image.sel-chargement::after {
  content: ""; position: absolute; width: 38px; height: 38px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.25); border-top-color: #fff;
  animation: sel-tourne 0.8s linear infinite;
}
@keyframes sel-tourne { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .sel-plein-image.sel-chargement::after { animation: none; }
}
.sel-plein-fermer {
  position: absolute; top: calc(12px + env(safe-area-inset-top, 0px)); right: 14px;
  width: 40px; height: 40px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(255, 255, 255, 0.92); font-size: 24px; line-height: 1;
}
.sel-plein-onglets { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.sel-plein-onglet {
  border: 1px solid rgba(255, 255, 255, 0.45); background: transparent; color: #fff;
  border-radius: 999px; padding: 6px 14px; font-size: 13px; font-family: inherit; cursor: pointer;
}
.sel-plein-onglet.actif { background: #fff; color: var(--encre, #221E33); border-color: #fff; }
.sel-cand img { cursor: zoom-in; }

/* Le mur n'a plus de palier : auto-fill s'adapte seul. Seule la fenêtre, à
   quatre colonnes fixes, doit se replier sur les petits écrans. */
@media (max-width: 620px) {
  .sel-fen-cands { grid-template-columns: repeat(2, 1fr); }
}

/* accessibilité */
:focus-visible { outline: 2px solid var(--tampon); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .rayon-bande { animation: none; }
}
