/* FORMULAIRES — champs, boutons, parametres, sous-onglets
 *
 * Tranche 04 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.
 */
/* Case a cocher personnalisee (2026-08-30, retour Nicolas : "meme degrade dore, interieur
   blanc" que les boutons). `accent-color` ne peut pas degrader — appearance:none et un
   coche dessine en CSS (deux bords blancs pivotes) remplacent le rendu natif. */
input[type="checkbox"] {
  appearance: none; -webkit-appearance: none; margin: 0;
  width: 1.1rem; height: 1.1rem; flex: 0 0 1.1rem;
  border: 1.5px solid var(--border-strong); border-radius: var(--radius-xs);
  background: var(--card-inner); cursor: pointer;
  display: inline-grid; place-content: center; vertical-align: middle;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
input[type="checkbox"]:hover { border-color: var(--gold-btn); }
input[type="checkbox"]:checked {
  background: linear-gradient(135deg, var(--gold-btn-bright) 0%, var(--gold) 45%, var(--gold-btn) 100%);
  border-color: var(--gold-btn);
}
input[type="checkbox"]:checked::after {
  content: ''; width: 0.32rem; height: 0.58rem;
  border: solid var(--btn-primary-text); border-width: 0 2px 2px 0;
  transform: rotate(45deg) translateY(-1px);
  animation: coche-apparait 0.2s ease-out;
}
/* La coche "pop" plutot que de se dessiner trait par trait (un vrai tracé demanderait un SVG
   a la place du triangle en bordures ci-dessus) — meme intention, technique plus simple. */
@keyframes coche-apparait {
  from { transform: rotate(45deg) translateY(-1px) scale(0); }
  to { transform: rotate(45deg) translateY(-1px) scale(1); }
}
input[type="checkbox"]:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
input[type="checkbox"]:disabled { opacity: 0.5; cursor: not-allowed; }
/* `display: inline-grid` ci-dessus (indispensable au dessin de la coche) l'emporte sur le
   `[hidden] { display: none }` de la feuille du navigateur : sans cette garde, TOUTE case à
   cocher marquée `hidden` reste dessinée. C'est le même piège que `.btn[hidden]`,
   `.modal-grid label[hidden]` et `.subtabs[hidden]` — vu à l'écran le 2026-08-31 sur la case
   d'état « calcul automatique des charges déductibles » du locatif, qui s'affichait comme un
   petit carré vide sans libellé au milieu de la carte Régime fiscal. */
input[type="checkbox"][hidden] { display: none !important; }

/* UN CLIC SUR L'ICÔNE EST UN CLIC SUR SON BOUTON.
 *
 * Sans cette ligne, `document.elementFromPoint` au CENTRE d'un bouton à icône renvoie le
 * `<svg>`, pas le bouton : viser le pictogramme — c'est-à-dire viser juste — ne déclenchait
 * rien dans les huit gestionnaires qui testent `e.target.classList.contains('btn-…')`.
 * Mesuré le 2026-08-31 sur la corbeille d'une ligne de charge : bouton de 27 px, icône de 14,
 * la moitié de la cible était morte. On cliquait, il ne se passait rien, on recliquait un peu
 * à côté — et cette fois ça partait.
 *
 * Corrigé ICI plutôt que dans les huit gestionnaires : la règle vaut pour tous les boutons à
 * icône du produit, y compris ceux qu'on n'a pas encore écrits. */
button svg { pointer-events: none; }

/* UNE SEULE recette de champ (2026-08-27).
 *
 * Avant ce jour, il n'existait AUCUNE regle commune : les cinq memes proprietes (fond,
 * bordure, couleur, arrondi, remplissage) etaient recopiees a la main dans dix endroits
 * differents, et le onzieme — la liste deroulante de la barre laterale — n'en avait
 * aucune, d'ou ses 19 px de haut contre 30 pour l'icone voisine (corrige au Bloc 1).
 * Meme piege que celui des boutons, meme remede.
 *
 * Cette regle ne vise que des NOMS D'ELEMENT : n'importe quelle regle d'ecran portant une
 * classe l'emporte sur elle, quel que soit l'ordre des feuilles. Les regles d'ecran ne
 * redisent donc plus que ce qui DIFFERE vraiment (une taille plus serree dans un tableau,
 * un fond plus clair dans une carte). Les cases a cocher, les boutons radio et les
 * selecteurs de couleur sont hors sujet : ils ne se dessinent pas comme un champ. */
/* UNE SEULE recette de champ, revue le 2026-09-22 (identite de la landing page) : le
   remplissage gris plein a disparu au profit d'un simple trait bas, sur le modele deja
   valide par `.compte-ligne-input` (11-enveloppes.css, "les champs doivent se lire comme
   des valeurs, pas comme un formulaire pose par-dessus le tableau") — generalise ici a
   TOUS les champs du produit, pas seulement ceux en tableau. Au repos le trait suffit a
   dire "champ" ; le survol l'assombrit ; le focus prend la couleur de marque. */
/* `:where` (2026-09-25) : six `:not([type])` donnaient à `input` le poids de six classes,
   contre zéro à `select`. Une règle d'écran `.X input, .X select { padding }` ne touchait
   donc que la liste, et une liste posée à côté d'un champ n'avait plus sa hauteur. */
input:where(:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="range"]):not([type="button"]):not([type="submit"])),
select,
textarea {
  background: transparent; border: none; border-bottom: 1px solid var(--border-strong);
  color: var(--text-strong);
  border-radius: 0; padding: 0.4rem 0.15rem;
  font-size: 0.85rem; font-family: var(--font-sans); min-height: 2.1rem;  transition: border-color 0.15s ease, background-color 0.15s ease;
  /* max-width: 100% (2026-09-17) : un champ à largeur FIXE (ex. .cible-input, .dca-input,
     70/90px) tenait pour acquis que sa cellule de tableau serait toujours plus large que lui.
     Sur un tableau à colonnes en pourcentage (table-layout: fixed, ex. #table-macro) qui
     rétrécit sur téléphone, ce n'est plus vrai : le champ débordait de sa cellule et
     chevauchait le texte voisin. Cette ligne ne RÉTRÉCIT un champ que si son conteneur est
     réellement plus étroit que sa largeur voulue ; elle ne change rien ailleurs. Ne corrige
     PAS le cas d'un champ SANS largeur du tout dans une grille CSS (voir min-width: 0 sur la
     cellule de grille, remède différent, cf. .projet-form-grid). */
  max-width: 100%;
}
input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="range"]):not([type="button"]):not([type="submit"]):hover:not(:disabled),
select:hover:not(:disabled),
textarea:hover:not(:disabled) { border-bottom-color: var(--muted); background-color: var(--bg-hover); }
/* Le navigateur impose à sa liste et à ses dates une hauteur minimale que n'a pas un champ
   texte : dans une rangée serrée (min-height: 0), la liste dépassait son voisin de 2 px.
   La liste est donc dessinée par la page, flèche comprise. Toute règle d'écran qui colore
   une liste pose `background-color`, jamais `background`, sinon elle efface la flèche.
   La marge droite EST la place de la flèche, d'où `!important` : seize règles d'écran
   réécrivaient `padding` en raccourci pour régler leur texte, et la flèche passait sur la
   valeur (« 08 » du Détail mensuel). Un écran règle le haut, le bas et la gauche, jamais elle. */
