/* Identité visuelle « Kraft » (B1), posée le 22/09 au soir, retenue parmi
   six maquettes (canevas « PickOne — propositions de mise en page ») : les
   listes et les cadeaux sont des ÉTIQUETTES CADEAU — coin coupé, trou pour
   la ficelle, liseré de couleur en pied — posées sur un fond papier. Ce qui
   est offert porte un CACHET daté, ce qui attend une décision est un
   POST-IT, et les petites mentions sont écrites à la main.

   Palette tirée du logo, comme la première passe : encre, corail, vert du
   badge-coche, jaune-ruban. Le corail des ACTIONS est assombri (#B8382A) :
   le #E14F3D du logo, en bouton plein sous du texte blanc ou en lien sur le
   papier, plafonne vers 3,9:1 — sous les 4,5:1 demandés pour du texte
   courant. Il reste celui des liserés et du cœur, où il n'y a rien à lire.

   Polices AUTO-HÉBERGÉES (static/cadeaux/polices/, licence OFL à côté) :
   pas d'appel à Google Fonts, donc pas d'adresse IP de visiteur envoyée à
   un tiers — et une page de partage qui s'affiche pareil hors ligne. */
@font-face {
  font-family: "Lora"; font-weight: 700; font-style: normal; font-display: swap;
  src: url("polices/lora-700.9c4d5c38f969.woff2") format("woff2");
}
@font-face {
  font-family: "Figtree"; font-weight: 400; font-style: normal; font-display: swap;
  src: url("polices/figtree-400.7bfd10a3def3.woff2") format("woff2");
}
@font-face {
  font-family: "Figtree"; font-weight: 600; font-style: normal; font-display: swap;
  src: url("polices/figtree-600.4376f5953b85.woff2") format("woff2");
}
@font-face {
  font-family: "Figtree"; font-weight: 700; font-style: normal; font-display: swap;
  src: url("polices/figtree-700.70aaa6879de5.woff2") format("woff2");
}
@font-face {
  font-family: "Caveat"; font-weight: 700; font-style: normal; font-display: swap;
  src: url("polices/caveat-700.9700119a3654.woff2") format("woff2");
}

:root {
  color-scheme: light dark;
  --fond: #F4EDE1;          /* le papier */
  --carte: #FFFBF3;         /* une étiquette, un formulaire */
  --texte: #22201C;
  --discret: #6B665C;
  --trait: #E0D5C2;
  --trou: #D8C9AE;          /* le bord du trou de ficelle, les liserés neutres */
  --kraft: #8A5A2B;         /* l'encre des mentions écrites à la main */
  --accent: #B8382A;        /* les actions : boutons pleins, liens */
  --sur-accent: #FFFFFF;    /* le texte posé sur l'accent */
  --corail: #E14F3D;        /* le liseré d'un coup de cœur, le cœur */
  --succes: #14803D;
  --sur-succes: #FFFFFF;    /* le texte posé sur le vert (pastille « Déjà acheté ») */
  --alerte: #9a3412;
  --postit: #FEF1B8;
  --postit-encre: #6A4A00;
  --postit-trait: #D9C27A;
  --ombre: rgba(80, 60, 20, 0.12);
  /* Le ruban doré d'un cadeau offert (24/09) : --ruban pour ce qui décore
     (ruban, liseré, fond du bouton, sous une encre sombre), --ruban-encre
     pour ce qui se lit (le cachet, la ligne « Offert le … ») — le doré
     lui-même plafonne sous 3:1 sur le papier. */
  --ruban: #E0A82E;
  --ruban-encre: #7A5200;
  /* Couleurs du mot "One" dans le logo d'en-tête : vert (badge) sur fond
     clair, corail sur fond sombre -- comme ".gift" dans le logo complet.
     "Pick" suit la même bascule : encre, puis jaune-ruban. */
  --marque-pick: #22201C;
  --marque-un: #14803D;
  /* La couverture kraft d'un carnet (une liste, voir .liste), son dos et
     sa tranche. */
  --couverture: #C99A6B;
  --couverture-dos: #A97B4F;
  --couverture-bord: #9C7046;
}
@media (prefers-color-scheme: dark) {
  /* Le papier devient un BLEU NUIT (25/09). Deux essais avant lui : le
     carton presque noir d'origine (#1E1B17), qui se lisait comme un écran
     éteint, les étiquettes s'y distinguant à peine (1,14:1) ; puis un brun
     plus clair, qui faisait sale. Sur le bleu nuit, le corail, le
     jaune-ruban et le vert du logo ressortent. L'accent et les encres sont
     éclaircis pour garder au moins 4,5:1 sur l'étiquette — vérifié par
     `ThemeSombreTest`, qui recalcule chaque contraste depuis ce bloc. Les
     couvertures de carnet passent du kraft brun au bleu ardoise. */
  :root {
    --fond: #1C2230; --carte: #283042; --texte: #F3F5FA; --discret: #B9C2D6;
    --trait: #3A4560; --trou: #4E5A78; --kraft: #E8CDA4;
    --accent: #FF9B87; --sur-accent: #1C2230; --corail: #FF8E78;
    --succes: #7AD9A0; --sur-succes: #1C2230; --alerte: #FFB88C;
    --postit: #4A4222; --postit-encre: #FFE490; --postit-trait: #7D6A33;
    --ombre: rgba(0, 0, 0, 0.35);
    --ruban: #E8B84A; --ruban-encre: #FFE490;
    --marque-pick: #FFE490; --marque-un: #FF9B87;
    --couverture: #4A5B7C; --couverture-dos: #3A4865; --couverture-bord: #2B3650;
  }
}

* { box-sizing: border-box; }
/* Une règle posant `display` peut l'emporter sur l'attribut [hidden] selon
   sa spécificité et son ordre : posé une bonne fois, comme sur soireejeux. */
[hidden] { display: none !important; }
body {
  margin: 0; background: var(--fond); color: var(--texte);
  font: 16px/1.5 Figtree, system-ui, -apple-system, "Segoe UI", sans-serif;
}
a { color: var(--accent); }

/* -- L'en-tête ------------------------------------------------------------ */

header {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  flex-wrap: wrap;
  padding: 14px 20px;
}
@media (min-width: 720px) { header { padding: 16px 32px; } }
@media (min-width: 1080px) { header { padding: 18px 48px; } }
header form { display: flex; align-items: center; gap: 12px; margin: 0; }
.marque {
  display: flex; align-items: center; gap: 10px;
  font-family: Lora, Georgia, serif; font-weight: 700; font-size: 1.35rem;
  color: inherit; text-decoration: none;
}
.marque-icone { display: block; width: 34px; height: 34px; flex: none; }
.marque-texte { color: var(--marque-pick); }
.marque-un { color: var(--marque-un); }
.marque-domaine { color: var(--discret); }
.qui { font-size: .95rem; }
.lien {
  background: none; border: 0; padding: 0; font: inherit; font-size: .9rem;
  color: var(--accent); text-decoration: underline; cursor: pointer;
  white-space: nowrap;
}

/* L'en-tête collé des pages de liste (26/09, demandé par Arnaud ; voir
   _entete_liste.html). Toujours en haut de l'écran sur ces deux pages, sur
   le fond du papier. Quand le titre de la page est passé dessous
   (.entete-compacte, posée par site.js), il reçoit un filet et une ombre,
   et le nom de la liste et le prénom apparaissent entre l'icône et le
   menu. Sur un téléphone, il n'y a de place que
   pour eux : le site s'y réduit à son icône, le menu à l'avatar. */
