/* =========================================================================
   Composants — cartes, boutons, champs, jauges, pastilles, modales, tableaux.
   =========================================================================
   Chaque composant est écrit une fois et réutilisé partout. Aucune règle ne
   dépend de l'écran où elle apparaît : c'est ce qui rend l'application
   cohérente sans effort, et modifiable sans peur.
   ========================================================================= */

/* ── Cartes ──────────────────────────────────────────────────────────────*/

.carte {
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--r-carte);
  padding: var(--e3);
  box-shadow: var(--ombre-1);
  /* Les cartes deviennent des conteneurs de requête : leur contenu peut
     s'adapter à la largeur de la carte, pas à celle de la fenêtre. C'est ce
     qui permet à la même carte d'être élégante dans une colonne étroite
     comme en pleine largeur. */
  container-type: inline-size;
}
.carte-titre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e2);
  margin-bottom: var(--e2);
}
.carte-titre h3 { margin: 0; }
.carte-legende {
  font-size: var(--t-petit);
  color: var(--encre-tenue);
  margin-top: -2px;
  margin-bottom: var(--e2);
}
.carte-cliquable {
  display: block;
  width: 100%;
  text-align: left;
  transition: transform var(--v-court) var(--sortie), box-shadow var(--v-court) var(--sortie),
              border-color var(--v-court) var(--sortie);
}
.carte-cliquable:hover {
  transform: translateY(-2px);
  box-shadow: var(--ombre-2);
  border-color: var(--trait-marque);
}
.carte-cliquable:active { transform: translateY(0); }

/* ── Boutons ─────────────────────────────────────────────────────────────
   Trois niveaux d'insistance, et un seul bouton plein par écran : c'est ce
   qui rend l'action principale évidente sans avoir à l'expliquer. */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e1);
  padding: .55rem 1rem;
  min-height: 40px;
  border-radius: var(--r-moyen);
  font-size: var(--t-base);
  font-weight: var(--graisse-moyenne);
  white-space: nowrap;
  /* Un bouton peut être un lien — vers le guide, par exemple. Sans cette
     ligne, il porterait le soulignement des liens et ne ressemblerait plus
     aux boutons voisins. */
  text-decoration: none;
  color: inherit;
  transition: background var(--v-court) var(--sortie), color var(--v-court) var(--sortie),
              border-color var(--v-court) var(--sortie), transform var(--v-court) var(--sortie);
}
.bouton:active { transform: scale(.97); }
.bouton svg { width: 18px; height: 18px; flex: none; }

.bouton-plein {
  background: var(--accent);
  color: var(--accent-encre);
  box-shadow: var(--ombre-1);
}
.bouton-plein:hover { background: var(--accent-fonce); }

.bouton-contour {
  border: 1px solid var(--trait-marque);
  color: var(--encre);
  background: var(--surface);
}
.bouton-contour:hover { border-color: var(--accent); color: var(--accent); }

.bouton-fantome { color: var(--encre-douce); }
.bouton-fantome:hover { background: var(--surface-creuse); color: var(--encre); }

.bouton-danger { color: var(--critique); }
.bouton-danger:hover { background: var(--critique-voile); }

/* Le bouton d'une action qu'on ne rattrape pas.
   `confirmer({ danger: true })` le demandait déjà ; faute de cette règle, une
   suppression définitive s'affichait dans la couleur d'accentuation, c'est-à-dire
   exactement comme un « Enregistrer ». */