select {
  appearance: none; -webkit-appearance: none; padding-right: 1.1rem !important;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: right 0.55rem center, right 0.25rem center;
  background-size: 0.3rem 0.3rem; background-repeat: no-repeat;
}
input::-webkit-datetime-edit, input::-webkit-datetime-edit-fields-wrapper { padding: 0; }
input::-webkit-calendar-picker-indicator { padding: 0; margin: 0; height: 1em; }
/* Un champ serre dans un tableau ou une grille dense n'a pas la hauteur d'un bouton. */
.charge-editor-row input,
.charge-editor-row select,
.detention-editor-row input,
.detention-editor-row select,
.frais-editor-row input,
.revenu-card-grid input,
.revenu-card-grid select,
.cible-input,
.dca-input,
.flux-ligne input,
.flux-ligne select,
.epargne-config-row input[type="number"],
.structure-date select { min-height: 0; }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none; border-bottom-color: var(--gold); box-shadow: 0 1px 0 0 var(--gold);
}
.alertes { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.35rem; }
.alerte { padding: 0.45rem 0.65rem; border-radius: var(--radius-input); font-size: 0.82rem; border: 1px solid; }
.alerte.danger { border-color: color-mix(in srgb, var(--red) 40%, transparent); background: color-mix(in srgb, var(--red) 8%, transparent); color: var(--red-text); }
.alerte.warning { border-color: color-mix(in srgb, var(--orange) 40%, transparent); background: color-mix(in srgb, var(--orange) 8%, transparent); color: var(--orange-text); }
/* Point de vigilance dans l'apercu de l'assistant de separation. */
.alerte-warning { color: var(--orange-text); }
.alerte.info { border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: color-mix(in srgb, var(--accent) 8%, transparent); color: var(--cat-vie-text); }
.params-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--ecart-blocs);
}
.params-grid label {
  display: flex; flex-direction: column; gap: 0.25rem;
  font-size: 0.78rem; color: var(--muted); margin-bottom: 0.5rem;
}
.params-grid label[hidden] { display: none !important; }
.rendements-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }
.regime-categorie { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 0.9rem; }
.regime-changement { display: flex; gap: 0.5rem; align-items: center; }
.regime-changement input, .regime-changement select { min-width: 0; }
.regime-boutons { display: flex; gap: 0.5rem; }
.regime-a-choisir { border-left: 4px solid var(--gold); background: var(--gold-soft); padding: 0.4rem 0.6rem; margin: 0; }
.regime-categorie .regime-ajouter { align-self: flex-start; }
.regime-comparaison:empty { display: none; }
/* Deux périodes ne tiennent pas sur un téléphone : le tableau défile dans sa zone, la page non. */
.regime-comparaison { overflow-x: auto; max-width: 100%; }
.regime-comparaison-titre { margin: 0.3rem 0 0.2rem; font-size: 0.78rem; color: var(--muted); }
.regime-comparaison-table { border-collapse: collapse; font-size: 0.82rem; }
.regime-comparaison-table th, .regime-comparaison-table td { padding: 0.2rem 0.8rem 0.2rem 0; text-align: right; white-space: nowrap; }
.regime-comparaison-table th:first-child { text-align: left; }
.regime-comparaison-table thead th { font-weight: 500; color: var(--muted); }
.regime-moins-cher { color: var(--accent-text); font-weight: 600; }
/* Seule grille du produit sans repli mobile jusqu'au 2026-09-17 (tour des onglets sur
   telephone) : le texte de "Foyer fiscal" et "Rendements annuels" debordait de l'ecran. */