header[data-entete-liste] {
  position: sticky; top: 0; z-index: 30;
  background: var(--fond);
  transition: box-shadow .2s;
}
/* Une ancre (« #ajouter », « #offerts ») ne doit pas finir sous l'en-tête. */
html:has(header[data-entete-liste]) { scroll-padding-top: 84px; }
.entete-liste-fixe {
  flex: 1 1 0; min-width: 0; height: 44px; display: none;
  flex-direction: column; justify-content: center; line-height: 1.1;
}
.entete-liste-qui { font-size: 1.05rem; line-height: 1; }
.entete-liste-titre {
  font-family: Lora, Georgia, serif; font-weight: 700; font-size: 1.15rem;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
/* Même hauteur déplié ou non : un en-tête collé qui changerait de taille
   ferait sauter la page, et le titre repasserait le seuil en boucle. */
header.entete-compacte {
  flex-wrap: nowrap;
  box-shadow: 0 1px 0 var(--trait), 0 6px 16px var(--ombre);
}
header.entete-compacte .entete-liste-fixe { display: flex; animation: entete-apparait .2s ease-out; }
@keyframes entete-apparait { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  header[data-entete-liste] { transition: none; }
  header.entete-compacte .entete-liste-fixe { animation: none; }
}
@media (max-width: 719px) {
  header.entete-compacte { gap: 12px; }
  header.entete-compacte .marque-texte,
  header.entete-compacte .menu-compte .qui,
  header.entete-compacte > a.lien { display: none; }
  header.entete-compacte .menu-compte > summary { padding-left: 6px; }
}

/* -- La page -------------------------------------------------------------- */

main { max-width: 680px; margin: 0 auto; padding: 16px 20px 56px; }
@media (min-width: 720px) {
  main { max-width: 920px; padding: 20px 32px 64px; }
}
@media (min-width: 1080px) {
  main { max-width: 1240px; padding: 24px 48px 72px; }
}
h1 {
  font-family: Lora, Georgia, serif; font-weight: 700;
  font-size: 2.1rem; line-height: 1.1; letter-spacing: -.01em;
  margin: 0 0 20px;
}
@media (min-width: 720px) { h1 { font-size: 2.8rem; } }
h2 {
  font-family: Lora, Georgia, serif; font-weight: 700;
  font-size: 1.45rem; line-height: 1.2; margin: 36px 0 16px;
}
h3 { font-family: Lora, Georgia, serif; font-weight: 700; }

/* Ce qui est « écrit à la main » : les mentions courtes seulement (pour
   qui est une liste, un coup de cœur, un aparté à côté d'un titre). Jamais
   un paragraphe — Caveat se lit mal au-delà de quelques mots. */
.manuscrit {
  font-family: Caveat, "Segoe Print", cursive; font-weight: 700;
  font-size: 1.4rem; line-height: 1.15; color: var(--kraft);
}
.entete-section .manuscrit { font-size: 1.35rem; }
p.manuscrit { margin: 0; }
/* Un aparté à la main au bout d'une phrase d'explication : un cran sous
   la taille par défaut, pour ne pas écraser le texte qui le précède. */
.detail .manuscrit { font-size: 1.3rem; }
/* Le titre d'une page, surmonté d'une mention à la main (« la liste de
   Céline »). */
.surtitre { display: block; margin: 0 0 2px; }
h1 + .detail { margin-top: -12px; margin-bottom: 20px; }

.detail { margin: 0; color: var(--discret); font-size: .94rem; }
.attente { color: var(--alerte); }
.avertissement {
  margin: 10px 0 0; padding: 10px 12px; border-radius: 8px; font-size: .9rem;
  color: var(--alerte); background: color-mix(in srgb, var(--alerte) 10%, transparent);
}
.vide { font-family: Caveat, cursive; font-weight: 700; font-size: 1.4rem; color: var(--kraft); }
.retour { margin: 0 0 6px; }
.retour a { color: var(--kraft); font-size: .95rem; font-weight: 600; text-decoration: none; }
.retour a:hover { text-decoration: underline; }

/* -- Les étiquettes ------------------------------------------------------- */

/* Un seul conteneur pour les listes de « Mes listes », les cadeaux d'une
   liste et ceux de la page de partage : une colonne sur mobile, autant
   qu'il en tient ensuite. */
.grille-cartes { display: grid; gap: 20px; }
@media (min-width: 640px) {
  .grille-cartes { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 24px; }
}

/* L'étiquette elle-même. Le coin coupé est un clip-path : il rogne aussi
   toute ombre et tout contour posés sur l'élément, d'où un survol et un
   focus signalés par la couleur du papier plutôt que par une ombre. Le trou
   de ficelle est un ::before, le liseré de couleur une bordure basse (que
   le clip-path épargne, il ne coupe que les coins du haut). */
.cadeau {
  position: relative;
  display: flex; flex-direction: column; gap: 4px;
  min-height: 190px;
  padding: 42px 20px 18px;
  background: var(--carte);
  border-bottom: 5px solid var(--trou);
  clip-path: polygon(24px 0, calc(100% - 24px) 0, 100% 24px, 100% 100%, 0 100%, 0 24px);
}
.cadeau::before {
  content: ""; position: absolute; top: 14px; left: 50%; margin-left: -8px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--fond); box-shadow: inset 0 0 0 2px var(--trou);
}
.liste h3, .cadeau h3 { margin: 0; font-size: 1.3rem; line-height: 1.2; }
.liste h3 a, .cadeau h3 a { color: inherit; text-decoration: none; }
.liste h3 a:hover { text-decoration: underline; }
/* Ce qui se lit en bas de l'étiquette : actions, prix, alerte. */
.liste .pied, .cadeau .pied {
  margin-top: auto; padding-top: 10px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 14px;
}
.pied .liens { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: .92rem; font-weight: 600; }
.prix { font-size: 1.25rem; font-weight: 700; }

/* Le liseré d'un coup de cœur. */
.cadeau.coup-de-coeur { border-bottom-color: var(--corail); }

/* Les listes sont des CARNETS (25/09, piste A retenue par Arnaud parmi
   quatre) : une couverture kraft reliée à gauche (l'ombre intérieure fait
   le dos), un élastique vertical à la couleur du rôle (::after), et le
   contenu sur une page crème. Ni coin coupé ni trou de ficelle : ceux-là
   sont aux cadeaux, et c'est ce qui distingue les deux d'un coup d'œil.
   --role porte la couleur : corail pour moi, vert je gère, alerte quand
   personne ne la gère. */
.liste {
  --role: var(--trou);
  position: relative;
  display: flex; flex-direction: column;
  min-height: 200px;
  padding: 20px 36px 18px 30px;
  background: var(--couverture);
  border-radius: 4px 14px 14px 4px;
  box-shadow: inset 12px 0 0 var(--couverture-dos), 0 2px 0 var(--couverture-bord), 0 10px 20px var(--ombre);
}
.liste::after {
  content: ""; position: absolute; top: 0; bottom: 0; right: 16px;
  width: 8px; border-radius: 2px; background: var(--role);
}
.liste-page {
  display: flex; flex-direction: column; gap: 4px; flex-grow: 1;
  padding: 14px 14px 16px; border-radius: 6px;
  background: var(--carte); box-shadow: 0 1px 0 rgba(0, 0, 0, .10);
}
.liste h3 { margin: 0; font-size: 1.3rem; line-height: 1.2; }
.liste h3 a { color: inherit; text-decoration: none; }
.liste h3 a:hover { text-decoration: underline; }
.liste.pour-moi { --role: var(--corail); }
.liste.geree { --role: var(--succes); }
.liste.orpheline { --role: var(--alerte); }

/* Carte entièrement cliquable (voir site.js) : le curseur, et le carnet
   qui se soulève d'un cran, l'annoncent. Sans JS, l'attribut reste là sans
   effet et le titre fait le travail. */
.liste[data-carte-lien] { cursor: pointer; transition: transform .15s, box-shadow .15s; }
.liste[data-carte-lien]:hover,
.liste[data-carte-lien]:focus-within {
  transform: translateY(-2px);
  box-shadow: inset 12px 0 0 var(--couverture-dos), 0 2px 0 var(--couverture-bord), 0 14px 26px var(--ombre);
}

.coeur { color: var(--corail); }
.statut { font-weight: 600; }
/* Le statut d'un cadeau qui reste à offrir — « Disponible » ou
   « Disponible à la maison » — s'écrit à la main (25/09, demandé par
   Arnaud) : une mention de deux ou trois mots, ce pour quoi Caveat est
   fait. « Offert » garde le sien. */
.statut {
  font-family: Caveat, "Segoe Print", cursive; font-weight: 700;
  font-size: 1.3rem; line-height: 1.15;
}
/* Une petite alerte à l'intérieur d'une étiquette (propositions à
   examiner) : une pastille pleine plutôt qu'une phrase en couleur. */
.etiquette-alerte {
  display: inline-block; margin: 0;
  padding: 3px 10px; border-radius: 999px; font-size: .85rem; font-weight: 700;
  color: var(--alerte); background: color-mix(in srgb, var(--alerte) 12%, transparent);
}

/* L'étiquette en pointillés qui crée : « + Créer une liste pour moi », « + Ajouter
   un cadeau ». Même taille que ses voisines, pas de coin coupé — elle
   n'existe pas encore. */
.etiquette-nouvelle {
  min-height: 190px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding: 16px; text-align: center; text-decoration: none;
  border: 2px dashed var(--trou); border-radius: 6px; color: var(--kraft);
}
/* Sur « Mes listes », l'emplacement vide a la silhouette d'un carnet. */
.grille-cartes .liste ~ .etiquette-nouvelle,
.grille-cartes .vide ~ .etiquette-nouvelle { border-radius: 4px 14px 14px 4px; }
.etiquette-nouvelle .manuscrit { font-size: 1.75rem; }
.etiquette-nouvelle .detail { font-size: .88rem; }
.etiquette-nouvelle:hover { border-color: var(--kraft); background: color-mix(in srgb, var(--carte) 50%, transparent); }

/* -- Les post-it : ce qui attend une décision ---------------------------- */

/* Propositions à examiner, listes à gérer, invitations, demandes
   d'inscription : même geste partout (accepter ou refuser), même papier.
   Légèrement de travers, jamais deux fois dans le même sens. */
.propositions { display: grid; gap: 16px; }
@media (min-width: 720px) {
  .propositions { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px; }
}
.propositions > h2, .propositions > .detail, .propositions > .entete-section { grid-column: 1 / -1; }
.propositions > h2 { margin-bottom: 0; }
.propositions .proposition {
  padding: 16px 18px; background: var(--postit); color: var(--texte);
  box-shadow: 0 8px 16px var(--ombre);
  transform: rotate(-.8deg);
}
.propositions .proposition:nth-of-type(even) { transform: rotate(.6deg); }
.propositions .proposition .detail { color: color-mix(in srgb, var(--texte) 70%, var(--postit)); }
.propositions .proposition p { margin: 0 0 12px; }
.propositions .actions { display: flex; flex-wrap: wrap; gap: 8px; }
.propositions .actions form { margin: 0; }
.propositions button[type="submit"].bouton-secondaire { border-color: var(--postit-trait); }

/* -- Les formulaires ------------------------------------------------------ */

/* Une fiche, pas une étiquette : pleine largeur de `main` (revu le 22/09,
   plus de plafond en pixels), coins à peine arrondis. */
.formulaire {
  padding: 20px 22px 22px; border-radius: 6px;
  background: var(--carte);
  box-shadow: 0 1px 0 var(--trait);
}

/* Nom, enseigne (qui porte un texte d'aide long) restent en pleine
   largeur ; lien, prix et cases vivent dans .champs-courts, en flexbox :
   le flex-grow redistribue toujours toute la largeur entre les champs
   présents sur la ligne, quel que soit leur nombre. */
