@import url('polices.css');

/* Le classement des tourtous — feuille unique.
 *
 * Reprise de la maquette sans réinterprétation : mêmes couleurs, mêmes
 * jetons, mêmes tailles. Ce qui change, et seulement ça : les trois
 * dispositions ne sont plus choisies par un sélecteur mais par la largeur
 * réelle de l'écran.
 *
 * Règle non négociable : AUCUNE valeur d'espacement écrite en dur.
 * Tout puise dans --gx et --s1..--s5. Si un espacement paraît faux, c'est
 * le jeton qu'on change, jamais l'exception qu'on ajoute.
 */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* ⚠ Sans cette règle, l'attribut hidden ne masque RIEN dès qu'une classe
 * donne un display à l'élément : les styles d'auteur l'emportent sur ceux du
 * navigateur. Le bouton « Enregistrer » des alertes restait donc affiché
 * après que le script l'eut masqué — et comme il renvoyait l'état des cases,
 * que les interrupteurs ne touchent pas, il ramenait les réglages en arrière.
 * Trois éléments du site sont dans ce cas. */
[hidden] { display: none !important; }

:root {
  --gx: 20px;
  --s1: 6px; --s2: 10px; --s3: 16px; --s4: 24px; --s5: 34px;

  --granit: #33303a;
  --brume: #dedcd7;
  --carte: #eae8e3;
  --bruyere: #6b4a73;
  --bruyere-cl: #a17faa;
  --brule: #9b4e23;
  --vert: #4a6b52;
  --trait: #c6c3bc;
  --sourd: #807a87;
  --barre: 76px;

  /* Piles de substitution : le site doit rester lisible si les woff2
   * ne chargent pas. Georgia et la sans-serif système sont partout. */
  --titre: 'Bricolage Grotesque', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
  --texte: 'Newsreader', Georgia, 'Times New Roman', serif;
}

body {
  background: var(--brume);
  color: var(--granit);
  font-family: var(--texte);
  /* dvh et non vh : sur Safari iOS, 100vh compte la barre d'adresse
   * rétractable et fait passer la navigation sous le pli. */
  min-height: 100dvh;
  overflow-x: hidden;
}

:focus-visible { outline: 2px solid var(--bruyere); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }

.g { font-family: var(--titre); }

/* Remise à zéro des boutons SANS nommer la balise : un sélecteur
 * `button.act` serait plus spécifique que `.row` et lui volerait sa
 * gouttière — c'est arrivé, et seules les lignes cliquables étaient
 * touchées, ce qui rend le symptôme incompréhensible. */
.act {
  appearance: none; border: 0; background: transparent; font: inherit;
  cursor: pointer; width: 100%; text-align: left; color: inherit; padding: 0;
  /* Les lignes de liste sont des <a> et non des <button> : une ligne de
   * classement mène à une page, elle doit s'ouvrir dans un onglet, se
   * copier, se partager. D'où la remise à zéro du soulignement. */
  text-decoration: none; display: block;
}
.act.row { padding: var(--s2) var(--gx); }

/* ── blocs de texte ────────────────────────────────────────────── */
.tete { padding: var(--s5) var(--gx) 0; }
.eyebrow {
  font-family: var(--titre); font-size: 10px; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--bruyere); margin: 0 0 var(--s2);
}
h1 { font-family: var(--titre); font-weight: 800; font-size: 32px; line-height: .96; letter-spacing: -.03em; margin: 0; }
h2 { font-family: var(--titre); font-weight: 800; font-size: 25px; letter-spacing: -.025em; margin: 0; line-height: 1.06; }
.sub { font-size: 14.5px; font-weight: 300; color: var(--sourd); margin: var(--s2) 0 0; line-height: 1.4; }
.lab {
  font-family: var(--titre); font-size: 10px; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--sourd); padding: var(--s4) var(--gx) var(--s2); margin: 0;
}
.pad { padding: 0 var(--gx); }

