/* Style propre à domeoimmo — ce que la charte partagée ne fournit pas.
   La coquille, la typographie et les thèmes viennent de domeo-ui
   (static/domeo-ui/). Unités relatives uniquement. */

/* Les TOKENS viennent désormais de la charte partagée
 * (static/domeo-ui/theme.css). Ce fichier ne garde que les noms français
 * historiques, en passerelle : les 380 lignes qui suivent continuent de
 * fonctionner sans être réécrites, et l'adoption reste réversible.
 *
 * Deux pièges évités, mesurés :
 *   --bordure NE pointe PAS vers --border de la charte (1,28:1, soit MOINS
 *   que l'ancienne valeur) mais vers --border-mid ; les contours
 *   fonctionnels prennent --border-strong (3,73:1) plus bas.
 *
 *   --border-mid EST le mélange qui était calibré ici : remonté au dépôt
 *   partagé le 31/07/2026 (décision D3), il y est devenu un jeton de la
 *   gamme. La substitution est exacte, pas approchante — color-mix(65%
 *   border-strong, surface) valait #b3afa3 en clair et #4d6659 en sombre,
 *   soit précisément les deux valeurs du jeton. Aucun pixel ne change.
 */
:root {
  --fond: var(--bg);
  --encre: var(--text);
  --encre-douce: var(--text-muted);
  --bordure: var(--border-mid);
  --bordure-forte: var(--border-strong);
  --accent-contraste: var(--on-accent);
  --ok: var(--success);
  --ko: var(--offline);
  --alerte-fond: var(--warning-soft);
  --alerte-bord: var(--warning-border);
}

/* En-tête ------------------------------------------------------------- */



/* Pages ---------------------------------------------------------------- */

.page { max-width: 70rem; margin: 0 auto; padding: 1.5rem 1.2rem; }
h1 { font-size: 1.4rem; margin: 0 0 1rem; }
h2 { font-size: 1.1rem; margin: 2rem 0 0.8rem; }
.note, .vide { color: var(--encre-douce); }

/* Cartes d'intégration -------------------------------------------------- */

.cartes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 1rem;
}

.carte {
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: 0.5rem;
  padding: 1rem;
}

.carte--degrade { border-color: var(--alerte-bord); }
.carte h2 { margin: 0 0 0.4rem; }
.carte dl { margin: 0.6rem 0 0; font-size: 0.9rem; }
.carte dt { color: var(--encre-douce); }
.carte dd { margin: 0 0 0.5rem; }

.statut { font-weight: 600; margin: 0; }
.statut--nominal { color: var(--ok); }
.statut--degrade { color: var(--ko); }
.erreur-detail { color: var(--ko); font-size: 0.85rem; }

/* Filtres et formulaires ------------------------------------------------ */

.filtres, .formulaire {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 1.2rem;
  align-items: end;
  margin: 0 0 1rem;
}

.formulaire { flex-direction: column; align-items: stretch; max-width: 28rem; }

label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.9rem; }
.filtres label { flex-direction: row; align-items: center; gap: 0.4rem; }

input, select, button {
  font: inherit;
  color: var(--encre);
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: 0.3rem;
  padding: 0.35rem 0.6rem;
}

select option { background: var(--surface); color: var(--encre); }

button {
  background: var(--accent);
  color: var(--accent-contraste);
  border-color: var(--accent);
  cursor: pointer;
  align-self: start;
}

/* Tableaux -------------------------------------------------------------- */

.tableau-defilant { overflow-x: auto; }

/* Une liste compacte dans une cellule de tableau — les postes de dépense
   d'une opération de travaux.

   ⚠️ Aucune couleur ici, uniquement des espacements en unités relatives : la
   règle n'a donc rien à redéfinir en thème sombre, et rien à revoir sur un
   écran étroit. La classe était employée par le gabarit sans exister dans
   cette feuille — la liste s'affichait avec les marges par défaut du
   navigateur. */
.liste-serree { margin: 0; padding-left: 1.2em; }
.liste-serree li + li { margin-top: 0.4rem; }

table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: 0.5rem;
  font-size: 0.9rem;
}