.bouton-danger-plein {
  background: var(--critique);
  color: #fff;
  border: 1px solid transparent;
}
.bouton-danger-plein:hover { background: color-mix(in oklab, var(--critique) 85%, #000); }

.bouton-petit { min-height: 32px; padding: .3rem .7rem; font-size: var(--t-petit); }
.bouton-icone { padding: 0; width: 36px; min-height: 36px; border-radius: var(--r-moyen); }

/* ── Segments ────────────────────────────────────────────────────────────
   Un sélecteur de quelques options exclusives. La pastille active glisse
   plutôt que de sauter, ce qui rend le changement lisible. */

.segments {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--surface-creuse);
  border-radius: var(--r-moyen);
}
.segment {
  padding: .35rem .8rem;
  border-radius: calc(var(--r-moyen) - 4px);
  font-size: var(--t-petit);
  font-weight: var(--graisse-moyenne);
  color: var(--encre-douce);
  transition: background var(--v-court) var(--sortie), color var(--v-court) var(--sortie);
}
.segment[aria-pressed="true"] {
  background: var(--surface);
  color: var(--encre);
  box-shadow: var(--ombre-1);
}

/* ── Champs ──────────────────────────────────────────────────────────────*/

.champ-groupe { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.champ-etiquette {
  font-size: var(--t-petit);
  font-weight: var(--graisse-moyenne);
  color: var(--encre-douce);
}
.champ-aide { font-size: var(--t-petit); color: var(--encre-tenue); }
.champ-erreur { font-size: var(--t-petit); color: var(--critique); font-weight: var(--graisse-moyenne); }

.champ {
  width: 100%;
  padding: .55rem .75rem;
  min-height: 42px;
  background: var(--surface-creuse);
  border: 1px solid transparent;
  border-radius: var(--r-moyen);
  color: var(--encre);
  transition: border-color var(--v-court) var(--sortie), background var(--v-court) var(--sortie);
}
.champ::placeholder { color: var(--encre-tenue); }
.champ:hover { border-color: var(--trait-marque); }
.champ:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-voile);
}
.champ[aria-invalid="true"] { border-color: var(--critique); }

select.champ {
  appearance: none;
  padding-right: 2rem;
  /* Le chevron est dessiné en fond : pas d'image externe, pas de requête. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23857e74' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5 8 10.5 12 6.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .7rem center;
  background-size: 16px;
}

textarea.champ { min-height: 84px; resize: vertical; line-height: 1.5; }

/* Le champ de montant : le symbole reste dans le champ, le chiffre est gros
   et tabulaire. Saisir de l'argent doit être agréable, c'est le geste le
   plus répété de toute l'application. */
.champ-montant { position: relative; }
.champ-montant input {
  padding-left: 2rem;
  font-size: var(--t-moyen);
  font-weight: var(--graisse-moyenne);
  font-variant-numeric: tabular-nums;
}
.champ-montant::before {
  content: "€";
  position: absolute;
  left: .8rem; top: 50%;
  translate: 0 -50%;
  color: var(--encre-tenue);
  font-weight: var(--graisse-moyenne);
  pointer-events: none;
}

/* Interrupteur */
.interrupteur { display: inline-flex; align-items: center; gap: var(--e2); cursor: pointer; }
.interrupteur input { position: absolute; opacity: 0; pointer-events: none; }
.interrupteur-piste {
  width: 44px; height: 26px;
  flex: none;
  border-radius: var(--r-plein);
  background: var(--trait-marque);
  position: relative;
  transition: background var(--v-moyen) var(--sortie);
}
.interrupteur-piste::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--ombre-1);
  transition: translate var(--v-moyen) var(--ressort);
}
.interrupteur input:checked + .interrupteur-piste { background: var(--accent); }
.interrupteur input:checked + .interrupteur-piste::after { translate: 18px 0; }
.interrupteur input:focus-visible + .interrupteur-piste { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ── Pastilles et étiquettes ─────────────────────────────────────────────*/

.pastille {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: var(--r-plein);
  font-size: var(--t-petit);
  font-weight: var(--graisse-moyenne);
  background: var(--surface-creuse);
  color: var(--encre-douce);
  white-space: nowrap;
}
.pastille svg { width: 13px; height: 13px; }
/* Les états portent toujours une icône : la couleur seule ne suffit jamais. */
.pastille-bien      { background: var(--bien-voile);      color: var(--bien-encre); }
.pastille-attention { background: var(--attention-voile); color: var(--attention); }
.pastille-critique  { background: var(--critique-voile);  color: var(--critique); }
.pastille-accent    { background: var(--accent-voile);    color: var(--accent); }

.pastille-groupe { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .04em; }

/* Un point de couleur qui porte l'identité d'une série ou d'une personne. */
.point {
  width: 9px; height: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--teinte, var(--accent));
}
.point-carre { border-radius: 3px; }

/* Pastille d'un membre du foyer : initiale sur fond de sa couleur. */
.jeton-membre {
  display: inline-grid;
  place-items: center;
  width: 26px; height: 26px;
  flex: none;
  border-radius: 50%;
  background: color-mix(in oklab, var(--teinte, var(--accent)) 22%, var(--surface));
  color: var(--teinte, var(--accent));
  font-size: var(--t-petit);
  font-weight: var(--graisse-forte);
  border: 1px solid color-mix(in oklab, var(--teinte, var(--accent)) 35%, transparent);
}