/* ⚠ Aucun attribut style="" dans les pages : la CSP interdit les styles en
 * ligne (style-src 'self'), et ils sont donc IGNORÉS — sans erreur visible,
 * sans rien dans la console. Un lien coloré en ligne restait bleu souligné.
 * Tout ce qui suit remplace ces styles-là. */
.serre { margin: 0; }
.centre { text-align: center; margin: 0; }
.avant-bloc { margin: 0 0 var(--s3); }
/* le lien discret d'un bloc de texte */
.lien {
  color: var(--bruyere);
  font-family: var(--titre);
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  background: none;
  border: 0;
  width: auto;
  padding: 0;
  cursor: pointer;
}
.lien:hover { text-decoration: underline; }
/* la case à cocher des alertes, quand le script n'a pas pris la main */
.case { width: 28px; height: 28px; flex: none; }

/* L'adresse où arrivent les messages : une information, pas un champ.
 * Un <input> laissait croire qu'on pouvait la modifier là. */
.adresse {
  margin: 0;
  font-family: var(--titre);
  font-size: 15px;
  font-weight: 600;
  color: var(--granit);
  word-break: break-all;
}
.adresse span { color: var(--sourd); }

/* Le crayon du chapeau : en haut à droite, hors du chemin.
 * 44 px de cible tactile alors que le dessin n'en fait que 18 — corriger un
 * nom se fait au doigt comme le reste. */
.editer {
  position: absolute;
  top: var(--s2);
  right: var(--gx);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--sourd);
  text-decoration: none;
  cursor: pointer;
}
.editer:hover { color: var(--granit); background: var(--carte); }

/* Le suffixe d'un champ chiffré : « € » posé dans le champ, à droite. */
.avec-unite { position: relative; }
.avec-unite .champ { padding-right: var(--s5); }
.avec-unite .unite {
  position: absolute;
  right: var(--s3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--sourd);
  font-size: 16.5px;
  pointer-events: none;
}
.retour { padding: var(--s3) var(--gx) 0; }
.retour .act { width: auto; font-family: var(--titre); font-size: 12px; font-weight: 600; color: var(--sourd); }

/* ── le vote ───────────────────────────────────────────────────── */

/* Le tourtou et sa note restent en haut pendant qu'on fait défiler : on lit
 * les avis de la famille sans perdre de vue ce dont on parle, et on peut
 * changer sa note à tout moment sans remonter.
 *
 * Le fond est opaque et l'ombre marque le passage : sans elle, le contenu
 * qui glisse dessous semble s'effacer au lieu de passer derrière.
 * Un seul bloc collant, sinon deux éléments sticky voisins se recouvrent. */
.tete-fiche {
  position: sticky;
  top: 0;
  z-index: 6;
  background: var(--brume);
}

/* L'ombre est portée par le BANDEAU DE NOTE seul, et seulement quand du
 * contenu passe réellement derrière lui. Une ombre permanente, ou posée sur
 * tout le bloc, dessine une séparation là où rien ne se chevauche.
 * La classe est posée par vote.js, qui mesure le chevauchement. */
/* Les deux ombres ont la MÊME géométrie : seule l'opacité change.
 * Une transition qui part de « none » n'est pas interpolable — elle restait
 * figée sur une ombre transparente, et l'ombre n'apparaissait jamais, alors
 * que la classe était bien posée. */
.tete-fiche .vote { box-shadow: 0 6px 14px rgba(51, 48, 58, 0); }
.tete-fiche.ombre .vote { box-shadow: 0 6px 14px rgba(51, 48, 58, .19); }
.vote { transition: padding .34s cubic-bezier(.22, .9, .26, 1.16), box-shadow .18s ease-out; }

/* Sur mobile, le bloc collant prenait 485 px sur 780 : le tourtou perd 20 %
 * pour laisser de quoi lire. Sur grand écran il n'y a pas de raison de le
 * réduire, la place ne manque pas. */