.formulaire-cadeau .champs-courts { display: flex; flex-wrap: wrap; gap: 14px 16px; }
.formulaire-cadeau .champs-courts > p { flex: 1 1 200px; margin: 0; }
.formulaire-cadeau .champs-courts + button[type="submit"] { margin-top: 18px; }
.formulaire p { margin: 0 0 16px; }
.formulaire label { display: block; margin-bottom: 4px; font-size: .9rem; font-weight: 600; color: var(--discret); }
.formulaire input, .formulaire textarea, .formulaire select {
  width: 100%; min-height: 44px; padding: 9px 12px; font: inherit;
  border: 1px solid var(--trait); border-radius: 8px;
  background: var(--fond); color: var(--texte);
}
.formulaire textarea { resize: vertical; }
.formulaire input:focus-visible, .formulaire textarea:focus-visible, .formulaire select:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent;
}
.email-propose { cursor: pointer; font-family: inherit; }
.formulaire input[type="checkbox"] { width: 18px; min-height: 0; height: 18px; accent-color: var(--accent); }

/* Les erreurs et les textes d'aide d'un formulaire, que Django ne met pas
   en forme : rattachés au champ dont ils parlent, en alerte et en discret. */
.formulaire .errorlist {
  margin: 0 0 6px; padding: 0; list-style: none;
  color: var(--alerte); font-size: .9rem;
}
.formulaire .helptext {
  display: block; margin-top: 4px; color: var(--discret); font-size: .85rem;
}

/* Deux champs dont on remplit l'un OU l'autre (le propriétaire d'une liste :
   son adresse ou son nom). Côte à côte avec un « ou » entre les deux sur
   grand écran, l'un sous l'autre sur mobile. Le texte d'aide est ici entre
   le libellé et la saisie : sous la saisie, il se lisait comme l'aide du
   champ suivant. Les colonnes sont alignées par le bas (align-items: end)
   pour que les deux saisies restent au même niveau quand les aides n'ont
   pas la même longueur. */
.formulaire .alternative { border: 0; padding: 0; margin: 0 0 20px; min-width: 0; }
.formulaire .alternative legend {
  padding: 0; margin-bottom: 10px; font-weight: 700; color: var(--texte);
}
.formulaire .alternative .helptext { margin: 0 0 6px; font-style: italic; }
.formulaire .alternative-choix label { margin-bottom: 2px; }
.formulaire .alternative-ou {
  display: block; margin: 10px 0; text-align: center;
  font-size: .85rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: var(--discret);
}
@media (min-width: 720px) {
  .formulaire .alternative { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0 16px; align-items: end; }
  .formulaire .alternative > legend, .formulaire .alternative > .errorlist { grid-column: 1 / -1; }
  .formulaire .alternative-ou { margin: 0; line-height: 44px; }
}
/* Le champ écarté par site.js : visiblement hors jeu, sans disparaître. */
.formulaire input:disabled { opacity: .45; cursor: not-allowed; }
.formulaire .alternative-choix:has(input:disabled) label,
.formulaire .alternative-choix:has(input:disabled) .helptext { opacity: .55; }

/* -- Les boutons ---------------------------------------------------------- */

button[type="submit"] {
  min-height: 44px; padding: 10px 20px; font: inherit; font-weight: 700; cursor: pointer;
  border: 0; border-radius: 999px; background: var(--accent); color: var(--sur-accent);
}
button[type="submit"]:hover { filter: brightness(1.08); }
/* `button[type="submit"]` (spécificité 0,1,1) l'emporterait sur une classe
   seule (0,1,0) : les variantes reprennent donc le type pour être sûres de
   gagner, plutôt que de compter sur l'ordre des règles. */
button[type="submit"].bouton-secondaire {
  padding: 10px 18px; font-weight: 600;
  border: 1px solid var(--trait); background: transparent; color: var(--texte);
}
/* La seule action irréversible du site mérite un bouton qui ne ressemble
   à aucun autre : l'alerte, jamais l'accent. */
button[type="submit"].bouton-danger {
  padding: 10px 18px; font-weight: 600;
  border: 1px solid var(--alerte);
  background: color-mix(in srgb, var(--alerte) 12%, transparent);
  color: var(--alerte);
}
/* Un lien qui a la forme d'un bouton plein : il mène vers une page, il ne
   soumet rien, mais il ouvre l'action principale de sa section. Le
   sélecteur porte le nom de balise : sans lui, `.lien` et celle-ci se
   départageraient à l'ordre du fichier. */
a.bouton-lien {
  display: inline-flex; align-items: center; min-height: 40px;
  padding: 8px 18px; font-size: .92rem; font-weight: 700;
  border-radius: 999px; background: var(--accent); color: var(--sur-accent);
  text-decoration: none; white-space: nowrap;
}
a.bouton-lien:hover { filter: brightness(1.08); }

/* « Se déconnecter » : `button[type="submit"]` (0,1,1) l'emporte sur
   `.lien` seule (0,1,0), et la classe n'annulait donc rien — le bouton
   s'est affiché des jours en plein accent. Le sélecteur reprend le type,
   comme .bouton-secondaire et .bouton-danger ; un test garde cette règle. */
button[type="submit"].lien {
  min-height: 0; background: none; border: 0; border-radius: 0; padding: 0;
  font: inherit; font-size: .9rem; font-weight: 400;
  color: var(--accent); text-decoration: underline;
}

/* -- Partage, confirmations ---------------------------------------------- */

/* Le lien de partage : un champ en lecture seule, copié au clic (site.js). */
.partage-lien {
  display: block; width: 100%; max-width: 520px; min-height: 44px; padding: 9px 14px; font: inherit;
  border: 1px dashed var(--trou); border-radius: 999px;
  background: var(--carte); color: var(--texte); cursor: pointer;
}
.partage-confirmation, .confirmation {
  margin: 8px 0 0; padding: 8px 12px; border-radius: 8px; font-size: .88rem;
  color: var(--succes); background: color-mix(in srgb, var(--succes) 12%, transparent);
}
/* « Lien copié ! » se pose PAR-DESSUS le bout droit du champ plutôt que
   dessous (25/09) : dans le flux, il poussait tout ce qui suit de sa
   hauteur pendant deux secondes, puis le laissait retomber — la page
   sautait à chaque copie. Hors du flux, il n'occupe aucune place ; le
   conteneur prend la largeur plafonnée du champ pour que « à droite »
   veuille dire au bout du champ, pas au bout de l'écran. */
.partage-champ { position: relative; max-width: 520px; }
.partage-confirmation {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  margin: 0; padding: 6px 12px; border-radius: 999px; pointer-events: none;
  background: var(--carte); box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--succes) 12%, transparent);
}


/* -- En-têtes de section, suppression ------------------------------------ */

/* Le titre d'une section et ce qui l'accompagne sur la même ligne : un
   bouton (« Créer une liste pour moi »), ou un aparté écrit à la main. Ils reviennent
   l'un sous l'autre quand la ligne ne suffit plus. */
.entete-section {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px 16px; flex-wrap: wrap;
}
.entete-section > h1, .entete-section > h2 { margin-bottom: 16px; }
.entete-section .aparte { flex: 1 1 auto; }
/* Deux boutons dans un même en-tête (« Modifier », « Gestionnaires ») :
   groupés, pour que l'espace libre reste entre le titre et eux. */
.boutons-entete { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
/* « Supprimer la liste », au même niveau que « Modifier » (25/09) : même
   contour que .bouton-danger, pas un bouton plein — il ne supprime rien
   lui-même, il ouvre la page de confirmation. */
a.bouton-lien.bouton-supprimer {
  border: 1px solid var(--alerte); color: var(--alerte);
  background: color-mix(in srgb, var(--alerte) 12%, transparent);
}

.actions-suppression {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 16px;
}
.actions-suppression form { margin: 0; }
.suppression { margin-top: 40px; }
.suppression a { color: var(--alerte); }

.cadeau form { margin: 8px 0 0; }
.cadeau button[type="submit"].lien { font-size: .92rem; font-weight: 600; text-decoration: none; }

/* -- Notifications -------------------------------------------------------- */

.notifications { display: grid; gap: 10px; }
.notifications .notification {
  margin: 0; padding: 12px 16px; border-radius: 6px; font-size: .95rem;
  background: var(--postit);
}
.notifications .notification a { color: inherit; font-weight: 700; }
.notification-date {
  display: block; font-size: .8rem; color: var(--discret); margin-bottom: 2px;
}
.notifications h2 { margin: 0; font-size: 1.05rem; }
.notifications + .notifications { margin-top: 28px; }
.notifications .detail { margin: 0; font-size: .85rem; color: var(--discret); }
/* Celles qui attendent une réponse (25/09) : elles restent tant qu'elle
   n'est pas donnée, un filet d'accent les distingue des informatives, qui
   ne passent qu'une fois. */
.notifications.a-traiter .notification { box-shadow: inset 4px 0 0 var(--accent); }

/* -- Le menu du compte ---------------------------------------------------- */

/* <details>/<summary> : le navigateur ouvre, ferme et gère le clavier tout
   seul, site.js n'ajoute que la fermeture au clic extérieur et à Échap. */
.menu-compte { position: relative; }
.menu-compte > summary {
  display: flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 4px 6px 4px 14px;
  border: 1px solid var(--trait); border-radius: 999px;
  background: var(--carte);
  cursor: pointer; list-style: none;
}
/* Le triangle par défaut de <summary> : deux notations, aucune n'étant
   comprise partout. L'avatar et le chevron du gabarit le remplacent. */
.menu-compte > summary::-webkit-details-marker { display: none; }
.menu-compte > summary::marker { content: ""; }
.menu-compte > summary:hover { border-color: var(--trou); }
.menu-compte > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.menu-chevron { color: var(--discret); font-size: .8rem; }
.menu-compte[open] .menu-chevron { transform: rotate(180deg); }
/* L'initiale, dans un rond au vert du badge. */
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--succes); color: #FFFFFF; font-weight: 700; font-size: .95rem;
}
/* Sur le vert éclairci du thème sombre, l'initiale passe à l'encre du fond. */
@media (prefers-color-scheme: dark) { .avatar { color: var(--fond); } }

