/* ============================================================================
   theme.css — Design system partagé de Budget App
   ----------------------------------------------------------------------------
   Un seul endroit pour la palette, la typographie et les composants de base.
   Chaque page HTML se contente d'inclure ce fichier :

       <link rel="stylesheet" href="theme.css?v=1">

   … et supprime son propre bloc `:root { }` / `body.theme-clair { }`.
   Les noms de variables sont EXACTEMENT ceux déjà utilisés dans les pages
   (--bg, --surface, --accent, --font-head…), donc l'existant continue de
   fonctionner sans retouche : seules les valeurs changent.

   Le thème clair n'est plus une simple inversion du sombre. Sur fond blanc,
   les accents saturés du thème sombre passent mal (contraste insuffisant sur
   texte, halo trop vif sur les aplats) : chaque couleur a donc sa variante
   propre, assombrie et légèrement désaturée.
   ========================================================================== */

/* ── 1. Reset ───────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── 2. Jetons — thème sombre (défaut) ──────────────────────────────────── */
:root {
  color-scheme: dark;

  /* Fonds, du plus profond au plus clair */
  --bg:          #0a0c11;
  --bg-soft:     #0e1116;
  --surface:     #12151d;
  --surface2:    #1a1e29;
  --surface3:    #222735;
  --border:      #242a38;
  --border-soft: #1c212c;

  /* Texte */
  --text:        #e9ebf2;
  --text-soft:   #b6bcca;
  /* Relevé de #6b7280 (l'ancien gris) à #7d8698 : sur le fond très sombre des
     cartes, l'ancien passait sous 4:1 et les libellés de graphiques étaient
     pénibles à lire. */
  --muted:       #7d8698;
  --faint:       #4e5665;

  /* Couleurs sémantiques */
  --accent:      #4f8ef7;
  --accent-2:    #3a7ae8;
  --green:       #2dd4a0;
  --red:         #f7605f;
  --amber:       #f7b955;
  --purple:      #8f74ff;
  --cyan:        #35c2e0;
  --pink:        #f472b6;

  /* Aplats translucides (badges, lignes actives, remplissages de graphiques) */
  --accent-soft: rgba(79,142,247,.14);
  --green-soft:  rgba(45,212,160,.14);
  --red-soft:    rgba(247,96,95,.14);
  --amber-soft:  rgba(247,185,85,.14);
  --purple-soft: rgba(124,92,252,.14);

  /* Variantes plus marquées (survol d'une ligne déjà teintée, bandes de
     section) et teintes de bordure. Elles évitent `color-mix()`, encore
     inégalement supporté selon les navigateurs. */
  --accent-wash: rgba(79,142,247,.07);
  --accent-fill: rgba(79,142,247,.13);
  --green-fill:  rgba(45,212,160,.10);
  --red-fill:    rgba(247,96,95,.10);
  --amber-fill:  rgba(247,185,85,.10);
  --amber-hover: rgba(247,185,85,.20);
  --amber-line:  rgba(247,185,85,.42);

  /* Texte posé SUR un aplat de couleur pleine */
  --on-accent:   #ffffff;

  /* Fond des éléments PLEINS qui portent du texte (boutons principaux, onglets actifs).
     `--accent` reste la couleur des liens, des bordures et des aplats translucides ;
     mais du blanc posé dessus ne faisait que 3,2:1 (4,1:1 au survol), sous le seuil AA
     de 4,5:1. Plutôt que d'assombrir l'accent partout — il sert surtout de couleur de
     TEXTE sur fond sombre, où il doit rester clair — les fonds pleins ont leur propre
     jeton. Blanc sur #2f6fe0 : 4,7:1 ; sur #245bc0 : 6,3:1. Mêmes valeurs dans les deux
     thèmes : en clair, ce sont déjà celles de `--accent` et `--accent-2`. */
  --accent-plein:       #2f6fe0;
  --accent-plein-hover: #245bc0;

  /* Graphiques (lus par ui.js pour theminger Chart.js et D3) */
  --chart-grid:  rgba(255,255,255,.06);
  --chart-tick:  #757e91;
  --chart-bg:    #12151d;

  /* Typographie */
  --font-head: 'Syne', system-ui, sans-serif;
  --font-mono: 'DM Mono', ui-monospace, monospace;

  --fs-xs:  .75rem;
  --fs-sm:  .76rem;
  --fs-md:  .84rem;
  --fs-lg:  .95rem;
  --fs-xl:  1.15rem;

  /* Formes et profondeur */
  --radius-sm: 8px;
  --radius:    12px;
  --radius-lg: 16px;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow:    0 6px 28px rgba(0,0,0,.45);
  --shadow-lg: 0 16px 48px rgba(0,0,0,.55);
  --ring:      0 0 0 3px rgba(79,142,247,.22);

  /* Rythme */
  --gap:      18px;
  --pad-card: 22px;
}