/* ── Jauges ──────────────────────────────────────────────────────────────
   La barre de progression est le composant le plus vu de l'application :
   enveloppes, projets, jalons. Extrémité arrondie de 4 px ancrée à la
   ligne de base, et un repère facultatif qui marque « où on devrait en
   être » — savoir qu'on a dépensé 60 % ne dit rien tant qu'on ignore qu'on
   est au 12 du mois. */

.jauge {
  position: relative;
  height: 8px;
  border-radius: var(--r-plein);
  background: var(--surface-creuse);
  overflow: hidden;
}
.jauge-haute { height: 12px; }
.jauge-remplissage {
  height: 100%;
  border-radius: var(--r-plein);
  background: var(--teinte, var(--accent));
  transition: width var(--v-long) var(--sortie);
}
.jauge-remplissage.bien      { background: var(--bien); }
.jauge-remplissage.attention { background: var(--attention-vif); }
.jauge-remplissage.critique  { background: var(--critique); }

/* Le repère du rythme attendu. */
.jauge-repere {
  position: absolute;
  top: -2px; bottom: -2px;
  width: 2px;
  background: var(--encre);
  opacity: .35;
  border-radius: var(--r-plein);
}

.jauge-legende {
  display: flex;
  justify-content: space-between;
  gap: var(--e2);
  margin-top: 5px;
  font-size: var(--t-petit);
  color: var(--encre-douce);
}

/* ── Chiffres ────────────────────────────────────────────────────────────*/

.chiffre-heros {
  font-size: var(--t-heros);
  font-weight: var(--graisse-forte);
  letter-spacing: -.03em;
  line-height: 1;
}
.montant { font-variant-numeric: tabular-nums; font-weight: var(--graisse-moyenne); }
.montant-sortant { color: var(--encre); }
.montant-entrant { color: var(--bien-encre); }
.montant-negatif { color: var(--critique); }

/* La tuile de statistique : une étiquette, une valeur, une évolution. */
.tuile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--e3);
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--r-carte);
}
.tuile-etiquette {
  font-size: var(--t-petit);
  color: var(--encre-douce);
  font-weight: var(--graisse-moyenne);
}
.tuile-valeur {
  font-size: clamp(1.35rem, 1.1rem + 1vw, 1.75rem);
  font-weight: var(--graisse-forte);
  letter-spacing: -.02em;
  line-height: 1.15;
}
.tuile-detail { font-size: var(--t-petit); color: var(--encre-tenue); }
.tuile-evolution {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--t-petit);
  font-weight: var(--graisse-moyenne);
}
.tuile-evolution.hausse { color: var(--critique); }
.tuile-evolution.baisse { color: var(--bien-encre); }
/* Sur un budget, une dépense qui monte est une mauvaise nouvelle et un
   revenu qui monte une bonne : le sens du bien et du mal s'inverse selon la
   tuile, d'où cette variante explicite. */
.tuile-evolution.inversee.hausse { color: var(--bien-encre); }
.tuile-evolution.inversee.baisse { color: var(--critique); }

/* ── Listes ──────────────────────────────────────────────────────────────*/

.liste { display: flex; flex-direction: column; }
.liste-ligne {
  display: flex;
  align-items: center;
  gap: var(--e2);
  padding: var(--e2) 0;
  border-bottom: 1px solid var(--trait-cheveu);
  min-width: 0;
}
.liste-ligne:last-child { border-bottom: none; }
.liste-ligne-cliquable {
  width: 100%;
  text-align: left;
  border-radius: var(--r-petit);
  transition: background var(--v-court) var(--sortie);
}
.liste-ligne-cliquable:hover { background: var(--surface-creuse); }