/* Le volet : détaché du flux pour ne pas pousser l'en-tête, aligné à
   droite pour rester dans la page sur mobile. */
.menu-compte-volet {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 20;
  min-width: 230px;
  display: flex; flex-direction: column;
  padding: 6px; border-radius: 10px;
  background: var(--carte);
  box-shadow: 0 0 0 1px var(--trait), 0 12px 28px var(--ombre);
}
.menu-compte-volet a,
.menu-compte-volet button[type="submit"] {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: 40px; padding: 9px 12px; border-radius: 6px;
  font-size: .95rem; text-align: left; text-decoration: none; color: var(--texte);
}
.menu-compte-volet a:hover,
.menu-compte-volet button[type="submit"]:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent); filter: none;
}
/* La déconnexion, dernière entrée : un trait la sépare des trois autres —
   c'est la seule qui ne mène pas à une page du site. Son formulaire perd
   le `display: flex` de `header form`. */
.menu-compte-volet form {
  display: block; margin: 4px 0 0; padding-top: 4px;
  border-top: 1px solid var(--trait);
}
.menu-compte-volet button[type="submit"].lien {
  font-size: .95rem; color: var(--texte); text-decoration: none; cursor: pointer;
}

/* Le décompte des notifications non lues (voir cadeaux.context_processors)
   : dans le résumé du menu, visible sur toutes les pages, et sur l'entrée
   qui y mène. */
.pastille {
  display: inline-block; min-width: 20px; padding: 1px 7px; border-radius: 999px;
  background: var(--accent); color: var(--sur-accent);
  font-size: .78rem; font-weight: 700; line-height: 1.45; text-align: center;
}

/* -- Retouches propres à certaines pages --------------------------------- */

/* La page des gestionnaires réutilise la grille des post-it, mais les
   gestionnaires en place n'attendent aucune décision : du papier ordinaire,
   droit. Seules les invitations en attente restent des post-it. */
.propositions.personnes .proposition {
  background: var(--carte); transform: none; box-shadow: 0 1px 0 var(--trait);
}
.propositions.personnes button[type="submit"].bouton-secondaire { border-color: var(--trait); }
.propositions > .avertissement, .propositions > .vide { grid-column: 1 / -1; }

.cadeau .manuscrit.succes { color: var(--succes); }

/* Page d'une liste : le lien de partage et les gestionnaires, côte à côte
   dès qu'il y a la place. */