/* ── 3. Jetons — thème clair (retravaillé) ─────────────────────────────── */
:root.theme-clair,
body.theme-clair {
  color-scheme: light;

  /* Fond très légèrement bleuté plutôt que gris pur : moins clinique, et les
     cartes blanches s'en détachent sans avoir besoin d'ombres marquées. */
  --bg:          #f4f6fb;
  --bg-soft:     #eef1f8;
  --surface:     #ffffff;
  --surface2:    #f2f4f9;
  --surface3:    #e7ebf3;
  --border:      #e0e5ef;
  --border-soft: #edf0f6;

  --text:        #131722;
  --text-soft:   #3d4557;
  --muted:       #646c80;   /* 5,3:1 sur blanc, 4,8:1 sur --surface2 */
  --faint:       #9aa2b4;

  /* Accents assombris : sur blanc, les versions du thème sombre tombent sous le
     seuil de contraste AA (4.5:1) pour du texte de petite taille — et le
     dashboard affiche beaucoup de montants colorés en petit corps. Les valeurs
     ci-dessous ont été choisies pour passer AA sur fond blanc :
     vert 4.5, rouge 4.8, ambre 4.6, bleu 4.7, violet 6.5. */
  --accent:      #2f6fe0;
  --accent-2:    #245bc0;
  --green:       #0b8763;
  --red:         #cf3b3b;
  --amber:       #a06a08;
  --purple:      #6141d8;
  --cyan:        #10809c;
  --pink:        #c73a7d;

  --accent-soft: rgba(47,111,224,.10);
  --green-soft:  rgba(11,135,99,.11);
  --red-soft:    rgba(207,59,59,.10);
  --amber-soft:  rgba(160,106,8,.12);
  --purple-soft: rgba(97,65,216,.10);

  /* Sur fond blanc, les mêmes opacités qu'en sombre donneraient des pastels
     délavés : on remonte légèrement chaque valeur. */
  --accent-wash: rgba(47,111,224,.06);
  --accent-fill: rgba(47,111,224,.12);
  --green-fill:  rgba(11,135,99,.09);
  --red-fill:    rgba(207,59,59,.08);
  --amber-fill:  rgba(160,106,8,.10);
  --amber-hover: rgba(160,106,8,.18);
  --amber-line:  rgba(160,106,8,.40);

  --on-accent:   #ffffff;

  --chart-grid:  rgba(19,23,34,.07);
  --chart-tick:  #6b7387;
  --chart-bg:    #ffffff;

  --shadow-sm: 0 1px 2px rgba(19,23,34,.05);
  --shadow:    0 4px 20px rgba(19,23,34,.07);
  --shadow-lg: 0 12px 40px rgba(19,23,34,.10);
  --ring:      0 0 0 3px rgba(47,111,224,.18);
}

/* ── 4. Base ───────────────────────────────────────────────────────────── */
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  transition: background .25s ease, color .25s ease;
}