@media (max-width: 900px) { .params-grid { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .rendements-grid { grid-template-columns: 1fr; } }
.params-actions { margin-top: 1rem; display: flex; gap: 0.5rem; }

/* DEUX tailles de bouton, et rien d'autre (2026-08-27) : `.btn` et `.btn.btn-sm`.
 *
 * Avant ce jour il y en avait HUIT, chacune posee a la main dans l'ecran qui en avait
 * besoin (`.timeline-card-actions .btn`, `.comparer-tile-actions .btn`, `.btn-flux-del`,
 * `.structure-outils .btn`…), si bien que deux boutons voisins n'avaient jamais tout a
 * fait la meme hauteur. Et `.btn.secondary` portait un `margin-top: 0.5rem` — pense pour
 * les boutons « + Ajouter… » isoles sous une liste — que HUIT selecteurs d'exception
 * devaient ensuite annuler, un par groupe de boutons. La marge est desormais portee par
 * le conteneur qui en a besoin (`.btn-ajout` pour les rares boutons sans conteneur), pas
 * par le bouton.
 *
 * La hauteur est posee en MIN-HEIGHT, pas en remplissage vertical : deux boutons cote a
 * cote font la meme hauteur meme si l'un est en gras et l'autre non, et un libelle trop
 * long pour une ligne fait grandir le bouton au lieu de deborder. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem;
  min-height: 2.1rem; padding: 0.3rem 0.85rem;
  background: var(--bg-hover); border: 1px solid var(--border); color: var(--text-strong);
  border-radius: var(--radius-btn); cursor: pointer; font-size: 0.83rem;
  font-weight: 500; font-family: var(--font-sans); line-height: 1.25;
  text-align: center; text-decoration: none; vertical-align: middle;
  box-shadow: inset 0 1px 0 color-mix(in srgb, white 5%, transparent), var(--shadow-btn);
  transition: transform 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease, border-color 0.12s ease;
}
.btn.btn-sm { min-height: 1.7rem; padding: 0.2rem 0.6rem; font-size: 0.75rem; }
/* HUIT BOUTONS NE SE CACHAIENT PAS. `display: inline-flex` ci-dessus est une regle
   d'auteur : elle l'emporte sur le `[hidden] { display: none }` de la feuille du navigateur,
   exactement comme `.modal-overlay[hidden]` et `.subtabs[hidden]` plus bas. Tout
   `bouton.hidden = true` du produit etait donc sans effet — « Apercu cash-flow » dans les
   fiches, les deux boutons de l'assistant du catalogue, « + Salaire »/« + Activite »,
   « Modifier » dans la fiche enveloppe, « Replacer » dans Structure, « Choisir » dans la
   fenetre de suppression. Ils restaient a l'ecran sans rien avoir a y faire. */
.btn[hidden] { display: none !important; }
/* Bouton reduit a une icone ou a un seul signe : carre, pas aplati. Le CSS ne voit pas un
   texte nu : une icone suivie d'un libelle met ce libelle dans un <span>, sinon le bouton
   passe pour une icone seule et son texte touche le bord. */
.btn:has(> svg:only-child) { padding-inline: 0; min-width: 2.1rem; }
.btn.btn-sm:has(> svg:only-child) { min-width: 1.7rem; }
/* La seule marge admise sur un bouton : celle du « + Ajouter… » pose seul sous une liste,
   sans conteneur d'actions pour l'espacer. */
.btn-ajout { margin-top: 0.5rem; }
.btn:hover { background: var(--border-strong); border-color: var(--border-strong); box-shadow: var(--shadow-btn-hover); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* Degrade a 3 tons (pas 2) pour un effet "brillant" plutot qu'un aplat mat — retour Nicolas
   2026-08-30. Le point chaud est en haut a gauche (135deg), la ou le libelle ne passe pas au
   centre, pour ne pas affaiblir le contraste du texte blanc sous le reflet.
   Mixte or -> vert par defaut (retour Nicolas 2026-09-22) : la plupart des boutons "primary"
   (Enregistrer, Ajouter un scenario a comparer...) traversent tout le spectre de la marque —
   "pas 100% vert en general", mais plus 100% dore non plus. `.btn.primary.mono` juste en
   dessous garde l'ancien degrade dore seul, reserve aux quelques actions qui doivent rester
   identiques partout dans l'app (Fermer une fiche, Gerer les enveloppes, Inviter). */
/* Degrade a 120deg (2026-09-22, troisieme reglage). Le passage par l'horizontal (90deg) avait
   ete choisi pour eviter un ecart de teinte entre les deux coins d'un meme bord (un degrade
   135deg projette une composante verticale sur un bouton COURT ET LARGE, cf. l'incident
   "bouton dore, bordure verte" resolu ce jour-la). A 120deg la composante verticale est reduite
   d'un tiers par rapport a 135deg (30deg d'inclinaison contre 45) : Nicolas a compare les trois
   angles sur un bouton agrandi (vraie taille DOM, pas un zoom CSS) avant de retenir celui-ci —
   l'ecart de coin existe toujours en theorie mais n'est plus visible a cette inclinaison.
   Le motif de couleur va fonce (--gold-btn-dark) a clair (--gold-btn-plateau, tenu en plateau
   de 22% a 45% pour laisser de la place au dore) puis retombe sur le vert EXACTEMENT comme
   avant (--accent puis --accent-btn-to, memes valeurs). `.btn.primary.mono` garde 135deg : un
   degrade a une seule teinte n'a pas ce probleme de coin, l'effet "brillant" y reste donc en
   diagonal franche. `border: none` (pas seulement border-color) pour ne laisser aucune boite
   de bordure residuelle. */
.btn.primary {
  position: relative; overflow: hidden;
  background: linear-gradient(120deg, var(--gold-btn-dark) 0%, var(--gold-btn-plateau) 22%, var(--gold-btn-plateau) 45%, var(--accent) 78%, var(--accent-btn-to) 100%);
  border: none;
  color: var(--btn-primary-text); font-weight: 600; letter-spacing: 0.01em;
  box-shadow: inset 0 1px 0 color-mix(in srgb, white 25%, transparent), 0 1px 2px rgba(0, 0, 0, 0.25);
}
.btn.primary:hover {
  background: linear-gradient(120deg, color-mix(in srgb, var(--gold-btn-dark) 85%, white 15%) 0%, color-mix(in srgb, var(--gold-btn-plateau) 88%, white 12%) 22%, color-mix(in srgb, var(--gold-btn-plateau) 88%, white 12%) 45%, color-mix(in srgb, var(--accent) 85%, white 15%) 78%, var(--accent) 100%);
  border: none;
  box-shadow: inset 0 1px 0 color-mix(in srgb, white 30%, transparent), var(--shadow-btn-hover);
}
.btn.primary.mono {
  background: linear-gradient(135deg, var(--btn-primary-from) 0%, var(--gold) 45%, var(--btn-primary-to) 100%);
  border-color: var(--btn-primary-border);
}
.btn.primary.mono:hover {
  background: linear-gradient(135deg, color-mix(in srgb, var(--btn-primary-from) 80%, white 20%) 0%, color-mix(in srgb, var(--gold) 85%, white 15%) 45%, var(--gold) 100%);
  border-color: var(--gold-btn-bright);
  box-shadow: inset 0 1px 0 color-mix(in srgb, white 30%, transparent), 0 0 0 1px color-mix(in srgb, var(--gold-btn-bright) 35%, transparent), var(--shadow-btn-hover);
}
/* Reflet qui balaie au survol (retour Nicolas, chantier 2 - animations). En dehors du flux
   (::before, largeur fixe), donc n'affecte jamais la taille du bouton — seul `left` bouge. */
.btn.primary::before {
  content: ''; position: absolute; top: 0; left: -60%; width: 40%; height: 100%;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, white 55%, transparent), transparent);
  transform: skewX(-20deg); transition: left 0.55s ease; pointer-events: none;
}
.btn.primary:hover::before { left: 120%;
}
.btn.secondary { background: transparent; border-color: var(--border); box-shadow: none; color: var(--text); }
.btn.secondary:hover { background: var(--bg-hover); border-color: var(--border-strong); box-shadow: none; transform: none; color: var(--text-strong); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
/* Le trait dore ne change plus de tab en tab, il GLISSE (socle/subtab-indicateur.js,
   chantier 2 - animations, 2026-08-30) : border-bottom-color retire de .active, .subtab garde
   sa reserve de 2px transparente pour que la mise en page ne bouge pas. */
.subtab.active { color: var(--text-strong); font-weight: 600; }
.subtab.inactive-env { opacity: 0.55; }
.kpi .value.positive { color: var(--accent); }
.kpi .value.negative { color: var(--red); }
/* « Horizon : 5 ans », « Patrimoine : net » : un choix d'affichage se lit comme une phrase,
   le libellé puis la valeur retenue. Même trait bas que tout champ, mais à la taille des
   anciens sous-onglets qu'il remplace, et à leur place (même marge basse). */
.choix-affichage {
  display: inline-flex; align-items: baseline; gap: 0.4rem;
  font-size: 0.8rem; color: var(--muted); margin-bottom: 0.85rem; white-space: nowrap;
}
.choix-affichage select {
  font-size: 0.8rem; font-weight: 500; min-height: 0; padding: 0.15rem 0.1rem; cursor: pointer;
  field-sizing: content;
}
/* Le trait des listes de choix d'affichage prend le dégradé des boutons principaux (or foncé,
   or clair, vert). Une bordure ne peut pas être dégradée : le trait est un fond de 1,5 px
   collé en bas. À 90deg, pas 120 comme les boutons : sur un trait sans hauteur, l'angle ne
   ferait qu'écraser le dégradé. Le survol ne pose que la couleur de fond, jamais `background`
   entier, sinon il effacerait le trait (d'où la spécificité de la règle de survol, qui doit
   battre `select:hover` plus haut). */
.choix-affichage select, select.hero-metric-mode {
  border-bottom: none;
  background:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%) right 0.55rem center / 0.3rem 0.3rem no-repeat,
    linear-gradient(135deg, var(--muted) 50%, transparent 50%) right 0.25rem center / 0.3rem 0.3rem no-repeat,
    linear-gradient(90deg, var(--gold-btn-dark) 0%, var(--gold-btn-plateau) 35%, var(--accent) 80%, var(--accent-btn-to) 100%)
    left bottom / 100% 1.5px no-repeat;
}
.choix-affichage select:hover:not(:disabled), select.hero-metric-mode:hover:not(:disabled) {
  background-color: var(--bg-hover);
}
.choix-affichage-rangee { display: flex; flex-wrap: wrap; column-gap: 1.5rem; }
.subtabs {
  position: relative;
  display: flex; gap: 0.9rem; margin-bottom: 0.85rem; border-bottom: 1px solid var(--border);
}
.subtab-indicateur {
  position: absolute; left: 0; bottom: -1px; height: 2px; width: 0;
  background: linear-gradient(90deg, var(--gold), var(--accent));
  border-radius: 1px; opacity: 0; pointer-events: none;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), width 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), opacity 0.15s ease;
}
/* Rangée « sous-onglets + action » : le bouton d'ajout s'aligne sur la même ligne que les
   sous-onglets, à droite, et la ligne de séparation court sous les deux. Les sous-onglets
   défilent si la liste d'enveloppes s'allonge, sans jamais chasser le bouton. */