.outils-liste { display: grid; gap: 0 32px; }
@media (min-width: 900px) { .outils-liste { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.outils-liste h2 { margin-top: 20px; margin-bottom: 8px; }
.outils-liste .detail + .detail { margin-top: 6px; }
.outils-liste .partage-champ { margin-top: 10px; }
.prix-texte { color: var(--texte); }

/* Le pied d'une étiquette est souvent un <p> : sa marge basse de
   navigateur ajoutait un vide sous le bouton. Et sur une seule colonne,
   la hauteur minimale ne sert plus à aligner des voisines — elle ne fait
   que creuser des trous : réservée aux grilles à plusieurs colonnes. */
.liste .pied, .cadeau .pied { margin-bottom: 0; }
@media (max-width: 639px) {
  .liste, .cadeau { min-height: 0; }
  .etiquette-nouvelle { min-height: 110px; }
}

/* -- À offrir (25/09) ---------------------------------------------------- */

/* « À offrir » (« Disponible » jusqu'au 25/09 au soir) en vert (25/09,
   demandé par Arnaud) : le texte du statut et le filet sur le bord
   gauche de l'étiquette. Même ombre intérieure, pour la même raison (le
   clip-path du coin coupé). */
.statut .disponible { color: var(--succes); }
.cadeau.disponible { box-shadow: inset 5px 0 0 var(--succes); }

/* -- Déjà acheté (24/09, revu le 25/09) ----------------------------------- */

/* « déjà acheté » dans une pastille verte PLEINE, après « À offrir · »
   (25/09, variante C retenue par Arnaud parmi quatre ; le libellé
   « À offrir · déjà acheté » le soir même, à la place de « Déjà acheté »
   seul, qui se lisait mal à côté de « Offert »). Le vert dit que le
   cadeau reste à offrir ; le plein et le filet deux fois plus épais
   cassent le rythme de la grille, pour qu'on s'arrête lire la consigne :
   ne pas l'acheter. L'ombre est intérieure : le clip-path du coin coupé
   rognerait une ombre portée. */
.a-la-maison {
  display: inline-block; padding: 1px 10px; border-radius: 999px;
  background: var(--succes); color: var(--sur-succes); font-weight: 700;
}
/* Sur la page pour offrir, le statut et la consigne forment un bloc à part,
   entre le texte d'introduction et le formulaire. */
.maison-offrir { margin: 14px 0 18px; padding-left: 12px; border-left: 4px solid var(--succes); }
.maison-offrir p { margin: 0 0 4px; }
.cadeau.deja-achete { box-shadow: inset 10px 0 0 var(--succes); }

/* -- Offert (24/09) ------------------------------------------------------- */

/* « Marquer offert » en toutes lettres, sur le formulaire « par qui » : un
   bouton doré, ni l'accent (il n'y a rien de risqué) ni le secondaire (c'est
   l'aboutissement du cadeau). Sur les étiquettes, c'est une icône. */
button[type="submit"].bouton-offert { background: var(--ruban); color: #22201C; }

/* La section des offerts : détachée de la grille par un trait de
   découpe, un paquet emballé par cadeau. */
.section-offerts { margin-top: 48px; padding-top: 4px; border-top: 2px dashed var(--trou); }
.section-offerts h2 .compte {
  display: inline-block; margin-left: 4px; padding: 2px 10px; border-radius: 999px;
  font-family: Figtree, system-ui, sans-serif; font-size: .95rem; vertical-align: middle;
  color: var(--ruban-encre); background: color-mix(in srgb, var(--ruban) 22%, transparent);
}

/* L'étiquette d'un cadeau offert : papier or plein, du même or que sa
   bordure (25/09, demandé par Arnaud : la teinte à 10 % donnait un olive
   terne sur le bleu nuit), un ruban vertical plus sombre sur le côté (le
   texte se décale pour le laisser passer), et un cachet de la poste daté
   en travers du coin.

   Sur l'or, tout s'écrit à l'encre, dans les deux thèmes : l'étiquette
   redéfinit ses propres couleurs (texte, discret, kraft, accent, encre du
   cachet), que tout ce qu'elle contient reprend sans règle de plus —
   titre, statut, cachet, « N'a pas été offert ? », icônes. Chacune garde au
   moins 4,5:1 sur les deux ors (#E0A82E en clair, #E8B84A en sombre) :
   voir ThemeSombreTest.

   En bloc plutôt qu'en flex, pour que le cachet FLOTTE : le titre et la
   ligne « Offert le … » s'enroulent autour de lui au lieu de passer
   dessous — un cachet en position absolue les recouvrait dès que le titre
   tenait sur une ligne (vu sur capture). */
.offerts-grille .cadeau.offert {
  display: block;
  min-height: 0;
  padding-left: 48px;
  --carte: var(--ruban);
  --texte: #22201C; --discret: #4A3A12; --kraft: #5A3808; --accent: #7C1D12;
  --ruban-encre: #22201C;
  --trait: color-mix(in srgb, #22201C 30%, var(--ruban));
  --trou: color-mix(in srgb, #22201C 35%, var(--ruban));
  color: var(--texte);
  border-bottom-color: var(--ruban);
  background:
    linear-gradient(90deg,
      transparent 18px,
      var(--trou) 18px, var(--trou) 30px,
      transparent 30px),
    var(--ruban);
}
/* Un mot long à côté du cachet (« déguisement ») sautait sous lui et
   laissait un trou dans le titre (vu sur capture). Un titre un cran plus
   petit — ce sont des archives, plus discrètes que ce qui reste à offrir —
   et la césure française en renfort, là où le navigateur la connaît. */
.offerts-grille .cadeau.offert h3 { font-size: 1.1rem; hyphens: auto; }
.statut-offert { color: var(--ruban-encre); font-weight: 600; margin-top: 4px; }
.cadeau.offert .pied-offert {
  clear: both; display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: 4px 14px; padding-top: 12px;
  font-size: .92rem; font-weight: 600;
}
.cadeau.offert .pied-offert form { margin: 0; }
/* « N'a pas été offert ? » : un lien vers la confirmation (25/09), du même
   poids que les gestes des étiquettes. */
.cadeau.offert .pied-offert a.lien { font-size: .92rem; font-weight: 600; text-decoration: none; }
.cadeau.offert .pied-offert a.lien:hover { text-decoration: underline; }
/* L'adresse du donateur, pour les gestionnaires : à l'encre de l'étiquette,
   coupée où il faut plutôt que de déborder. */
.cadeau.offert .email-donateur { margin: 2px 0 0; overflow-wrap: anywhere; }
.cadeau.offert .email-donateur a { color: inherit; }

.cachet {
  float: right; margin: -16px -6px 6px 10px; transform: rotate(-14deg);
  width: 70px; height: 70px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: var(--ruban-encre);
  border: 3px solid currentColor;
  box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--carte) 85%, transparent),
              inset 0 0 0 5px currentColor;
  background: color-mix(in srgb, var(--carte) 70%, transparent);
  pointer-events: none;
}
.cachet-mot { font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.cachet-date { font-size: .7rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* « Voir 10 de plus » : un bouton en creux, et où l'on en est. */
.plus-offerts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: 24px 0 0; }
a.bouton-lien.bouton-plus {
  background: transparent; color: var(--texte); border: 1px solid var(--trait);
}
a.bouton-lien.bouton-plus[aria-busy="true"] { opacity: .6; pointer-events: none; }

/* -- Les icônes d'action d'un cadeau (24/09) ------------------------------ */

/* Œil, cadeau, stylo : en ligne sous l'étiquette, toutes du même rond
   cerné (choix d'Arnaud : ni liseré de couleur, ni fond doré pour
   offrir). 42px : une cible confortable au
   doigt. Le nom de chaque geste est dans aria-label et title. Le sélecteur
   des boutons reprend le type, comme .bouton-secondaire : sinon
   `button[type="submit"]` (0,1,1) imposerait son fond plein. */
.cadeau .icones { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.cadeau .icones form { margin: 0; }
.cadeau .pied-offert .icones { margin-top: 0; }
a.icone, button[type="submit"].icone {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; min-height: 0; padding: 0;
  border: 1px solid var(--trait); border-radius: 999px;
  background: transparent; color: var(--accent);
  cursor: pointer; text-decoration: none;
}
a.icone:hover, button[type="submit"].icone:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent); filter: none;
}
a.icone:focus-visible, button[type="submit"].icone:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.icone-svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* Le nom du cadeau et celui de la boutique, quand ils mènent au site
   marchand : l'encre du texte, un souligné en pointillés qui annonce le
   lien sans crier, plein au survol. */
.cadeau a.vers-marchand {
  color: inherit; text-decoration: underline dotted; text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.cadeau a.vers-marchand:hover { text-decoration-style: solid; }

/* -- La catégorie d'un cadeau (25/09) ------------------------------------- */

/* Sur l'étiquette : une grande icône au trait, en filigrane dans le fond,
   côté droit, centrée en hauteur (revu le 25/09 à la demande d'Arnaud :
   d'abord petite, en haut à droite). `z-index: -1` la glisse SOUS le texte sans passer sous
   le papier : le clip-path de l'étiquette crée un contexte d'empilement,
   dont le fond se peint toujours en premier. Ni clic ni survol. */
.cadeau .categorie {
  position: absolute; z-index: -1; top: 50%; right: 12px; transform: translateY(-50%);
  display: inline-flex; color: var(--texte); opacity: .09;
  pointer-events: none;
}
.cadeau .categorie .icone-svg { width: 104px; height: 104px; stroke-width: 1.5; }
/* Sur une étiquette offerte, plus basse, un filigrane un peu plus petit,
   centré lui aussi. */
.offerts-grille .cadeau.offert .categorie .icone-svg { width: 84px; height: 84px; }

/* Le mot de la catégorie devant le nom du cadeau (« BD », « Briques »,
   « Jeu de société »…) : plus petit, à l'encre kraft, comme une mention ajoutée. */
.prefixe-categorie {
  font-size: .72em; font-weight: 700; letter-spacing: .04em; color: var(--kraft);
  vertical-align: .08em; margin-right: .15em;
}

/* -- Le choix de la catégorie, dans les formulaires (26/09) ---------------- */

/* Vingt et une catégories rangées par familles (maquette validée par
   Arnaud le 26/09), en tuiles : l'icône et le nom court, quatre par ligne.
   Des boutons radio dont le rond est masqué mais reste là, pour le clavier
   et les lecteurs d'écran. Les sélecteurs reprennent `.formulaire` :
   `.formulaire label` et `.formulaire input` imposeraient sinon leur bloc
   et leur pleine largeur.

   La grille vit dans un <dialog> (voir _choix_categorie.html). Envoyé
   ouvert, SANS JavaScript, il reste une grille dans le cours du
   formulaire (`:not(:modal)`) ; site.js le referme et en fait une
   fenêtre modale (`:modal`), ouverte depuis la pastille : une feuille qui
   monte du bas de l'écran sur téléphone, une fenêtre centrée au-delà de
   640px. */
.formulaire .choix-categorie { border: 0; padding: 0; margin: 0 0 16px; min-width: 0; }
.formulaire .choix-categorie legend {
  padding: 0; margin-bottom: 6px; font-size: .9rem; font-weight: 600; color: var(--discret);
}

/* La pastille qui résume le choix : l'icône, le libellé complet, et
   « Changer ». 52px de haut, pour le pouce. */
.categorie-pastille {
  display: flex; align-items: center; gap: 10px; width: 100%; max-width: 440px; min-height: 52px;
  padding: 6px 8px 6px 14px; border-radius: 26px; cursor: pointer;
  border: 1px solid var(--accent); color: var(--texte); text-align: left;
  background: color-mix(in srgb, var(--accent) 10%, var(--carte));
  font: inherit; font-size: 1rem; font-weight: 600;
}
.categorie-pastille[hidden] { display: none; }
.categorie-pastille:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.categorie-pastille-icone { display: inline-flex; color: var(--accent); }
.categorie-pastille-icone .icone-svg { width: 24px; height: 24px; stroke-width: 1.75; }
.categorie-pastille-nom { flex: 1; min-width: 0; }
.categorie-pastille-changer {
  flex: none; padding: 8px 12px; border-radius: 18px; background: var(--carte);
  font-size: .85rem; color: var(--accent);
}

/* La feuille, sans JavaScript : une grille ordinaire dans le formulaire,
   sans cadre ni en-tête (on ne ferme pas ce qui n'a pas été ouvert).
   `[open]` compte : sans lui, la règle afficherait aussi la feuille une
   fois refermée par site.js. */
.feuille-categories[open]:not(:modal) {
  position: static; display: block; width: auto; max-width: none; height: auto;
  margin: 0; padding: 0; border: 0; background: transparent; color: inherit;
}
.feuille-categories[open]:not(:modal) .feuille-entete { display: none; }

/* La feuille ouverte par la pastille. `display` n'est posé que sur
   `:modal` : posé sur le <dialog> fermé, il l'afficherait quand même. */
.feuille-categories:modal {
  display: flex; flex-direction: column; box-sizing: border-box;
  position: fixed; inset: auto 0 0 0; margin: 0;
  width: 100%; max-width: 100%; max-height: 90vh; max-height: 90dvh; padding: 0;
  border: 0; border-radius: 22px 22px 0 0; background: var(--carte); color: var(--texte);
  box-shadow: 0 -10px 30px var(--ombre);
}
.feuille-categories::backdrop { background: rgba(34, 32, 28, .46); }
@media (min-width: 640px) {
  .feuille-categories:modal {
    inset: 0; margin: auto; width: min(560px, calc(100% - 32px)); max-height: 80vh;
    border-radius: 18px;
  }
}
.feuille-entete {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 14px 10px 8px 20px;
}
.feuille-entete h2 { margin: 0; font-size: 1.25rem; }
.feuille-fermer {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 44px; height: 44px; padding: 0; border: 0; border-radius: 22px;
  background: transparent; color: var(--texte); cursor: pointer;
}
.feuille-fermer:hover { background: color-mix(in srgb, var(--texte) 8%, transparent); }
.feuille-fermer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.feuille-categories:modal .feuille-corps {
  overflow-y: auto; overscroll-behavior: contain; padding: 4px 16px 24px;
}
.feuille-corps { display: flex; flex-direction: column; gap: 14px; }
.formulaire .categorie-groupe-titre {
  margin: 0 0 6px 2px; font-size: .75rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--discret);
}

/* Les tuiles : quatre par ligne, quelle que soit la largeur — un nom
   passe au besoin sur deux lignes, entre deux mots. */
.formulaire .categories { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.formulaire .categories-autre { grid-template-columns: minmax(0, 1fr); }
.formulaire .categorie-choix {
  position: relative; display: block; min-width: 0; margin: 0; cursor: pointer;
  container-type: inline-size;
}
.formulaire .categorie-choix input[type="radio"] {
  position: absolute; top: 0; left: 0; width: 1px; height: 1px; min-height: 0;
  margin: 0; padding: 0; opacity: 0;
}
.formulaire .categorie-case {
  position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 6px; box-sizing: border-box; min-height: 78px; padding: 8px 4px;
  border-radius: 12px; border: 1px solid var(--trait); background: var(--fond); color: var(--discret);
  transition: background-color .15s, color .15s, border-color .15s;
}
.formulaire .categories-autre .categorie-case { flex-direction: row; gap: 10px; min-height: 52px; }
.formulaire .categorie-case .icone-svg { width: 26px; height: 26px; stroke-width: 1.6; }
.formulaire .categorie-choix:hover .categorie-case { color: var(--texte); }
.formulaire .categorie-choix input:checked + .categorie-case {
  color: var(--accent); border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--carte));
  box-shadow: inset 0 0 0 1px var(--accent);
}
/* Cochée : une coche dans une pastille, en haut à droite, en plus de la
   couleur (qui ne doit pas porter le sens à elle seule). */
.formulaire .categorie-choix input:checked + .categorie-case::after {
  content: ""; position: absolute; top: 5px; right: 5px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--accent) no-repeat center / 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5 9-10'/%3E%3C/svg%3E");
}
.formulaire .categorie-choix input:focus-visible + .categorie-case {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.formulaire .categorie-nom {
  max-width: 100%; font-size: .8rem; font-weight: 600; line-height: 1.15; text-align: center;
  color: var(--texte); overflow-wrap: anywhere;
}
.formulaire .categorie-choix input:checked + .categorie-case .categorie-nom { color: var(--texte); }
/* Sur téléphone, le nom suit la largeur de SA tuile (unité cqi : la
   tuile est un conteneur) : « Gourmandises », le plus long mot, tient
   d'un seul tenant dans son quart de largeur, dans la feuille comme dans
   le formulaire sans script, un peu plus étroit, et jusqu'à 320px. Les
   navigateurs sans requêtes de conteneur gardent le .72rem. */
@media (max-width: 479px) {
  .formulaire .categorie-case { padding: 8px 2px; }
  .formulaire .categorie-nom {
    font-size: .72rem; font-size: min(.8rem, calc((100cqi - 8px) / 6.9));
    letter-spacing: -.01em;
  }
}
@media (max-width: 359px) {
  .formulaire .categories { gap: 5px; }
}

/* « Coup de cœur » et « Déjà acheté » (25/09, variante B retenue par
   Arnaud) : deux pastilles dans le style des choix de catégorie — même
   bordure, même arrondi, même fond —, l'icône et le nom côte à côte,
   juste sous les catégories. Des cases à cocher masquées, comme les boutons
   radio des catégories, pour le clavier et les lecteurs d'écran. Cochée, la
   pastille prend la couleur de ce qu'elle marque sur les étiquettes :
   corail pour le coup de cœur (et le cœur se remplit), vert pour ce qui
   est déjà à la maison. Les sélecteurs reprennent `.formulaire`, sans quoi
   `.formulaire label` et `.formulaire input` imposeraient les leurs. */
.formulaire .bascules { display: flex; flex-wrap: wrap; gap: 8px; margin: -4px 0 16px; }
.formulaire .bascule {
  position: relative; display: inline-flex; margin: 0; cursor: pointer;
  font-size: .9rem; font-weight: 600;
}
.formulaire .bascule input[type="checkbox"] {
  position: absolute; top: 0; left: 0; width: 1px; height: 1px; min-height: 0;
  margin: 0; padding: 0; opacity: 0;
}
.formulaire .bascule-case {
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 14px 0 12px; border-radius: 10px;
  border: 1px solid var(--trait); background: var(--fond); color: var(--discret);
  transition: background-color .15s, color .15s, border-color .15s;
}
.formulaire .bascule:hover .bascule-case { color: var(--texte); }
.formulaire .bascule input:focus-visible + .bascule-case {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.formulaire .bascule-coeur input:checked + .bascule-case {
  --marque: var(--corail);
}
.formulaire .bascule-maison input:checked + .bascule-case {
  --marque: var(--succes);
}
/* Le texte et l'icône mêlent 30 % d'encre à la couleur : pure, elle ne
   tenait pas 4,5:1 sur sa propre teinte en thème clair (3,2:1 pour le
   corail). La bordure, elle, garde la couleur franche. */
.formulaire .bascule input:checked + .bascule-case {
  color: color-mix(in srgb, var(--marque) 70%, var(--texte)); border-color: var(--marque);
  background: color-mix(in srgb, var(--marque) 12%, var(--carte));
  box-shadow: inset 0 0 0 1px var(--marque);
}
.formulaire .bascule-coeur input:checked + .bascule-case .icone-svg { fill: currentColor; }

/* Sur un écran large (26/09, demandé par Arnaud) : la pastille de la
   catégorie et les deux bascules sur une même ligne, la pastille prenant
   toute la largeur qui reste, à la hauteur des bascules (52px). Seulement
   quand la pastille est là, c'est-à-dire avec JavaScript : sans lui, la
   grille des tuiles occupe la place et les bascules restent dessous. Sous
   760px, la pastille avec un long libellé (« Cuisine & art de la table »)
   n'aurait plus la place à côté des deux bascules. */
@media (min-width: 760px) {
  .formulaire .categorie-et-bascules:has(.categorie-pastille:not([hidden])) {
    display: flex; align-items: flex-end; gap: 10px; margin-bottom: 16px;
  }
  .formulaire .categorie-et-bascules:has(.categorie-pastille:not([hidden])) .choix-categorie {
    flex: 1; min-width: 0; margin: 0;
  }
  .formulaire .categorie-et-bascules:has(.categorie-pastille:not([hidden])) .categorie-pastille {
    max-width: none;
  }
  .formulaire .categorie-et-bascules:has(.categorie-pastille:not([hidden])) .bascules {
    flex: none; flex-wrap: nowrap; margin: 0;
  }
  .formulaire .categorie-et-bascules:has(.categorie-pastille:not([hidden])) .bascule-case {
    height: 52px; border-radius: 14px;
  }
}

/* -- La page de présentation (25/09 ; « guirlande d'étiquettes » le 26/09) - */

/* Sur / et sur /connexion (proposition A retenue par Arnaud le 26/09) :
   une guirlande d'étiquettes sur toute la largeur, puis l'accroche et ses
   paquets à gauche, la connexion — ou le compte — en étiquette à droite ;
   l'explication ensuite sur toute la largeur, en bandeaux. En dessous de
   900px tout s'empile, la connexion juste après l'accroche (l'ordre du
   HTML) : qui revient pour se connecter n'a pas à traverser toute
   l'explication. La guirlande disparaît sous 640px, où ses mots
   deviendraient illisibles. */
.presentation { display: grid; gap: 28px; }
.illu-guirlande { display: none; }
@media (min-width: 640px) {
  .illu-guirlande { display: block; width: 100%; height: auto; margin: -8px 0 -16px; }
}
@media (min-width: 900px) {
  .presentation {
    grid-template-columns: minmax(0, 1fr) 360px;
    grid-template-areas: "guirlande guirlande" "accroche connexion" "suite suite";
    column-gap: 64px; row-gap: 40px; align-items: start;
  }
  .illu-guirlande { grid-area: guirlande; }
  .presentation-accroche { grid-area: accroche; }
  .presentation-suite { grid-area: suite; }
  .presentation-connexion { grid-area: connexion; }
}
.presentation h1 { max-width: 11em; margin-bottom: 16px; }
@media (min-width: 900px) { .presentation h1 { font-size: 3.6rem; line-height: 1.05; } }
.presentation-chapeau { margin: 0; font-size: 1.2rem; max-width: 32em; }
.presentation-complement { margin: 12px 0 0; max-width: 36em; color: var(--discret); }
.illu-paquets { display: block; width: 100%; max-width: 520px; height: auto; margin-top: 24px; }

/* La connexion est une étiquette : coin coupé, trou de ficelle, liseré
   corail en pied. Le formulaire, dedans, perd son propre habit de carte. */
.presentation-connexion {
  position: relative; padding: 42px 26px 24px;
  background: var(--carte); border-bottom: 6px solid var(--corail);
  clip-path: polygon(28px 0, calc(100% - 28px) 0, 100% 28px, 100% 100%, 0 100%, 0 28px);
}
.presentation-connexion::before {
  content: ""; position: absolute; top: 14px; left: 50%; margin-left: -8px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--fond); box-shadow: inset 0 0 0 2px var(--trou);
}
.presentation-connexion .formulaire { padding: 0; background: none; box-shadow: none; }
.presentation-connexion h2 { margin: 0 0 16px; }
.presentation-connexion button[type="submit"] { width: 100%; }
.presentation-inscription { margin-top: 14px; }

/* L'explication : des sections l'une sous l'autre ; certaines sont des
   bandeaux couleur étiquette, d'autres restent sur le papier. */
.presentation-suite { display: flex; flex-direction: column; gap: 56px; margin-top: 16px; }
.presentation-suite h2 { margin: 0 0 14px; font-size: 1.6rem; line-height: 1.2; }
@media (min-width: 720px) { .presentation-suite h2 { font-size: 2.1rem; } }
.bandeau {
  padding: 28px 20px; border-radius: 16px;
  background: var(--carte); box-shadow: 0 1px 0 var(--trait);
}
@media (min-width: 720px) { .bandeau { padding: 48px 56px; } }
.bandeau-illustre { display: grid; gap: 24px; align-items: center; }
@media (min-width: 900px) {
  .bandeau-illustre { grid-template-columns: 420px minmax(0, 1fr); gap: 56px; }
  .bandeau-illustre.bandeau-inverse { grid-template-columns: minmax(0, 1fr) 360px; }
}
.bandeau-centre { display: flex; flex-direction: column; align-items: center; text-align: center; }
.presentation-texte { max-width: 38em; }
.presentation-texte p { margin: 0 0 12px; font-size: 1.05rem; }
.presentation-texte p:last-child { margin-bottom: 0; }
.illu-doublons { display: block; width: 100%; max-width: 480px; height: auto; }
.illu-serrure { display: block; width: 100%; max-width: 360px; height: auto; justify-self: center; }
.illu-timbres { display: block; width: 100%; max-width: 900px; height: auto; margin-top: 28px; }
#titre-esprit { text-align: center; }
/* « Comment ça marche », écrit à la main au-dessus du titre de la section. */
.presentation-suite .surtitre { margin: 0; font-size: 1.8rem; }
.presentation-suite .surtitre + h2 { margin-top: 0; }

/* Les liserés de couleur, en pied d'une étape ou à gauche d'un principe. */
.lisere-corail { --lisere: var(--corail); }
.lisere-vert { --lisere: var(--succes); }
.lisere-ruban { --lisere: var(--ruban); }
.lisere-kraft { --lisere: var(--couverture); }
.lisere-encre { --lisere: var(--texte); }

/* Les trois étapes : trois étiquettes pendues à une ficelle, un peu de
   travers, le numéro écrit à la main. Sous 640px, elles s'empilent, bien
   droites, et la ficelle disparaît. */
.illu-ficelle-etapes { display: none; }
.presentation-etapes {
  display: grid; gap: 20px; width: 100%; margin: 20px 0 0; padding: 0;
  list-style: none; text-align: left;
}
@media (min-width: 640px) {
  .illu-ficelle-etapes { display: block; width: 100%; height: 48px; margin-top: 20px; }
  .presentation-etapes { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; margin-top: 0; }
  .presentation-etapes li:nth-child(1) { transform: rotate(-1.5deg); }
  .presentation-etapes li:nth-child(2) { transform: rotate(.8deg) translateY(12px); }
  .presentation-etapes li:nth-child(3) { transform: rotate(-.6deg); }
}
.presentation-etapes li {
  position: relative; padding: 42px 22px 24px;
  background: var(--carte); border-bottom: 5px solid var(--lisere, var(--trou));
  clip-path: polygon(24px 0, calc(100% - 24px) 0, 100% 24px, 100% 100%, 0 100%, 0 24px);
}
.presentation-etapes li::before {
  content: ""; position: absolute; top: 12px; left: 50%; margin-left: -7px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--fond); box-shadow: inset 0 0 0 2px var(--trou);
}
.etape-tete { display: flex; align-items: flex-end; justify-content: space-between; }
.presentation-etapes .manuscrit { font-size: 3.2rem; line-height: .9; color: var(--corail); }
.presentation-etapes .illu-picto { width: 64px; height: auto; }
.presentation-etapes h3 { margin: 14px 0 8px; font-size: 1.15rem; line-height: 1.25; }
.presentation-etapes p { margin: 0; font-size: .96rem; color: var(--discret); }
.presentation-etapes p + p { margin-top: 8px; }

/* L'esprit du site : six fiches (cinq jusqu'au 08/10, la cagnotte en plus) —
   deux rangées de trois sur un grand écran —, chacune ouverte par son pictogramme et
   son idée, un liseré de couleur à gauche comme une marge annotée. */
.presentation-principes { display: grid; gap: 16px; margin: 8px 0 0; padding: 0; list-style: none; }
@media (min-width: 720px) { .presentation-principes { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) {
  .presentation-principes { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 22px; }
  .presentation-principes li { grid-column: span 2; }
}
.presentation-principes li {
  padding: 22px 22px 24px; border-radius: 4px 14px 14px 4px;
  background: var(--fond); border-left: 6px solid var(--lisere, var(--succes));
}
.presentation-principes .illu-picto { width: 48px; height: auto; }
.presentation-principes h3 { margin: 10px 0 8px; font-size: 1.15rem; line-height: 1.25; }
.presentation-principes p { margin: 6px 0 0; font-size: .96rem; }
.presentation-principes h3 + p { margin-top: 0; }

/* La FAQ de l'accueil (26/09) : une question par ligne, séparées par un
   filet, la réponse dépliée dessous. Le titre h3 reste dans le <summary>
   (le HTML l'autorise) pour que la structure des titres tienne ; le
   triangle natif laisse place à un « + », « − » une fois ouvert. Deux
   colonnes indépendantes à partir de 900px. */
.presentation-faq { display: grid; column-gap: 48px; }
.presentation-faq-colonne { border-top: 1px solid var(--trait); }
.presentation-faq-colonne + .presentation-faq-colonne { border-top: 0; }
@media (min-width: 900px) {
  .presentation-faq { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .presentation-faq-colonne + .presentation-faq-colonne { border-top: 1px solid var(--trait); }
}
.presentation-faq details { border-bottom: 1px solid var(--trait); }
.presentation-faq summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 14px 0; cursor: pointer; list-style: none;
}
.presentation-faq summary::-webkit-details-marker { display: none; }
.presentation-faq summary::after {
  content: "+"; flex: none; width: 1ch; text-align: center;
  font-size: 1.3rem; line-height: 1; color: var(--corail);
}
.presentation-faq details[open] summary::after { content: "−"; }
.presentation-faq h3 { margin: 0; font-size: 1.02rem; line-height: 1.3; }
.presentation-faq p { margin: 0 0 8px; color: var(--discret); }
.presentation-faq p:last-child { margin-bottom: 14px; }

/* Les illustrations de l'accueil (26/09) sont des SVG en ligne : leurs
   paquets gardent leurs couleurs franches, mais tout ce qui est papier,
   ficelle, trou ou encre suit le thème — sombre compris. */
.illu .i-carte { fill: var(--carte); }
.illu .i-fond { fill: var(--fond); }
.illu .i-trait { stroke: var(--trou); }
.illu .i-bord { stroke: var(--couverture-bord); }
.illu .i-ficelle { fill: none; stroke: var(--kraft); }
.illu .i-trace { fill: none; stroke: var(--texte); }
.illu .i-couverture { fill: var(--couverture); }
.illu .i-couverture-dos { fill: var(--couverture-dos); }
.illu .i-couture { fill: none; stroke: var(--couverture-dos); }
.illu .i-sol { fill: var(--trait); }
.illu .i-perfo { stroke: var(--fond); }
.illu .i-rature { stroke: var(--accent); opacity: .85; }
.illu .i-mot { font-family: Caveat, "Segoe Print", cursive; font-weight: 700; font-size: 26px; fill: var(--kraft); }

/* Qui est connecté trouve, à la place de la connexion, son nom et les
   entrées du menu du compte, toutes en lignes comme dans le volet de
   l'en-tête — « Mes listes » compris, qui n'est plus un bouton plein
   (25/09, demandé par Arnaud) —, la déconnexion détachée par un trait. */
.presentation-compte .manuscrit { margin: 0 0 4px; }
.presentation-compte h2 { display: flex; align-items: center; gap: 10px; }
.presentation-compte-liens { display: flex; flex-direction: column; gap: 2px; }
.presentation-compte-liens a,
.presentation-compte-liens button[type="submit"].lien {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: 40px; padding: 9px 12px; border-radius: 6px;
  font-size: .95rem; text-align: left; text-decoration: none; color: var(--texte);
}
.presentation-compte-liens a:hover,
.presentation-compte-liens button[type="submit"].lien:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent); filter: none;
}
.presentation-compte-liens form {
  margin: 4px 0 0; padding-top: 4px; border-top: 1px solid var(--trait);
}