h1, h2, h3, h4 { font-family: var(--font-head); font-weight: 800; letter-spacing: -.5px; line-height: 1.2; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-2); }

::selection { background: var(--accent-soft); }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--surface3); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--faint); }

:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--radius-sm); }

/* ── 5. Titres de page ─────────────────────────────────────────────────── */
.page-title {
  font-family: var(--font-head);
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -1px;
}
.page-title span {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: 400;
  letter-spacing: .5px;
  color: var(--muted);
  margin-bottom: 2px;
}

/* ── 6. Cartes ─────────────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--pad-card);
  box-shadow: var(--shadow-sm);
}
.card-title {
  font-family: var(--font-head);
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: -.2px;
}
.card-sub {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin-top: 3px;
}
.card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 14px; margin-bottom: 18px;
}

/* ── 7. Boutons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  padding: 8px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface2);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  transition: background .18s, border-color .18s, color .18s, transform .18s;
}
.btn:hover { background: var(--surface3); }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent-plein); border-color: var(--accent-plein); color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-plein-hover); border-color: var(--accent-plein-hover); }
.btn-ghost { background: transparent; }
.btn-ghost:hover { background: var(--surface2); }
.btn-danger { color: var(--red); border-color: transparent; background: var(--red-soft); }
.btn-sm { padding: 5px 10px; font-size: var(--fs-xs); }
.btn:disabled { opacity: .45; cursor: not-allowed; }

/* ── 8. Champs ─────────────────────────────────────────────────────────── */
.input, .select, select.select, textarea.input {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--text);
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  outline: none;
  transition: border-color .18s, box-shadow .18s;
}
.input:focus, .select:focus { border-color: var(--accent); box-shadow: var(--ring); }
.select { cursor: pointer; }
label.field { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-xs); color: var(--muted); }

/* Groupe de contrôles (barre de filtres) */
.toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 14px;
}

/* Sélecteur segmenté (onglets compacts) */
.segmented { display: inline-flex; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 3px; gap: 3px; }
/* Les onglets du hub Bourse sont de vrais liens (`<a>`) et non des boutons : ils mènent à
   une autre page, donc le clic milieu, le « ouvrir dans un nouvel onglet » et la
   restitution par un lecteur d'écran doivent fonctionner. Un <button onclick=location>
   ne donne aucun des trois. Ils partagent l'apparence des boutons segmentés — d'où la
   liste de sélecteurs plutôt qu'un second bloc de règles qui dériverait. */
.segmented button,
.segmented a {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  padding: 6px 12px; border: none; border-radius: 6px;
  background: transparent; color: var(--muted); cursor: pointer; transition: all .18s;
  text-decoration: none; display: inline-block; white-space: nowrap;
}
.segmented button:hover,
.segmented a:hover { color: var(--text); }
.segmented button.active,
.segmented a.active { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }

