/* FLUX — budget, revenus, depenses, arbre du scenario
 *
 * Tranche 08 de public/styles.css, decoupe le 2026-08-24. Les fichiers sont
 * NUMEROTES parce que l'ordre de chargement compte : une regle plus bas l'emporte sur une
 * regle de meme portee plus haut. Ne pas reordonner les <link> de index.html.
 */
/* LE GABARIT DE LIGNE DE L'ONGLET FLUX (bloc 5)
   Les quatre familles — revenus d'investissement, activité & compléments, évolutions
   futures, dépenses — passaient chacune par sa propre structure : trois grilles, trois
   tailles de texte, trois places pour le montant. Elles partagent désormais `.flux-ligne`
   (public/champs/ligne-flux.js), et TOUTES ses colonnes existent même vides : une piste
   manquante décale ce qui suit, et c'est ce qui faisait qu'un montant ne tombait jamais au
   même endroit d'une famille a l'autre. */
.flux-dated-list { display: flex; flex-direction: column; margin-bottom: 0.65rem; }

.flux-ligne { position: relative; border-bottom: 1px solid var(--border); transition: background-color 0.15s ease; }
.flux-ligne:last-child { border-bottom: none; }
.flux-ligne:hover { background: var(--bg-hover); }
.flux-ligne:has(.flux-ligne-detail:not([hidden])) { background: var(--bg-hover); }

/* Pastille posee sur la PREMIERE ligne (top fixe, pas 50 %) : elle ne bouge plus quand le
   detail se deplie et fait grandir la ligne. */
.flux-ligne::before {
  content: ''; position: absolute; left: 0.1rem; top: 0.95rem;
  width: 6px; height: 6px; border-radius: 50%; background: var(--border-strong);
}
.flux-ligne.is-revenu::before { background: var(--accent); }
.flux-ligne.is-depense::before { background: var(--red); }
/* `neutre` : l'argent change de poche sans toucher au patrimoine net (capital remboursé,
   apport capitalisé) — ni un gain ni une perte, donc ni vert ni rouge. `--gold` est
   theme-invariant (01-socle.css), pas besoin d'une variante -text séparée pour le texte. */
.flux-ligne.is-neutre::before { background: var(--gold); }
/* `mixte` : une mensualité de crédit regroupée (capital doré + intérêts rouges,
   `regrouperMensualitesCredit`, flux-theorique.js) — une pastille coupée au vrai prorata,
   posé par le JS via la variable `--mix-pct`, jamais une des deux couleurs choisie au hasard. */
.flux-ligne.is-mixte::before {
  background: conic-gradient(var(--red) 0% var(--mix-pct, 50%), var(--gold) var(--mix-pct, 50%) 100%);
}

/* Colonnes PROPORTIONNELLES, avec un minimum par colonne : en largeurs fixes, les cinq
   colonnes mangeaient 525 px des 584 px de la carte et il ne restait que 27 px au libellé,
   réduit à une lettre (mesuré à l'écran, pas supposé). Chaque colonne peut maintenant rendre
   de la place, et le libellé — la seule colonne qu'on lit vraiment — grandit avec la carte. */
.flux-ligne-corps {
  display: grid;
  grid-template-columns:
    24px minmax(7rem, 1.6fr) minmax(6rem, 1fr) minmax(6rem, 1fr) minmax(4rem, 0.6fr) 6.8rem;
  grid-template-areas: "fleche libelle quand montant taux actions";
  gap: 0.4rem; align-items: center; padding: 0.5rem 0.15rem 0.5rem 0.9rem;
  min-height: 3.2rem;
}
/* Dans « Flux théorique », c'est « %/an » que plus personne ne remplit, et « quand » qui sert.
   L'inverse était vrai jusqu'au 2026-09-08 : la colonne « quand » y était mise à 0 parce
   qu'aucune ligne ne l'utilisait, et « %/an » portait le champ de croissance. Depuis que les
   réglages d'une ligne saisie sont passés dans la fenêtre « Modifier », « %/an » a quitté la
   ligne et « quand » porte les trois mentions de l'écran : l'échéance d'une ligne saisie
   (« 7, 8 »), le « ce mois-ci » d'une ligne ponctuelle, et le « dès juin 2040 » d'une carte de
   revenu. Une piste à 0 les faisait toutes passer à la ligne suivante, sous le libellé (vu à
   l'écran le 2026-09-08 ; les deux dernières étaient déjà dans cet état sans qu'on l'ait vu).
   `:where()` garde une spécificité identique à `.flux-ligne-corps` seul : le repli étroit
   ci-dessous (une seule classe aussi) continue de l'emporter en dessous de son seuil, sans
   avoir besoin d'être dupliqué ici. */