th, td {
  text-align: left;
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--bordure);
  vertical-align: top;
}

th { color: var(--encre-douce); font-weight: 600; }
td pre {
  margin: 0.3rem 0 0;
  padding: 0.4rem;
  background: var(--fond);
  border-radius: 0.3rem;
  font-size: 0.8rem;
  white-space: pre-wrap;
  word-break: break-word;
}

.ok { color: var(--ok); }
.ko { color: var(--ko); }

/* Cases à cocher (groupes, équipes, droits) ----------------------------- */

.case {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
}

.formulaire h2, .formulaire h3 { margin: 1rem 0 0.3rem; }
textarea { font: inherit; color: var(--encre); background: var(--surface);
  border: 1px solid var(--bordure); border-radius: 0.3rem; padding: 0.35rem 0.6rem; }

/* Action en ligne dans un tableau (remplacement d'IBAN, suppressions) ---- */

.ligne-action { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.ligne-action input[type="text"] { min-width: 12rem; }

.liste-alias { list-style: none; padding: 0; margin: 0 0 1rem; }
.liste-alias li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.25rem 0;
}

.versions { margin: 0 0 1rem; padding-left: 1.4rem; font-size: 0.9rem; }
.versions li { padding: 0.15rem 0; }

/* Plan de comptes — l'arborescence se lit d'un coup d'œil */
.plan .numero { font-family: ui-monospace, monospace; margin-right: 0.5rem; }
.plan tr.regroupement { background: color-mix(in srgb, var(--fond) 60%, transparent); }
.plan tr.regroupement td { font-weight: 600; }
.plan tr.feuille .numero { font-weight: 400; }
.plan tr.inactif { opacity: 0.5; }

.liens-directs { white-space: nowrap; }
.liens-directs a { margin-right: 0.6rem; color: var(--accent); text-decoration: none; }
.liens-directs a:hover { text-decoration: underline; }

/* Grille de tantièmes (matrice lots × clés) ----------------------------- */

.page--large { max-width: 100rem; }

.grille { max-height: 70vh; overflow: auto; }
.grille table { font-size: 0.85rem; }

/* En-tête et pied restent visibles pendant le défilement : les totaux par
   clé doivent être lisibles à tout moment pendant la saisie. */
.grille thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--bordure-forte);
}

.grille tfoot th {
  position: sticky;
  bottom: 0;
  z-index: 2;
  background: var(--surface);
  box-shadow: inset 0 1px 0 var(--bordure);
  text-align: right;
}

/* Tous les en-têtes de clés tiennent sur EXACTEMENT deux lignes — libellé
   puis exercice — quelle que soit la longueur du libellé : un nom long est
   tronqué (le titre complet reste en infobulle) plutôt que de passer à la
   ligne et de décaler la colonne voisine. */
.grille thead th { vertical-align: bottom; }
.grille tbody td { vertical-align: middle; }

.grille .colonne-lot, .grille .colonne-usage { white-space: nowrap; }
/* ⚠ `display: block` ne doit porter QUE sur le <small> : posé sur la cellule
   elle-même, il la sort du modèle de tableau et désaligne toute la colonne. */
.grille .colonne-lot small { display: block; font-size: 0.75rem; }
.grille .colonne-usage { font-size: 0.8rem; color: var(--encre-douce); }