/* ── 9. Badges ─────────────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-xs); font-weight: 500;
  padding: 3px 9px; border-radius: 999px;
  background: var(--surface2); color: var(--muted);
  white-space: nowrap;
}
.badge-green  { background: var(--green-soft);  color: var(--green); }
.badge-red    { background: var(--red-soft);    color: var(--red); }
.badge-amber  { background: var(--amber-soft);  color: var(--amber); }
.badge-accent { background: var(--accent-soft); color: var(--accent); }

/* ── 10. Tableaux ──────────────────────────────────────────────────────── */
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table thead th {
  text-align: left; font-weight: 500; font-size: var(--fs-xs);
  text-transform: uppercase; letter-spacing: .7px;
  color: var(--muted); padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
.table tbody td { padding: 10px 12px; border-bottom: 1px solid var(--border-soft); }
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover td { background: var(--surface2); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── 11. Barres de progression ─────────────────────────────────────────── */
.progress { height: 8px; background: var(--surface3); border-radius: 999px; overflow: hidden; }
.progress > span { display: block; height: 100%; border-radius: 999px; background: var(--accent); transition: width .7s cubic-bezier(.22,1,.36,1); }
.progress-thin { height: 5px; }

/* ── 12. États ─────────────────────────────────────────────────────────── */
.empty { text-align: center; color: var(--muted); font-size: var(--fs-sm); padding: 32px 12px; }
.skeleton {
  background: linear-gradient(90deg, var(--surface2) 25%, var(--surface3) 37%, var(--surface2) 63%);
  background-size: 400% 100%;
  animation: sk 1.3s ease infinite;
  border-radius: var(--radius-sm);
}
@keyframes sk { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.pos { color: var(--green); }
.neg { color: var(--red); }
.num { font-variant-numeric: tabular-nums; }

/* ── 13. Navigation latérale (menu hamburger partagé) ──────────────────── */
.nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 13px; border-radius: var(--radius-sm);
  color: var(--muted); text-decoration: none;
  font-size: var(--fs-sm); transition: background .18s, color .18s;
}
.nav-item:hover { background: var(--surface2); color: var(--text); }
.nav-item.active { background: var(--accent-soft); color: var(--accent); }
.nav-icon { font-size: 1rem; width: 20px; text-align: center; flex-shrink: 0; }

/* ── 14. Toasts ────────────────────────────────────────────────────────── */
/* Deux usages coexistent : les pages historiques ont un unique élément
   `<div class="toast" id="toast">` qu'elles font apparaître avec `.show`, et
   `UI.toast()` empile des messages dans une `.toast-zone`. Les deux partagent
   l'apparence ; seul le positionnement diffère. */
.toast {
  position: fixed; bottom: 26px; right: 26px; z-index: 900;
  background: var(--surface); border: 1px solid var(--accent);
  border-radius: var(--radius-sm); padding: 13px 20px; font-size: var(--fs-sm);
  box-shadow: var(--shadow);
  opacity: 0; transform: translateY(14px); pointer-events: none;
  transition: opacity .25s, transform .25s;
}
.toast.show { opacity: 1; transform: none; pointer-events: auto; }
.toast.ok, .toast.success { border-color: var(--green); }
.toast.err, .toast.error  { border-color: var(--red); }

.toast-zone { position: fixed; bottom: 24px; right: 24px; z-index: 900; display: flex; flex-direction: column; gap: 10px; }
.toast-zone .toast {
  position: static; opacity: 1; transform: none; pointer-events: auto;
  animation: toastIn .25s ease;
}
@keyframes toastIn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }

/* ── 16. Chrome applicatif : bouton menu, voile, panneau ───────────────── */
.nav-fab {
  position: fixed; top: 18px; left: 18px; z-index: 300;
  width: 42px; height: 42px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
  font-size: 1.05rem; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm); transition: background .18s, opacity .2s, transform .18s;
}
.nav-fab:hover { background: var(--surface2); transform: translateY(-1px); }

.nav-scrim {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(4,6,10,.55); backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none; transition: opacity .25s;
}
body.theme-clair .nav-scrim { background: rgba(19,23,34,.35); }

.app-nav {
  position: fixed; top: 0; left: 0; z-index: 250;
  width: 264px; height: 100vh;
  background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 4px; padding: 26px 16px 20px;
  transform: translateX(-100%); transition: transform .25s cubic-bezier(.4,0,.2,1);
  box-shadow: var(--shadow-lg);
}
.nav-brand {
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--font-head); font-size: 1.22rem; font-weight: 800;
  color: var(--accent); letter-spacing: -.5px; margin-bottom: 20px; padding: 0 6px;
}
.nav-brand span { color: var(--text); }
.nav-brand button {
  background: var(--surface2); border: none; color: var(--muted);
  width: 28px; height: 28px; border-radius: 8px; cursor: pointer; font-size: .85rem;
}
.nav-brand button:hover { color: var(--text); background: var(--surface3); }
.nav-user {
  background: var(--surface2); border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); padding: 10px 13px; margin-bottom: 14px;
}
.nav-user b { display: block; font-size: var(--fs-sm); font-weight: 600; }
.nav-user small { color: var(--muted); font-size: .75rem; }
/* Zone défilante des liens.
   ⚠️ `min-height: 0` n'est pas décoratif : un élément flex refuse par défaut de
   descendre sous la taille de son contenu, et `overflow-y` reste alors sans effet.
   Sans cette règle, sur une fenêtre courte, les liens se faisaient comprimer puis
   rogner — la dernière entrée avant le pied (Macro) disparaissait purement et
   simplement de l'écran, alors qu'elle était bien présente dans le HTML. */