/* -- Les réglages d'une liste, repliés (25/09) --------------------------- */

/* Sur la page d'une liste, modifier, supprimer, partager et les
   gestionnaires se replient derrière un engrenage, à droite du titre.
   Le <summary> est posé en absolu à hauteur du titre (qui lui laisse la
   place) ; le volet se déplie dessous, dans le flux. Même rond que les
   gestes d'un cadeau (a.icone), en plein quand le volet est ouvert. */
.entete-liste { position: relative; }
.entete-liste > h1 { padding-right: 56px; }
.reglages-liste > summary {
  position: absolute; top: 2px; right: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 1px solid var(--trait); border-radius: 999px;
  color: var(--accent); cursor: pointer; list-style: none;
}
@media (min-width: 720px) { .reglages-liste > summary { top: 8px; } }
.reglages-liste > summary::-webkit-details-marker { display: none; }
.reglages-liste > summary:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.reglages-liste > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.reglages-liste[open] > summary { background: var(--accent); border-color: var(--accent); color: var(--sur-accent); }
.reglages-liste > summary .icone-svg { transition: transform .2s; }
.reglages-liste[open] > summary .icone-svg { transform: rotate(60deg); }
/* Le lien vers la liste, à gauche de l'engrenage (08/10) : une mention à
   la main et un bouton rond qui copie le lien de partage — le même rond
   que l'engrenage, posé en absolu sur la même ligne. Le titre leur laisse
   la place : celle du seul bouton sur un écran étroit, où la mention est
   retirée (elle prendrait la largeur du titre), celle des deux au-delà.
   Le bloc naît masqué et site.js le révèle : `[hidden]` doit donc
   l'emporter sur le `display` posé ici. « Lien copié ! » s'affiche sous
   le bouton, hors du flux, comme celui du champ (rien ne saute). */