.grille .colonne-cle { min-width: 9rem; max-width: 14rem; }
.grille .colonne-cle a {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.grille .colonne-cle small {
  display: block;
  font-weight: 400;
  font-size: 0.75rem;
  white-space: nowrap;
}

.cellule-tantieme { padding: 0.15rem; text-align: right; }
/* Un champ de saisie doit se voir SANS être survolé (SC 1.4.11). La
   bordure transparente donnait 1,00:1 : dans une grille de plusieurs
   centaines de cellules, on ne savait pas où l'on pouvait taper.

   On garde la grille aérée — pas un mur de boîtes — en ne conservant que
   le TRAIT DU BAS, à 3,73:1. C'est le motif classique du champ en ligne :
   il désigne la zone de saisie sans l'encadrer. */
.cellule-tantieme input {
  width: 100%;
  min-width: 5rem;
  text-align: right;
  border: 1px solid transparent;
  border-bottom-color: var(--bordure-forte);
  border-radius: 0;
  background: transparent;
  padding: 0.3rem 0.4rem;
}
.cellule-tantieme input:hover {
  border-color: var(--bordure-forte);
  border-radius: 0.25rem;
}
.cellule-tantieme input:focus {
  border-color: var(--accent);
  border-radius: 0.25rem;
  background: var(--surface);
}

.cellule-total small { display: block; font-weight: 400; font-size: 0.75rem; }

/* Alertes et messages --------------------------------------------------- */

.alerte, .alerte-expiration, .messages li {
  background: var(--alerte-fond);
  border: 1px solid var(--alerte-bord);
  border-radius: 0.3rem;
  padding: 0.2rem 0.5rem;
}

.alerte { display: block; padding: 0.6rem 0.8rem; margin: 0 0 1rem; }
.alerte-expiration { font-size: 0.8rem; margin-left: 0.4rem; }

.messages { list-style: none; padding: 0; margin: 0 0 1rem; }
.messages li { margin-bottom: 0.5rem; }

/* Page de connexion ----------------------------------------------------- */

.page-connexion {
  max-width: 24rem;
  margin: 12vh auto 0;
  padding: 2rem;
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: 0.6rem;
  text-align: center;
}

.bouton {
  display: inline-block;
  margin-top: 1rem;
  padding: 0.6rem 1.4rem;
  background: var(--accent);
  color: var(--accent-contraste);
  border-radius: 0.4rem;
  text-decoration: none;
  font-weight: 600;
}

/* Écritures comptables --------------------------------------------------- */

.journal .numero { font-family: ui-monospace, monospace; margin-right: 0.4rem; }
.journal .montant { text-align: right; white-space: nowrap; }
.journal tr.annulee { opacity: 0.55; text-decoration: line-through; }
.journal tr.annulee .note { text-decoration: none; }

/* Les lignes d'un mouvement, repliées dans la liste du journal.
   ⚠️ Un mouvement d'appel de fonds en porte des dizaines — une par
   copropriétaire, lot et clé. Dépliées d'office, elles noyaient la liste des
   mouvements sous le détail d'un seul. */
.journal details.lignes-repliees > summary {
  cursor: pointer;
  padding: 0.15rem 0;
}
.journal table.lignes-du-mouvement {
  width: 100%;
  margin-top: 0.4rem;
  font-size: 0.85rem;
  border-collapse: collapse;
}
.journal table.lignes-du-mouvement th,
.journal table.lignes-du-mouvement td {
  padding: 0.15rem 0.4rem;
  border-bottom: 1px dashed var(--bordure);
  vertical-align: top;
}
.journal table.lignes-du-mouvement tr:last-child td { border-bottom: none; }
/* Les colonnes de montants restent lisibles côte à côte : deux colonnes
   étroites, alignées à droite, plutôt qu'une largeur fixe qui déborderait sur
   un écran étroit. */
.journal table.lignes-du-mouvement .montant {
  text-align: right;
  white-space: nowrap;
  width: 18%;
}

.grille-champs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.8rem;
  margin-bottom: 0.8rem;
}
.grille-champs label { display: flex; flex-direction: column; gap: 0.2rem; }
.grille-champs .large { grid-column: 1 / -1; }

table.saisie select, table.saisie input { width: 100%; min-width: 6rem; }
table.saisie td { padding: 0.2rem 0.3rem; }

/* Les deux colonnes de montant. Plus étroites que les déroulants : deux
   fois 6 rem pour y taper « 120,00 » repoussaient le tiers hors de vue. Et
   alignées à droite, sans quoi comparer deux montants d'une colonne
   obligerait à compter les chiffres. */
table.saisie input.montant { min-width: 5rem; text-align: right; }

/* Le pied de la saisie : chaque total SOUS sa colonne, et l'écart en
   toutes lettres. Le déséquilibre se lit (« Solde débiteur de … ») ; le
   fond ambre ne fait que l'appuyer, il ne porte jamais l'information seul
   (WCAG 1.4.1) — c'est aussi ce qui le rend juste en thème sombre, où la
   couleur bascule avec le jeton. */