.subtabs-row { display: flex; align-items: flex-end; gap: 0.9rem; }
/* overflow-y: hidden est indispensable : avec overflow-x seul, le calcul CSS force
   overflow-y a auto et le navigateur dessine une barre de defilement VERTICALE (deux
   petites fleches) a cote du bouton. */
.subtabs-row .subtabs {
  flex: 1; min-width: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin;
  /* 2px de marge interne : sans elle, overflow-y: hidden rogne le soulignement de l'onglet
     actif, qui touche exactement le bas de la zone visible. */
  padding-bottom: 2px; margin-bottom: 0;
}
.subtabs-row > .btn-add-event { flex-shrink: 0; }
/* display:flex l'emporte sur la règle UA [hidden] — sans ce !important, hidden=true ne
   masquerait pas les onglets (même piège que .modal-overlay[hidden]). */
.subtabs[hidden] { display: none !important; }
.subtab {
  background: transparent; border: none; border-bottom: 2px solid transparent; color: var(--muted);
  padding: 0.35rem 0.05rem; margin-bottom: -1px; cursor: pointer; font-size: 0.8rem; font-weight: 500;
  border-radius: 0;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.subtab:hover { color: var(--text-strong); }
.env-subpanel { display: none; }
.env-subpanel.active { display: flex; flex-direction: column; gap: var(--ecart-blocs); }
.card.inner { background: var(--bg-inset); border-color: var(--bg-hover); }
td.statut-sur { color: var(--red); }
td.statut-sous { color: var(--orange); }
td.statut-ok { color: var(--accent); }
.cible-input { width: 70px; border-radius: var(--radius-xs); padding: 0.25rem 0.35rem; font-size: 0.8rem; }
/* DCA éditable dans le tableau de flux (même look que .cible-input) */
.dca-input { width: 90px; border-radius: var(--radius-xs); padding: 0.25rem 0.35rem; font-size: 0.8rem; }
.modal-overlay {
  position: fixed; inset: 0; background: var(--overlay); z-index: 100;
  display: flex; align-items: center; justify-content: center; padding: 1rem;
}
.modal-overlay[hidden] { display: none !important; }
/* .modal-grid{display:grid} a la même spécificité que [hidden]{display:none} de la
   feuille UA et vient après dans l'ordre des règles → il l'emporte, laissant les
   champs conditionnels visibles malgré l'attribut hidden (cf. tous les panneaux
   Déclenchement à sections conditionnelles). Règle générale plutôt qu'une liste d'ids, pour ne pas re-tomber
   dans ce piège à chaque nouveau champ conditionnel. */
.modal-grid[hidden] { display: none !important; }
.modal {
  background: var(--card); box-shadow: var(--shadow-card); border-radius: var(--radius-card);
  padding: 1.25rem; max-width: 520px; width: 100%; max-height: 90vh; overflow-y: auto;
}
.modal.modal-wide { max-width: 1040px; }
/* Panneau "État de mes enveloppes à cette date" : s'ouvre en latéral (bord droit de l'écran)
   plutôt qu'empilé au centre, pour rester visible à côté de la modale Projet/RP déjà ouverte
   dessous — copier-coller aisé entre les deux au lieu de devoir fermer/rouvrir. Pas de fond
   assombri (l'overlay laisse passer les clics) ni de centrage : seul le panneau capte les clics. */
.modal-overlay-side {
  justify-content: flex-end; align-items: stretch; background: transparent; padding: 0;
  pointer-events: none;
}
.modal-overlay-side .modal {
  pointer-events: auto; max-width: 480px; width: 100%; max-height: 100vh; height: 100vh;
  border-radius: 0; box-shadow: -8px 0 24px rgba(0, 0, 0, 0.25); border-left: 1px solid var(--border);
}
.patrimoine-pick-month-hint {
  background: var(--bg-inset); border: 1px solid var(--border); border-radius: var(--radius-input);
  padding: 0.5rem 0.7rem; margin: 0 0 0.5rem;
}

/* La liste déroulante à cocher des mois d'échéance (public/champs/mois-echeance.js).
   AUCUN `display` sur `.mois-echeance` elle-même : sans display d'auteur, la règle
   `[hidden] { display: none }` du navigateur suffit et aucune garde n'est nécessaire.
   La liste, elle, pose un display mais ne reçoit jamais `hidden` — c'est `<details>` qui
   l'ouvre et la ferme. */
.mois-echeance > summary {
  cursor: pointer;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--card-inner);
  color: var(--text);
  font-size: 0.8rem;
}
/* EN FLUX, PAS EN SURIMPRESSION. Posée en `position: absolute`, la liste ouverte recouvrait
   le bouton « Enregistrer » juste en dessous : le clic destiné à valider cochait un mois, et
   il fallait refermer la liste pour pouvoir enregistrer. Vu à l'écran le 2026-09-08. Dans une
   fenêtre qui a la place de la déplier, la liste pousse le contenu au lieu de le masquer. */