.nav-links {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px;
  scrollbar-width: thin;
}
.nav-links::-webkit-scrollbar { width: 5px; }
.nav-links::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

/* Groupes du menu.
   Le `gap: 4px` de `.nav-links` sépare désormais des GROUPES, pas des liens : chaque
   groupe redéclare donc sa propre colonne avec le même écart, sinon les liens d'un
   même groupe se retrouveraient collés. */
.nav-group { display: flex; flex-direction: column; gap: 4px; }
/* L'espace au-dessus de l'intitulé est ce qui fait le regroupement — bien plus que le
   texte lui-même. Il est posé sur le groupe et non sur le titre pour ne pas creuser un
   blanc au-dessus du tout premier intitulé, collé à l'encart utilisateur. */
.nav-group + .nav-group { margin-top: 16px; }
/* Un intitulé n'est pas une entrée : il doit se lire comme une étiquette, pas comme un
   lien désactivé. D'où le contraste volontairement bas, la petite taille et
   l'interlettrage — les trois signaux qui disent « ceci ne se clique pas ». Le
   `padding` horizontal reprend celui de `.nav-item` (13px) pour que le texte du titre
   s'aligne verticalement sur celui des liens, et non sur leurs icônes. */
.nav-group-title {
  padding: 0 13px 5px;
  font-size: .75rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); opacity: .62;
  user-select: none;
}
/* En thème clair, `--muted` est déjà sombre : la même opacité y donnerait un gris
   presque noir, plus lourd que les liens qu'il coiffe. */
body.theme-clair .nav-group-title { opacity: .55; }

.nav-foot {
  margin-top: auto; padding-top: 16px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 4px;
  flex-shrink: 0;
}
/* Le bouton de déconnexion héritait de `.nav-item` sans couleur propre : chaque page
   la repassait en style en ligne, avec des valeurs légèrement différentes. */
.nav-item.danger { color: var(--red); }
.nav-item.danger:hover { background: var(--red-soft); color: var(--red); }
/* `.nav-item` s'applique aussi à des <button> : sans ces réinitialisations, ils
   héritaient de l'apparence native et ne s'alignaient pas sur les liens <a>. */
button.nav-item {
  background: transparent; border: none; width: 100%;
  font-family: inherit; text-align: left; cursor: pointer;
}
button.nav-item {
  background: transparent; border: none; width: 100%; text-align: left;
  font-family: var(--font-mono); cursor: pointer;
}
button.nav-item.danger { color: var(--red); }
button.nav-item.danger:hover { background: var(--red-soft); color: var(--red); }

/* ── 17. En-tête de page ───────────────────────────────────────────────── */
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 18px; flex-wrap: wrap; margin-bottom: 22px;
}