.liste-principal { flex: 1; min-width: 0; }
.liste-titre {
  font-weight: var(--graisse-moyenne);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.liste-meta {
  font-size: var(--t-petit);
  color: var(--encre-tenue);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* ── Tableaux ────────────────────────────────────────────────────────────
   Le tableau déborde dans son propre conteneur : la page ne défile jamais
   horizontalement, même avec dix colonnes sur un téléphone. */

.tableau-cadre {
  overflow-x: auto;
  margin-inline: calc(var(--e3) * -1);
  padding-inline: var(--e3);
}
.tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-base);
}
.tableau th {
  text-align: left;
  font-size: var(--t-petit);
  font-weight: var(--graisse-moyenne);
  color: var(--encre-tenue);
  padding: var(--e1) var(--e2);
  border-bottom: 1px solid var(--trait);
  white-space: nowrap;
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 1;
}
.tableau td {
  padding: var(--e2);
  border-bottom: 1px solid var(--trait-cheveu);
  vertical-align: middle;
}
.tableau tbody tr { transition: background var(--v-court) var(--sortie); }
.tableau tbody tr:hover { background: var(--surface-creuse); }
.tableau .numerique { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── Vide ────────────────────────────────────────────────────────────────
   Un écran vide est une occasion, pas un échec. Il explique ce qui va se
   passer et propose le premier geste. */

.vide {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--e2);
  padding: var(--e5) var(--e3);
  color: var(--encre-douce);
}
.vide-icone {
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border-radius: var(--r-grand);
  background: var(--accent-voile);
  color: var(--accent);
}
.vide h3 { color: var(--encre); }
.vide p { max-width: 44ch; font-size: var(--t-base); }

/* ── Modale ──────────────────────────────────────────────────────────────
   Bâtie sur l'élément <dialog> natif : le piégeage du focus, la touche
   Échap et l'inertie de l'arrière-plan sont gérés par le navigateur. */

dialog.modale {
  width: min(560px, calc(100vw - var(--e3) * 2));
  max-height: min(86dvh, 780px);
  padding: 0;
  border: 1px solid var(--trait);
  border-radius: var(--r-grand);
  background: var(--surface-haute);
  color: var(--encre);
  box-shadow: var(--ombre-4);
  overflow: hidden;
}
dialog.modale::backdrop {
  background: var(--voile);
  backdrop-filter: blur(3px);
}
dialog.modale[open] { animation: modale-entree var(--v-moyen) var(--sortie); }
@keyframes modale-entree {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
}
dialog.modale[open]::backdrop { animation: fondu-simple var(--v-moyen) var(--sortie); }
@keyframes fondu-simple { from { opacity: 0; } }

.modale-entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e2);
  padding: var(--e3);
  border-bottom: 1px solid var(--trait);
}
.modale-entete h2 { font-size: var(--t-moyen); }
.modale-corps { padding: var(--e3); overflow-y: auto; max-height: 62dvh; }
.modale-pied {
  display: flex;
  justify-content: flex-end;
  gap: var(--e1);
  padding: var(--e3);
  border-top: 1px solid var(--trait);
  background: var(--surface);
}

/* Sur téléphone, la modale devient une feuille qui monte du bas : le geste
   attendu sur mobile, et le contenu reste près du pouce. */
@media (max-width: 640px) {
  dialog.modale {
    width: 100vw;
    max-width: 100vw;
    max-height: 92dvh;
    margin: auto 0 0;
    border-radius: var(--r-grand) var(--r-grand) 0 0;
    border-bottom: none;
  }
  dialog.modale[open] { animation: feuille-entree var(--v-moyen) var(--sortie); }
  @keyframes feuille-entree { from { transform: translateY(100%); } }
  .modale-pied { padding-bottom: calc(var(--e3) + env(safe-area-inset-bottom)); }
}

/* ── Notifications ───────────────────────────────────────────────────────*/

.plateau-messages {
  position: fixed;
  z-index: 120;
  left: 50%;
  bottom: calc(var(--e4) + env(safe-area-inset-bottom));
  translate: -50% 0;
  display: flex;
  flex-direction: column-reverse;
  gap: var(--e1);
  width: min(420px, calc(100vw - var(--e3) * 2));
  pointer-events: none;
}
@media (max-width: 900px) {
  .plateau-messages { bottom: calc(var(--hauteur-barre-mobile) + env(safe-area-inset-bottom) + var(--e5) + var(--e3)); }
}

.message {
  display: flex;
  align-items: center;
  gap: var(--e2);
  padding: var(--e2) var(--e3);
  border-radius: var(--r-moyen);
  background: var(--surface-haute);
  border: 1px solid var(--trait);
  box-shadow: var(--ombre-3);
  font-size: var(--t-base);
  pointer-events: auto;
  animation: message-entree var(--v-moyen) var(--ressort);
}
.message.partant { animation: message-sortie var(--v-moyen) var(--sortie) forwards; }
@keyframes message-entree { from { opacity: 0; transform: translateY(14px) scale(.96); } }
@keyframes message-sortie { to { opacity: 0; transform: translateY(8px) scale(.98); } }
.message-icone { flex: none; width: 20px; height: 20px; }
.message-bien     .message-icone { color: var(--bien-encre); }
.message-erreur   .message-icone { color: var(--critique); }
.message-corps { flex: 1; min-width: 0; }
.message-action { font-weight: var(--graisse-moyenne); color: var(--accent); }