.mois-echeance-liste {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.2rem 0.4rem;
  margin-top: 0.25rem;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--card);
}
.mois-echeance-liste label {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.75rem;
  color: var(--text);
  border: 0;
  padding: 0;
}

/* Menu « ⋮ » (public/champs/menu-actions.js) : les actions rares ou destructrices d'une ligne,
   rangées derrière un seul bouton. La liste se pose sous le bouton, alignée à droite, pour ne
   pas déborder de la fenêtre qui porte la ligne. */
.menu-actions { position: relative; display: inline-flex; flex: 0 0 auto; }
.menu-actions-liste {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 20;
  display: flex; flex-direction: column; min-width: 11rem; padding: 0.25rem;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-input); box-shadow: var(--shadow-card-sm);
}
.menu-actions-liste[hidden] { display: none !important; }
.menu-actions-item {
  text-align: left; padding: 0.45rem 0.6rem; border: 0; background: transparent;
  border-radius: var(--radius-xs); font-size: 0.82rem; color: var(--text); cursor: pointer;
}
.menu-actions-item:hover, .menu-actions-item:focus-visible { background: var(--bg-hover); color: var(--text-strong); outline: none; }
.menu-actions-item.is-danger { color: var(--red-text); }
.menu-actions .btn.secondary.menu-actions-declencheur { border-color: transparent; }
.menu-actions:hover .menu-actions-declencheur, .menu-actions-declencheur[aria-expanded="true"] { border-color: var(--border); }