table.saisie tfoot th {
  padding: 0.4rem 0.3rem;
  border-top: 2px solid var(--bordure-forte);
}
table.saisie tfoot tr[data-etat="debiteur"] [data-total="solde"],
table.saisie tfoot tr[data-etat="crediteur"] [data-total="solde"] {
  background: var(--alerte-fond);
}

.note.avertissement {
  background: var(--alerte-fond);
  border-left: 3px solid var(--alerte-bord);
  padding: 0.4rem 0.6rem;
}

button.lien {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  text-decoration: underline;
}

details.carte > summary { cursor: pointer; }
details.carte > summary h2 { display: inline; }

.journal tr.solde-anterieur td { border-bottom: 2px solid var(--bordure); }
.journal tfoot th { border-top: 2px solid var(--bordure); }

.journal .lettre {
  padding: 0 0.35rem;
  border: 1px solid var(--bordure);
  border-radius: 0.7rem;
  color: var(--encre-douce);
  font-size: 0.75rem;
}

a.lettre { text-decoration: none; color: var(--accent); }
a.lettre:hover { text-decoration: underline; }

dl.cle-lettrage {
  display: grid;
  grid-template-columns: minmax(6rem, auto) 1fr;
  gap: 0.3rem 1rem;
  margin: 0.6rem 0 0;
  font-size: 0.9rem;
}
dl.cle-lettrage dt { color: var(--encre-douce); }
dl.cle-lettrage dd { margin: 0; }


/* ═══ Le défilement interne de la coquille ═══════════════════════════
   Bandeau et barre du haut fixes, seul le contenu défile — le même
   comportement que les SPA de la gamme.

   Historique (31/07/2026) : `theme.css` imposait `html, body { overflow:
   hidden }` à tous ses consommateurs, avec le commentaire « l'app gère son
   propre scroll en interne ». Vrai des SPA Vue, où `#app` porte le
   conteneur de défilement ; faux en rendu serveur, où plus rien ne défilait
   et où le contenu était coupé sans barre ni indice. Remonté au dépôt
   partagé et corrigé là-bas (décision D2) : la règle est devenue une classe
   qu'on DEMANDE, `body.defilement-interne`.

   domeoimmo la demande — mais seulement sur les écrans qui portent la
   coquille (cf. `base.html`) : la page de connexion n'en a pas et doit
   défiler normalement. Les trois déclarations ci-dessous suffiraient
   d'ailleurs à elles seules ; la classe n'est que la ceinture. */

.app-shell { height: 100vh; }

/* `min-height: 0` est indispensable : sans lui, un enfant de grille ou de
   flexbox refuse de rétrécir sous la taille de son contenu, et le
   conteneur de défilement déborde au lieu de défiler. */
.app-main-col { min-height: 0; }

.app-content {
  overflow-y: auto;
  min-height: 0;
}

/* La navigation peut dépasser sur un écran court : elle défile aussi. */
.app-sidebar { overflow-y: auto; }

/* La barre du haut ne défile pas avec le contenu. */
.app-topbar { flex-shrink: 0; }

/* ═══ Navigation du bandeau — la charte fournit le cadre, pas les liens ═══ */

.app-nav { display: flex; flex-direction: column; gap: 0.1rem; padding: 0 0.75rem; }

.app-nav__titre {
  margin: 1rem 0 0.35rem 0.6rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-subtle);
}