:where(.theorique-arbre) .flux-ligne-corps {
  grid-template-columns: 24px minmax(7rem, 1.7fr) minmax(4rem, 0.8fr) minmax(6rem, 1.1fr) 0 7.25rem;
}
/* 7.25rem : les quatre boutons d'un dossier (4 × 27 px et leurs écarts). À 6.8rem ils
   débordaient sur le montant (mesuré le 2026-09-29). */
/* « Investissements réguliers » : ni croissance ni échéance sur une ligne de DCA, un seul
   bouton. Les pistes vides rendent leur place au nom (« Compte courant » était coupé en
   « Compt… », vu à l'écran le 2026-09-10). Même spécificité que la règle de l'arbre. */
:where(#theorique-invest-card) .flux-ligne-corps {
  grid-template-columns: 24px minmax(0, 1fr) auto minmax(6rem, auto) 0 auto;
}
.flux-ligne-corps > .line-toggle { grid-area: fleche; }
.flux-ligne-libelle { grid-area: libelle; }
.flux-ligne-quand { grid-area: quand; }
.flux-ligne-montant { grid-area: montant; }
.flux-ligne-taux { grid-area: taux; }
.flux-ligne-actions { grid-area: actions; }
.flux-ligne-corps > div { min-width: 0; }
.flux-ligne-libelle { display: flex; align-items: center; gap: 0.3rem; }
/* Le libelle est le titre de la ligne : meme traitement pour les quatre familles (avant, la
   carte d'activite l'avait en gras sans bordure, la ligne datee en champ ordinaire). */
.flux-ligne-libelle input[type=text] {
  flex: 1; min-width: 0; font-weight: 600; font-size: var(--flux-taille, 0.88rem);
  background: transparent; border: none; border-bottom: 1px solid transparent;
  color: var(--text-strong); padding: 0.15rem 0; border-radius: 0;
}
/* Un libellé en simple texte (lignes du DCA) : il se coupe au lieu de déborder sur le montant.
   Un texte nu dans un conteneur flex ne prend pas les points de suspension, d'où l'élément. */
.flux-ligne-libelle { min-width: 0; }
.flux-ligne-texte {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600; font-size: var(--flux-taille, 0.88rem); color: var(--text-strong);
}
.flux-ligne-libelle input[type=text]:hover { border-bottom-color: var(--border); }
.flux-ligne-libelle input[type=text]:focus { outline: none; border-bottom-color: var(--gold); }
.flux-ligne-montant { justify-self: end; font-variant-numeric: tabular-nums; }
.flux-ligne-montant .revenu-net { font-weight: 700; color: var(--accent); font-size: var(--flux-taille, 0.88rem); }
/* `flex-wrap` : dans le repli étroit, la colonne ne tient que deux boutons. Sans retour à la
   ligne, ceux d'un dossier débordaient vers la gauche, sur le montant (« 530 € + »). */
.flux-ligne-actions {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 0.15rem;
}
.flux-ligne-actions button { flex: none; }
.flux-ligne label { display: flex; align-items: center; gap: 0.25rem; font-size: 0.68rem; color: var(--muted); white-space: nowrap; }
/* `min-width: 0` : sans lui, un champ impose sa largeur NATURELLE (~170 px pour un champ
   nombre) comme minimum de sa colonne, et la grille prend cette place au libellé — mesuré :
   la colonne du libellé tombait à 0 px dans une carte étroite. */
.flux-ligne input, .flux-ligne select {
  background-color: var(--card); padding: 0.32rem 0.45rem; font-size: 0.82rem;
  width: 100%; min-width: 0;
  transition: border-color 0.12s ease;
}

/* Ligne non modifiable : sa valeur vient de l'evenement qui la produit, et se change la-bas.
   Seul le gris le dit — pas de champ desactive, il n'y a pas de champ du tout. */
/* `.is-auto` atténue le LIBELLÉ, jamais le montant : une ligne calculée garde la couleur de
   sa colonne (verte en revenus, rouge en dépenses), et c'est le cadenas qui dit qu'elle se
   modifie ailleurs. La règle `strong { color: var(--muted) }` grisait le montant d'un revenu
   dont la barre latérale restait verte : deux signes qui se contredisaient sur la même ligne. */