@media (max-width: 767px) {
  .tete-fiche .chapeau svg { width: 120px; height: auto; }
  .tete-fiche .chapeau h2 { font-size: 21px; }
  .tete-fiche .chapeau { padding-top: var(--s2); }
}

.chapeau { position: relative; padding: var(--s3) var(--gx) var(--s2); text-align: center; }

/* Pendant qu'on règle les curseurs, il faut voir le tourtou changer — c'est
 * la seule raison d'ouvrir ce bloc. Plutôt que de rapetisser le dessin, qui
 * est ce qu'on vient regarder, on fait DESCENDRE la note d'un cran : les
 * curseurs se glissent juste sous le tourtou, et le vote reste visible
 * immédiatement en dessous.
 *
 * Tout se joue sur l'ordre d'affichage, pas sur le document : le HTML garde
 * le bloc de vote avant le reste, comme le veut le brief, et rien n'est
 * déplacé pour un lecteur d'écran ni pour la navigation au clavier. */
/* Rien ne se déplace : le bloc de note reste où il est, et se REPLIE en
 * bandeau pendant qu'on règle les détails. On gagne la hauteur du titre, de
 * l'aide et des grands disques — assez pour que les curseurs remontent près
 * du tourtou, qui garde sa taille.
 *
 * Le repli est animé, et l'amorti dépasse légèrement avant de revenir :
 * un bloc qui s'arrête net paraît calculé, un bloc qui amortit paraît avoir
 * du poids. La courbe est asymétrique — retenue au départ, franche à la fin.
 * (@media prefers-reduced-motion, plus haut, coupe tout ça d'un coup.) */
.vote .val { transition: font-size .34s cubic-bezier(.22, .9, .26, 1.16); }
.dq svg { transition: width .34s cubic-bezier(.22, .9, .26, 1.16), opacity .12s, filter .12s, transform .12s; }
.plus .corps { transition: opacity .2s ease-out; }
body.note-repliee .vote {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) var(--gx);
  text-align: left;
}
body.note-repliee .vote .q,
body.note-repliee .vote .aide { display: none; }
body.note-repliee .vote .disques { gap: 2px; }
/* 36 px de dessin + 2×4 px de marge : la cible reste au-dessus de 44 px. */
body.note-repliee .dq { padding: 4px; }
body.note-repliee .dq svg { width: 36px; height: auto; }
/* nowrap : sans lui, le « / 5 » passe à la ligne dans le bandeau serré et la
 * note se lit sur deux lignes. */
body.note-repliee .vote .val { margin: 0 0 0 auto; font-size: 22px; white-space: nowrap; }
body.note-repliee .vote .val.vide { font-size: 14px; }