/* ── Squelettes ──────────────────────────────────────────────────────────
   Pendant le chargement, on montre la forme de ce qui arrive plutôt qu'un
   vide ou un tourniquet : l'attente paraît plus courte, et rien ne saute
   quand les données arrivent. */

.squelette {
  border-radius: var(--r-petit);
  background: linear-gradient(90deg,
      var(--surface-creuse) 25%,
      color-mix(in oklab, var(--surface-creuse) 55%, var(--surface)) 37%,
      var(--surface-creuse) 63%);
  background-size: 400% 100%;
  animation: squelette 1.4s ease-in-out infinite;
  color: transparent !important;
  user-select: none;
}
@keyframes squelette { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* ── Séparateur ──────────────────────────────────────────────────────────*/
.separateur { height: 1px; background: var(--trait); border: none; margin: var(--e3) 0; }

/* ── Infobulle de graphique ──────────────────────────────────────────────*/
.infobulle {
  position: fixed;
  z-index: 130;
  pointer-events: none;
  padding: var(--e1) var(--e2);
  border-radius: var(--r-petit);
  background: var(--surface-haute);
  border: 1px solid var(--trait);
  box-shadow: var(--ombre-3);
  font-size: var(--t-petit);
  line-height: 1.45;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--v-court) var(--sortie);
}
.infobulle.visible { opacity: 1; }
.infobulle-titre { font-weight: var(--graisse-forte); margin-bottom: 2px; }
.infobulle-ligne { display: flex; align-items: center; gap: 6px; }
.infobulle-valeur { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: var(--graisse-moyenne); }

/* ── Légende de graphique ────────────────────────────────────────────────
   Présente dès qu'il y a deux séries : l'identité ne repose jamais sur la
   seule couleur. */
.legende {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e1) var(--e3);
  margin-top: var(--e2);
  font-size: var(--t-petit);
  color: var(--encre-douce);
}
.legende-entree { display: inline-flex; align-items: center; gap: 6px; }
.legende-valeur { color: var(--encre); font-variant-numeric: tabular-nums; font-weight: var(--graisse-moyenne); }

/* =========================================================================
   Palette de commandes
   =========================================================================
   Un seul champ pour tout faire. Elle s'ouvre haut sur l'écran plutôt qu'au
   centre : c'est là que l'œil va chercher une barre de recherche, et ça
   laisse la place à la liste de résultats en dessous sans la déplacer.
   ========================================================================= */

dialog.palette {
  width: min(620px, calc(100vw - var(--e3) * 2));
  max-height: 70dvh;
  margin-top: 12vh;
  padding: 0;
  border: 1px solid var(--trait);
  border-radius: var(--r-grand);
  background: var(--surface-haute);
  color: var(--encre);
  box-shadow: var(--ombre-4);
  overflow: hidden;
}
dialog.palette::backdrop {
  background: var(--voile);
  backdrop-filter: blur(4px);
}
dialog.palette[open] { animation: palette-entree var(--v-moyen) var(--sortie); }
@keyframes palette-entree {
  from { opacity: 0; transform: translateY(-12px) scale(.98); }
}

.palette-entete {
  display: flex;
  align-items: center;
  gap: var(--e2);
  padding: var(--e2) var(--e3);
  border-bottom: 1px solid var(--trait);
}
.palette-loupe { color: var(--encre-tenue); flex: none; }
.palette-champ {
  flex: 1;
  border: none;
  background: none;
  outline: none;
  font-size: var(--t-moyen);
  color: var(--encre);
  min-height: 40px;
}
.palette-champ::placeholder { color: var(--encre-tenue); }

.palette-touche {
  padding: 1px 6px;
  border-radius: 5px;
  border: 1px solid var(--trait);
  background: var(--surface-creuse);
  font-family: var(--police);
  font-size: var(--t-micro);
  color: var(--encre-tenue);
}