.flux-ligne.is-auto { color: var(--muted); font-size: 0.82rem; }
.flux-ligne.is-auto strong { font-weight: 600; }
/* Le montant reprend explicitement la couleur de SA NATURE : `color` étant hérité, retirer
   la règle grise du `strong` ne suffisait pas, il aurait hérité du gris de la ligne. Pas de
   règle pour `.is-mixte` : un montant qui mélange deux natures n'a pas de couleur juste,
   la pastille bicolore suffit à le dire. */
.flux-ligne.is-auto.is-revenu .flux-ligne-montant strong { color: var(--accent-text); }
.flux-ligne.is-auto.is-depense .flux-ligne-montant strong { color: var(--red-text); }
.flux-ligne.is-auto.is-neutre .flux-ligne-montant strong { color: var(--gold); }
/* Un revenu d'investissement reste VERT, même non modifiable : le gris de la ligne dit qu'on
   ne la saisit pas ici, il n'a pas à effacer la couleur de ce qu'elle représente. Les deux
   règles précédentes avaient éteint les montants verts de la liste des revenus automatiques
   (régression du bloc 5, signalée par Nicolas le 2026-08-29). */
.flux-ligne.is-auto strong.statut-ok { color: var(--accent); }
.flux-ligne.is-auto strong.statut-warn { color: var(--orange); }
/* Flux futur : estompe, mais pleinement modifiable. */
.flux-ligne.is-future { opacity: 0.55; }
.flux-ligne.is-future:hover { opacity: 0.85; }
/* Source eteinte : se repere sans avoir a la deplier, puisque la case Actif est dans le
   detail depuis le bloc 5. */
.flux-ligne.is-inactif { opacity: 0.5; }
/* Prévu ce mois-ci mais pas encore confirmé : le fond des événements en attente, comme leur
   carte. Compté dans les flux du mois, pas encore dans le patrimoine du jour. */
.flux-ligne.is-a-confirmer { background: var(--en-attente-fond); border-radius: 8px; }
.flux-ligne.is-a-confirmer .flux-ligne-mention { color: var(--gold-strong); font-weight: 600; }
.flux-ligne.is-inactif .flux-ligne-libelle input[type=text] { text-decoration: line-through; }

.flux-ligne-detail { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; padding: 0 0.15rem 0.6rem 2.05rem; }
/* `display:flex` d'auteur l'emporte sur le `[hidden]{display:none}` du navigateur : c'est le
   piege des huit boutons du bloc 9, ici desamorce des l'ecriture de la regle. */
.flux-ligne-detail[hidden] { display: none !important; }
.flux-ligne-detail > label { font-size: 0.72rem; }
.flux-ligne-detail > label input { width: auto; }
/* Le detail d'une source d'activite est une grille de champs : elle prend la ligne entiere
   du detail plutot que de s'aligner a cote de la date des flux dates. */
.flux-ligne-detail > .revenu-card-grid,
.flux-ligne-detail > .revenu-card-projet-hint,
.flux-ligne-detail > .revenu-card-linked-hint { flex: 1 1 100%; }
/* La fleche masquee garde sa piste (visibility, pas display) : retiree du flux, elle
   decalerait le libelle d'une colonne. */
.flux-ligne .line-toggle[hidden] { visibility: hidden; }

.flux-ligne .btn-flux-timeline { background: transparent; border-color: transparent; color: var(--muted); }
.flux-ligne .btn-flux-timeline:hover { background: color-mix(in srgb, var(--gold) 12%, transparent); border-color: color-mix(in srgb, var(--gold) 35%, transparent); color: var(--text-strong); }
.flux-mod-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.1rem; height: 1.1rem; padding: 0 0.3rem;
  border-radius: 999px; background: var(--gold); color: var(--bg); font-size: 0.62rem; font-weight: 700;
  vertical-align: middle; flex: none;
}
/* Mention portee par une ligne non modifiable : « ce mois-ci », « deja deduite du loyer
   net ». Elle occupe la colonne « quand », qui serait vide autrement. */
.flux-ligne-mention { font-size: 0.68rem; color: var(--muted); white-space: nowrap; }
/* Bilan flux mensuel (2026-09-06) : les lignes DCA par enveloppe se replient sous une seule
   ligne « Investissements » — même chevron pivotant que `.line-toggle`, posé ici sur le
   bouton lui-même (pas un enfant `.line-toggle`, d'où une règle dédiée plutôt que la classe
   partagée). */