/* Le chevron qui redéploie la note. 44 px de cible, comme le reste. */
.deplier {
  flex: none;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: #a8a2ae;
  cursor: pointer;
  transform: rotate(180deg);
}
.deplier:hover { color: var(--brume); background: rgba(255, 255, 255, .08); }
.vote { background: var(--granit); color: var(--brume); padding: var(--s4) var(--gx); text-align: center; }
.vote .q { font-family: var(--titre); font-weight: 800; font-size: 20px; letter-spacing: -.02em; margin: 0; }
.vote .aide { font-size: 14px; font-weight: 300; color: #a8a2ae; margin: var(--s1) 0 var(--s3); line-height: 1.35; }
.disques { display: flex; justify-content: center; gap: var(--s1); }

/* Cible tactile : 46 px de dessin + 2×4 px = 54 px, au-dessus des 44 px
 * exigés. La demi-note se prend sur la moitié gauche du disque. */
.dq { position: relative; background: transparent; border: 0; padding: 4px; cursor: pointer; line-height: 0; border-radius: 10px; }
.dq svg { opacity: .24; filter: grayscale(.85); transition: opacity .12s, filter .12s, transform .12s; }
.dq.on svg { opacity: 1; filter: none; }
.dq.demi svg { opacity: 1; filter: none; clip-path: inset(0 50% 0 0); }
.dq:hover svg { transform: scale(1.06); }
.vote .val { font-family: var(--titre); font-weight: 800; font-size: 30px; letter-spacing: -.03em; margin: var(--s3) 0 0; }
.vote .val small { font-size: 14px; color: #a8a2ae; font-weight: 600; }
.vote .val.vide { color: #7d7684; font-size: 17px; font-weight: 600; letter-spacing: 0; }

/* Le retour immédiat après la touche : c'est lui qui donne envie de
 * recommencer. Il ne doit jamais sauter pour gagner de la place. */
.recu {
  background: var(--vert); color: #eaf2ec; display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--gx); font-family: var(--titre); font-size: 13.5px; font-weight: 600;
}
.recu .act { margin-left: auto; width: auto; color: #eaf2ec; text-decoration: underline; }

/* Toute action a une branche d'erreur VISIBLE : une case qui revient à sa
 * place sans un mot se lit comme « je m'y prends mal », pas comme « le
 * site a refusé ». */
.rate {
  background: var(--brule); color: #f7ece5; display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--gx); font-family: var(--titre); font-size: 13.5px; font-weight: 600;
}
.rate .act { margin-left: auto; width: auto; color: #f7ece5; text-decoration: underline; }

/* ── le repli des critères facultatifs ─────────────────────────── */
.plus { border-top: 1px solid var(--trait); border-bottom: 1px solid var(--trait); }
.plus > .act {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--gx); background: var(--carte);
}
.plus > .act .signe {
  flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--bruyere); color: #f4eff6;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--titre); font-weight: 600; font-size: 19px; line-height: 1;
}
/* display:block parce que ce sont des <span> : un <p> est interdit dans un
 * <button> et lui fait perdre son nom accessible. */
.plus > .act .titre { display: block; font-family: var(--titre); font-size: 15px; font-weight: 600; color: var(--granit); margin: 0; }
.plus > .act .aide { display: block; font-size: 13.5px; font-weight: 300; color: var(--sourd); margin: 2px 0 0; line-height: 1.3; }
.plus .corps { padding: var(--s4) var(--gx); display: none; }
.plus.ouvert .corps { display: block; }

.sl { margin: 0 0 var(--s3); }
.sl .slab {
  font-family: var(--titre); font-size: 10.5px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--granit); margin: 0;
}
.ends { display: flex; justify-content: space-between; font-size: 13px; font-weight: 300; color: var(--sourd); }

/* ⚠ La HAUTEUR de l'input, pas celle du rail.
 * Un input[type=range] sans hauteur déclarée prend celle de son rail — ici
 * 3 px. La zone qu'on peut attraper faisait donc 3 pixels de haut : à peine
 * saisissable à la souris, impossible au doigt, et très loin des 44 px de
 * cible tactile exigés. Le rail reste fin, c'est l'input qui est haut. */
input[type=range] {
  -webkit-appearance: none; appearance: none;
  width: 100%; display: block; background: transparent;
  height: 44px;
  margin: var(--s1) 0 0;
  cursor: pointer;
}
input[type=range]::-webkit-slider-runnable-track { height: 3px; background: var(--trait); }
input[type=range]::-moz-range-track { height: 3px; background: var(--trait); }
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--bruyere); margin-top: -11.5px; cursor: pointer; box-shadow: 0 1px 3px rgba(0, 0, 0, .28);
}
input[type=range]::-moz-range-thumb { width: 26px; height: 26px; border: 0; border-radius: 50%; background: var(--bruyere); }