.palette-resultats {
  overflow-y: auto;
  max-height: 46dvh;
  padding: var(--e1);
}
.palette-groupe + .palette-groupe { margin-top: var(--e1); }
.palette-genre {
  padding: var(--e1) var(--e2) 4px;
  font-size: var(--t-micro);
  font-weight: var(--graisse-moyenne);
  color: var(--encre-tenue);
  text-transform: uppercase;
  letter-spacing: .05em;
}

.palette-entree {
  display: flex;
  align-items: center;
  gap: var(--e2);
  width: 100%;
  padding: var(--e2);
  border-radius: var(--r-moyen);
  text-align: left;
  transition: background var(--v-court) var(--sortie);
}
.palette-entree:hover,
.palette-entree[aria-selected="true"] { background: var(--surface-creuse); }
/* L'entrée de saisie rapide se distingue : c'est celle qu'on veut, et elle
   doit se voir sans avoir à lire les autres. */
.palette-entree.vedette {
  background: var(--accent-voile);
  border: 1px solid color-mix(in oklab, var(--accent) 30%, transparent);
}
.palette-entree.vedette[aria-selected="true"] { background: var(--accent-halo); }
.palette-icone {
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  flex: none;
  border-radius: 10px;
  background: var(--surface-creuse);
  color: var(--encre-douce);
}
.palette-entree.vedette .palette-icone { background: var(--accent); color: var(--accent-encre); }
.palette-texte { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.palette-titre {
  font-weight: var(--graisse-moyenne);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.palette-detail {
  font-size: var(--t-petit);
  color: var(--encre-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.palette-vide {
  padding: var(--e5) var(--e3);
  text-align: center;
  color: var(--encre-tenue);
}

.palette-pied {
  display: flex;
  gap: var(--e3);
  flex-wrap: wrap;
  padding: var(--e1) var(--e3);
  border-top: 1px solid var(--trait);
  background: var(--surface);
  font-size: var(--t-micro);
  color: var(--encre-tenue);
}
.palette-pied kbd { margin-right: 3px; }

@media (max-width: 640px) {
  dialog.palette { margin-top: 4vh; max-height: 86dvh; }
  .palette-pied { display: none; }
}

/* ── Bandeau du jeu de démonstration ──────────────────────────────────────
   Assez visible pour qu'on ne s'y trompe pas, assez sobre pour ne pas gêner
   celui qui explore volontairement. Il disparaît de lui-même dès que la base
   ne contient plus de données fictives. */

.bandeau-demo {
  display: flex;
  align-items: center;
  gap: var(--e2);
  flex-wrap: wrap;
  padding: var(--e2) var(--e3);
  margin-bottom: var(--e3);
  border-radius: var(--r-moyen);
  border: 1px dashed var(--attention);
  background: color-mix(in oklab, var(--attention) 8%, transparent);
}
.bandeau-demo-icone { display: flex; color: var(--attention); flex: none; }
.bandeau-demo-texte { display: flex; flex-direction: column; flex: 1 1 16rem; min-width: 0; }
.bandeau-demo-texte strong { font-size: var(--t-base); }
.bandeau-demo-texte span { font-size: var(--t-petit); color: var(--encre-douce); }

/* ── Commandes et adresses à recopier ─────────────────────────────────────
   Une commande à taper et une adresse à retenir sont des chaînes exactes : un
   caractère près, elles ne marchent pas. Elles méritent une fonte à chasse
   fixe, un fond qui les détache, et surtout de pouvoir être sélectionnées
   d'un geste. */

.bloc-commande {
  margin: var(--e2) 0;
  padding: var(--e2) var(--e3);
  border-radius: var(--r-petit);
  background: var(--surface-creuse);
  border: 1px solid var(--trait);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--t-petit);
  overflow-x: auto;
  user-select: all;
  white-space: pre;
}

.adresse-distante {
  padding: var(--e1) var(--e2);
  border-radius: var(--r-petit);
  background: var(--accent-voile);
  border: 1px solid var(--accent);
  color: var(--encre);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--t-petit);
  /* Un clic suffit à tout sélectionner : c'est une adresse, on la prend en
     entier ou pas du tout. */
  user-select: all;
  word-break: break-all;
}

/* ── Choix d'une catégorie, replié par famille ────────────────────────────
   Une trentaine de pastilles à plat, c'est un mur : l'œil balaie au lieu de
   chercher. Replier ramène la liste à trois lignes, et la famille contenant
   la catégorie retenue s'ouvre d'elle-même — on voit toujours où l'on est. */

.choix-categorie {
  margin-top: 4px;
  border: 1px solid var(--trait);
  border-radius: var(--r-moyen);
  overflow: hidden;
}

.choix-famille + .choix-famille { border-top: 1px solid var(--trait-cheveu); }

.choix-entete {
  display: flex;
  align-items: center;
  gap: var(--e2);
  width: 100%;
  padding: var(--e2) var(--e3);
  text-align: left;
  background: none;
  transition: background var(--v-court) var(--sortie);
}
.choix-entete:hover { background: var(--surface-creuse); }

.choix-chevron {
  display: flex;
  flex: none;
  color: var(--encre-tenue);
  transition: transform var(--v-court) var(--sortie);
}
.choix-famille.ouverte .choix-chevron { transform: rotate(90deg); }

.choix-titre { font-weight: var(--graisse-moyenne); flex: none; }
.choix-aide {
  color: var(--encre-tenue);
  font-size: var(--t-petit);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.choix-pastilles {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 var(--e3) var(--e3);
}

/* ── Aide d'écran, dépliable ──────────────────────────────────────────────
   Un bouton discret au bout de l'en-tête, et un panneau qui se déroule
   dessous. Ouvert à la première visite d'un écran, refermé ensuite et
   mémorisé : un panneau toujours ouvert devient du décor qu'on ne lit plus,
   un panneau toujours fermé n'est jamais découvert. */

.aide-bouton {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--encre-tenue);
  border: 1px solid var(--trait);
  background: none;
  transition: color var(--v-court) var(--sortie),
              border-color var(--v-court) var(--sortie),
              background var(--v-court) var(--sortie);
}
.aide-bouton:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-voile);
}
.aide-bouton[aria-expanded="true"] {
  color: var(--accent-encre);
  background: var(--accent);
  border-color: var(--accent);
}