.app-nav a {
  display: block;
  padding: 0.45rem 0.6rem;
  border-radius: 0.4rem;
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.9rem;
}
.app-nav a:hover { background: var(--hover); color: var(--text); }
.app-nav a.actif { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

.app-sidebar__utilisateur {
  margin: 0 0 0.4rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.app-topbar__fil { color: var(--text-muted); font-size: 0.9rem; }

/* L'écran de connexion n'a pas de coquille : c'est lui qui doit défiler,
   sinon un message d'erreur un peu long devient inatteignable. */
.page-publique {
  height: 100vh;
  overflow-y: auto;
  display: grid;
  place-items: center;
}

/* ═══ Les liens de contenu ════════════════════════════════════════════
   La charte neutralise les liens (`a { color: inherit }`) : sans cette
   règle, ils sont indiscernables du texte. Une seule couleur, sans
   distinction des visités — à terme tous les liens auront été visités
   (décision de l'éditeur, 29/07/2026).

   Le soulignement est PERMANENT, et ce n'est pas décoratif : l'écart entre
   la couleur du lien et celle du texte voisin n'est que de 1,90:1, si bien
   que la couleur ne suffit pas à dire « ceci est cliquable ». Le SC 1.4.1
   (normatif) interdit qu'elle soit le SEUL moyen visuel — c'est l'échec F73,
   et le soulignement permanent y répond sans qu'on touche à la couleur.

   Ne pas écrire « sous le seuil de 3:1 de WCAG 1.4.1 » : le critère ne fixe
   aucun ratio. Le 3:1 vient de la technique G183, informative, qui décrit le
   chemin de celui qui distingue le lien PAR LA COULEUR SEULE — 3:1 avec le
   texte voisin ET un indice au survol. Être en dessous ne met rien en échec,
   cela ferme ce chemin. Cf. domeo-ui, décision D4. */

.app-content a:not(.bouton):not(.app-nav a),
.page a:not(.bouton) {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.app-content a:not(.bouton):hover,
.page a:not(.bouton):hover {
  color: var(--accent-hover);
  text-decoration-thickness: 2px;
}

/* Un lien déguisé en bouton garde le texte du bouton — sinon on obtient
   de l'accent sur de l'accent, soit 1,00:1. */
a.bouton { color: var(--on-accent); text-decoration: none; }

/* ═══ Contours fonctionnels (SC 1.4.11, ≥3:1) ═════════════════════════
   À distinguer des filets entre lignes, volontairement plus discrets — les
   porter à 3:1 zébrerait un tableau dense.

   Ces filets-là restent hors du périmètre du SC 1.4.11 tant qu'ils ne sont
   qu'un RENFORT : la grille est déjà perceptible à l'œil par le contenu des
   cellules et leur alignement. L'argument est visuel, jamais structurel — le
   balisage `table`/`th` ne prouve rien ici, il relève du SC 1.3.1.
   L'exemption tombe si le filet porte un ÉTAT (ligne sélectionnée, colonne
   triée, cellule cliquable), si le tableau est en fait une image, ou s'il
   devient le seul moyen de rattacher une donnée à sa ligne. Cf. domeo-ui, D3. */

input, select, textarea, button, table, .carte, details.carte {
  border-color: var(--bordure-forte);
}

tfoot th, tr.solde-anterieur td { border-color: var(--bordure-forte); }

/* ═══ États atténués ══════════════════════════════════════════════════
   `opacity` s'applique au texte comme au fond et fait tomber le contraste
   à 3,10:1. On atténue par la couleur, ce que la charte prescrit. */

.journal tr.annulee, .plan tr.inactif { opacity: 1; }
.journal tr.annulee td, .plan tr.inactif td { color: var(--text-disabled); }

/* ═══ Messages, par niveau ════════════════════════════════════════════
   Tous recevaient l'habillage ambre d'avertissement, y compris les succès. */

.messages { list-style: none; padding: 0; margin: 0 0 1.2rem; }
.message {
  padding: 0.6rem 0.9rem;
  margin-bottom: 0.5rem;
  border-radius: 0.5rem;
  border-left: 3px solid;
}
.message--success { background: var(--success-soft); border-color: var(--success); }
.message--warning { background: var(--warning-soft); border-color: var(--warning); }
.message--error { background: var(--offline-soft); border-color: var(--offline); }
.message--info, .message--debug { background: var(--surface-tinted); border-color: var(--border-strong); }

/* Sous-totaux de la balance — les regroupements totalisent, ils ne portent
   aucun mouvement (A4.40). Ils se distinguent par la graisse et un fond
   très léger : une couleur seule ne suffirait pas (WCAG 1.4.1), et une
   bordure zébrerait le tableau. */
.grille tr.sous-total > td,
table tr.sous-total > td {
  font-weight: 600;
  background: color-mix(in srgb, var(--texte) 5%, transparent);
}

/* Une ligne de brouillon dans un grand livre — elle n'est pas au livre, et
   cela doit se voir. Le sens est porté par la colonne « E », qui affiche
   « B », et par la référence préfixée « B- » dans le libellé ; ce fond ne
   fait que les appuyer, la couleur seule ne suffisant jamais (WCAG 1.4.1). */
table tr.brouillon > td {
  background: color-mix(in srgb, var(--texte) 4%, transparent);
  font-style: italic;
}

/* La colonne d'état du grand livre. Étroite à dessein : elle ne porte
   quelque chose que sur une minorité de lignes, et une colonne large aux
   trois quarts vide repousserait les montants hors de vue. */
th.etat, td.etat {
  width: 1.5rem;
  text-align: center;
  font-weight: 600;
  font-style: normal;
}
th.etat abbr { text-decoration: none; }

/* Documents de cabinet — attestation de fonds mandants, état des fonds ---
   (lot B2-1)

   ⚠️ Tout passe par les JETONS de la charte, jamais par une couleur en dur.
   Le premier jet n'avait aucun style : le graphique arrivait avec ses
   couleurs de PDF — un trait noir, invisible sur le fond sombre — et les
   blocs se confondaient avec la page. Relevé à la validation navigateur du
   8 août 2026. */

.attestation .immeubles { border: 1px solid var(--bordure); border-radius: 6px;
                          padding: 0.8rem 1rem; margin: 0.8rem 0; }
.attestation .immeubles legend { font-weight: 600; padding: 0 0.4rem; }
.attestation .immeubles__actions { display: flex; gap: 0.5rem;
                                   margin: 0.5rem 0 0.7rem; }
.attestation .immeubles__actions button { font-size: 0.85rem;
                                          padding: 0.2rem 0.6rem; }
/* En colonnes : sur quarante immeubles, une liste en une colonne oblige à
   dérouler la page pour cocher deux cases voisines. */
.attestation .immeubles__liste { list-style: none; margin: 0; padding: 0;
                                 columns: 2; column-gap: 1.5rem; }
.attestation .immeubles__liste li { break-inside: avoid; padding: 0.15rem 0; }
.attestation .immeubles__liste label { display: flex; gap: 0.4rem;
                                       align-items: baseline; cursor: pointer; }
.attestation .immeubles__liste .code { color: var(--encre-douce);
                                       font-variant-numeric: tabular-nums; }
.attestation .immeubles__liste .type { color: var(--encre-douce);
                                       font-size: 0.8rem; }

.attestation .apercu { border: 1px solid var(--bordure); border-radius: 6px;
                       padding: 1rem 1.2rem; margin-top: 1.5rem;
                       background: var(--surface); }
.attestation .chiffre { display: flex; gap: 0.6rem; align-items: baseline;
                        flex-wrap: wrap; margin-bottom: 0.3rem; }
.attestation .chiffre .maximum { font-size: 2rem; font-weight: 700;
                                 font-variant-numeric: tabular-nums; }
.attestation .chiffre .jour { color: var(--encre-douce); font-size: 1.05rem; }

/* La courbe hérite de l'encre de la page — c'est ce qui la rend lisible dans
   les deux thèmes, le SVG étant dessiné en `currentColor`. Le disque du
   maximum prend la couleur du FOND pour se détacher du trait. */
.attestation .courbe { color: var(--encre); margin: 0.8rem 0 0.3rem;
                       overflow-x: auto; }
.attestation .courbe svg { max-width: 100%; height: auto; }
.attestation .courbe .repere { fill: var(--surface); }

.attestation .decomptes { margin: 1rem 0; border-collapse: collapse; }
.attestation .decomptes th { text-align: left; font-weight: 400;
                             color: var(--encre-douce);
                             padding: 0.25rem 1.5rem 0.25rem 0; }
.attestation .decomptes td { padding: 0.25rem 0;
                             font-variant-numeric: tabular-nums; }
.attestation .decomptes .alerte { color: var(--ko); font-size: 0.85rem;
                                  margin-left: 0.5rem; }

.attestation .reserve { border-left: 3px solid var(--alerte-bord);
                        background: var(--alerte-fond);
                        padding: 0.6rem 0.9rem; margin: 1rem 0;
                        border-radius: 0 4px 4px 0; }
.attestation .reserve h3 { font-size: 0.95rem; margin: 0 0 0.3rem; }
.attestation .reserve ul { margin: 0.4rem 0 0; padding-left: 1.1rem; }

/* Le refus « les chiffres ont bougé ». Il doit arrêter l'œil sans crier :
   ce n'est pas une panne, c'est une invitation à relire. */
.attestation .ecart { border-left: 3px solid var(--ko);
                      background: var(--alerte-fond);
                      padding: 0.8rem 1rem; margin: 1.2rem 0;
                      border-radius: 0 4px 4px 0; }
.attestation .ecart h2 { margin: 0 0 0.4rem; font-size: 1.05rem;
                         color: var(--ko); }
.attestation .ecart p { margin: 0.3rem 0; }

.attestation .editer { margin-top: 1.2rem; padding-top: 1rem;
                       border-top: 1px solid var(--bordure); }
.attestation table.detail { width: 100%; border-collapse: collapse;
                            margin-top: 1rem; font-size: 0.9rem; }
.attestation table.detail th { text-align: left; }
.attestation table.detail td.montant,
.attestation table.detail th.montant { text-align: right;
                                       font-variant-numeric: tabular-nums; }
.attestation table.detail td.code { color: var(--encre-douce);
                                    font-variant-numeric: tabular-nums; }

/* --- Onglets sans JavaScript ---------------------------------------------
   Deux lectures d'une même donnée, commandées par des boutons radio.

   ⚠️ **Aucune ligne de JavaScript, et c'est un choix.** La navigation au
   clavier est celle du navigateur — flèches entre les radios d'un même
   groupe —, l'état survit à un rechargement du fragment, et rien ne casse si
   un script échoue à charger.

   ⚠️ **Les radios doivent être SŒURS des panneaux** : `:checked ~` ne
   remonte pas. Les enfermer dans une barre afficherait les deux vues.

   ⚠️ **Le nom du groupe doit être unique dans la page.** Deux fragments qui
   le partageraient se commanderaient l'un l'autre.
   ------------------------------------------------------------------------ */

.onglets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0;
}

/* Hors du flux visuel mais toujours FOCUSABLE : c'est l'étiquette qui est
   peinte, la radio qui reçoit le clavier. */
.onglets__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.onglets__onglet {
  padding: 0.35rem 0.9rem;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--encre-douce);
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}

.onglets__radio--un + .onglets__onglet {
  border-radius: 0.4rem 0 0 0.4rem;
}

.onglets__radio--deux + .onglets__onglet {
  border-radius: 0 0.4rem 0.4rem 0;
  border-left-width: 0;
}

.onglets__onglet:hover {
  background: var(--hover);
  color: var(--encre);
}

.onglets__radio:checked + .onglets__onglet {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contraste);
}

/* ⚠️ Le focus se voit sur l'ÉTIQUETTE : la radio étant masquée, son propre
   contour serait invisible et l'écran deviendrait inutilisable au clavier. */
.onglets__radio:focus-visible + .onglets__onglet {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.onglets__panneau {
  flex: 1 0 100%;
  display: none;
  margin-top: 0.75rem;
}

.onglets__radio--un:checked ~ .onglets__panneau--un,
.onglets__radio--deux:checked ~ .onglets__panneau--deux {
  display: block;
}

/* ⚠️ À l'impression, les DEUX vues sortent : le papier n'a pas d'onglet, et
   une feuille qui n'en montrerait qu'une laisserait croire que l'autre
   n'existe pas. */
@media print {
  .onglets__onglet { display: none; }
  .onglets__panneau { display: block !important; }
}

/* ⚠️ Employée par les gabarits pour porter un libellé destiné aux seuls
   lecteurs d'écran — elle n'était définie NULLE PART, si bien que ces
   libellés s'affichaient. Le motif est celui de la recommandation WAI :
   on retire l'élément du flux sans le retirer de l'arbre d'accessibilité,
   ce que `display: none` ferait. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