/* ── champs ────────────────────────────────────────────────────── */
.champ {
  width: 100%; background: var(--carte); border: 1px solid var(--trait); padding: var(--s3);
  font-family: var(--texte); font-size: 16.5px; color: var(--granit); display: block;
}
.champ::placeholder { color: #9d98a3; }
.champ.gros { font-family: var(--titre); font-weight: 600; font-size: 19px; }
.f {
  display: block; font-family: var(--titre); font-size: 10px; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--sourd); margin: 0 0 var(--s1);
}
.pile { display: grid; gap: var(--s3); }

/* ── lignes de liste ───────────────────────────────────────────── */
.tete + .bandeau { margin-top: var(--s4); }
.espace { height: var(--s5); }
.row { display: flex; align-items: center; gap: var(--s2); padding: var(--s2) var(--gx); border-top: 1px solid var(--trait); width: 100%; }
.row + .lab { border-top: 1px solid var(--trait); }
.row .n { font-family: var(--titre); font-weight: 600; font-size: 13px; color: var(--sourd); width: 15px; flex: none; }
.row .txt { flex: 1; min-width: 0; }
.row .nom {
  font-family: var(--titre); font-weight: 600; font-size: 15.5px; letter-spacing: -.01em; margin: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row .lieu { font-size: 13.5px; font-weight: 300; color: var(--sourd); margin: 2px 0 0; }
.row .sc { font-family: var(--titre); font-weight: 800; font-size: 19px; color: var(--bruyere); flex: none; }
/* Un lieu jamais noté n'a pas de rang : la pastille prend la place du
 * score, et c'est elle qui appelle l'action. */
.row .anoter {
  flex: none; font-family: var(--titre); font-size: 11px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: #f4eff6;
  background: var(--bruyere); padding: 7px 11px; border-radius: 999px;
}
.row.actif { background: var(--carte); box-shadow: inset 3px 0 0 var(--bruyere); }
.fin { border-bottom: 1px solid var(--trait); }

.cta {
  display: block; width: 100%; background: var(--bruyere); color: #f4eff6; border-radius: 999px;
  padding: var(--s3); font-family: var(--titre); font-weight: 600; font-size: 15.5px;
  text-align: center; cursor: pointer; border: 0;
}
.cta.ghost { background: transparent; color: var(--granit); box-shadow: inset 0 0 0 1.5px var(--granit); }
.cta:disabled { opacity: .38; cursor: not-allowed; }
.foot { padding: var(--s4) var(--gx) var(--s5); display: grid; gap: var(--s2); }

.avis { border-top: 1px solid var(--trait); padding: var(--s3) var(--gx); }
.avis p { font-size: 16px; font-weight: 300; line-height: 1.5; margin: 0 0 var(--s1); font-style: italic; }
.avis .who { font-family: var(--titre); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--bruyere); }

.bandeau { background: #efe4d3; border-bottom: 1px solid #d9c9b0; padding: var(--s3) var(--gx); display: flex; align-items: center; gap: var(--s3); }
.bandeau p { margin: 0; font-size: 14.5px; font-weight: 300; line-height: 1.35; }
.bandeau b { font-family: var(--titre); font-weight: 600; font-size: 14px; }
.bandeau .go {
  flex: none; font-family: var(--titre); font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: #f4eff6; background: var(--granit);
  padding: 8px 12px; border-radius: 999px; cursor: pointer; border: 0; width: auto;
}

.opt { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) var(--gx); border-top: 1px solid var(--trait); }
.opt p { margin: 0; font-size: 15.5px; font-weight: 300; line-height: 1.3; }
.opt .d { font-size: 13.5px; color: var(--sourd); margin-top: 2px; }
.sw { flex: none; width: 48px; height: 28px; border-radius: 999px; background: var(--trait); position: relative; cursor: pointer; border: 0; padding: 0; }
.sw::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; transition: left .14s; }
.sw[aria-checked="true"] { background: var(--bruyere); }
.sw[aria-checked="true"]::after { left: 23px; }