#flux-invest-toggle { display: inline-flex; align-items: center; gap: 0.35rem; }
#flux-invest-toggle svg { transition: transform 0.15s ease; }
#flux-invest-toggle.expanded svg { transform: rotate(90deg); }
#flux-invest-total-inline { color: var(--muted); font-weight: 500; }
/* Sous une certaine largeur DE LA CARTE (pas de la fenêtre : les deux colonnes de Flux sont
   étroites même sur un grand écran), la ligne se replie sur deux rangées plutôt que d'écraser
   le libellé. Le montant reste à droite, à la même place, et ne prend que sa largeur : une
   colonne réservée à 6,5 rem laissait six lettres au nom (Nicolas, 2026-10-12). */
.budget-section { container-type: inline-size; }
@container (max-width: 33rem) {
  /* Le detail d'une source suit : trois colonnes de champs n'entrent pas dans une carte
     etroite, meme sur un grand ecran. */
  .revenu-card-grid { grid-template-columns: 1fr 1fr; }
  .flux-ligne-corps {
    grid-template-columns: 24px minmax(0, 1fr) auto 4.6rem;
    grid-template-areas:
      "fleche libelle montant actions"
      ".      quand   taux    .";
    row-gap: 0.3rem;
  }
}
/* Sur un téléphone, libellés et montants un cran plus petits : le nom de la ligne, qu'on lit
   vraiment, était réduit à six lettres (Nicolas, 2026-10-12). */
@media (max-width: 720px) {
  .flux-ligne { --flux-taille: 0.8rem; }
  .flux-ligne-montant strong { font-size: var(--flux-taille); }
}
@media (max-width: 720px) {
  .flux-ligne-corps {
    grid-template-columns: 24px minmax(0, 1fr) auto 4.6rem;
    grid-template-areas:
      "fleche libelle montant actions"
      ".      quand   taux    .";
    row-gap: 0.3rem;
  }
}
/* « Investissements réguliers » dans les deux replis ci-dessus : un seul bouton et un montant
   court, qui ne prennent que la place de leur contenu. Le repli leur réservait 104 + 74 px
   quoi qu'il arrive, et il restait 64 px au nom (mesuré le 2026-09-10 sur une carte de
   334 px). Même spécificité, posée après : elle l'emporte sur ce bloc seulement. */
@container (max-width: 33rem) {
  :where(#theorique-invest-card) .flux-ligne-corps { grid-template-columns: 24px minmax(0, 1fr) auto auto; }
}
@media (max-width: 720px) {
  :where(#theorique-invest-card) .flux-ligne-corps { grid-template-columns: 24px minmax(0, 1fr) auto auto; }
}
.budget-section h2 { margin-bottom: 0.35rem; }
.line-toggle {
  background: transparent; border: 1px solid var(--border); color: var(--muted);
  border-radius: var(--radius-input); width: 1.6rem; height: 1.6rem; font-size: 0.75rem; cursor: pointer;
  flex: 0 0 auto; line-height: 1; transition: color 0.12s ease, border-color 0.12s ease;
  display: inline-flex; align-items: center; justify-content: center;
}
.line-toggle svg { transition: transform 0.15s ease; }
.line-toggle:hover { color: var(--text-strong); border-color: var(--border-strong); }
.line-toggle.expanded { color: var(--gold); border-color: var(--gold); }
.line-toggle.expanded svg { transform: rotate(90deg); }
.revenu-card-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.45rem;
}
@media (max-width: 720px) { .revenu-card-grid { grid-template-columns: 1fr 1fr; } }
/* min-width: 0 + width: 100% : cette grille ne descend jamais sous 2 colonnes (ni à 720px, ni
   au conteneur étroit ci-dessus), donc contrairement à .modal-grid ou .catalog-wizard-fields
   elle NE PEUT PAS compter sur un repli à une colonne pour éviter le débordement sur
   téléphone. Même piège que .projet-form-grid (2026-09-16), même remède ici. */
.revenu-card-grid label { font-size: 0.72rem; color: var(--muted); display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
/* Sans elle, le `display: flex` ci-dessus montrait la case « Croissance %/an » d'un salaire, dont
   la hausse se règle par « Évolution dans le temps » : ce qu'on y tapait n'était jamais lu. */
.revenu-card-grid label[hidden] { display: none !important; }
.revenu-card-grid input, .revenu-card-grid select {
  width: 100%; background-color: var(--card); border-radius: var(--radius-xs); padding: 0.3rem 0.4rem; font-size: 0.82rem;
}
/* Les cases à cocher de la carte : la grille empile libellé et champ en colonne, une case
   se lit en ligne. Vaut pour « Actif » comme pour « Somme imposable ». */
.revenu-card-grid label.revenu-case { flex-direction: row; align-items: center; gap: 0.35rem; }
.revenu-card-grid label.span-2 { grid-column: span 2; }
.revenu-net-detail { font-size: 0.7rem; color: var(--muted); grid-column: span 2; align-self: center; }
.revenu-card-projet-hint { font-size: 0.72rem; color: var(--orange); margin-top: 0.35rem; }
.revenu-card-linked-hint { font-size: 0.7rem; color: var(--muted); margin-top: 0.35rem; }

.modal h2 { margin: 0 0 0.35rem; }
.modal-body label { display: block; font-size: 0.75rem; color: var(--muted); margin: 0.55rem 0 0.15rem; }
.modal-body label:has(input[type="checkbox"]) { display: flex; flex-direction: row; align-items: center; gap: 0.35rem; }
.modal-body input, .modal-body select, .modal-body textarea { width: 100%; padding: 0.4rem; }
/* Annule le width:100% de la regle ci-dessus, PAS "auto" : une case personnalisee
   (appearance:none, Bloc 8) n'a plus de taille intrinseque a laquelle revenir. */
.modal-body input[type="checkbox"] { width: 1.1rem; }
.modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem; }
.projet-form-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.5rem; margin-bottom: 0.5rem;
}
/* min-width: 0 : sans lui, un <input> sans largeur explicite impose sa largeur naturelle du
   navigateur (~170 px) à sa colonne de grille, quelle que soit la place réellement offerte —
   invisible sur les 4 colonnes larges du bureau, ça fait déborder la carte dès 2 colonnes sur
   téléphone (repli à 900px ci-dessous). Piège déjà connu du projet, jamais recontrôlé ici. */