/* ── 18. Modales ───────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(4,6,10,.62); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  opacity: 0; pointer-events: none; transition: opacity .22s;
}
.modal-overlay.open { opacity: 1; pointer-events: all; }
body.theme-clair .modal-overlay { background: rgba(19,23,34,.42); }

.modal, .modal-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  width: 560px; max-width: 100%; max-height: 88vh; overflow-y: auto;
  transform: translateY(14px) scale(.985); transition: transform .22s cubic-bezier(.22,1,.36,1);
}
.modal-overlay.open .modal, .modal-overlay.open .modal-box { transform: none; }
.modal { padding: 28px 30px 30px; }

.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-bottom: 22px;
}
.modal-box .modal-header { margin: 0; padding: 18px 22px; border-bottom: 1px solid var(--border); }
.modal-title, .modal-header h3 {
  font-family: var(--font-head); font-size: 1.08rem; font-weight: 700;
  letter-spacing: -.3px; margin: 0;
}
.modal-close {
  background: var(--surface2); border: none; color: var(--muted);
  width: 32px; height: 32px; border-radius: 9px; cursor: pointer; font-size: .95rem;
  display: flex; align-items: center; justify-content: center; transition: all .18s;
  flex-shrink: 0;
}
.modal-close:hover { background: var(--surface3); color: var(--text); }
.modal-body { padding: 22px; display: flex; flex-direction: column; gap: 15px; }
.modal-footer {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 16px 22px; border-top: 1px solid var(--border);
}

/* ── 19. Formulaires ───────────────────────────────────────────────────── */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
.form-row  { display: flex; gap: 12px; }
.form-row .form-group { flex: 1; min-width: 0; }
.form-group { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.form-group.full { grid-column: 1 / -1; }
.form-group > label {
  font-size: var(--fs-xs); color: var(--muted);
  letter-spacing: .6px; text-transform: uppercase;
}
.form-group input, .form-group select, .form-group textarea,
.modal input, .modal select, .modal textarea,
.modal-box input, .modal-box select, .modal-box textarea {
  width: 100%;
  background: var(--surface2); border: 1px solid var(--border); color: var(--text);
  padding: 9px 13px; border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: var(--fs-md);
  outline: none; transition: border-color .18s, box-shadow .18s;
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus,
.modal input:focus, .modal select:focus, .modal textarea:focus,
.modal-box input:focus, .modal-box select:focus, .modal-box textarea:focus {
  border-color: var(--accent); box-shadow: var(--ring);
}
.form-group textarea, .modal textarea { resize: vertical; min-height: 76px; }
.form-check { flex-direction: row; align-items: center; }
.form-check label { display: flex; align-items: center; gap: 9px; cursor: pointer; text-transform: none; letter-spacing: 0; font-size: var(--fs-sm); color: var(--text); }
.form-check input[type=checkbox] { width: auto; accent-color: var(--accent); cursor: pointer; }
.form-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 24px; }
.form-section-label {
  font-size: var(--fs-xs); color: var(--muted);
  text-transform: uppercase; letter-spacing: .7px; margin-bottom: 11px;
}

/* ── 20. Sections colorées (entrées / dépenses / épargne / transferts) ──── */
/* Une bande colorée à gauche remplace la pastille + trait : elle relie
   visuellement l'en-tête au tableau qu'il coiffe, ce qui aide à s'orienter
   quand quatre sections se suivent. */
.sec-entree    { --sec: var(--green);  --sec-soft: var(--green-soft); }
.sec-depense   { --sec: var(--red);    --sec-soft: var(--red-soft); }
.sec-epargne   { --sec: var(--amber);  --sec-soft: var(--amber-soft); }
.sec-transfert { --sec: var(--purple); --sec-soft: var(--purple-soft); }
.sec-retard    { --sec: var(--amber);  --sec-soft: var(--amber-soft); }

/* ── 15. Grilles utilitaires ───────────────────────────────────────────── */
.grid    { display: grid; gap: var(--gap); }
.grid-2  { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3  { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid-4  { grid-template-columns: repeat(4, minmax(0,1fr)); }
.grid-21 { grid-template-columns: 2fr 1fr; }
.grid-12 { grid-template-columns: 1fr 2fr; }

@media (max-width: 1180px) {
  .grid-4  { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .grid-21, .grid-12 { grid-template-columns: 1fr; }
}
@media (max-width: 780px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .page-title { font-size: 1.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