/* Les pages sans navigation — entrée, lien reçu par e-mail. Une colonne
 * centrée, rien d'autre à l'écran que ce qu'on doit faire.
 *
 * ⚠ Le .shell devient une grille à partir de la tablette. Sans la règle
 * ci-dessous, ce bloc se retrouve dans la PREMIÈRE colonne — 222 px, celle
 * prévue pour le rail — et le formulaire d'entrée paraît minuscule et collé
 * à gauche. Ces pages n'ont pas de colonnes : le shell redevient un bloc. */
.seul { width: 100%; max-width: 460px; margin: 0 auto; padding: 0 var(--gx); }
.seul .pile { margin-top: var(--s4); }

body.vue-entree .shell {
  /* Ni grille ni colonnes : le bloc est posé au milieu de l'écran, et il
   * défile normalement si le contenu dépasse. */
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  height: auto;
  padding: var(--s5) 0;
}
/* Les gouttières viennent de .seul : sans cette remise à zéro, elles
 * s'ajouteraient à celles des blocs qu'il contient. */
body.vue-entree .seul .tete,
body.vue-entree .seul .pad,
body.vue-entree .seul .foot { padding-left: 0; padding-right: 0; }

/* ═══ MOBILE — la référence, c'est là que ça se joue ═══════════════ */

.rail { display: none; }
.shell { display: block; }
/* Une seule vue à la fois : la classe posée sur <body> par la page PHP
 * décide, sans une ligne de JavaScript. */
body.vue-classement .detail { display: none; }
body.vue-tourtou .colonne,
body.vue-ajouter .colonne,
body.vue-alertes .colonne,
body.vue-moi .colonne { display: none; }

/* Le contenu doit pouvoir défiler AU-DESSUS de la barre : sans cette
 * réserve, la dernière ligne de liste reste cachée dessous. */
.shell { padding-bottom: calc(var(--barre) + env(safe-area-inset-bottom, 0px)); }

/* fixed et non sticky : sticky se fait recouvrir dès qu'un ancêtre a un
 * overflow, et le symptôme est intermittent. */
.tabs {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  height: calc(var(--barre) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--granit);
  display: grid; grid-template-columns: 1fr 1fr 84px 1fr 1fr; align-items: center;
}
.tab {
  background: transparent; border: 0; cursor: pointer; font-family: var(--titre); font-size: 10px;
  font-weight: 600; color: #8b8492; text-align: center; line-height: 1.6; padding: 0;
  text-decoration: none; display: block;
}
.tab[aria-current="page"] { color: var(--brume); }
.tab .ic { display: block; font-size: 16px; }
/* Le + au centre, sous le pouce. */
.tabadd {
  grid-column: 3; justify-self: center; width: 62px; height: 62px; border-radius: 50%;
  background: var(--bruyere); color: #f4eff6; border: 4px solid var(--granit); margin-top: -22px;
  cursor: pointer; font-family: var(--titre); font-weight: 800; font-size: 26px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35); text-decoration: none;
}

.colonne, .detail { min-width: 0; }
.deux .droite { display: none; }

/* ═══ TABLETTE — deux colonnes, on note à la chaîne ════════════════ */
@media (min-width: 768px) {
  :root { --gx: 26px; }
  .colonne { --gx: 20px; }

  .tabs { display: none; }
  .shell {
    display: grid; grid-template-columns: 340px 1fr;
    height: 100dvh; padding-bottom: 0;
  }
  /* Les colonnes défilent indépendamment : on garde la liste en place
   * pendant qu'on lit une fiche. */
  .colonne { border-right: 1px solid var(--trait); overflow-y: auto; }
  .detail { overflow-y: auto; background: var(--brume); }
  body.vue-classement .detail,
  body.vue-tourtou .colonne,
  body.vue-ajouter .colonne,
  body.vue-alertes .colonne,
  body.vue-moi .colonne { display: block; }
  .retour { display: none; }

  /* Pas de colonne de liste sur ces pages : une seule colonne, sinon leur
   * contenu se retrouve dans les 340 px réservés au classement. */
  body.vue-ajouter .shell,
  body.vue-alertes .shell,
  body.vue-moi .shell { grid-template-columns: 1fr; }
}