.projet-form-grid label { font-size: 0.75rem; color: var(--muted); display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.projet-form-grid label:has(input[type="checkbox"]) { flex-direction: row; align-items: center; }
/* `display: flex` d'auteur sur CHAQUE label l'emporte sur le `[hidden] { display: none }` de
   la feuille du navigateur (même piège que `.modal-grid label[hidden]`) : sans cette garde,
   masquer un champ sans objet — rendement d'un compte courant, risque d'un livret, cf.
   `src/epargne/capacites-enveloppe.js` — resterait sans le moindre effet. */
.projet-form-grid label[hidden] { display: none !important; }
.projet-form-grid input {
  width: 100%;
  background: var(--bg-inset); border: 1px solid var(--border); color: var(--text-strong);
  border-radius: var(--radius-input); padding: 0.35rem 0.45rem; font-size: 0.82rem;
}
.projet-row {
  border: 1px solid var(--border); border-radius: var(--radius-input); padding: 0.5rem 0.65rem;
  margin-bottom: 0.4rem; font-size: 0.82rem;
}
.projet-row summary { cursor: pointer; font-weight: 500; }
@media (max-width: 900px) { .projet-form-grid { grid-template-columns: 1fr 1fr; } }

/* --- Sous-onglets de Flux : « Vue mensuelle » et « Charges théoriques » --- */
.budget-subpanel { display: none; }
/* Le même écart entre cartes que `.panel.active` (02-mise-en-page.css) : en `display: block`,
   le sous-panneau échappait à ce `gap` et ses cartes se touchaient (2026-09-10). */
.budget-subpanel.active { display: flex; flex-direction: column; gap: var(--ecart-blocs); }
@media (max-width: 900px) { .budget-subpanel.active { gap: 0; } }
/* Le Bilan en totaux (flux-bilan.js) : la couleur dit la nature. Par classe et non par id :
   le Résumé de la fenêtre mensuelle réclame le même tableau. */
.bilan-flux .positive { color: var(--accent); }
.bilan-flux .negative { color: var(--red); }
.bilan-flux .neutre { color: var(--gold); }
/* L'alerte sur la variation du compte (posée par l'écran) et celles du serveur forment UN
   groupe : sans ce conteneur, l'écart entre blocs du panneau les séparait. */
.flux-alertes { display: flex; flex-direction: column; gap: 0.35rem; }
/* Même écart qu'entre deux alertes d'une zone (`.alertes`, 04-formulaires.css) : la marge haute
   de chaque zone s'y ajoutait, 20 px au lieu de 6 (mesuré le 2026-09-10). */
.flux-alertes > .alertes { margin-top: 0; }
/* Les deux totaux se détachent : une ligne vide avant et après, un trait plein au-dessus, un
   texte plus grand (demande de Nicolas, 2026-09-10). */
.bilan-flux tr.bilan-espace td { height: 0.8rem; padding: 0; border: none; }
.bilan-flux tr.bilan-total td {
  border-top: 2px solid var(--text-strong); border-bottom: 2px solid var(--text-strong);
  font-size: 1.05rem; padding-top: 0.6rem; padding-bottom: 0.6rem;
}
/* [hidden] de l'UA ne l'emporte pas sur un display d'auteur, cf. gardes-hidden.test.mjs */
.budget-subpanel[hidden] { display: none !important; }

.charges-th-total { font-size: 1.05rem; margin: 0.6rem 0 0.2rem; }
/* Une RANGÉE, pas deux boutons posés comme du texte. `.btn-ajout` (marge haute de 0.5rem,
   faite pour un bouton SEUL sous une liste) décalait « + Revenu » vers le bas à côté de
   « Nouveau dossier » : la classe a été retirée du balisage, et la marge est neutralisée ici
   pour tout enfant qui la porterait à nouveau. */
.charges-th-actions {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.4rem; margin: 0.4rem 0 1rem;
}
.charges-th-actions > .btn { margin-top: 0; }

/* Ligne calculée : un CADENAS dans la colonne d'actions, et la ligne GARDE SA COULEUR.
   Le marqueur textuel « verrouillée » redisait en mots ce que le grisage disait déjà — et
   mal, puisque `.is-auto` grisait le montant d'un revenu dont la barre latérale restait
   verte. Un signe, un sens. */
.charge-th-cadenas {
  display: inline-flex; align-items: center; color: var(--muted); flex: none;
}
.charge-th-cadenas svg { display: block; }

/* Le trait d'insertion du glisser-déposer. Posé en absolu dans la colonne (qui porte donc
   `position: relative`), il ne déplace RIEN : c'est tout l'intérêt, la page ne change qu'au
   relâchement. */
.theorique-arbre { position: relative; }
.th-trait-insertion {
  position: absolute; height: 2px; background: var(--accent); border-radius: 2px;
  pointer-events: none; z-index: 3;
}
.th-trait-insertion[hidden] { display: none !important; }

/* Un dossier vide s'affiche comme les autres (choix du 2026-09-07) : ni cadre en pointillés
   ni zone d'accueil. Son total à zéro s'estompe, pour qu'il ne se lise pas comme un chiffre
   qu'on aurait raté. */
.charge-th-dossier.est-vide .flux-ligne-montant { color: var(--muted); }

/* Glisser-déposer dans « Flux théorique » — deux colonnes, la carte de revenu comprise. */
.charge-th-ligne[draggable], .charge-th-dossier[draggable],
.theorique-arbre .revenu-card[draggable] { cursor: grab; }
.charge-th-ligne[draggable]:active, .charge-th-dossier[draggable]:active,
.theorique-arbre .revenu-card[draggable]:active { cursor: grabbing; }
.th-drop-dans { outline: 2px dashed var(--accent); outline-offset: -2px; }

/* --- « Flux théorique » : plan repliable, profondeur maîtrisée --- */
/* `.theorique-arbre` (2026-09-06) est posée sur les DEUX colonnes (Revenus, Dépenses) — une
   seule règle plutôt que dupliquée par id, comme du temps de l'unique arbre « Charges
   théoriques ». Retrait FIXE par niveau (pas cumulatif exponentiel), et un filet plutôt que du
   vide au-delà. « Flux actuel » montre le même arbre, déplié de la même façon. */
:is(.theorique-arbre, .flux-actuel-liste) .flux-ligne-detail {
  display: block; padding: 0 0 0 0.75rem; margin-left: 0.15rem;
  border-left: 1px solid var(--border);
}
:is(.theorique-arbre, .flux-actuel-liste) .flux-ligne-detail > .flux-ligne { width: 100%; }
/* Le libellé ne se replie jamais : il tronque, le montant reste calé à droite. */
.theorique-arbre .charge-th-ligne .flux-ligne-libelle,
.theorique-arbre .charge-th-dossier .flux-ligne-libelle {
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
@media (max-width: 640px) {
  .theorique-arbre .flux-ligne-detail { padding-left: 0.5rem; }
}
/* UNE LIGNE CALCULÉE SE LIT COMME SES VOISINES (2026-09-24, demande de Nicolas) : un loyer
   calculé s'écrivait plus petit et en gris sous deux revenus saisis en vert. Le cadenas dit
   déjà qu'elle se modifie ailleurs ; la taille et la couleur n'ont pas à le redire. Tous les
   montants de la colonne des revenus prennent le vert d'un revenu de carte (`.revenu-net`). */
.theorique-arbre .flux-ligne.is-auto { color: inherit; font-size: inherit; }
.theorique-arbre .flux-ligne.is-revenu .flux-ligne-montant strong {
  color: var(--accent); font-weight: 700; font-size: var(--flux-taille, 0.88rem);
}

/* --- Le Sankey du mois courant --- */
/* Aucune hauteur ici : le dessin garde sa proportion (trois de large pour un de haut,
   `PROPORTION`), la même sur ordinateur et sur téléphone. */
.sankey-wrap { position: relative; margin: 0.5rem 0 0.25rem; }
.sankey-entete { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
.sankey-entete h2 { margin: 0; }
.btn-deplier[hidden] { display: none !important; }
.sankey-wrap canvas[hidden] { display: none !important; }
.sankey-wrap .hint[hidden] { display: none !important; }
/* Sur un téléphone tenu droit, le Sankey ne se dessine pas dans la carte : 335 pixels coupaient
   les noms à six lettres. Un bouton l'ouvre en plein écran, où il se lit téléphone tourné
   (`plein-ecran.js`, Nicolas, 2026-10-12). `.btn.` : la règle `display` des boutons, chargée
   avant, l'emporterait sinon à spécificité égale. */
.btn.sankey-ouvrir, .btn.sankey-fermer, .sankey-tourner { display: none; }
.sankey-wrap[hidden] + .btn.sankey-ouvrir { display: none !important; }
@media (max-width: 720px) {
  .sankey-wrap:not(.plein-ecran) > canvas { display: none !important; }
  .btn.sankey-ouvrir { display: inline-flex; margin: 0.5rem 0; }
}
/* Au-dessus de la barre du haut et du menu (90), sous les fiches (100) qu'un ruban ouvre. */
.sankey-wrap.plein-ecran {
  position: fixed; inset: 0; z-index: 95; margin: 0;
  /* Pas de marge sur les côtés : le dessin prend la largeur de son conteneur marge comprise,
     et la débordait d'autant (« 26 750 € » coupé, barre de défilement). */
  padding: 3rem 0 0.75rem; overflow: hidden auto; background: var(--card);
}
.sankey-wrap.plein-ecran .btn.sankey-fermer { display: inline-flex; position: fixed; top: 0.6rem; right: 0.75rem; }
@media (orientation: portrait) {
  .sankey-wrap.plein-ecran > canvas { display: none !important; }
  .sankey-wrap.plein-ecran .sankey-tourner {
    display: flex; align-items: center; justify-content: center; min-height: 60vh;
    text-align: center; color: var(--muted); padding: 0 1.5rem;
  }
}
body.sankey-plein-ecran { overflow: hidden; }

/* Le second diagramme : ce qui change de valeur sans passer par le compte. Plus court que le
   circuit — il porte moins de rubans, et il ne doit pas lui voler la vedette. */
/* Pas de hauteur fixe : elle suit celle du canvas, que `hauteurValorisations` pose,
   proportionnelle aux montants. */
#theorique-valeur-wrap { position: relative; margin: 0.25rem 0 0.5rem; }
#theorique-valeur[hidden] { display: none !important; }
#theorique-valeur-wrap .hint[hidden] { display: none !important; }
#theorique-valeur-titre[hidden] { display: none !important; }
/* Le clic sur le graphique de la Vue d'ensemble fait défiler jusqu'à cette carte : sans cette
   marge, son titre et le choix du mois passaient sous la barre du haut, collante. */
#theorique-sankey-card { scroll-margin-top: 5.5rem; }
/* Le mois regardé (Flux théorique et Flux actuel) : flèches, mois, année, et le choix sur le
   graphique, qui passe à la ligne sur un téléphone plutôt que de pousser la page de côté. */
.mois-choix { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0.75rem 0; }
.mois-choix select { padding: 0.4rem 0.6rem; }
/* « Ranger » et « Tout déplier » à droite du titre ; un bouton `hidden` ne laisse pas de trou. */
.sankey-entete-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
/* La vue Détail de Flux actuel : la liste des opérations du mois. */
#actuel-detail[hidden] { display: none !important; }
/* La vue Détail empile plusieurs .card.inner (positifs, négatifs, gain net, neutres) : sans
   marge propre, rien ne les sépare. */
#theorique-detail { display: flex; flex-direction: column; gap: 0.75rem; }
#theorique-detail[hidden] { display: none !important; }


/* --- Les opérations du mois (vue Détail de Flux actuel) --- */
.operations-resume { margin: 0.25rem 0; }
/* Le tableau défile seul : le choix du mois et les totaux restent sous les yeux. */
.operations-defilement { max-height: 60vh; overflow: auto; }
.operations-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.operations-table th {
  position: sticky; top: 0; background: var(--card); text-align: left;
  padding: 0.45rem 0.5rem; color: var(--muted); font-weight: 600; white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
.operations-table td { text-align: left; padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
.operations-table .operation-montant { text-align: right; white-space: nowrap; }
/* Une carte s'appelle parfois « Carte Visa Classic - Mr J DOE 02Xx (Débitée Sur Compte Courant 2) » :
   coupée à l'écran, lisible en entier au survol. */
.operations-table .operation-compte { max-width: 11rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.operations-table td:first-child { min-width: 9rem; }
.operations-table .operation-montant.negative { color: var(--red-text); }
.operations-table .operation-montant.positive { color: var(--accent-text); }
/* Ni dépense ni revenu : lu, mais en retrait. */
.operations-table tr.operation-hors-compte td { color: var(--muted); }
.operations-table tr.operation-hors-compte .operation-ligne { background: transparent; color: var(--muted); }
/* Le montant aussi : rouge ou vert, il se lisait comme une dépense ou un revenu du mois. */
.operations-table tr.operation-hors-compte .operation-montant { color: var(--muted); }
/* La ligne d'une opération : un bouton qui la rouvre dans le tri. */
.operation-ligne {
  background: var(--card); border: 1px solid var(--border); border-radius: 999px;
  color: var(--text-strong); font: inherit; font-size: 0.82rem; padding: 0.2rem 0.65rem; cursor: pointer; max-width: 15rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.operation-ligne:hover { background: var(--bg-hover); }
/* Reste à ranger : l'or de l'appel du haut de l'écran, sur le bouton et en liseré de la rangée. */
.operation-ligne.est-a-ranger { border: 1px dashed var(--gold); background: var(--gold-soft); color: var(--gold-strong); font-weight: 600; }
.operations-table tr.operation-a-ranger td:first-child { box-shadow: inset 3px 0 0 var(--gold); }
.operation-ligne-regle { margin-left: 0.4rem; padding-left: 0.4rem; border-left: 1px solid var(--border); font-size: 0.68rem; color: var(--muted); }
/* Proposée, pas encore choisie : la bordure le dit, le tri le confirme. */
.operation-ligne.est-propose { border-style: dashed; }

/* --- « Flux actuel » : le réel d'abord, le prévu dessous --- */
/* Rien ne s'y saisit : ni date, ni taux, ni action. Le libellé et le montant prennent toute la
   ligne. Deux classes : l'emporte aussi sur les replis étroits de `.flux-ligne-corps`. */
.flux-actuel-liste .flux-ligne-corps {
  grid-template-columns: 24px minmax(0, 1fr) auto;
  grid-template-areas: "fleche libelle montant";
}
.flux-actuel-liste :is(.flux-ligne-quand, .flux-ligne-taux, .flux-ligne-actions) { display: none; }
.flux-actuel-liste .flux-ligne-montant { display: flex; flex-direction: column; align-items: flex-end; gap: 0.05rem; }
/* Le réel est le chiffre de l'écran. Sans couleur (choix de Nicolas, 2026-09-30) : la pastille
   dit la nature de la ligne, le montant dit combien. */
.flux-actuel-liste .flux-ligne-montant .flux-reel { font-size: 1rem; font-weight: 700; color: var(--text-strong); }
.flux-actuel-liste .flux-reel.est-nul { color: var(--muted); font-weight: 600; }
.flux-prevu { font-size: 0.72rem; font-weight: 400; color: var(--muted); white-space: nowrap; }
/* Pas de banque reliée : pas de réel, le prévu reprend la place du montant. */
.flux-reel:empty { display: none; }
.flux-actuel-liste .flux-reel:empty + .flux-prevu { font-size: 0.88rem; font-weight: 600; color: var(--text); }
.flux-actuel-total { display: flex; flex-direction: column; align-items: flex-end; gap: 0.1rem; margin: 0.4rem 0 0; }
.flux-actuel-total strong { font-size: 0.95rem; color: var(--text-strong); }
.flux-actuel-total:empty { display: none; }

/* --- L'émoji d'une ligne ou d'un dossier (règles communes dans 04-formulaires.css) --- */
.flux-ligne:hover > .flux-ligne-corps .bouton-emoji.est-vide, .bouton-emoji.est-vide:focus-visible { opacity: 0.7; }
.flux-ligne-libelle:has(> .bouton-emoji) { display: flex; align-items: center; min-width: 0; }