.aide-panneau {
  margin: 0 0 var(--e3);
  padding: var(--e3);
  border-radius: var(--r-moyen);
  border: 1px solid var(--trait);
  background: var(--surface);
  animation: aide-entree var(--v-moyen) var(--sortie);
}
@keyframes aide-entree {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .aide-panneau { animation: none; }
}

.aide-quoi {
  margin: 0 0 var(--e2);
  font-size: var(--t-base);
  font-weight: var(--graisse-moyenne);
}

/* Les étapes sont numérotées à la main : la remise à zéro des listes du
   projet supprime les marqueurs natifs, et l'ordre porte ici une information —
   on déclare ses charges avant de fixer ses enveloppes, pas l'inverse. */
.aide-etapes {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: aide-etape;
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  color: var(--encre-douce);
  font-size: var(--t-petit);
}
.aide-etapes li {
  counter-increment: aide-etape;
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: var(--e2);
  align-items: start;
}
.aide-etapes li::before {
  content: counter(aide-etape);
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--accent-voile);
  color: var(--accent);
  font-size: var(--t-micro);
  font-weight: var(--graisse-forte);
  font-variant-numeric: tabular-nums;
}

.aide-piege {
  display: flex;
  gap: var(--e2);
  margin-top: var(--e3);
  padding: var(--e2) var(--e3);
  border-radius: var(--r-petit);
  border-left: 3px solid var(--attention);
  background: color-mix(in oklab, var(--attention) 7%, transparent);
}
.aide-piege-icone { display: flex; flex: none; color: var(--attention); margin-top: 2px; }
.aide-piege-titre { font-weight: var(--graisse-moyenne); font-size: var(--t-petit); }
.aide-piege-texte { color: var(--encre-douce); font-size: var(--t-petit); margin-top: 2px; }

.aide-note {
  margin: var(--e2) 0 0;
  color: var(--encre-tenue);
  font-size: var(--t-petit);
}

.aide-pied { margin-top: var(--e3); }
.aide-lien {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--accent);
  font-size: var(--t-petit);
  font-weight: var(--graisse-moyenne);
  text-decoration: none;
}
.aide-lien:hover { text-decoration: underline; }

/* Le motif d'une règle est une chaîne exacte : il se lit à chasse fixe, comme
   la commande qu'il est en réalité. */
.motif-regle {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .88em;
  background: var(--surface-creuse);
  border-radius: 4px;
  padding: .1em .35em;
}