.lien-liste {
  position: absolute; top: 2px; right: 54px; margin: 0;
  display: inline-flex; align-items: center; gap: 10px;
}
.lien-liste[hidden] { display: none; }
.lien-liste .manuscrit { display: none; font-size: 1.35rem; line-height: 1; white-space: nowrap; }
button[type="button"].icone {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; min-height: 0; padding: 0;
  border: 1px solid var(--trait); border-radius: 999px;
  background: transparent; color: var(--accent); cursor: pointer;
}
button[type="button"].icone:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
button[type="button"].icone:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.lien-liste-confirmation {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 2;
  padding: 6px 12px; border-radius: 999px; white-space: nowrap; pointer-events: none;
  font-size: .88rem; color: var(--succes);
  background: var(--carte); box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--succes) 12%, transparent);
}
.entete-liste:has(.lien-liste:not([hidden])) > h1 { padding-right: 108px; }
@media (min-width: 720px) {
  .lien-liste { top: 8px; }
  .lien-liste .manuscrit { display: inline; }
  .entete-liste:has(.lien-liste:not([hidden])) > h1 { padding-right: 300px; }
}
.reglages-volet {
  margin: 0 0 16px; padding: 16px 20px 20px; border-radius: 6px;
  background: var(--carte); box-shadow: 0 1px 0 var(--trait);
}
.reglages-volet .boutons-entete { margin-bottom: 0; }
.reglages-volet .outils-liste h2 { margin-top: 18px; }
.reglages-volet .outils-liste .detail + .detail { margin-top: 12px; }

/* Le pied de toutes les pages : les liens légaux (26/09), puis le numéro
   de version, discret — il sert surtout à vérifier quel commit répond
   après un déploiement. Les liens passent à la ligne sur un écran étroit
   plutôt que de déborder ; 44px de haut pour le doigt. */
.pied-site { padding: 0 20px 24px; text-align: center; }
.pied-site .meta { margin: 0; font-size: .8rem; color: var(--discret); opacity: .75; }
.liens-legaux {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0 18px;
  margin: 0 0 6px; padding-top: 14px; border-top: 1px solid var(--trait);
}
.liens-legaux a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: .85rem; color: var(--discret); text-decoration: none;
}
.liens-legaux a:hover, .liens-legaux a:focus-visible { color: var(--accent); text-decoration: underline; }