/* ═══ ORDINATEUR — trois colonnes ══════════════════════════════════ */
@media (min-width: 1100px) {
  .shell { grid-template-columns: 222px 360px 1fr; }
  /* Ces pages n'ont pas de colonne de liste : sans cette règle, leur contenu
   * irait se loger dans les 360 px prévus pour le classement. Même cause que
   * le formulaire d'entrée coincé dans la colonne du rail. */
  body.vue-ajouter .shell,
  body.vue-alertes .shell,
  body.vue-moi .shell { grid-template-columns: 222px 1fr; }
  body.vue-ajouter .detail > .deux,
  body.vue-alertes .detail > .deux,
  body.vue-moi .detail > .deux { grid-template-columns: minmax(0, 640px); }
  .rail {
    display: flex; flex-direction: column; gap: 2px;
    background: var(--granit); color: var(--brume); padding: var(--s5) var(--s3);
  }
  .rail .marque { font-family: var(--titre); font-weight: 800; font-size: 19px; line-height: 1.05; letter-spacing: -.02em; margin: 0 0 var(--s4); }
  .rail a, .rail .act {
    display: flex; align-items: center; gap: var(--s2); background: transparent; border: 0;
    color: #a49dab; cursor: pointer; font-family: var(--titre); font-size: 14px; font-weight: 600;
    padding: var(--s2) var(--s3); border-radius: 8px; text-align: left; width: 100%; text-decoration: none;
  }
  .rail a[aria-current="page"] { background: #46424f; color: var(--brume); }
  .rail .ajout { margin-top: var(--s3); background: var(--bruyere); color: #f4eff6; justify-content: center; }
  .rail .moi { margin-top: auto; color: #8b8492; font-size: 13px; }

  .deux { display: grid; grid-template-columns: 1fr 320px; min-height: 100%; }
  /* « Reste à noter » reste sous les yeux, comme le tourtou : c'est une liste
   * d'appels à l'action, elle ne sert à rien une fois défilée hors champ.
   * align-self:start est indispensable — sans lui la colonne s'étire sur
   * toute la hauteur de la grille et n'a plus rien à faire coller. */
  .deux .droite {
    display: block;
    border-left: 1px solid var(--trait);
    --gx: 20px;
    position: sticky;
    top: 0;
    align-self: start;
    /* min ET max à la hauteur de l'écran : align-self:start réduit la
     * colonne à son contenu, et le filet de séparation s'arrêtait alors au
     * milieu de la page au lieu de descendre jusqu'en bas. */
    min-height: 100dvh;
    max-height: 100dvh;
    overflow-y: auto;
  }
  h1 { font-size: 26px; }
}

/* La mention qui distingue l'adresse d'inscription des adresses ajoutées. */
.marque-adresse {
  font-family: var(--titre);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sourd);
  border: 1px solid var(--trait);
  border-radius: 999px;
  padding: 2px 7px;
  margin-left: var(--s1);
  vertical-align: middle;
}

/* ── Les notifications ─────────────────────────────────────────────
 * En haut à droite, posées par-dessus la page : un bandeau inséré dans le
 * flux pousse tout le contenu au moment où on regarde ailleurs.
 *
 * Sobres, à la façon du système : un fond translucide et flouté, des angles
 * très arrondis, une ombre large et douce, et le texte dans la couleur du
 * site. La couleur ne sert qu'à une pastille — un aplat vert ou orange plein
 * écran crie plus fort que ce que le message mérite. */
.notifs {
  position: fixed;
  top: var(--s3);
  right: var(--s3);
  left: var(--s3);
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--s2);
  pointer-events: none;
}
@media (min-width: 560px) {
  .notifs { left: auto; max-width: 340px; }
}

.notif {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--s2);
  width: 100%;
  padding: var(--s2) var(--s3);
  border-radius: 16px;
  background: rgba(222, 220, 215, .88);
  /* le flou est ce qui donne la matière ; sans lui, le fond translucide
     paraît simplement délavé */
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(51, 48, 58, .08);
  box-shadow: 0 10px 32px rgba(51, 48, 58, .16);
  /* Le fond du site, et un texte adouci : une notification informe, elle
     n'a pas à crier plus fort que le contenu. */
  color: #57535f;
  font-family: var(--titre);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
}