/* --- Le bouton d'un émoji (lignes de Flux, événements de la chronologie) --- */
/* Il se choisit d'un clic. Sans émoji, sa place ne se voit qu'au survol de la ligne ou de la
   carte (ou au clavier) : vingt sourires vides chargeraient la liste. */
.bouton-emoji {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 1.7rem; height: 1.7rem; margin-right: 0.3rem; padding: 0; border: 1px solid transparent;
  border-radius: var(--radius-btn); background: none; font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.bouton-emoji:hover, .bouton-emoji:focus-visible { border-color: var(--border); background: var(--bg-hover); }
.bouton-emoji.est-vide { color: var(--muted); opacity: 0; }
@media (hover: none) { .bouton-emoji.est-vide { opacity: 0.45; } }

/* « Ce qu'elle détient » : une ligne par élément, tout sur une même hauteur. */
.detient-ligne { display: flex; align-items: center; gap: 0.5rem; padding: 0.3rem 0; border-bottom: 1px solid var(--border); }
.detient-nom { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.modal-card .detient-ligne input { flex: 0 0 4.5rem; width: 4.5rem; padding: 0.3rem 0.4rem; font-size: 0.8rem; }
.detient-unite { color: var(--muted); }
.detient-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.detient-actions .btn[hidden] { display: none !important; }