/* Le sélecteur de langue (02/10, comptes/_langue.html) : sur la ligne des
   liens légaux, même ton. La langue en cours est en texte simple, un peu
   plus appuyée ; les autres sont des boutons de formulaire habillés en
   liens, comme la déconnexion du menu du compte. Sur « Mon compte », le
   même sélecteur s'aligne à gauche, avec le reste de la page. */
.choix-langue {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0 18px;
  margin: 0 0 6px; font-size: .85rem;
}
.choix-langue span, .choix-langue button[type="submit"].lien {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: .85rem; color: var(--discret); text-decoration: none; cursor: pointer;
}
.choix-langue span[aria-current] { font-weight: 600; }
.choix-langue button[type="submit"].lien:hover,
.choix-langue button[type="submit"].lien:focus-visible { color: var(--accent); text-decoration: underline; }
main .choix-langue { justify-content: flex-start; font-size: 1rem; }
main .choix-langue span, main .choix-langue button[type="submit"].lien { font-size: 1rem; color: var(--texte); }
main .choix-langue button[type="submit"].lien { color: var(--accent); text-decoration: underline; }

/* Les documents légaux (26/09) : du texte long, donc une colonne de
   lecture — environ 70 caractères — plutôt que toute la largeur de `main`.
   Titres plus petits que ceux des pages de l'application : ce sont des
   articles numérotés, pas des sections. */
.document-legal { max-width: 70ch; line-height: 1.6; overflow-wrap: anywhere; }
.document-legal h1 { font-size: 2rem; }
@media (min-width: 720px) { .document-legal h1 { font-size: 2.4rem; } }
.document-legal .mise-a-jour { margin: -8px 0 28px; color: var(--discret); font-size: .92rem; }
.document-legal h2 { font-size: 1.25rem; margin: 32px 0 10px; }
.document-legal h3 { font-size: 1.05rem; margin: 22px 0 8px; }
.document-legal p { margin: 0 0 12px; }
.document-legal ul { margin: 0 0 14px; padding-left: 1.3em; }
.document-legal li { margin: 0 0 4px; }
.document-legal address { font-style: normal; margin: 0 0 12px; }

/* Les cases à cocher d'un formulaire (26/09 : l'acceptation des CGU, les
   communications facultatives) : la case À GAUCHE de son libellé, sur la
   même ligne, et non le libellé en bloc au-dessus comme pour un champ de
   saisie. Les sélecteurs reprennent `.formulaire` : `.formulaire label`
   imposerait sinon son bloc et sa couleur discrète. */
.formulaire .case { display: flex; align-items: flex-start; gap: 10px; }
.formulaire .case input[type="checkbox"] { flex: none; margin: 2px 0 0; width: 20px; height: 20px; }
.formulaire .case label { display: inline; margin: 0; font-weight: 400; font-size: .95rem; color: var(--texte); }
.formulaire .case-bloc { margin: 0 0 16px; }
.formulaire .case-bloc .errorlist { margin-left: 30px; }
.formulaire .case-bloc .helptext { margin-left: 30px; }
.formulaire .facultatif { margin-top: 20px; padding-top: 16px; border-top: 1px dashed var(--trait); }
/* Une information courte sous un formulaire, avec un lien vers la page
   qui en dit plus (l'usage des coordonnées d'un donateur, par exemple). */
.formulaire .info-donnees { margin: 16px 0 0; color: var(--discret); font-size: .85rem; }

/* -- La frise des catégories, au-dessus des cadeaux (26/09) ----------------
   Une rangée de puces rondes, rien que l'icône (le nom est dans la bulle),
   « Tout » seul en toutes lettres ; dans le style des bascules du
   formulaire. Sur téléphone, une seule ligne qui défile sous
   le doigt, sans barre visible : c'est une frise, pas un bloc qui pousse
   les cadeaux vers le bas. Sur un écran large, elle passe à la ligne.
   Une puce allumée prend la teinte de l'accent (même recette que les
   bascules cochées : 30 % d'encre mêlés à la couleur pour le contraste). */
.frise-categories { margin: -4px 0 20px; }
.frise-puces {
  display: flex; gap: 8px; overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none; padding: 2px 2px 4px; margin: 0 -2px;
}
.frise-puces::-webkit-scrollbar { display: none; }
@media (min-width: 640px) {
  .frise-puces { flex-wrap: wrap; overflow-x: visible; }
}
.frise-puce {
  flex: none; display: inline-flex; align-items: center; gap: 7px;
  height: 38px; min-height: 0; margin: 0; padding: 0 14px 0 12px;
  border-radius: 19px; border: 1px solid var(--trait);
  background: var(--carte); color: var(--discret);
  font: inherit; font-size: .88rem; font-weight: 600; white-space: nowrap;
  cursor: pointer; box-shadow: none; -webkit-tap-highlight-color: transparent;
  transition: background-color .15s, color .15s, border-color .15s;
}
.frise-puce.frise-tout { height: 40px; padding: 0 16px; }
.frise-puce.frise-icone { width: 40px; height: 40px; padding: 0; justify-content: center; border-radius: 50%; }
.frise-puce .icone-svg { width: 20px; height: 20px; stroke-width: 1.8; }
.frise-puce:hover { color: var(--texte); background: var(--carte); }
.frise-puce:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.frise-nombre { font-weight: 500; font-size: .8em; opacity: .75; }
.frise-puce[aria-pressed="true"] {
  color: color-mix(in srgb, var(--accent) 70%, var(--texte)); border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--carte));
  box-shadow: inset 0 0 0 1px var(--accent);
}
/* « Coup de cœur » allumé prend le corail des étiquettes, cœur plein. */
.frise-puce.frise-coeur[aria-pressed="true"] {
  color: color-mix(in srgb, var(--corail) 70%, var(--texte)); border-color: var(--corail);
  background: color-mix(in srgb, var(--corail) 12%, var(--carte));
  box-shadow: inset 0 0 0 1px var(--corail);
}
.frise-puce.frise-coeur[aria-pressed="true"] .icone-svg { fill: currentColor; }
/* L'annonce du nombre de cadeaux affichés : pour les lecteurs d'écran
   seulement. */
.frise-annonce {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* -- La cagnotte (07/10) --------------------------------------------------- */

/* La jauge : un <progress> natif, habillé. Tout ce qu'un visiteur voit
   d'une cagnotte. Le rail est un trait de l'étiquette, le remplissage doré
   comme le ruban des cadeaux offerts — c'est vers « Offert » qu'elle
   avance. Trois sélecteurs pour une même barre : chaque moteur nomme la
   sienne, et une règle qui en regroupe deux est ignorée par les deux. */
.cagnotte { margin-top: 6px; }
.cagnotte .statut { margin-bottom: 4px; }
.statut .en-cagnotte { color: var(--ruban-encre); }
.jauge {
  appearance: none; -webkit-appearance: none;
  display: block; width: 100%; height: 12px;
  border: 1px solid var(--trou); border-radius: 999px; overflow: hidden;
  background: var(--fond); color: var(--ruban);
}
.jauge::-webkit-progress-bar { background: var(--fond); }
.jauge::-webkit-progress-value { background: var(--ruban); border-radius: 999px; }
.jauge::-moz-progress-bar { background: var(--ruban); border-radius: 999px; }
.cagnotte-detail { margin-top: 6px; }
/* Sur les pages de la cagnotte (participer, détail), hors étiquette : plus
   haute, et de la largeur du formulaire qu'elle surmonte. */
.jauge-page { max-width: 560px; height: 16px; margin: 0 0 18px; }
.cagnotte-rappel { margin: 0 0 8px; }

/* « Rien ne se paie ici » : la précision qui compte le plus sur ces pages,
   dans un encadré au filet doré, sur le modèle de la consigne « déjà
   acheté » de la page pour offrir. */
.sans-paiement {
  max-width: 560px; margin: 0 0 18px; padding-left: 12px;
  border-left: 4px solid var(--ruban);
}
.sans-paiement p { margin: 0; font-size: .94rem; }
.vers-cagnotte { margin: 0 0 16px; }

/* Le détail tenu par les gestionnaires : une ligne par participation, sur
   le papier droit de la page des gestionnaires. */
.participations .montant { font-weight: 700; }
.participations + .avertissement { margin: 14px 0 0; max-width: 560px; }

/* Les réglages de la cagnotte, sur la page « Paramètres de la liste ». */
.formulaire .reglage-cagnotte {
  border: 0; border-top: 1px dashed var(--trait);
  margin: 20px 0 4px; padding: 16px 0 0; min-width: 0;
}
.formulaire .reglage-cagnotte legend {
  padding: 0 8px 0 0; font-weight: 700; color: var(--texte);
}
.formulaire .reglage-cagnotte .champ-seuil input { max-width: 140px; }

/* -- Le journal des nouveautés (07/10) ------------------------------------ */

/* Dans le pied de page, le lien garde l'encre discrète de la ligne. */
.pied-site .meta a { color: inherit; }
.pied-site .meta a:hover, .pied-site .meta a:focus-visible { color: var(--accent); }
/* La page reprend la colonne de lecture des documents légaux. Une version,
   un titre et sa date sur la même ligne, puis ses quelques lignes. */
.nouveautes .version h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.nouveautes .version-date { font-family: Figtree, sans-serif; font-size: .88rem; font-weight: 400; color: var(--discret); }
/* L'entrée à venir, visible hors production seulement : un post-it, pour
   qu'on ne la prenne pas pour une version publiée. */
.nouveautes .a-venir {
  margin: 0 0 8px; padding: 2px 16px 6px;
  background: var(--postit); color: var(--postit-encre);
  border: 1px dashed var(--postit-trait); border-radius: 6px;
}
.nouveautes .a-venir h2 { margin-top: 14px; }
.nouveautes .a-venir .version-date { color: inherit; }