/* La pastille : le seul endroit coloré. */
.notif::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--vert);
}
.notif.rate::before { background: var(--brule); }

.notif-texte { flex: 1; min-width: 0; }
.notif-texte sup { font-size: .7em; }

.notif-action {
  flex: none;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--bruyere);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  cursor: pointer;
}
.notif-action:hover { background: rgba(107, 74, 115, .1); }

.notif-fermer {
  flex: none;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--sourd);
  font-size: 17px;
  line-height: 1;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  cursor: pointer;
  opacity: .55;
}
.notif-fermer:hover { opacity: 1; background: rgba(51, 48, 58, .08); }

/* ── Corriger en place ─────────────────────────────────────────────
 * Les champs prennent la place exacte du texte qu'ils remplacent. */
.edition { display: grid; gap: var(--s2); text-align: left; margin-top: var(--s2); }
.champ-place {
  width: 100%;
  background: var(--carte);
  border: 1px solid var(--trait);
  border-radius: 8px;
  padding: var(--s2) var(--s3);
  font-family: var(--texte);
  font-size: 15px;
  color: var(--granit);
}
.champ-place.gros {
  font-family: var(--titre);
  font-weight: 800;
  font-size: 21px;
  letter-spacing: -.02em;
}
.edition-boutons { display: flex; gap: var(--s2); }
.edition-boutons .cta { flex: 1; padding: var(--s2) var(--s3); font-size: 14px; }

/* ── Arrivée et petits gestes ──────────────────────────────────────
 * Un fondu, court et discret. Rien qui glisse, rien qui rebondit à
 * l'ouverture d'une page : ce qu'on vient chercher, c'est le classement,
 * pas une mise en scène.
 *
 * ⚠ Aucune transform sur .detail ni ses ancêtres : elle annulerait
 * position:sticky du bloc du tourtou et de la colonne « Reste à noter ».
 * Le fondu, lui, ne touche que l'opacité. */
@keyframes entree-fondu { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: no-preference) {
  .shell { animation: entree-fondu .16s ease-out both; }
}

/* Les gestes, eux, répondent : c'est ce qui donne le sentiment que le site
 * est vivant sous le doigt, sans rien animer à l'écran. */
.cta, .dq, .tab, .tabadd, .sw, .editer, .deplier, .notif-action {
  transition: transform .12s cubic-bezier(.3, .8, .4, 1);
}
.cta:active, .tab:active, .editer:active, .deplier:active, .notif-action:active { transform: scale(.95); }
.tabadd:active { transform: scale(.92); }
.dq:active { transform: scale(.9); }
.row { transition: background .14s ease-out; }
.act.row:hover { background: rgba(51, 48, 58, .045); }

/* ── Le logo ───────────────────────────────────────────────────────
 * Sa typographie vient de la feuille, pas d'un attribut : un attribut SVG
 * n'accepte pas var(--titre), et le logo doit porter la même police que les
 * titres du site — c'est le principe même de cette identité, le logo étant
 * composé comme un titre. */
.logo text, .logo-rail text { font-family: var(--titre); }
.logo { display: block; width: 100%; max-width: 260px; height: auto; margin: 0 auto var(--s4); }
.logo-rail { display: block; width: 100%; max-width: 190px; height: auto; margin: 0 0 var(--s4); }
