/* =====================================================================
   app-cc — feuille de style (thème clair)
   Navigation horizontale à deux niveaux + contenu pleine largeur,
   typographie Poppins auto-hébergée.
   ===================================================================== */

/* =====================================================================
   Polices — Poppins AUTO-HÉBERGÉE
   ---------------------------------------------------------------------
   Les fichiers vivent dans public/assets/fonts/ : AUCUNE dépendance
   externe (ni Google Fonts, ni CDN, ni @import distant). Une déclaration
   par graisse réellement fournie — 400, 500, 600, 700, 900 — et rien
   d'autre : aucune graisse absente n'est demandée ailleurs dans la
   feuille, ce qui évite toute synthèse approximative par le navigateur.
   font-display: swap → le texte s'affiche tout de suite avec la police
   de repli, puis bascule sur Poppins dès qu'elle est chargée.
   ===================================================================== */

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/assets/fonts/poppins-v24-latin-regular.woff2") format("woff2");
}

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/assets/fonts/poppins-v24-latin-500.woff2") format("woff2");
}

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/assets/fonts/poppins-v24-latin-600.woff2") format("woff2");
}

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/assets/fonts/poppins-v24-latin-700.woff2") format("woff2");
}

/* Poppins Black : graisse de la signature « Cédric. » de la barre */
@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 900;
    font-display: swap;
    src: url("/assets/fonts/poppins-v24-latin-900.woff2") format("woff2");
}

:root {
    /* Palette claire */
    --color-bg:          #f8fafc;
    --color-surface:     #ffffff;
    --color-surface-2:   #f1f5f9;
    /* Fond des GRANDES cartes conteneurs (.card) uniquement : blanc à 80 %
       d'opacité, soit exactement rgba(255, 255, 255, 0.8). Dérivé de
       --color-surface pour suivre la palette. Il laisse transparaître le décor
       de fond de l'application (.app-deco) en filigrane là où il passe derrière
       une carte, sans jamais toucher au CONTENU : on agit sur la couleur de
       fond, JAMAIS sur opacity, qui pâlirait textes et chiffres. Les sous-cartes
       KPI gardent leur fond gris plein (--kpi-fond). */
    --fond-carte-translucide: color-mix(in srgb, var(--color-surface) 80%, transparent);
    --color-border:      #e2e8f0;
    --color-border-2:    #cbd5e1;
    --color-gris-moyen:  #b9bdc3; /* gris moyen neutre : pastilles d'en-tête d'accueil */
    --color-text:        #0f172a;
    --color-muted:       #64748b;
    --color-primary:     #0284c7;
    --color-primary-h:   #0369a1;
    --color-accent-soft: rgba(14, 165, 233, 0.08);
    --color-fdm-zebra:   color-mix(in srgb, var(--color-primary) 6%, var(--color-surface)); /* fond alterné bleu très clair : lignes « à faire » de Fin de mois */
    --color-fdm-phare:   var(--color-primary); /* Couleur de mise en valeur de la ligne Salaire net versé — changer ici */
    --color-focus-ring:  color-mix(in srgb, var(--color-primary) 20%, transparent);
    --color-danger-bg:   #fef2f2;
    --color-danger-fg:   #991b1b;

    /* Statuts */
    --color-success:      #16a34a;
    --color-warning:      #ca8a04;
    --color-warning-soft: rgba(202, 138, 4, 0.08);
    --color-error:        #dc2626;

    /* Qualité alimentaire (courbe unique, source SyntheseAlimentation) : couleurs
       partagées par les anneaux, les barres du Journal et les tuiles du Suivi.
       Seuils : haut > 75 %, moyen 25–75 %, bas < 25 %. Le bleu médian est une
       teinte propre au module. */
    --color-qualite-haut:  var(--color-success);
    --color-qualite-moyen: #00aaef;
    --color-qualite-bas:   var(--color-error);

    /* Accessoires (Rapport) : gris neutre des barres et du badge, pour distinguer
       les ingrédients écartés du classement principal du bleu des fréquences. */
    --color-accessoire: var(--color-muted);

    /* Point indicatif en tête des lignes « Mes ingrédients » : vert = aliment
       (réutilise le vert de qualité), bleu de marque = accessoire. */
    --color-point-plein:      var(--color-qualite-haut);
    --color-point-accessoire: #00aaef;

    /* Service renseigné (Suivi) : fond vert très léger + bordure verte douce,
       dérivés du vert de qualité et mélangés à la surface/bordure pour rester
       subtils et s'adapter au thème. Un service vide garde l'apparence neutre. */
    --color-service-rempli-fond: color-mix(in srgb, var(--color-qualite-haut) 12%, var(--color-surface));
    --color-service-rempli-bord: color-mix(in srgb, var(--color-qualite-haut) 45%, var(--color-border-2));

    /* Palette des rubriques Alimentation (slugs gérés par l'utilisateur).
       Teintes distinctes, lisibles en clair comme en sombre ; seules ces
       variables portent des hex pour les pastilles de rubrique. */
    --color-cat-indigo:   #6366f1;
    --color-cat-bleu:     #2563eb;
    --color-cat-vert:     #16a34a;
    --color-cat-teal:     #0d9488;
    --color-cat-jaune:    #ca8a04;
    --color-cat-ambre:    #d97706;
    --color-cat-noisette: #8a6d3b;
    --color-cat-rose:     #e11d48;
    --color-cat-violet:   #7c3aed;
    --color-cat-gris:     #64748b;

    /* 3e série du graphique sport (minutes) : violet calme */
    --color-graph-minutes: #7c6fd6;

    /* Module Agenda : bleu de marque (jour courant) et teintes de fond des zones.
       Seules ces variables portent ces hex ; aucune couleur en dur dans les
       règles du module. */
    --color-agenda-marque:       #00aaef;
    --color-agenda-jour-fond:    #f6f6f6; /* fond gris clair des colonnes */
    --color-agenda-blanc:        #ffffff; /* fond des vignettes d'événement */
    --color-agenda-courant-soft: color-mix(in srgb, var(--color-agenda-marque) 10%, var(--color-agenda-blanc));
    /* Fond vert léger d'un événement d'agenda COCHÉ (dérivé du vert de qualité). */
    --color-agenda-fait-fond:    color-mix(in srgb, var(--color-qualite-haut) 14%, var(--color-agenda-blanc));
    --color-agenda-fait-bord:    color-mix(in srgb, var(--color-qualite-haut) 45%, var(--color-border));
    /* Temps du jour scindé : Repas = vert Perso ; Travail = bleu de marque. */
    --color-agenda-repas:   var(--color-qualite-haut);
    --color-agenda-travail: var(--color-agenda-marque);

    /* Module « Idées de vidéo ».
       DEUX FAMILLES DE COULEUR, POINT : le bleu de marque #00aaef et le gris
       #f6f6f6, chacun avec ses déclinaisons (fonds très clairs, bordures,
       textes). Ni vert, ni orange, ni violet, ni multicolore. Seules ces
       variables portent ces valeurs : aucune couleur en dur dans les .idv-*. */
    --color-idv-marque:     #00aaef; /* bleu de marque */
    --color-idv-bleu-texte: #0090cc; /* bleu foncé, lisible sur fond clair */
    --color-idv-bleu-fond:  #e6f6fd; /* bleu très clair, pastille remplie */
    --color-idv-bleu-bord:  #a5ddf5; /* bleu clair, pastille en contour */
    --color-idv-gris:       #f6f6f6; /* gris de base (fond des lignes) */
    --color-idv-gris-fond:  #ececec; /* gris un peu plus soutenu (pastilles) */
    --color-idv-gris-bord:  #dedede; /* bordure grise */
    --color-idv-gris-texte: #6b6b6b; /* texte gris lisible */
    /* Fond des lignes de liste */
    --color-idv-fond: var(--color-idv-gris);
    /* STATUTS — neutre par défaut (gris doux) : c'est l'état de l'onglet Externe
       (à regarder / vu / à revoir), volontairement discret, et le point de
       départ « Idée » du pipeline de production. */
    --color-idv-statut-fond:  var(--color-idv-gris-fond);
    --color-idv-statut-bord:  var(--color-idv-gris-bord);
    --color-idv-statut-texte: var(--color-idv-gris-texte);

    /* ÉCHELLE DE VERT du pipeline de PRODUCTION (Lano / Allô / Autres) : la
       pastille verdit à mesure que la vidéo avance vers la publication.
       Idée = gris (ci-dessus) → À tourner → Tournée → Montage → Publiée.
       TOUT est dérivé du vert de qualité du projet : aucune valeur verte en dur,
       et changer --color-qualite-haut suffit à retourner l'échelle entière.
       Le vert est RÉSERVÉ au statut : le classement reste bleu, les mots-clés gris. */
    --color-idv-vert: var(--color-qualite-haut);
    /* Texte vert foncé commun aux trois paliers teintés. Assombri à 58 % pour
       rester au-dessus de 4,5:1 de contraste jusque sur le palier « Montage »,
       le plus soutenu des trois (mesuré : 6,88 / 6,00 / 5,08:1). */
    --color-idv-vert-texte: color-mix(in srgb, var(--color-idv-vert) 58%, black);
    /* À tourner : vert très clair */
    --color-idv-statut-atourner-fond: color-mix(in srgb, var(--color-idv-vert) 12%, var(--color-surface));
    --color-idv-statut-atourner-bord: color-mix(in srgb, var(--color-idv-vert) 30%, transparent);
    /* Tournée : vert clair */
    --color-idv-statut-tournee-fond:  color-mix(in srgb, var(--color-idv-vert) 24%, var(--color-surface));
    --color-idv-statut-tournee-bord:  color-mix(in srgb, var(--color-idv-vert) 46%, transparent);
    /* Montage : vert moyen, bien marqué */
    --color-idv-statut-montage-fond:  color-mix(in srgb, var(--color-idv-vert) 38%, var(--color-surface));
    --color-idv-statut-montage-bord:  color-mix(in srgb, var(--color-idv-vert) 62%, transparent);
    /* Publiée : vert fort, pastille pleine et texte clair. Le vert est assombri
       à 80 % pour que le texte blanc reste lisible (4,88:1 ; le vert brut n'était
       qu'à 3,30:1). */
    --color-idv-statut-publiee-fond:  color-mix(in srgb, var(--color-idv-vert) 80%, black);
    --color-idv-statut-publiee-bord:  color-mix(in srgb, var(--color-idv-vert) 80%, black);
    --color-idv-statut-publiee-texte: var(--color-surface);
    /* Fond de la LIGNE ENTIÈRE d'une vidéo publiée (très léger, lisible sous le
       titre) et sa variante au survol. */
    --color-idv-item-publie-fond:   color-mix(in srgb, var(--color-idv-vert) 7%, var(--color-surface));
    --color-idv-item-publie-survol: color-mix(in srgb, var(--color-idv-vert) 13%, var(--color-surface));

    /* CLASSEMENT — trois déclinaisons BLEUES nettement distinctes, différenciées
       par le remplissage plutôt que par la teinte :
         RUBRIQUE  : bleu PROFOND plein, texte clair ;
         FORMATION : bleu très clair REMPLI, texte bleu foncé ;
         MODULE    : bleu en CONTOUR sur fond blanc.
       Le bleu de la rubrique est assombri à 70 % du bleu de marque pour que le
       texte clair y reste lisible (5,00:1 ; le bleu brut n'était qu'à 2,63:1). */
    --color-idv-rubrique-fond:   color-mix(in srgb, var(--color-idv-marque) 70%, black);
    --color-idv-rubrique-texte:  var(--color-surface);
    --color-idv-formation-fond:  var(--color-idv-bleu-fond);
    --color-idv-formation-texte: var(--color-idv-bleu-texte);
    --color-idv-module-bord:     var(--color-idv-bleu-bord);
    --color-idv-module-texte:    var(--color-idv-bleu-texte);
    /* MOTS-CLÉS : petites étiquettes grises. */
    --color-idv-mot-fond:  var(--color-idv-gris-fond);
    --color-idv-mot-texte: var(--color-idv-gris-texte);
    /* Étiquettes d'ORIGINE (résultats de recherche) : une INTENSITÉ par onglet,
       du bleu foncé au gris clair — jamais des teintes multicolores. */
    --color-idv-lano:    var(--color-idv-bleu-texte);
    --color-idv-allo:    var(--color-idv-marque);
    --color-idv-autres:  var(--color-idv-bleu-fond);
    --color-idv-externe: var(--color-idv-gris-fond);

    /* Tiers de membres Lano (accueil) : camaïeu de bleu (clair → foncé),
       teintes distinctes et lisibles en clair comme en sombre. */
    --color-tier-std:     color-mix(in srgb, var(--color-primary) 45%, white); /* bleu clair (base éclaircie) */
    --color-tier-premium: var(--color-primary);                               /* bleu moyen = base de l'appli */
    --color-tier-vip:     color-mix(in srgb, var(--color-primary) 70%, black); /* bleu foncé (base assombrie) */

    /* =================================================================
       Navigation horizontale (refonte graphique, étape 1)
       -----------------------------------------------------------------
       TROIS teintes de base, et tout le reste en dérive (color-mix) :
       aucune couleur n'est écrite ailleurs que dans ce bloc.
       ================================================================= */
    /* SEUIL DE BASCULE DESKTOP → MOBILE de la navigation.
       Au-dessus : barre horizontale à deux niveaux, inchangée. En dessous :
       barre repliée (signature + avatar + burger) et panneau de menu.
       ⚠ DEUX ENDROITS À GARDER SYNCHRONES si vous changez cette valeur :
         1. cette variable — elle est lue par /assets/js/nav.js ;
         2. le `@media (max-width: 1000px)` du bloc « NAVIGATION MOBILE »,
            en fin de section navigation (une media query CSS ne peut pas
            consommer une variable).
       Le reste en découle tout seul. */
    --nav-seuil-mobile: 1000px;

    --nav-marque: #00aaef; /* bleu de marque */
    --nav-gris:   #f6f6f6; /* gris de fond neutre */
    --nav-sombre: #1a1b2f; /* sombre du texte et de la signature */
    --nav-blanc:  #ffffff; /* fond de barre / texte sur pastille pleine */

    /* Barre principale (niveau 1). Le fond de la barre reste BLANC : seuls les
       onglets de modules reposent sur un bandeau gris clair. */
    --nav-respiration:  10px; /* air au-dessus ET au-dessous du bandeau */

    /* Gabarit horizontal de la barre. Ces trois mesures placent le début des
       onglets de modules ; la sous-navigation s'en sert pour s'aligner dessus
       (cf. --nav-onglets-depart). Les redéfinir dans une media query déplace
       les deux ensemble. */
    --nav-marge-laterale: 1.5rem;  /* padding latéral de la barre */
    --nav-ecart:          1.25rem; /* écart entre signature, onglets et droite */
    /* Largeur RÉSERVÉE à la signature « Cédric. ».
       Mesurée sur la police livrée (poppins-v24-latin-900.woff2, 1000 upem) :
       somme des avances C+é+d+r+i+c+. = 3766/1000 em, soit 78.33px à 1.3rem
       (20.8px), moins l'interlettrage de -0.02em × 7 caractères (-2.91px)
       = 75.42px rendus. On réserve 78px : la signature occupe une largeur
       FERME, ce qui rend le point de départ des onglets calculable — et donc
       l'alignement de la sous-navigation exact par construction. Un éventuel
       débord irait dans l'écart de 20px, sans jamais être rogné. */
    --nav-signature-largeur: 78px;

    /* Filet de séparation entre la barre principale et la sous-navigation :
       4px d'un gris soutenu (déclinaison du gris de base), doublé d'une ombre
       portée discrète qui matérialise la frontière entre les deux niveaux. */
    --nav-filet:         4px;
    --nav-filet-couleur: color-mix(in srgb, var(--nav-gris) 88%, var(--nav-sombre));
    --nav-ombre:         0 2px 6px color-mix(in srgb, var(--nav-sombre) 9%, transparent);

    /* HAUTEUR TOTALE DE LA BARRE — DÉRIVÉE, jamais saisie à la main.
       Elle vaut : bandeau des onglets (l'élément le plus haut de la barre)
       + la respiration en haut et en bas + le filet du bas. box-sizing:
       border-box, donc c'est bien la hauteur EXTÉRIEURE de la barre, et donc
       le décalage exact auquel la sous-navigation vient se coller (top).
       Toucher à la respiration ou au bandeau met à jour cette valeur tout
       seul : plus rien à resynchroniser. */
    --nav-hauteur: calc(
        var(--nav-onglets-hauteur) + 2 * var(--nav-respiration) + var(--nav-filet)
    );

    --nav-fond:         var(--nav-blanc);
    --nav-bordure:      color-mix(in srgb, var(--nav-sombre) 12%, var(--nav-blanc));
    --nav-texte:        color-mix(in srgb, var(--nav-sombre) 52%, var(--nav-blanc));
    --nav-texte-fort:   var(--nav-sombre);
    --nav-actif:        var(--nav-marque); /* pastille pleine de l'onglet actif */
    --nav-actif-texte:  var(--nav-blanc);
    --nav-pastille-rayon: 9px;

    /* Signature « Cédric. » : la graisse la plus lourde disponible */
    --nav-signature-taille:  1.3rem;
    --nav-signature-graisse: 900;

    /* Bandeau gris des onglets de modules : EXACTEMENT le gris de base
       (#f6f6f6), sans déclinaison. Le padding intérieur (vertical ET latéral)
       est ce qui fait « respirer » la pastille bleue de l'onglet actif : elle
       ne touche jamais les bords du gris. */
    --nav-onglets-fond:      var(--nav-gris);
    --nav-onglets-rayon:     16px;
    --nav-onglets-padding-v: 10px; /* air au-dessus/au-dessous de la pastille */
    --nav-onglets-padding-h: 10px;
    /* Padding propre à un onglet (donc à la pastille bleue de l'actif) */
    --nav-onglet-padding-v:  0.35rem;
    --nav-onglet-padding-h:  0.7rem;
    /* Hauteur d'un onglet (texte 15px, interligne 1.5, padding 0.35rem) portée
       à 36px : léger jeu pour absorber les variations de métriques de Poppins
       sans que le bandeau ne déborde de la barre. */
    --nav-onglet-hauteur:    36px;
    --nav-onglets-hauteur:   calc(var(--nav-onglet-hauteur) + 2 * var(--nav-onglets-padding-v));
    --nav-onglet-taille:     15px;
    --nav-onglet-graisse:    600;

    /* POINT DE DÉPART HORIZONTAL du premier onglet de modules, mesuré depuis le
       bord gauche de la fenêtre. C'est la référence d'alignement de la
       sous-navigation : marge de la barre + largeur réservée à la signature +
       écart + padding du bandeau gris + padding de l'onglet lui-même. Tout est
       dérivé, donc l'alignement suit automatiquement le moindre réglage. */
    --nav-onglets-depart: calc(
          var(--nav-marge-laterale)
        + var(--nav-signature-largeur)
        + var(--nav-ecart)
        + var(--nav-onglets-padding-h)
        + var(--nav-onglet-padding-h)
    );
    --nav-onglet-texte:    color-mix(in srgb, var(--nav-sombre) 74%, var(--nav-blanc)); /* gris foncé */
    /* Filets « | » : entre onglets, et entre les deux groupes de raccourcis */
    --nav-filet-texte:     color-mix(in srgb, var(--nav-sombre) 22%, var(--nav-blanc));

    /* Tuiles de raccourcis : accent bleu clair (groupe principal) ou gris.
       Teintes exactes de la charte, déclarées ici et nulle part ailleurs. */
    --nav-tuile-fond:         #f1f2f4;
    --nav-tuile-texte:        var(--nav-texte);
    --nav-tuile-accent-fond:  #e6f5fd;
    --nav-tuile-accent-texte: #0090cc;
    --nav-tuile-taille:       26px;

    /* Sous-navigation (niveau 2) : souligné bleu épais, jamais de pastille.
       Sticky juste sous la barre principale, donc sous son z-index. Hauteur
       FERME pour qu'elle ne varie pas d'un pixel au défilement, et fond
       EXACTEMENT #f6f6f6 (le gris de base). */
    /* 3.25rem : laisse assez d'air SOUS le libellé pour que le souligné de
       l'onglet actif tienne dans la barre — la hauteur fixe crée un conteneur
       de défilement, qui rognerait tout débord. Marge confortable, y compris
       avec les métriques de Poppins (plus hautes que celles de system-ui). */
    --nav-sous-hauteur:    3.25rem;
    --nav-sous-fond:       var(--nav-gris);
    --nav-sous-point:      color-mix(in srgb, var(--nav-sombre) 26%, var(--nav-blanc));
    --nav-sous-souligne:   3px;
    /* Padding latéral d'un sous-onglet : retranché du retrait de la sous-nav
       pour que le BORD DU LIBELLÉ tombe pile sur celui du premier onglet. */
    --nav-sous-onglet-padding-h: 0.55rem;
    /* Air ajouté SOUS la sous-navigation, avant le contenu de la page */
    --nav-sous-espace-bas: 14px;

    /* =================================================================
       Cases « Points retirés » du Suivi alimentation
       -----------------------------------------------------------------
       Teintes dérivées du bleu de marque et du gris de base. L'état
       sélectionné reprend exactement le bleu clair de la charte
       (#e6f5fd / #00aaef / #0090cc) ; au repos, gris neutre.
       ================================================================= */
    --note-gap:           8px;
    --note-fond:          var(--nav-gris);   /* #f6f6f6 */
    --note-bordure:       color-mix(in srgb, var(--nav-sombre) 14%, var(--nav-gris));
    --note-chiffre:       var(--nav-sombre); /* #1a1b2f */
    --note-libelle:       color-mix(in srgb, var(--nav-sombre) 50%, var(--nav-blanc));
    --note-actif-fond:    var(--nav-tuile-accent-fond);  /* #e6f5fd */
    --note-actif-bordure: var(--nav-marque);             /* #00aaef */
    --note-actif-texte:   var(--nav-tuile-accent-texte); /* #0090cc */

    /* Sélecteur de période (niveau 3) : années · | · douze mois. Actif en bleu
       de marque, SANS soulignement — le souligné reste réservé à la
       sous-navigation, ce qui garde les niveaux distinguables. */
    --nav-periode-taille:   0.9rem;
    --nav-periode-actif:    var(--nav-marque);
    --nav-periode-graisse:  600;

    /* =================================================================
       Cartes KPI — STYLE UNIQUE pour toute l'application
       -----------------------------------------------------------------
       Un seul jeu de teintes, dérivé du gris de fond et du sombre du
       texte : aucune couleur décorative par module. La seule couleur en
       plus est --kpi-valeur-negatif, et elle est FONCTIONNELLE (valeur
       négative / alerte), jamais ornementale.
       ================================================================= */
    --kpi-fond:            var(--nav-gris);   /* #f6f6f6 */
    --kpi-bordure:         color-mix(in srgb, var(--nav-sombre) 9%, var(--nav-gris));
    --kpi-rayon:           12px;
    --kpi-label:           #8a8f96;           /* gris des libellés */
    --kpi-valeur:          var(--nav-sombre); /* #1a1b2f */
    --kpi-sub:             color-mix(in srgb, var(--nav-sombre) 45%, var(--nav-blanc));
    --kpi-valeur-negatif:  #c8372d;           /* rouge sobre, lisible sur #f6f6f6 */
    --nav-z-barre:         200;
    --nav-z-sous:          150;
    /* Modales plein écran : AU-DESSUS des deux barres sticky, sinon elles
       apparaîtraient derrière. Unique référence pour tout l'empilement. */
    --z-modal:             300;

    /* Layout */
    /* Gouttières de la zone de contenu. SOURCE UNIQUE : .main s'en sert pour
       son padding, et la sous-navigation pour les annuler (marges négatives)
       afin de se coller sous la barre et de couvrir toute la largeur. Les
       redéfinir dans une media query suffit à déplacer les deux ensemble. */
    --main-gouttiere-haut: 1.5rem;
    --main-gouttiere-cote: 2rem;
    /* Écart vertical entre deux blocs de contenu — c'est le `gap` de .main, donc
       le rythme vertical de TOUTES les pages. SOURCE UNIQUE : un élément qui doit
       ANNULER cet écart pour se coller au bloc précédent (la barre d'onglets
       d'Idées sous la sous-nav du module) reprend la même variable en marge
       négative. Les deux ne peuvent donc plus diverger. */
    --main-espace: 1.25rem;
    --radius:        10px;
    --gap:           1rem;
    --shadow-sm:     0 1px 2px rgba(15, 23, 42, 0.05);
    --shadow-md:     0 1px 3px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.04);
    --shadow-lg:     0 8px 24px rgba(15, 23, 42, 0.08);
    /* Police de toute l'application : Poppins auto-hébergée, puis repli
       système si les fichiers woff2 ne sont pas encore chargés. */
    --font:          "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    color: var(--color-text);
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.5;
}

/* Fond de page porté par la SEULE racine : le navigateur propage le fond de
   <html> au canevas, qui couvre donc toute la fenêtre (rendu identique à
   l'ancien fond posé aussi sur <body>). Ce point est structurant : <body>
   restant transparent, le calque décoratif de l'application (.app-deco,
   z-index négatif) se voit par-dessus le canevas tout en restant DERRIÈRE
   l'intégralité du contenu. */
html { background: var(--color-bg); }

/* Les contrôles de formulaire n'héritent PAS de la police par défaut :
   on la leur impose ici, une fois pour toutes, pour que Poppins couvre
   réellement toute l'interface (champs, listes, boutons, zones de texte). */
input,
button,
select,
textarea {
    font-family: inherit;
}

h1, h2, h3 { margin: 0 0 0.5rem; font-weight: 600; color: var(--color-text); }

/* Masqué à l'écran, révélé à l'impression (cf. @media print en fin de feuille) */
.print-only { display: none; }
p { margin: 0.5rem 0; }
.muted { color: var(--color-muted); }

a { color: var(--color-primary); text-decoration: none; }
a:hover { color: var(--color-primary-h); text-decoration: underline; }

/* =====================================================================
   Layout authentification (page /login)
   ===================================================================== */

.auth-body {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.auth-container { width: 100%; max-width: 380px; padding: 1.5rem; }

.login-form {
    background: var(--color-surface);
    padding: 2rem;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-lg);
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

.login-title    { margin: 0; color: var(--color-primary); text-align: center; letter-spacing: 0.02em; }
.login-subtitle { margin: 0; text-align: center; color: var(--color-muted); font-size: 0.95rem; }

/* =====================================================================
   Layout application authentifiée : barre horizontale + contenu pleine largeur
   ---------------------------------------------------------------------
   La colonne latérale gauche a été supprimée : toute la navigation vit dans la
   barre horizontale sticky du haut (niveau 1, rendue une fois par le layout) et
   dans la sous-navigation des modules à onglets (niveau 2). Le contenu occupe
   donc toute la largeur disponible.
   ===================================================================== */

/* Pas de fond ici : il est porté par <html> (cf. plus haut) afin que le calque
   décoratif .app-deco reste visible sous le contenu. */
.app-body {
    min-height: 100vh;
}

/* =====================================================================
   Barre principale (niveau 1) — horizontale, sticky
   ===================================================================== */

.topbar {
    position: sticky;
    top: 0;
    z-index: var(--nav-z-barre);
    display: flex;
    align-items: center;
    gap: var(--nav-ecart);
    /* Hauteur FERME (et non min-height) : la sous-navigation sticky se cale
       dessus au pixel via top: var(--nav-hauteur). Voir le repli < 600px, où la
       barre passe en hauteur libre et la sous-nav cesse d'être collée.
       La respiration verticale et le filet sont DÉJÀ comptés dans
       --nav-hauteur (box-sizing: border-box) : le contenu garde sa hauteur
       utile au lieu d'être comprimé par le padding. */
    height: var(--nav-hauteur);
    padding: var(--nav-respiration) var(--nav-marge-laterale);
    background: var(--nav-fond);
    /* Filet épais + ombre discrète : frontière nette avec le niveau 2. L'ombre
       est peinte par-dessus la sous-navigation (z-index supérieur), ce qui
       renforce la lecture des deux plans. */
    border-bottom: var(--nav-filet) solid var(--nav-filet-couleur);
    box-shadow: var(--nav-ombre);
}

/* ----- Signature « Cédric. » : point en bleu, reste en sombre ----- */

.topbar-signature {
    flex-shrink: 0;
    /* Largeur FERME : elle rend le début des onglets calculable, et donc
       l'alignement de la sous-navigation exact (cf. --nav-onglets-depart).
       nowrap + overflow visible : un débord éventuel irait dans l'écart de la
       barre plutôt que d'être coupé ou de passer à la ligne. */
    width: var(--nav-signature-largeur);
    white-space: nowrap;
    font-size: var(--nav-signature-taille);
    /* Graisse la plus lourde disponible dans la pile système (« Black ») */
    font-weight: var(--nav-signature-graisse);
    color: var(--nav-sombre);
    letter-spacing: -0.02em;
    user-select: none;
}

.topbar-signature-point { color: var(--nav-marque); }

/* ----- Onglets de modules -------------------------------------------
   Les onglets — et EUX SEULS — reposent sur un bandeau gris clair arrondi : le
   reste de la barre (signature, raccourcis, avatar) demeure sur fond blanc. Le
   bandeau épouse la largeur des onglets, il ne s'étire pas sur toute la barre.
   Onglet actif = pastille bleue pleine posée sur ce bandeau. */

.topbar-onglets {
    display: flex;
    align-items: center;
    gap: 0;
    /* Padding intérieur en haut/bas ET sur les côtés : c'est lui qui donne sa
       marge visuelle à la pastille bleue de l'onglet actif, quelle que soit sa
       position dans le bandeau (premier onglet, dernier, ou au milieu). */
    padding: var(--nav-onglets-padding-v) var(--nav-onglets-padding-h);
    border-radius: var(--nav-onglets-rayon);
    background: var(--nav-onglets-fond);
    /* Le bandeau se dimensionne sur son contenu (pas de flex: 1). Écran
       étroit : il peut se comprimer et défiler horizontalement, discrètement,
       plutôt que de déborder ou d'écraser les raccourcis de droite. */
    flex: 0 1 auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}
.topbar-onglets::-webkit-scrollbar { display: none; }

/* Filet « | » intercalé entre deux libellés d'onglet */
.topbar-onglets-filet {
    flex-shrink: 0;
    padding: 0 0.1rem;
    color: var(--nav-filet-texte);
    font-size: var(--nav-onglet-taille);
    font-weight: 400;
    user-select: none;
}

.topbar-onglet {
    flex-shrink: 0;
    padding: var(--nav-onglet-padding-v) var(--nav-onglet-padding-h);
    border-radius: var(--nav-pastille-rayon);
    font-size: var(--nav-onglet-taille);
    font-weight: var(--nav-onglet-graisse);
    color: var(--nav-onglet-texte);
    background: transparent;
    white-space: nowrap;
    transition: background-color 0.15s, color 0.15s;
}

.topbar-onglet:hover {
    color: var(--nav-texte-fort);
    background: var(--nav-blanc);
    text-decoration: none;
}

.topbar-onglet.is-active,
.topbar-onglet.is-active:hover {
    color: var(--nav-actif-texte);
    background: var(--nav-actif);
}

.topbar-onglet:focus-visible {
    outline: 2px solid var(--nav-marque);
    outline-offset: 2px;
}

/* ----- Bloc de droite : raccourcis, filet, avatar ----- */

.topbar-droite {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-left: auto;
    flex-shrink: 0;
}

.topbar-raccourcis {
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

/* Filet « | » séparant les deux groupes de raccourcis (L S P A | F S O O) */
.topbar-raccourcis-filet {
    padding: 0 0.15rem;
    color: var(--nav-filet-texte);
    font-size: 0.95rem;
    user-select: none;
}

/* Tuile carrée arrondie à initiale. Bleu clair pour le groupe principal (avant
   le filet), gris pour le second groupe : la classe is-accent est posée par
   App\Lib\Sites d'après l'ordre de la configuration. */
.topbar-tuile {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--nav-tuile-taille);
    height: var(--nav-tuile-taille);
    border-radius: 7px;
    background: var(--nav-tuile-fond);
    color: var(--nav-tuile-texte);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    transition: background-color 0.12s, color 0.12s;
}

.topbar-tuile.is-accent {
    background: var(--nav-tuile-accent-fond);
    color: var(--nav-tuile-accent-texte);
}

.topbar-tuile:hover {
    background: var(--nav-tuile-accent-fond);
    color: var(--nav-tuile-accent-texte);
    text-decoration: none;
}

.topbar-tuile:focus-visible {
    outline: 2px solid var(--nav-marque);
    outline-offset: 2px;
}

/* Infobulle CSS : nom complet du site SOUS la tuile (elle n'affiche qu'une
   lettre). L'attribut title assure le repli sans CSS / l'accessibilité. */
.topbar-tuile-nom {
    position: absolute;
    top: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    padding: 0.25rem 0.5rem;
    border-radius: 6px;
    background: var(--nav-sombre);
    color: var(--nav-blanc);
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.12s ease;
    box-shadow: var(--shadow-md);
    z-index: 5;
}
.topbar-tuile:hover .topbar-tuile-nom,
.topbar-tuile:focus-visible .topbar-tuile-nom {
    opacity: 1;
    visibility: visible;
}

/* Fin séparateur vertical entre les raccourcis et l'avatar */
.topbar-filet {
    width: 1px;
    height: 22px;
    background: var(--nav-bordure);
    flex-shrink: 0;
}

.topbar-compte-form { margin: 0; display: flex; }

/* Avatar : cercle bleu plein à l'initiale. Porte la déconnexion (bouton de
   formulaire POST) : c'est la seule action de compte de l'application. */
.topbar-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--nav-actif);
    color: var(--nav-actif-texte);
    font-family: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: filter 0.12s;
}

.topbar-avatar:hover { filter: brightness(0.93); }

.topbar-avatar:focus-visible {
    outline: 2px solid var(--nav-marque);
    outline-offset: 2px;
}

/* =====================================================================
   Sous-navigation (niveau 2) — modules à onglets internes
   ---------------------------------------------------------------------
   Style SOBRE, volontairement distinct du niveau 1 : onglets séparés par des
   points « · », actif SOULIGNÉ en bleu épais. Aucune pastille ici : la pastille
   pleine reste le marqueur exclusif de la barre principale.

   STICKY : elle se colle juste SOUS la barre principale (top = hauteur exacte
   de celle-ci, d'où la hauteur ferme de .topbar) et reste visible au défilement.
   Son z-index passe SOUS celui de la barre principale et AU-DESSUS du contenu :
   la barre couvre la sous-nav si les deux se croisent, et le contenu défile
   sous les deux. Le fond opaque empêche le contenu de transparaître derrière.

   HAUTEUR FERME : la barre garde exactement la même taille au repos et une fois
   collée, elle ne « saute » donc jamais au défilement. Corollaire : pas de
   retour à la ligne des onglets (il ferait déborder la hauteur fixe) — sur
   écran étroit, la rangée défile horizontalement, comme celle du niveau 1.
   ===================================================================== */

.sousnav {
    position: sticky;
    top: var(--nav-hauteur);
    z-index: var(--nav-z-sous);
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 0.1rem;
    height: var(--nav-sous-hauteur);
    /* Marges négatives calées sur les gouttières de .main :
       - en HAUT, elles annulent le padding supérieur de .main, sinon la
         sous-nav démarrerait plus bas que la barre au repos et laisserait un
         trou visible entre les deux (elle ne devenait jointive qu'une fois
         collée). Résultat : elle touche le filet de 4px, au pixel ;
       - sur les CÔTÉS, elles font courir le fond opaque et le trait inférieur
         sur toute la largeur, gouttières comprises. */
    margin: calc(-1 * var(--main-gouttiere-haut))
            calc(-1 * var(--main-gouttiere-cote))
            var(--nav-sous-espace-bas);
    /* ALIGNEMENT SUR LE NIVEAU 1 : le retrait à gauche place le bord du premier
       LIBELLÉ pile sous celui du premier onglet de modules. On part du point de
       départ de cet onglet et on retranche le padding du sous-onglet, qui
       décalerait sinon le texte vers la droite. Les deux valeurs viennent des
       mêmes variables que la barre : l'alignement reste juste même si la marge,
       l'écart ou les paddings changent.
       À droite, la gouttière habituelle du contenu. */
    padding: 0
             var(--main-gouttiere-cote)
             0
             calc(var(--nav-onglets-depart) - var(--nav-sous-onglet-padding-h));
    background: var(--nav-sous-fond);
    border-bottom: 1px solid var(--nav-bordure);
    overflow-x: auto;
    scrollbar-width: none;
}
.sousnav::-webkit-scrollbar { display: none; }

/* La barre d'onglets d'Idées de vidéos est masquée pendant une recherche
   (attribut hidden posé en JS) : display:flex ne doit pas l'emporter. */
.sousnav[hidden] { display: none; }

/* ----- Module « Idées » : DEUX barres de sous-navigation empilées -----
   La page « Idées de vidéos » porte deux .sousnav l'une sous l'autre : celle du
   MODULE (Idées de Cédric · Idées de vidéos) puis celle des ONGLETS du
   sous-module (Lano / Allô / Autres / Externe). Sans réglage, les deux se
   colleraient au même « top » au défilement et se recouvriraient.
   On les EMPILE donc : la barre de module reste sous la barre principale, celle
   des onglets se cale exactement d'une hauteur plus bas, et les deux demeurent
   jointives (aucun trou entre elles).
   L'écart du bas n'est annulé que si la barre d'onglets est bien VISIBLE : en
   mode recherche elle disparaît, et la barre de module retrouve son écart
   normal avant le contenu.

   DEUX écarts à neutraliser, pas un : annuler la marge basse de la première
   barre ne suffit pas, car .main est une colonne FLEX dont le `gap` s'insère
   entre TOUS ses enfants — il laissait donc une bande de fond de page entre les
   deux barres au repos, alors qu'elles redevenaient jointives une fois collées.
   D'où la marge haute NÉGATIVE, prise sur la même variable que ce gap : les deux
   barres se touchent au pixel, au repos comme au défilement, et l'écart entre le
   BLOC de sous-navigation et le contenu qui suit reste celui de tous les autres
   modules (gap de .main + --nav-sous-espace-bas, comme sous-nav → sélecteur de
   période en Comptabilité). */
.sousnav.idees-sousnav:has(+ .sousnav.idv-tabs:not([hidden])) { margin-bottom: 0; }
.sousnav.idv-tabs {
    top: calc(var(--nav-hauteur) + var(--nav-sous-hauteur));
    margin-top: calc(-1 * var(--main-espace));
}

.sousnav-point {
    flex-shrink: 0;
    color: var(--nav-sous-point);
    font-size: 0.9rem;
    user-select: none;
}

/* flex-shrink: 0 + white-space: nowrap : en rangée non repliable à hauteur
   fixe, les onglets ne doivent ni se comprimer ni voir leur libellé passer à
   la ligne — sinon la hauteur ferme serait débordée. */
.sousnav-onglet {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    gap: 0.4rem;
    padding: 0.25rem var(--nav-sous-onglet-padding-h);
    border: none;
    background: none;
    font-family: inherit;
    font-size: 0.925rem;
    color: var(--nav-texte);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.15s;
}

.sousnav-onglet:hover {
    color: var(--nav-texte-fort);
    text-decoration: none;
}

.sousnav-onglet:focus-visible {
    outline: 2px solid var(--nav-marque);
    outline-offset: 2px;
    border-radius: 4px;
}

.sousnav-onglet.is-active {
    color: var(--nav-texte-fort);
    font-weight: 500;
}

/* Souligné bleu épais sous le LIBELLÉ seul (un éventuel compteur reste hors
   du trait). Coins légèrement arrondis en haut. */
.sousnav-libelle { position: relative; }

.sousnav-onglet.is-active .sousnav-libelle::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -0.35rem;
    height: var(--nav-sous-souligne);
    border-radius: 2px 2px 0 0;
    background: var(--nav-actif);
}

/* Pastille de comptage (Idées de vidéo) */
.sousnav-compte {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.3rem;
    border-radius: 999px;
    background: var(--nav-gris);
    color: var(--nav-texte);
    font-size: 0.72rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.sousnav-onglet.is-active .sousnav-compte {
    background: var(--nav-tuile-accent-fond);
    color: var(--nav-tuile-accent-texte);
}

/* =====================================================================
   Sélecteur de période (niveau 3) — App\Lib\SelecteurPeriode
   ---------------------------------------------------------------------
   Navigation temporelle unifiée, rendue par un composant unique et posée en
   tête de contenu, juste sous la sous-navigation :

       2026 · 2025  |  Jan · Fév · … · Déc

   Style sobre et cohérent avec la sous-nav (mêmes points « · », même échelle),
   mais SANS soulignement : ici l'actif est simplement en bleu de marque. Chaque
   niveau garde donc son marqueur — pastille pleine (barre principale), souligné
   (sous-navigation), bleu simple (période).
   ===================================================================== */

.periode {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.1rem 0.15rem;
    font-size: var(--nav-periode-taille);
}

/* Un groupe = les années, ou les douze mois. Il ne se coupe pas au milieu d'un
   libellé ; c'est la ligne entière qui se replie si la place manque. */
.periode-groupe {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.1rem 0.15rem;
}

.periode-item {
    padding: 0.1rem 0.3rem;
    border-radius: 5px;
    color: var(--nav-texte);
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.15s;
}

.periode-item:hover {
    color: var(--nav-texte-fort);
    text-decoration: none;
}

.periode-item:focus-visible {
    outline: 2px solid var(--nav-marque);
    outline-offset: 1px;
}

/* Année ou mois actif : bleu de marque, plus gras. Aucun souligné. */
.periode-item.is-active,
.periode-item.is-active:hover {
    color: var(--nav-periode-actif);
    font-weight: var(--nav-periode-graisse);
}

/* ----- VARIANTE SOULIGNÉE (.periode--souligne) -----
   Même grammaire que ci-dessus — texte cliquable, points « · », même échelle —
   mais l'actif est marqué comme dans la sous-navigation : texte SOMBRE surmonté
   d'un souligné bleu épais, plutôt que du texte bleu.

   À réserver aux sélecteurs posés DANS le contenu (la ligne d'années de
   l'Historique), là où le marqueur bleu simple du sélecteur de tête se
   confondrait avec les liens voisins. Le trait reprend les variables du souligné
   de la sous-nav (épaisseur et bleu de marque) : les deux ne peuvent pas
   diverger. Le souligné ne couvre que le TEXTE, pas le padding de l'item. */
.periode--souligne { padding-bottom: 0.35rem; }

.periode--souligne .periode-item.is-active,
.periode--souligne .periode-item.is-active:hover {
    position: relative;
    color: var(--nav-texte-fort);
    font-weight: 500;
}

.periode--souligne .periode-item.is-active::after {
    content: "";
    position: absolute;
    left: 0.3rem;
    right: 0.3rem;
    bottom: -0.1rem;
    height: var(--nav-sous-souligne);
    border-radius: 2px 2px 0 0;
    background: var(--nav-actif);
}

/* Points de séparation entre deux items : gris clair, comme la sous-nav */
.periode-point {
    color: var(--nav-sous-point);
    user-select: none;
}

/* Filet « | » entre le groupe des années et celui des mois */
.periode-filet {
    padding: 0 0.4rem;
    color: var(--nav-filet-texte);
    user-select: none;
}

/* Deux niveaux de navigation temporelle empilés — le sélecteur année/mois puis
   le sélecteur semaine|jour (Exercices, Agenda). Posé HORS CARTE, directement
   sur le fond de page, comme le sélecteur seul de la Comptabilité : ni fond, ni
   bordure, ni ombre, ni retrait. Seul rôle de ce conteneur : garder les deux
   lignes serrées et n'occuper qu'un élément de .main, dont le gap fournit
   l'espacement au-dessus et au-dessous — le rythme vertical reste donc le même
   d'un module à l'autre. */
.periode-duo {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

/* ----- Zone principale : pleine largeur sous les barres ------------ */

.main {
    padding: var(--main-gouttiere-haut) var(--main-gouttiere-cote) 2.5rem;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--main-espace);
}

/* Grande carte conteneur — la brique qui structure toutes les pages (Finances,
   Lano, Exercices, Alimentation, Comptabilité, Agenda, Idées, Gains…). Son fond
   est TRANSLUCIDE (blanc à 80 %) pour laisser deviner le décor de fond derrière
   elle ; bordure, arrondi et ombre sont inchangés. Le contenu de la carte reste
   parfaitement opaque : aucune règle d'opacity n'est posée ici ni sur un parent. */
.card {
    background: var(--fond-carte-translucide);
    padding: 1.5rem 2rem;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-md);
}

/* =====================================================================
   Illustration décorative de l'application — CALQUE UNIQUE
   ---------------------------------------------------------------------
   Une seule image pour toute l'application, posée une seule fois dans le
   layout global (App\Lib\Deco::fond(), appelé par layouts/app.php) : elle
   apparaît donc automatiquement sur toutes les pages, et il n'y a qu'un point
   à maintenir. Plus aucune déco par rubrique.

   Collée dans le coin bas droit de la FENÊTRE du navigateur (position: fixed,
   right/bottom à 0, aucune marge), affichée à sa TAILLE RÉELLE : aucune largeur
   ni hauteur imposée, et max-width neutralisé pour qu'aucune règle ne la
   réduise. Hors flux : elle n'appartient à aucune grille et ne contraint donc
   aucune mise en page.

   Le fond de l'illustration vaut exactement --color-bg, donc le raccord est
   invisible : surtout aucune carte, bordure, ombre ni arrondi autour.

   Empilement : z-index négatif. Le calque se peint juste au-dessus du canevas
   (le fond de <html>) et DERRIÈRE absolument tout le reste — fonds de cartes,
   contenu, barres de navigation, modales — sans qu'aucune page n'ait à remonter
   quoi que ce soit. C'est pour cela que <body> ne porte plus de fond opaque
   (cf. html { background } plus haut) : il masquerait le calque. Avec
   pointer-events: none, il ne capte jamais un clic ni une sélection.

   Débordement : ancré à droite: 0, il ne peut pas dépasser à droite (aucun
   défilement horizontal) ; un élément fixé ne crée pas non plus de défilement
   vertical. Ce qui sort du cadre en haut et à gauche est simplement masqué,
   c'est voulu : le sujet est en bas à droite et le reste se fond dans le fond
   de page.
   ===================================================================== */
.app-deco {
    position: fixed;
    right: 0;
    bottom: 0;
    z-index: -1;
    max-width: none; /* taille réelle : jamais réduite */
    margin: 0;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    pointer-events: none;
    user-select: none;
}

/* =====================================================================
   Champs de formulaire
   ===================================================================== */

.field { display: flex; flex-direction: column; gap: 0.35rem; }
.field-label { font-size: 0.85rem; color: var(--color-muted); }

input[type="text"],
input[type="password"],
input[type="email"] {
    width: 100%;
    padding: 0.6rem 0.75rem;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-size: 1rem;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}

input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* =====================================================================
   Boutons
   ===================================================================== */

.btn {
    display: inline-block;
    padding: 0.55rem 0.95rem;
    border: 1px solid transparent;
    border-radius: 6px;
    font-size: 0.95rem;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.btn-primary {
    background: var(--color-primary);
    color: #ffffff;
    font-weight: 600;
}
.btn-primary:hover { background: var(--color-primary-h); }

.btn-ghost {
    background: transparent;
    color: var(--color-muted);
    border-color: var(--color-border-2);
}
.btn-ghost:hover {
    color: var(--color-text);
    border-color: var(--color-muted);
    background: var(--color-surface-2);
}

.btn-block { width: 100%; }

/* =====================================================================
   Alertes
   ===================================================================== */

.alert { padding: 0.7rem 0.9rem; border-radius: 6px; font-size: 0.9rem; }
.alert-error {
    background: var(--color-danger-bg);
    color: var(--color-danger-fg);
    border: 1px solid #fecaca;
}
/* Succès : fond vert plein, texte blanc bien lisible */
.alert-success {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 1rem;
    background: color-mix(in srgb, var(--color-success) 90%, black);
    color: #ffffff;
    font-weight: 500;
    font-size: 0.95rem;
    border: 1px solid color-mix(in srgb, var(--color-success) 70%, black);
    border-radius: var(--radius);
    transition: opacity 0.4s ease; /* fondu avant retrait automatique (JS) */
}
.alert-success svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

/* Avertissement : fond ambre plein, texte blanc (dérivé de --color-warning) */
.alert-warning {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 1rem;
    background: color-mix(in srgb, var(--color-warning) 90%, black);
    color: #ffffff;
    font-weight: 500;
    font-size: 0.95rem;
    border: 1px solid color-mix(in srgb, var(--color-warning) 70%, black);
    border-radius: var(--radius);
}

/* =====================================================================
   NAVIGATION MOBILE — burger + panneau
   ---------------------------------------------------------------------
   ÉTAT PAR DÉFAUT (= DESKTOP) : le burger et le panneau n'existent PAS.
   `display: none` les retire complètement du rendu et du flux, donc la
   barre du haut, ses onglets, ses raccourcis et son avatar sont
   strictement ceux d'avant, au pixel. Tout ce qui suit ne s'allume que
   dans la media query du bas de section.
   ===================================================================== */

.topbar-burger { display: none; }
.navmob { display: none; }

/* =====================================================================
   Responsive minimal (< 900px)
   ===================================================================== */

@media (max-width: 900px) {
    /* Gouttières de contenu ET gabarit horizontal de la barre resserrés. On
       redéfinit les VARIABLES, pas les règles : .main (padding), .topbar (marge,
       écart, padding d'onglet) et .sousnav (marges négatives, retrait
       d'alignement) suivent toutes seules. Le collage au pixel comme
       l'alignement de la sous-nav sur le premier onglet restent donc vrais. */
    :root {
        --main-gouttiere-haut:  1.25rem;
        --main-gouttiere-cote:  1rem;
        --nav-marge-laterale:   1rem;
        --nav-ecart:            0.75rem;
        --nav-onglet-padding-h: 0.55rem;
    }

    /* Barre principale compactée : la signature et les onglets se serrent, la
       zone d'onglets défile horizontalement (cf. .topbar-onglets) plutôt que
       d'écraser les raccourcis. Le bloc de droite reste sur la même ligne.
       La respiration verticale de 10px est conservée : sans quoi --nav-hauteur
       ne correspondrait plus à la hauteur réelle et le collage se décalerait. */
    .topbar-onglet { font-size: 0.9rem; }

    .topbar-droite { gap: 0.4rem; }

    .main { padding-bottom: 2rem; }
}

/* =====================================================================
   NAVIGATION MOBILE — le seul bloc qui change la navigation
   ---------------------------------------------------------------------
   SEUIL : 1000px. À régler ICI **et** dans --nav-seuil-mobile (:root),
   que lit /assets/js/nav.js — une media query ne peut pas consommer une
   variable CSS, d'où ces deux points volontairement documentés.

   Ce bloc remplace l'ancien repli < 600px, qui faisait passer la barre
   sur deux lignes (onglets en pleine largeur) et renonçait au collage de
   la sous-navigation. Il n'a plus lieu d'être : les onglets quittant la
   barre, celle-ci garde sa hauteur FERME et la sous-nav reste collée
   dessous, à tous les gabarits.
   ===================================================================== */

@media (max-width: 1000px) {

    /* ----- Barre repliée : signature | … | avatar + burger -----
       Les onglets de modules et les raccourcis sortent de la barre : ils
       vivent désormais dans le panneau. Rien d'autre ne bouge — la barre
       garde sa hauteur, son filet et son ombre. */
    .topbar-onglets { display: none; }
    .topbar-droite .topbar-raccourcis,
    .topbar-droite .topbar-filet { display: none; }

    .topbar-burger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 34px;
        height: 34px;
        margin-left: 0.15rem;
        border-radius: 8px;
        color: var(--nav-texte-fort);
        background: transparent;
        transition: background-color 0.12s, color 0.12s;
    }
    .topbar-burger:hover {
        background: var(--nav-gris);
        color: var(--nav-marque);
        text-decoration: none;
    }
    .topbar-burger:focus-visible {
        outline: 2px solid var(--nav-marque);
        outline-offset: 2px;
    }
    .topbar-burger svg { width: 22px; height: 22px; }

    /* ----- Panneau : tiroir latéral droit sur voile sombre -----
       FERMÉ = `visibility: hidden` : le panneau sort du rendu ET de l'ordre
       de tabulation ET de l'arbre d'accessibilité, sans qu'aucun aria-hidden
       n'ait à être piloté à la main. Deux sélecteurs l'ouvrent :
        - `.is-ouvert` posée par le script (cas normal) ;
        - `:target`, le REPLI SANS JS — le burger étant un lien vers
          #nav-mobile, le menu s'ouvre même si nav.js ne se charge pas. */
    .navmob {
        display: block;
        position: fixed;
        inset: 0;
        z-index: var(--z-modal);
        visibility: hidden;
    }
    .navmob.is-ouvert,
    .navmob:target { visibility: visible; }

    /* Voile : c'est aussi la cible du « clic en dehors » (un lien, pour que
       la fermeture marche également sans JS). */
    .navmob-fond {
        position: absolute;
        inset: 0;
        background: color-mix(in srgb, var(--nav-sombre) 45%, transparent);
        opacity: 0;
        transition: opacity 0.18s ease;
    }
    .navmob.is-ouvert .navmob-fond,
    .navmob:target .navmob-fond { opacity: 1; }

    .navmob-panneau {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: min(19rem, 86vw);
        display: flex;
        flex-direction: column;
        padding: var(--nav-respiration) var(--nav-marge-laterale);
        background: var(--nav-fond);
        box-shadow: -8px 0 24px color-mix(in srgb, var(--nav-sombre) 18%, transparent);
        overflow-y: auto;
        transform: translateX(100%);
        transition: transform 0.18s ease;
    }
    .navmob.is-ouvert .navmob-panneau,
    .navmob:target .navmob-panneau { transform: translateX(0); }

    /* En-tête du panneau : la signature, et la croix de fermeture. */
    .navmob-entete {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        height: var(--nav-onglets-hauteur);
        flex-shrink: 0;
    }
    /* La signature reprend le style de la barre ; seule sa largeur ferme
       (calée sur le gabarit de la barre) n'a pas de sens ici. */
    .navmob-entete .topbar-signature { width: auto; }

    .navmob-fermer {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 34px;
        height: 34px;
        flex-shrink: 0;
        border-radius: 8px;
        color: var(--nav-texte);
        transition: background-color 0.12s, color 0.12s;
    }
    .navmob-fermer:hover {
        background: var(--nav-gris);
        color: var(--nav-texte-fort);
        text-decoration: none;
    }
    .navmob-fermer:focus-visible {
        outline: 2px solid var(--nav-marque);
        outline-offset: 2px;
    }
    .navmob-fermer svg { width: 20px; height: 20px; }

    /* ----- Les 8 modules, en liste verticale -----
       Même règle d'onglet actif que la barre, et même marqueur : pastille
       bleue pleine (--nav-actif = #00aaef), pour que les deux affichages se
       lisent pareil. */
    .navmob-liste {
        display: flex;
        flex-direction: column;
        gap: 0.15rem;
        margin-top: 0.75rem;
    }
    .navmob-lien {
        padding: 0.7rem 0.85rem;
        border-radius: var(--nav-pastille-rayon);
        font-size: 1rem;
        font-weight: var(--nav-onglet-graisse);
        color: var(--nav-onglet-texte);
        transition: background-color 0.15s, color 0.15s;
    }
    .navmob-lien:hover {
        color: var(--nav-texte-fort);
        background: var(--nav-gris);
        text-decoration: none;
    }
    .navmob-lien.is-active,
    .navmob-lien.is-active:hover {
        color: var(--nav-actif-texte);
        background: var(--nav-actif);
    }
    .navmob-lien:focus-visible {
        outline: 2px solid var(--nav-marque);
        outline-offset: 2px;
    }

    /* Filet fin de séparation avant les raccourcis. */
    .navmob-filet {
        display: block;
        height: 1px;
        margin: 1rem 0;
        background: var(--nav-bordure);
        flex-shrink: 0;
    }

    /* ----- Raccourcis, en bas du panneau -----
       Les MÊMES tuiles que la barre (même composant App\Lib\Sites, mêmes
       liens, même code couleur), simplement autorisées à passer à la ligne.
       L'infobulle survolée n'a pas de sens au doigt : on la neutralise ici,
       l'attribut title restant en place. */
    .navmob-raccourcis { padding-bottom: 0.5rem; }
    .navmob-raccourcis .topbar-raccourcis { flex-wrap: wrap; gap: 0.4rem; }
    .navmob-raccourcis .topbar-tuile { width: 34px; height: 34px; font-size: 0.85rem; }
    .navmob-raccourcis .topbar-tuile-nom { display: none; }

    /* ----- Sous-navigations : DÉFILANTES au doigt -----
       Elles défilaient déjà (overflow-x), mais sans repère visuel et avec
       l'ascenseur totalement masqué. On rend le défilement fluide au doigt,
       on redonne un ascenseur fin, et on signale le débord.

       FONDUS DE BORD, 100 % CSS, sans balise ni script : quatre dégradés
       superposés. Les deux premiers (attachement `local`) DÉFILENT avec le
       contenu et masquent l'ombre quand on est arrivé au bout ; les deux
       suivants (attachement `scroll`) restent collés aux bords et FONT
       l'ombre. Résultat : l'ombre droite n'apparaît que s'il reste du
       contenu à droite, la gauche que si l'on a déjà défilé. */
    .sousnav {
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
        scrollbar-color: var(--nav-bordure) transparent;
        background-image:
            linear-gradient(to right, var(--nav-sous-fond), transparent),
            linear-gradient(to left,  var(--nav-sous-fond), transparent),
            linear-gradient(to right, color-mix(in srgb, var(--nav-sombre) 14%, transparent), transparent),
            linear-gradient(to left,  color-mix(in srgb, var(--nav-sombre) 14%, transparent), transparent);
        background-position: left center, right center, left center, right center;
        background-repeat: no-repeat;
        background-size: 30px 100%, 30px 100%, 14px 100%, 14px 100%;
        background-attachment: local, local, scroll, scroll;
    }
    .sousnav::-webkit-scrollbar { display: block; height: 3px; }
    .sousnav::-webkit-scrollbar-track { background: transparent; }
    .sousnav::-webkit-scrollbar-thumb {
        background: var(--nav-bordure);
        border-radius: 3px;
    }

    /* =================================================================
       MENUS DÉROULANTS de la navigation (montés par nav.js)
       -----------------------------------------------------------------
       Deux emplois, un seul habillage : la SOUS-NAVIGATION du module et
       la NAVIGATION TEMPORELLE (« Temps »). Le conteneur .navcol est
       créé par le script ; les barres d'origine sont DÉPLACÉES dedans,
       jamais recopiées — les règles ci-dessous ne font donc que les
       remettre en page verticalement.

       Si le script n'a pas tourné, aucun .navcol n'existe : les barres
       s'affichent défilantes comme ci-dessus, et rien n'est perdu.
       ================================================================= */

    /* Bloc autonome, PLEINE LARGEUR DE SON CONTENEUR : les sélecteurs de
       période vivent selon les modules tantôt à la racine du contenu,
       tantôt dans un conteneur intermédiaire (.periode-duo en Exercices).
       Aucune marge négative ici, donc : le menu s'insère proprement quel
       que soit son hôte, au lieu de déborder de celui-ci. */
    .navcol {
        width: 100%;
        margin: 0;
        border: 1px solid var(--nav-bordure);
        border-radius: 10px;
        background: var(--nav-sous-fond);
        overflow: hidden;
    }
    /* La sous-navigation ouvre la page : elle récupère l'écart qui la
       séparait du contenu. */
    .navcol--sousnav { margin-bottom: var(--nav-sous-espace-bas); }

    /* ----- En-tête replié : bouton pleine largeur ----- */
    .navcol-tete {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        width: 100%;
        padding: 0.7rem 0.85rem;
        border: none;
        background: transparent;
        font-family: inherit;
        font-size: 0.95rem;
        font-weight: 500;
        color: var(--nav-texte-fort);
        text-align: left;
        cursor: pointer;
    }
    .navcol-tete:focus-visible {
        outline: 2px solid var(--nav-marque);
        outline-offset: -2px;
    }
    .navcol-icone { display: inline-flex; flex-shrink: 0; color: var(--nav-texte); }
    .navcol-icone svg { width: 18px; height: 18px; }

    /* Libellé : l'onglet actif pour une sous-nav, « Temps » pour la période. */
    .navcol-titre {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Rappel discret de la période courante, poussé à droite. */
    .navcol-resume {
        margin-left: auto;
        flex-shrink: 0;
        font-size: 0.85rem;
        font-weight: 400;
        color: var(--nav-texte);
        white-space: nowrap;
    }

    /* Chevron : bas au repos, retourné une fois déplié (le jeu maison n'a
       qu'un chevron, on le pivote — même procédé que le bloc « Ajouter un
       ingrédient » d'Alimentation). */
    .navcol-chevron {
        display: inline-flex;
        flex-shrink: 0;
        margin-left: auto;
        color: var(--nav-texte);
        transition: transform 0.15s;
    }
    .navcol-resume + .navcol-chevron { margin-left: 0.4rem; }
    .navcol-chevron svg { width: 18px; height: 18px; display: block; }
    .navcol.is-ouvert .navcol-chevron { transform: rotate(180deg); }

    /* ----- Corps déplié ----- */
    .navcol-corps {
        padding: 0 0.85rem 0.7rem;
        border-top: 1px solid var(--nav-bordure);
        background: var(--nav-fond);
    }
    .navcol-corps[hidden] { display: none; }

    /* ----- La SOUS-NAVIGATION, remise en liste verticale -----
       On neutralise ici tout ce qui faisait d'elle une barre collée :
       position, hauteur ferme, marges négatives, fond, défilement et
       fondus de bord. Les onglets, eux, sont les mêmes éléments. */
    .navcol .sousnav {
        position: static;
        display: flex;
        flex-direction: column;
        align-items: stretch;
        height: auto;
        margin: 0;
        padding: 0.35rem 0 0;
        background: transparent;
        background-image: none;
        border-bottom: none;
        overflow: visible;
    }
    .navcol .sousnav-point { display: none; }

    .navcol .sousnav-onglet {
        position: relative;
        justify-content: flex-start;
        width: 100%;
        padding: 0.6rem 0.75rem;
        border-radius: var(--nav-pastille-rayon);
        font-size: 0.95rem;
    }
    /* Onglet ACTIF : pastille bleue pleine (--nav-actif = #00aaef) et coche
       blanche dessinée en CSS, sans image ni police d'icônes. Le souligné
       du niveau 2, qui n'a pas de sens sur fond plein, est neutralisé. */
    .navcol .sousnav-onglet.is-active {
        color: var(--nav-actif-texte);
        background: var(--nav-actif);
        font-weight: 600;
    }
    .navcol .sousnav-onglet.is-active .sousnav-libelle::after { display: none; }
    .navcol .sousnav-onglet.is-active::after {
        content: "";
        position: absolute;
        right: 0.9rem;
        top: 50%;
        width: 0.3rem;
        height: 0.6rem;
        border: solid var(--nav-blanc);
        border-width: 0 2px 2px 0;
        transform: translateY(-60%) rotate(45deg);
    }

    /* ----- La NAVIGATION TEMPORELLE, niveau par niveau -----
       Chaque groupe (année, mois, semaine, jour) devient une section
       intitulée. Le titre est produit à partir de l'attribut posé par le
       script : aucun élément de texte n'est fabriqué, et les liens
       demeurent ceux des composants SelecteurPeriode / SelecteurSemaineJour. */
    .navcol .periode {
        display: block;
        font-size: 0.95rem;
    }
    .navcol .periode-filet,
    .navcol .periode-point { display: none; }

    .navcol .periode-groupe {
        display: flex;
        flex-wrap: wrap;
        gap: 0.35rem;
        padding-bottom: 0.5rem;
    }
    .navcol .periode-groupe[data-titre]::before {
        content: attr(data-titre);
        flex-basis: 100%;
        padding-top: 0.55rem;
        color: var(--color-muted);
        font-size: 0.72rem;
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
    }

    /* Choix de période : pastilles cliquables, confortables au doigt.
       L'actif prend le fond bleu clair et le texte bleu de marque. */
    .navcol .periode-item {
        padding: 0.4rem 0.7rem;
        border: 1px solid var(--nav-bordure);
        border-radius: 999px;
        background: var(--nav-blanc);
    }
    .navcol .periode-item.is-active {
        color: var(--nav-marque);
        background: color-mix(in srgb, var(--nav-marque) 12%, var(--nav-blanc));
        border-color: color-mix(in srgb, var(--nav-marque) 40%, transparent);
        font-weight: 600;
    }
}

/* =====================================================================
   Module Comptabilité (Finances)
   ===================================================================== */

/* Barre d'onglets du module */
.compta-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 1rem;
}

.compta-tab {
    padding: 0.45rem 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.9rem;
    color: var(--color-muted);
    background: var(--color-surface);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.compta-tab:hover {
    color: var(--color-primary);
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
    text-decoration: none;
}
.compta-tab.is-active {
    color: var(--color-primary);
    background: var(--color-accent-soft);
    border-color: var(--color-primary);
    font-weight: 600;
}

/* Indicateurs de synthèse (budget total / minoré / minimum brut HT) */
.compta-indicateurs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--gap);
    margin: 1rem 0 1.5rem;
}

/* =====================================================================
   CARTE KPI — style UNIQUE de toute l'application (App\Lib\Kpi)
   ---------------------------------------------------------------------
   Une seule famille de classes, appliquée dans tous les modules : fond gris,
   libellé en petites majuscules grises, grande valeur sombre, sous-libellé
   optionnel. Les anciennes familles par module (.compta-indicateur,
   .accueil-kpi, .exo-kpi, .tdb-carte) et leurs variantes colorées (fonds
   bleutés, ambrés, barres d'accent) ont été supprimées : un KPI se présente
   désormais à l'identique partout.

   Seule couleur admise en plus du sombre : le rouge de --kpi-valeur-negatif,
   posé par App\Lib\Kpi quand la valeur est négative. C'est FONCTIONNEL, pas
   décoratif — voir .kpi-valeur.is-negatif.
   ===================================================================== */

.kpi {
    display: flex;
    flex-direction: column;
    min-width: 0; /* autorise la carte à rétrécir dans sa colonne */
    padding: 0.9rem 1.1rem;
    border: 1px solid var(--kpi-bordure);
    border-radius: var(--kpi-rayon);
    background: var(--kpi-fond);
}

.kpi-label {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--kpi-label);
    overflow-wrap: break-word;
}

.kpi-valeur {
    margin-top: 0.25rem;
    font-size: 22px;
    font-weight: 600;
    color: var(--kpi-valeur);
    font-variant-numeric: tabular-nums;
}

/* Alerte : valeur négative (ou seuil métier explicite). Unique dérogation
   chromatique, décidée côté PHP par App\Lib\Kpi::classeValeur(). */
.kpi-valeur.is-negatif { color: var(--kpi-valeur-negatif); }

.kpi-sub {
    margin-top: 0.15rem;
    font-size: 0.85rem;
    color: var(--kpi-sub);
    overflow-wrap: break-word;
}

/* =====================================================================
   CONTRÔLE SEGMENTÉ — composant RÉUTILISABLE (.segmented)
   ---------------------------------------------------------------------
   Un groupe d'options mutuellement exclusives, réunies dans un même rail gris :
   l'option retenue est une pastille BLEUE PLEINE, les autres restent en gris sur
   fond transparent. C'est le pendant « commande » de la carte KPI : une seule
   écriture pour toute l'application.

   Volontairement AGNOSTIQUE du mécanisme : les options peuvent être des <a>
   (bascule par rechargement serveur, comme l'Historique de la Comptabilité) ou
   des <button> (bascule côté client). Le composant ne décide de rien, il habille
   — l'état retenu se déclare avec .est-actif, et rien d'autre.

   Couleurs : le bleu vient de la variable de MARQUE existante. Les deux teintes
   propres au composant (le gris du rail, le gris des options au repos) n'existent
   pas dans la palette globale : elles sont déclarées ICI, en portée locale, pour
   ne pas grossir :root d'entrées à usage unique — même parti pris que les barres
   du ratio de l'onglet Charges.
   ===================================================================== */

.segmented {
    --segmented-fond:        #eef1f5;                    /* rail gris clair */
    --segmented-texte:       #5f5e5a;                    /* options au repos */
    --segmented-survol:      rgba(255, 255, 255, 0.65);  /* effleurement */
    --segmented-actif-fond:  var(--nav-marque);          /* #00aaef */
    --segmented-actif-texte: var(--nav-blanc);
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    padding: 3px;
    border-radius: 9px;
    background: var(--segmented-fond);
}

.segmented-option {
    padding: 7px 15px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--segmented-texte);
    font-family: inherit;
    font-size: 0.85rem;
    line-height: 1.2;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

/* Survol RÉSERVÉ aux options non retenues : la pastille active ne réagit pas,
   elle est déjà l'état courant. */
.segmented-option:not(.est-actif):hover {
    background: var(--segmented-survol);
    color: var(--nav-sombre);
    text-decoration: none;
}

.segmented-option:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 1px;
}

.segmented-option.est-actif {
    background: var(--segmented-actif-fond);
    color: var(--segmented-actif-texte);
    font-weight: 500;
}

/* Tableaux par catégorie (bandeau coloré + une ligne par poste) */
.compta-table {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: var(--gap);
    background: var(--color-surface);
}

.compta-table-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6rem 1rem;
    background: var(--color-primary);
    color: #ffffff;
    border-bottom: 1px solid var(--color-border);
}

.compta-table-titre { font-weight: 700; font-size: 1.05rem; }

.compta-table-soustotal {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.compta-table-mention {
    display: block;
    font-weight: 400;
    font-size: 0.8rem;
    opacity: 0.85;
}

/* Corps d'un bloc à bandeau (contenu sous l'en-tête bleu) : padding + colonne.
   Partagé par les blocs Tableau de bord / Charges convertis au style « Échéances ». */
.compta-bloc-corps {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 1rem 1.2rem;
}
/* (L'ancienne règle « .tdb-declarations .compta-table » n'a plus d'objet : le
   tableau de bord Compta n'imbrique plus de .compta-table dans .tdb-declarations,
   cette grille ne servant plus qu'à la carte de bilan de l'onglet Charges.) */

/* Variante verte « validation » du bloc « Frais compressibles » */
.compta-table--compressibles .compta-table-entete {
    background: var(--color-success);
    color: #ffffff;
}

.compta-postes {
    width: 100%;
    border-collapse: collapse;
}

.compta-postes td {
    padding: 0.4rem 1rem;
    vertical-align: middle;
}

/* Zébrure des lignes paires */
.compta-postes tbody tr:nth-child(even) td { background: var(--color-surface-2); }

.compta-libelle { font-size: 0.9rem; }

.compta-cellule-montant {
    text-align: right;
    width: 200px;
    white-space: nowrap;
}

/* Libellé éditable : discret au repos, encadré au survol / à la saisie */
input.compta-libelle-input {
    width: 100%;
    padding: 0.35rem 0.5rem;
    font-size: 0.9rem;
    font-family: inherit;
    color: var(--color-text);
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
input.compta-libelle-input:hover { border-color: var(--color-border-2); }
input.compta-libelle-input:focus {
    outline: none;
    background: var(--color-surface);
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Bouton discret de suppression d'une ligne */
.compta-supprimer {
    width: 28px;
    height: 28px;
    margin-left: 0.4rem;
    vertical-align: middle;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--color-muted);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.compta-supprimer:hover {
    color: var(--color-error);
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
}

/* Pied de tableau : ajout d'une ligne */
.compta-table-pied {
    padding: 0.45rem 1rem;
    border-top: 1px solid var(--color-border);
    background: var(--color-surface);
}

.compta-ajouter {
    padding: 0.25rem 0.45rem;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--color-primary);
    font-size: 0.85rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.compta-ajouter:hover {
    background: var(--color-accent-soft);
    color: var(--color-primary-h);
}

/* --- Onglet Recettes (lecture seule) --- */

/* Navigation mensuelle centrée */
.compta-mois {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin: 1rem 0;
}

/* (.compta-mois-courant / .compta-mois-lien retirées : la navigation par
   chevrons « ‹ mois › » a été remplacée partout par le sélecteur de période
   unifié — cf. les règles .periode plus haut.) */

/* Carte ambre (sommes à mettre de côté : prélèvements) */
/* (La variante ambre des indicateurs est supprimée : les KPI n'ont plus de
   teinte décorative par module — cf. la carte KPI unique .kpi.) */

/* Cellules numériques alignées à droite */
.compta-cellule-nombre {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Tableau des encaissements : en-tête sur bandeau plein */
.compta-recettes {
    width: 100%;
    border-collapse: collapse;
}

.compta-recettes th,
.compta-recettes td {
    padding: 0.5rem 0.9rem;
    vertical-align: middle;
    font-size: 0.9rem;
}

.compta-recettes thead th {
    background: var(--color-primary);
    color: #ffffff;
    text-align: left;
    font-size: 0.85rem;
    font-weight: 600;
}
.compta-recettes thead th.compta-cellule-nombre { text-align: right; }

.compta-recettes tbody tr:nth-child(even) td { background: var(--color-surface-2); }

.compta-recettes tfoot td {
    background: var(--color-surface-2);
    border-top: 2px solid var(--color-border-2);
    font-weight: 700;
}

/* Encarts côte à côte (répartition par source / déclaration TVA) */
.compta-colonnes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--gap);
    margin-top: var(--gap);
    margin-bottom: 1.5rem; /* espace avec le tableau des encaissements en dessous */
}
.compta-colonnes .compta-table { margin-bottom: 0; }

/* Mois sans encaissement */
.compta-vide {
    padding: 1.5rem 1rem;
    text-align: center;
    border: 1px dashed var(--color-border-2);
    border-radius: var(--radius);
}

/* --- Onglet Recettes : tableau éditable --- */

/* Texte accessible aux lecteurs d'écran uniquement */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Liste en LECTURE : chaque ligne n'affiche que du texte ; ses contrôles
   de saisie restent dans le DOM (soumis avec « Enregistrer le mois »)
   mais sont masqués — toute la saisie passe par la fenêtre modale. */
.compta-recettes--liste tbody input,
.compta-recettes--liste tbody select {
    display: none;
}

.compta-recettes--liste th,
.compta-recettes--liste td {
    padding: 0.4rem 0.55rem;
    font-size: 0.85rem;
    white-space: nowrap;
}

/* Champs de saisie de la fenêtre modale (texte, date, nombre et listes).
   `input.compta-recette-input` pour primer sur la règle globale
   input[type="text"] (même spécificité, déclarée plus haut). */
input.compta-recette-input,
.compta-recette-select {
    width: 100%;
    padding: 0.45rem 0.6rem;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-size: 0.9rem;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}
input.compta-recette-input:focus,
.compta-recette-select:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Filet de sécurité pour les très petits écrans uniquement : à largeur
   de bureau, la liste (texte seul) tient sans barre horizontale */
.compta-table:has(> .compta-recettes--liste) {
    overflow-x: auto;
}

/* Colonne du bouton d'action (crayon) */
.compta-cellule-action {
    width: 44px;
    text-align: center;
    white-space: nowrap;
}

/* Bouton crayon : gabarit discret, dans l'esprit du × */
.compta-ligne-action {
    width: 28px;
    height: 28px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--color-muted);
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.compta-ligne-action svg {
    width: 15px;
    height: 15px;
    vertical-align: middle;
}
.compta-action-modifier:hover {
    color: var(--color-primary);
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
}

/* --- Onglet Tableau de bord --- */

/* Trois cartes de déclaration */
.tdb-declarations {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--gap);
    margin: 1rem 0 1.5rem;
}

/* (.tdb-carte et ses variantes sont supprimées : ces cartes de statistiques —
   avec leur barre d'accent bleue et leur valeur parfois colorée — passent
   désormais par la carte KPI unique .kpi.) */

/* Une carte KPI qui occupe toute la largeur de sa grille */
.kpi--large { grid-column: 1 / -1; }

/* Mention d'état sous un KPI (ex. badge de fiabilité du trimestre) */
.kpi-statut { margin-top: 0.25rem; }

/* Mini-tableaux TVA / URSSAF dans les cartes : montants alignés à droite */
.tdb-mini-table { width: 100%; margin: 0.4rem 0; }
.tdb-mini-table th,
.tdb-mini-table td {
    padding: 0.25rem 0.4rem;
    font-size: 0.85rem;
}
.tdb-mini-table th {
    font-weight: 600;
    color: var(--color-muted);
    text-align: left;
}
.tdb-mini-table .compta-cellule-nombre {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.tdb-mini-table tfoot td {
    font-weight: 700;
}
/* Filet de séparation au-dessus de la première ligne du pied seulement */
.tdb-mini-table tfoot tr:first-child td {
    border-top: 1px solid var(--color-border);
}

/* (La valeur « salaire » en bleu est supprimée : une valeur de KPI est sombre,
   et rouge seulement si elle est négative.) */

/* Jauge du plafond micro */
.tdb-jauge {
    margin: 0 0 1.5rem;
    padding: 1rem 1.2rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
}
.tdb-jauge-entete {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    font-size: 0.9rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
}
.tdb-jauge-piste {
    height: 14px;
    border-radius: 999px;
    background: var(--color-surface-2);
    overflow: hidden;
}
.tdb-jauge-remplissage {
    height: 100%;
    border-radius: 999px;
    background: var(--color-primary);
    transition: width 0.3s ease;
}
.tdb-jauge-remplissage.is-alerte { background: var(--color-error); }
.tdb-jauge-pied { margin-top: 0.4rem; font-size: 0.85rem; }

/* Mention secondaire dans l'en-tête d'une jauge (ex. « · plafond mensuel
   5 016 € ») : même traitement discret que sur l'accueil. */
.tdb-jauge-mention { font-weight: 400; }

/* .tdb-echeances a été retirée : les échéances ne sont plus un bloc autonome en
   pied d'onglet mais la 3e colonne de la grille (cf. .tdb-colonnes ci-dessous),
   qui porte elle-même son espacement. */

/* =====================================================================
   Onglet « Tableau de bord » de la Comptabilité — agencement pleine largeur
   ---------------------------------------------------------------------
   Mise en page calquée sur le tableau de bord principal : KPI en cartes,
   jauges, puis trois colonnes à en-tête « pastille d'icône + titre ». Les
   composants visuels (.compta-indicateur, .tdb-jauge, .accueil-grille,
   .accueil-bloc-entete, .accueil-pastille) sont RÉUTILISÉS tels quels ; on ne
   règle ici que ce qui est propre à cet agencement.
   ===================================================================== */

/* (.tdb-titre-ligne / .tdb-mois-nav retirées : le titre « Tableau de bord —
   Mois » et ses chevrons ont cédé la place au sélecteur de période unifié.) */

/* KPI de cet onglet : quatre colonnes sur écran large, avec les mêmes paliers
   de repli que la grille de l'accueil (2 colonnes puis 1). */
.tdb-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 1500px) {
    .tdb-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 1100px) {
    .tdb-kpis { grid-template-columns: 1fr; }
}

/* Les trois colonnes TVA / URSSAF / Échéances : hauteurs égalisées. C'est le
   comportement par défaut d'une grille (align-items: stretch), rendu explicite
   pour que l'intention soit lisible. */
.tdb-colonnes { align-items: stretch; }

/* Les cartes de colonne organisent leur contenu de haut en bas, le tableau
   occupant la place restante : les mentions de pied (total, échéance, badge)
   restent alignées d'une carte à l'autre. */
.tdb-colonnes > .card {
    display: flex;
    flex-direction: column;
}
.tdb-colonnes .tdb-mini-table { margin-bottom: auto; }

/* Mention sous l'en-tête d'une colonne (mois concerné, précision) */
.tdb-colonne-mention {
    margin: -0.25rem 0 0.5rem;
    font-size: 0.85rem;
}

/* --- Onglet Banque (lecture seule) --- */

/* Libellé bancaire tronqué (le détail complet est dans le title = memo) */
.compta-banque-libelle {
    max-width: 380px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Montants signés : crédits en vert, débits en rouge */
.compta-montant-positif { color: var(--color-success); }
.compta-montant-negatif { color: var(--color-error); }

/* Badge de nature d'un mouvement (teintes dérivées de la palette) */
.compta-badge {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
    background: var(--color-surface-2);
    color: var(--color-muted);
    border: 1px solid var(--color-border);
}
.compta-badge--recette {
    background: color-mix(in srgb, var(--color-success) 12%, transparent);
    color: var(--color-success);
    border-color: color-mix(in srgb, var(--color-success) 35%, transparent);
}
.compta-badge--frais-bancaire {
    background: var(--color-warning-soft);
    color: var(--color-warning);
    border-color: color-mix(in srgb, var(--color-warning) 35%, transparent);
}
.compta-badge--charge-sociale {
    background: color-mix(in srgb, var(--color-error) 10%, transparent);
    color: var(--color-error);
    border-color: color-mix(in srgb, var(--color-error) 30%, transparent);
}
.compta-badge--impot-cfe {
    background: var(--color-danger-bg);
    color: var(--color-danger-fg);
    border-color: color-mix(in srgb, var(--color-danger-fg) 25%, transparent);
}
.compta-badge--tva {
    background: var(--color-accent-soft);
    color: var(--color-primary);
    border-color: color-mix(in srgb, var(--color-primary) 35%, transparent);
}
.compta-badge--salaire {
    background: color-mix(in srgb, var(--color-primary-h) 12%, transparent);
    color: var(--color-primary-h);
    border-color: color-mix(in srgb, var(--color-primary-h) 35%, transparent);
}
/* Virement interne et Autre : style neutre par défaut de .compta-badge */

/* « à vérifier » : encaissement créé depuis la banque, non confirmé */
.compta-badge--avertir {
    background: var(--color-warning-soft);
    color: var(--color-warning);
    border-color: color-mix(in srgb, var(--color-warning) 35%, transparent);
}

/* --- Onglet Charges (lecture seule) --- */

/* PARTIE HAUTE — deux KPI « héros » puis la visualisation du ratio.
   (L'ancienne carte bilan — deux colonnes séparées d'un trait vertical,
   .charges-bilan / -colonne / -separateur — et sa bande grise de ratio
   .charges-bilan-ratio ont été retirées : la partie haute passe désormais par
   la carte KPI unique de l'application, plus deux barres comparables.) */

/* Les deux héros : DEUX COLONNES ÉGALES, pleine largeur. Elles se replient
   l'une sous l'autre sous 720px plutôt que d'écraser les montants. */
.charges-heros {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap);
    margin: 1rem 0 1rem;
}
@media (max-width: 720px) {
    .charges-heros { grid-template-columns: minmax(0, 1fr); }
}

/* Variante « héros » de la carte KPI : exactement le même objet (fond gris,
   libellé majuscule, valeur sombre) avec une valeur agrandie et un peu plus
   d'air, pour marquer que ces deux chiffres dominent la page. Rien d'autre
   n'est redéfini : la carte reste la .kpi de App\Lib\Kpi. */
.kpi--hero { padding: 1.15rem 1.3rem; }
.kpi--hero .kpi-valeur { font-size: 29px; }

/* ----- Ratio charges / net : deux barres horizontales -----
   Le NET sert de référence à 100 % ; les CHARGES occupent la fraction
   correspondante, largeur posée en style inline par la vue depuis les valeurs
   réelles. Deux teintes seulement, et surtout PAS de rouge : des charges
   payées ne sont pas une anomalie, juste une grandeur à comparer.
   Les deux couleurs sont déclarées ICI (portée locale au composant), pas dans
   la palette globale : le bleu reprend la variable de marque existante, le gris
   neutre est propre à cette visualisation. */
.charges-ratio {
    --charges-barre-net:     var(--nav-marque); /* #00aaef — bleu de marque */
    --charges-barre-charges: #b4b2a9;           /* gris neutre, volontairement pas rouge */
    margin: 0 0 1.5rem;
}

/* Entête : intitulé à gauche, chiffres du ratio à droite, sur une seule ligne
   qui se replie si la place manque. */
.charges-ratio-entete {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.3rem 1rem;
    margin-bottom: 0.6rem;
}
.charges-ratio-titre {
    font-size: 0.9rem;
    font-weight: 600;
}
.charges-ratio-valeur {
    font-size: 0.85rem;
    color: var(--color-muted);
}
.charges-ratio-valeur strong {
    color: var(--kpi-valeur);
    font-variant-numeric: tabular-nums;
}
.charges-ratio-point { margin: 0 0.15rem; }

.charges-ratio-barres {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Une ligne = libellé (largeur fixe) | rail extensible | montant (aligné à
   droite). Les deux rails partagent donc exactement la même largeur : c'est ce
   qui rend les deux barres comparables d'un coup d'œil. */
.charges-barre {
    display: grid;
    grid-template-columns: 6.5rem 1fr auto;
    align-items: center;
    gap: 0.75rem;
}
.charges-barre-label {
    font-size: 0.85rem;
    color: var(--color-muted);
}
.charges-barre-rail {
    height: 14px;
    border-radius: 999px;
    background: var(--color-surface-2);
    overflow: hidden;
}
.charges-barre-jauge {
    display: block;
    height: 100%;
    border-radius: 999px;
    transition: width 0.3s ease;
}
.charges-barre-jauge--net     { background: var(--charges-barre-net); }
.charges-barre-jauge--charges { background: var(--charges-barre-charges); }
.charges-barre-montant {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--kpi-valeur);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Écran étroit : le libellé passe au-dessus de son rail plutôt que de rogner
   la barre à quelques pixels. */
@media (max-width: 560px) {
    .charges-barre {
        grid-template-columns: 1fr auto;
        gap: 0.25rem 0.75rem;
    }
    .charges-barre-label  { grid-column: 1 / -1; }
    .charges-barre-rail   { grid-column: 1; }
    .charges-barre-montant { grid-column: 2; }
}

/* (Le chevron inerte de bout de plage n'a plus lieu d'être : le sélecteur de
   période liste directement les années, sans chevrons.) */

/* En-tête de colonnes du détail des paiements (table .compta-postes) */
.compta-charges-detail thead th {
    padding: 0.45rem 1rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-align: left;
    color: var(--color-muted);
    border-bottom: 1px solid var(--color-border);
}
.compta-charges-detail thead th.compta-cellule-nombre { text-align: right; }

/* --- Onglet Recettes : panneau « Sources de revenu » (repliable) --- */

.compta-sources,
.compta-import {
    margin-top: var(--gap);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
}

.compta-sources > summary,
.compta-import > summary {
    padding: 0.65rem 1rem;
    font-weight: 600;
    color: var(--color-text);
    cursor: pointer;
    user-select: none;
    list-style: none;
}
.compta-sources > summary::-webkit-details-marker,
.compta-import > summary::-webkit-details-marker { display: none; }
.compta-sources > summary::marker,
.compta-import > summary::marker { content: ""; }
.compta-sources > summary::after,
.compta-import > summary::after {
    content: "\203A"; /* › */
    float: right;
    color: var(--color-muted);
    transition: transform 0.2s ease;
    transform: rotate(90deg);
}
.compta-sources[open] > summary::after,
.compta-import[open] > summary::after { transform: rotate(-90deg); }
.compta-sources[open] > summary,
.compta-import[open] > summary { border-bottom: 1px solid var(--color-border); }

/* Formulaire d'import OFX (onglet Banque) */
.compta-import-form {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.75rem 1rem 1rem;
}
.compta-import-aide { margin: 0; font-size: 0.85rem; }
.compta-import-champs {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.compta-sources-table { width: 100%; }

/* Colonne du code abrégé (badge bancaire « Recette : XX ») */
.compta-sources-abrege {
    width: 90px;
}
.compta-sources-abrege .compta-libelle-input {
    text-transform: uppercase;
}

.compta-sources-actif {
    width: 80px;
    white-space: nowrap;
}
.compta-source-actif {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    color: var(--color-muted);
    cursor: pointer;
}

.compta-sources-nb {
    width: 140px;
    font-size: 0.8rem;
    text-align: right;
    white-space: nowrap;
}

/* Zone d'ajout d'une source : champ + bouton sur une ligne */
.compta-sources-ajout {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 1rem;
    border-top: 1px solid var(--color-border);
}
.compta-sources-ajout input {
    max-width: 240px;
    padding: 0.45rem 0.6rem;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-size: 0.9rem;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.compta-sources-ajout input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.compta-sources-actions {
    padding: 0 1rem 1rem;
    margin-top: 0.5rem;
}

/* --- Onglet Recettes : fenêtre modale de saisie --- */

.compta-modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.compta-modal[hidden] { display: none; }

/* Fond assombri, dérivé de la palette */
.compta-modal-fond {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, var(--color-text) 45%, transparent);
}

.compta-modal-carte {
    position: relative;
    width: 100%;
    max-width: 560px;
    max-height: 90vh;
    overflow-y: auto;
    padding: 1.25rem 1.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

.compta-modal-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}
.compta-modal-entete h3 { margin: 0; }
.compta-modal-croix { font-size: 1.25rem; }

.compta-modal-erreur { margin: 0 0 0.9rem; }

/* Champs en deux colonnes */
.compta-modal-grille {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem 1rem;
}

/* Bandeau d'aperçu : HT / TVA / prélèvements / net */
.compta-modal-apercu {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.5rem;
    margin: 1rem 0;
    padding: 0.75rem 1rem;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.compta-modal-apercu-item {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.compta-modal-apercu-item span {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-muted);
}
.compta-modal-apercu-item strong {
    font-size: 0.95rem;
    color: var(--color-text);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.compta-modal-apercu-item--net strong { color: var(--color-primary); }

/* Pied : Supprimer à gauche, Annuler / Valider à droite, séparé du contenu */
.compta-modal-pied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}
.compta-modal-pied-droite {
    display: flex;
    gap: 0.5rem;
    margin-left: auto;
}
.compta-modal-supprimer { color: var(--color-error); }
.compta-modal-supprimer:hover {
    color: var(--color-error);
    border-color: var(--color-error);
    background: var(--color-danger-bg);
}

/* Rappel lecture seule du mouvement bancaire corrigé (modal Banque) */
.compta-modal-mouvement {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-bottom: 1rem;
    padding: 0.6rem 0.9rem;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.9rem;
}
.compta-modal-mouvement .muted { font-size: 0.8rem; }
.compta-modal-montant {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Grille du modal : champ pleine largeur et case à cocher en ligne */
.compta-modal-pleine { grid-column: 1 / -1; }
.compta-modal-case {
    flex-direction: row;
    align-items: center;
    gap: 0.45rem;
    color: var(--color-muted);
    cursor: pointer;
}

@media (max-width: 600px) {
    .compta-modal-grille { grid-template-columns: 1fr; }
    .compta-modal-apercu { grid-template-columns: 1fr 1fr; }
}

/* Sélecteur année + mois (pastilles, même style que .compta-tab) */
.compta-nav {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    margin: 0.5rem 0;
}

/* .compta-annees sert encore aux commandes d'analyse de l'onglet Historique
   (vue d'ensemble / par année, série affichée). .compta-mois-ligne a disparu
   avec la navigation par chevrons. */
.compta-annees {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
}

.compta-pastille {
    padding: 0.35rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.85rem;
    color: var(--color-muted);
    background: var(--color-surface);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
a.compta-pastille:hover {
    color: var(--color-primary);
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
    text-decoration: none;
}
.compta-pastille.is-active {
    color: var(--color-primary);
    background: var(--color-accent-soft);
    border-color: var(--color-primary);
    font-weight: 600;
}
.compta-pastille.is-vide {
    color: var(--color-muted);
    opacity: 0.55;
    cursor: default;
}

/* --- Onglet Historique (graphiques en barres pur CSS) --- */

.compta-graph {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 0.6rem;
    min-height: 300px;
    padding: 1rem 0.75rem 0.5rem;
    margin: 1rem 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    overflow-x: auto;
}

/* Chaque période occupe une part égale de la largeur, barre centrée */
.compta-graph-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 0.25rem;
    flex: 1 1 0;
    min-width: 0;
}

.compta-graph-valeur {
    font-size: 0.75rem;
    color: var(--color-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.compta-graph-label {
    font-size: 0.75rem;
    color: var(--color-muted);
    white-space: nowrap;
}

.compta-graph-barre {
    width: 62%;
    max-width: 56px;
    min-width: 14px;
    min-height: 2px;
    background: var(--color-primary);
    border-radius: 4px 4px 0 0;
}

/* Variante « Net » : même bleu, nuance plus claire */
.compta-graph-barre--net { opacity: 0.45; }

/* Année en cours : barre en pointillés, plus claire */
.compta-graph-barre.is-en-cours {
    background: var(--color-accent-soft);
    border: 1px dashed var(--color-primary);
}

/* Graphique groupé (2 barres par période) */
.compta-graph-groupe {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 2px;
    width: 100%;
}
.compta-graph--groupe .compta-graph-barre {
    width: 34%;
    max-width: 28px;
    min-width: 8px;
}

/* Légende du graphique */
.compta-legende {
    display: flex;
    justify-content: center;
    gap: 1.25rem;
    margin: 0.5rem 0;
    font-size: 0.85rem;
    color: var(--color-muted);
}

.compta-legende-carre {
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-right: 0.35rem;
    vertical-align: -1px;
    border-radius: 3px;
    background: var(--color-primary);
}
.compta-legende-carre--net { opacity: 0.45; }

/* Mention « en cours » dans le tableau de synthèse */
.compta-mention-encours {
    margin-left: 0.4rem;
    font-size: 0.75rem;
    font-style: italic;
    color: var(--color-muted);
}

/* Graphique + cartes KPI côte à côte (les deux vues de l'Historique) */
.compta-graphkpi {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: var(--gap);
    margin: 0.5rem 0 1rem;
}

/* Barre d'outils de l'Historique : mode à gauche, série à droite */
.compta-barre {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--gap);
    margin: 0.75rem 0 0.25rem;
}

.compta-barre .compta-nav { margin: 0; }

/* Ligne de sélection d'année de l'Historique (vue « Par année »), posée juste
   sous la barre d'outils : on lui rend la respiration verticale qu'avait la
   rangée de pastilles qu'elle remplace (.compta-nav, marge 0.5rem). */
.compta-barre + .periode--souligne { margin: 0.5rem 0; }

/* Rangée des pastilles d'années : alignée à gauche, pleine largeur */
.compta-annees--gauche {
    justify-content: flex-start;
    width: 100%;
}

.compta-graphkpi .compta-graph {
    flex: 1 1 320px;
    margin: 0;
}

.compta-kpi {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    flex: 0 0 210px;
}

/* Colonne de KPI de l'Historique : cartes un peu resserrées, la place étant
   partagée avec le graphique. Le STYLE reste celui de la carte unique. */
.compta-kpi .kpi { padding: 0.7rem 0.9rem; }
.compta-kpi .kpi-valeur { font-size: 1.15rem; }

@media (max-width: 900px) {
    .compta-kpi { flex: 1 1 100%; }
}

/* Champ montant (input number, non couvert par les styles génériques) */
.compta-montant {
    width: 140px;
    padding: 0.45rem 0.6rem;
    text-align: right;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-size: 0.95rem;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.compta-montant:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Montants à zéro grisés (classe maintenue en direct par le JS) */
.compta-montant.is-zero { color: var(--color-muted); }

.compta-taux {
    max-width: 280px;
    margin: 0.5rem 0 1rem;
}
.compta-taux .compta-montant { text-align: left; }

.compta-actions { margin-top: 1rem; }

/* =====================================================================
   Module Exercices (.exo-*) — cartes à plat, barre d'accent, jauges
   ===================================================================== */

/* ----- Carte de tête du module Exercices -----
   En-tête de navigation pleine largeur (semaine puis jour), séparé du contenu
   par un filet fin ; puis trois colonnes : le graphique « Pas », et deux
   colonnes de quatre KPI empilés. (.exo-kpi et ses parties ont été supprimées :
   les KPI passent par la carte unique .kpi ; seules les grilles restent propres
   à chaque page.) */
/* align-items: stretch (défaut) : les trois colonnes font la hauteur de la plus
   haute — celle des KPI empilés — ce qui permet au graphique de s'étirer. */
.exo-tete-grille {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--gap);
    margin-top: 1rem;
}
/* Colonnes de KPI : empilement vertical, calé en haut. */
.exo-kpi-colonne {
    display: grid;
    gap: var(--gap);
    align-content: start;
    min-width: 0;
}
/* Le graphique remplit toute la hauteur de la rangée : la colonne, puis le
   composant, puis la zone de tracé sont des boîtes flex qui se transmettent la
   hauteur disponible. La zone de barres absorbe le reste (flex: 1), si bien que
   le bas des barres s'aligne sur le bas du dernier KPI. Les barres sont
   dimensionnées en POURCENTAGE de cette zone : elles se remettent simplement à
   l'échelle, leurs proportions et leur calcul PHP sont inchangés. Les initiales
   de jours et les valeurs restent sous la zone, à leur hauteur naturelle. */
.exo-tete-graph {
    min-width: 0;
    display: flex;
}
.exo-tete-graph .sport-graph {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
    margin-top: 0;
}
.exo-tete-graph .sport-graph-zone {
    height: auto;      /* remplace la hauteur fixe du composant partagé */
    flex: 1;
    min-height: 180px; /* plancher = hauteur d'origine */
}

/* Repli : le graphique passe en pleine largeur au-dessus des deux colonnes de
   KPI, puis tout s'empile sur écran étroit. */
@media (max-width: 1400px) {
    .exo-tete-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .exo-tete-graph { grid-column: 1 / -1; }
}
@media (max-width: 820px) {
    .exo-tete-grille { grid-template-columns: minmax(0, 1fr); }
    .exo-tete-graph { grid-column: auto; }
}

/* Navigateur de jour */
.exo-nav-jour {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}
.exo-nav-lien {
    padding: 0.35rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.9rem;
    color: var(--color-muted);
    white-space: nowrap;
}
.exo-nav-lien:hover {
    color: var(--color-primary);
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
    text-decoration: none;
}
.exo-jour-courant {
    font-size: 1.05rem;
    font-weight: 600;
    text-align: center;
    flex: 1;
}

/* Grille de cartes */
.exo-cartes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--gap);
    margin: 1rem 0;
}

/* ----- « Objectifs du jour » et « Séances » côte à côte -----
   Deux colonnes de largeur égale, chacune gardant sa propre carte. Les cartes
   sont étirées à la même hauteur (align-items: stretch par défaut). */
.exo-duo {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap);
}
.exo-duo > .card { min-width: 0; }

/* Objectifs : trois colonnes internes, cartes à hauteur égale (le bouton de
   chacune est plaqué en bas, cf. .exo-carte > .btn). */
.exo-cartes--objectifs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: stretch;
}
/* Séances : les deux tuiles de récapitulatif côte à côte. */
.exo-cartes--seances { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Formulaire d'ajout de séance : champs alignés sur trois colonnes égales, le
   bouton sur toute la largeur en dessous. Variante propre à cette section — le
   .exo-form-inline générique (Activités, module Gains) n'est pas touché. */
/* Double classe : .exo-form-inline est déclarée plus bas dans la feuille, il
   faut donc une spécificité supérieure pour que la grille l'emporte sur son
   display: flex — sans quoi la variante serait sans effet. */
.exo-form-inline.exo-form-seance {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: end;
    gap: 0.75rem 1rem;
}
.exo-form-inline.exo-form-seance .field { min-width: 0; }
.exo-form-inline.exo-form-seance > .btn { grid-column: 1 / -1; }

/* ----- « Dernières séances » : bloc repliable natif, fermé par défaut ----- */
.exo-dernieres { margin-top: 1.25rem; }
.exo-dernieres-tete {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0;
    cursor: pointer;
    font-weight: 600;
    list-style: none; /* pas de triangle natif */
}
.exo-dernieres-tete::-webkit-details-marker { display: none; }
.exo-dernieres-tete:hover { color: var(--color-primary); }
.exo-dernieres-titre { flex: 1; min-width: 0; }
/* Compteur de séances, à droite du libellé */
.exo-dernieres-nb {
    font-size: 0.85rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--color-muted);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
}
.exo-dernieres-chevron {
    display: inline-flex;
    flex-shrink: 0;
    color: var(--color-muted);
    transition: transform 0.15s;
}
.exo-dernieres-chevron svg { width: 18px; height: 18px; display: block; }
.exo-dernieres[open] .exo-dernieres-chevron { transform: rotate(180deg); }

/* Replis : les deux sections passent l'une sous l'autre, puis les cartes
   d'objectifs et le formulaire de séance se réorganisent. */
@media (max-width: 1400px) {
    .exo-duo { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 900px) {
    .exo-cartes--objectifs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .exo-form-inline.exo-form-seance { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
    .exo-cartes--objectifs,
    .exo-cartes--seances,
    .exo-form-inline.exo-form-seance { grid-template-columns: minmax(0, 1fr); }
}

/* Carte d'objectif / tuile de séance : bordure fine sur les QUATRE côtés et
   coins arrondis, comme partout ailleurs dans l'application. Plus de liseré
   bleu latéral (l'ancien border-left de 4px en --color-primary est retiré). */
.exo-carte {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem 1.1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
/* Le bouton d'enregistrement est plaqué en bas : les cartes d'une même rangée
   étant à hauteur égale, leurs boutons s'alignent. */
.exo-carte > .btn { margin-top: auto; }

.exo-carte-tete {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}
.exo-carte-icone {
    display: inline-flex;
    align-items: center;
    color: var(--color-muted);
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}
.exo-carte-nom { font-weight: 600; }

.exo-valeur { font-size: 0.95rem; color: var(--color-muted); }
.exo-valeur .exo-total {
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--color-text);
    font-variant-numeric: tabular-nums;
}

/* Jauge de progression */
.exo-jauge {
    height: 8px;
    border-radius: 999px;
    background: var(--color-surface-2);
    overflow: hidden;
}
.exo-jauge-barre {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: var(--color-primary); /* bleu : objectif non atteint */
    transition: width 0.25s ease, background 0.25s ease;
}
.exo-jauge-barre--atteint { background: var(--color-success); } /* vert : atteint */

/* Saisies des objectifs / variantes */
.exo-variantes {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.exo-variante-ligne {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}
.exo-variante-nom { font-size: 0.9rem; color: var(--color-muted); }
.exo-variante-ligne .exo-input { max-width: 110px; }

/* Champs (couvre number/date/select, non couverts par le style global) */
.exo-input {
    width: 100%;
    padding: 0.5rem 0.6rem;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-size: 0.95rem;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.exo-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Ligne de série */
.exo-serie {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    color: var(--color-muted);
}
.exo-serie-icone {
    display: inline-flex;
    align-items: center;
    color: var(--color-primary);
    width: 20px;
    height: 20px;
}
.exo-serie strong { color: var(--color-text); }

/* Formulaires en ligne (ajout de séance / d'activité) */
.exo-form-inline {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin: 0.75rem 0 1rem;
}
.exo-form-inline .field { min-width: 150px; }
.exo-champs-quotidien {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
}

/* Liste des dernières séances */
.exo-liste-seances {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
}
.exo-seance-ligne {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--color-border);
}
.exo-seance-infos {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.exo-seance-date { color: var(--color-muted); font-size: 0.9rem; min-width: 90px; }
.exo-seance-nom { font-weight: 600; }
.exo-seance-duree { color: var(--color-text); font-variant-numeric: tabular-nums; }

.exo-actions { display: flex; align-items: center; gap: 0.3rem; }
.exo-form-suppr { margin: 0; }
.exo-lien-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--color-muted);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.exo-lien-action svg { width: 16px; height: 16px; }
.exo-lien-action:hover {
    color: var(--color-primary);
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
}
.exo-lien-action--suppr:hover { color: var(--color-error); }

/* Mini-formulaire de modification de séance (révélé en JS) */
.exo-modif-form {
    display: none;
    flex-basis: 100%;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin-top: 0.5rem;
    padding: 0.75rem;
    background: var(--color-surface-2);
    border-radius: var(--radius);
}
.exo-modif-form.is-open { display: flex; }

/* Liste des activités + badges */
.exo-activites-liste {
    list-style: none;
    margin: 0.5rem 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.exo-activite-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--color-border);
}
.exo-activite-nom { font-weight: 600; }
.exo-badge {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    background: var(--color-accent-soft);
    color: var(--color-primary);
    border: 1px solid color-mix(in srgb, var(--color-primary) 35%, transparent);
    white-space: nowrap;
}
.exo-badge--seance {
    background: var(--color-surface-2);
    color: var(--color-muted);
    border-color: var(--color-border);
}

/* =====================================================================
   Tableau de bord d'accueil (.accueil-*) — cockpit Finances + Exercices
   Cartes KPI sobres calquées sur .compta-indicateur ; jauges réutilisées
   depuis .exo-jauge.
   ===================================================================== */

/* En-tête de bloc : titre + lien vers le module */
/* Grille du tableau de bord : trois colonnes égales dans la largeur de contenu
   existante (paliers responsives ci-dessous). minmax(0, 1fr) empêche tout
   débordement des graphiques/tableaux internes ; min-width: 0 sur les cartes
   permet à leur contenu de se réduire. */
.accueil-grille {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--gap);
}
.accueil-grille > .card { min-width: 0; }
.accueil-grille > .card > * { max-width: 100%; }

/* Palier intermédiaire : deux colonnes entre ~1100px et ~1500px */
@media (max-width: 1500px) {
    .accueil-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Repli une colonne sur écran étroit / portable */
@media (max-width: 1100px) {
    .accueil-grille { grid-template-columns: 1fr; }
}

/* ---- Rangée basse du tableau de bord : Alimentation sur 2 colonnes ----
   Reprend la grille à 3 colonnes ci-dessus (donc colonnes alignées avec la
   rangée du dessus) : le bloc Alimentation occupe les DEUX premières colonnes,
   la 3e reste libre. Plus aucun lien avec le décor de fond de l'application,
   qui est un calque fixe hors flux (cf. .app-deco) : la mise en page du bloc
   est entièrement autonome — hauteur, largeur, replis. */
.accueil-grille-bas > .accueil-alim-bloc { grid-column: span 2; }

/* Sous 1500px la rangée basse repasse sur une seule colonne : Alimentation
   reprend toute la largeur disponible. */
@media (max-width: 1500px) {
    .accueil-grille-bas { grid-template-columns: minmax(0, 1fr); }
    .accueil-grille-bas > .accueil-alim-bloc { grid-column: auto; }
}

.accueil-bloc-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}
.accueil-bloc-entete h2 { margin: 0; }
.accueil-bloc-lien {
    font-size: 0.9rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Pastille ronde + titre, groupés à gauche de l'en-tête (le lien reste à droite) */
.accueil-entete-titre {
    display: flex;
    align-items: center;
    gap: 12px;
}
.accueil-pastille {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--color-surface);
    border: 1.5px solid var(--color-gris-moyen);
    color: var(--color-gris-moyen); /* l'icône hérite via currentColor */
}
.accueil-pastille svg {
    width: 20px;
    height: 20px;
}

/* Grille de cartes KPI (identique aux indicateurs de la comptabilité) */
.accueil-kpis {
    display: grid;
    /* Une seule colonne : les KPI sont empilés, une carte (aplatie) par ligne.
       Ce format compact reste valable en demi-largeur comme en pleine largeur
       (repli responsive), sans multi-colonnes. */
    grid-template-columns: 1fr;
    gap: var(--gap);
    margin: 0.5rem 0 1rem;
}
/* (.accueil-kpi et ses parties sont supprimées, variante bleutée « accent »
   comprise : les KPI de l'accueil passent par la carte KPI unique .kpi, comme
   partout ailleurs. Seule la grille .accueil-kpis subsiste.) */

/* Ligne « Prochaine échéance » */
.accueil-echeance {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
    color: var(--color-muted);
}
.accueil-echeance strong { color: var(--color-text); }
.accueil-echeance-icone {
    display: inline-flex;
    align-items: center;
    color: var(--color-muted);
    width: 18px;
    height: 18px;
}

/* Sous-titres « Aujourd'hui » / « Cette année » + série à côté.
   min-height : la boîte occupe une hauteur FERME (l'espace réservé moins sa
   marge haute), pour que les cartes sans sous-titre puissent réserver
   exactement la même place et garder les graphiques alignés. */
.accueil-sous-titre {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.5rem;
    min-height: calc(var(--accueil-sous-titre-espace, 2.5rem) - 0.5rem);
}
.accueil-sous-titre h3 { margin: 0; }

/* Jauge du plafond micro sur l'accueil : réutilise .tdb-jauge*, simple
   espacement au-dessus (classes de couleur héritées de la compta) */
.accueil-plafond { margin-top: 1rem; }

/* Bloc Plafond autonome (pleine largeur, en tête de page) : la jauge remplit la
   carte sans marge superflue. */
.accueil-plafond-bloc .accueil-plafond { margin: 0; }
.accueil-plafond-mention { font-weight: 400; }

/* ---- Bloc Alimentation (rangée basse, 2 colonnes) : 3 anneaux + top 5 ----
   Le contenu se répartit en DEUX MOITIÉS ÉGALES (1fr / 1fr) pour remplir toute
   la largeur des deux colonnes du bloc : à gauche les trois anneaux d'équilibre,
   à droite le top 5 qui s'étale sur toute sa moitié. Les deux moitiés sont
   séparées par une gouttière et un filet fin, et alignées en haut. */
.alim-tbd-grille {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.5rem;
    align-items: start;
    margin-top: 0.5rem;
}
/* Moitié gauche : les trois anneaux côte à côte, à parts égales, chacun centré
   dans son tiers — ils occupent donc toute la largeur de la moitié. */
.alim-tbd-anneaux {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
    gap: 0.5rem;
}
.alim-tbd-col { padding: 0.75rem 1.25rem; }
/* Filet unique entre la zone des anneaux et celle du top 5 */
.alim-tbd-top { border-left: 1px solid var(--color-border); }

/* Colonnes d'anneaux : donut centré + libellé dessous. Marges latérales
   resserrées : chaque anneau se centre dans son tiers de moitié, les trois se
   répartissent donc régulièrement sur toute la largeur de la moitié gauche. */
.alim-tbd-col--anneau {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
}
.alim-anneau-wrap {
    position: relative;
    width: 100px;
    height: 100px;
}
.alim-anneau { width: 100px; height: 100px; display: block; }
/* Donut fait main : piste (fond) + arc (valeur), tracés en SVG, aucune lib.
   Le viewBox fait 100 × 100 et le SVG est rendu à 100px : une unité = un pixel,
   l'épaisseur ci-dessous est donc bien de 12px à l'écran. Rayon des cercles :
   44 (cf. dashboard.php), pour que l'anneau affleure le bord sans être rogné. */
.alim-anneau-track,
.alim-anneau-val {
    fill: none;
    stroke-width: 12;
}
.alim-anneau-track { stroke: var(--color-border); }
.alim-anneau-val { stroke-linecap: round; }
.alim-anneau--haut  { stroke: var(--color-qualite-haut); }
.alim-anneau--moyen { stroke: var(--color-qualite-moyen); }
.alim-anneau--bas   { stroke: var(--color-qualite-bas); }
/* Valeur au centre (superposée au SVG) : taille remontée pour rester
   proportionnée au donut de 100px et à son anneau de 12px. */
.alim-anneau-valeur {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 1.35rem;
    font-variant-numeric: tabular-nums;
    color: var(--color-text);
}
.alim-anneau-valeur.is-neutre { color: var(--color-muted); }
.alim-anneau-legende {
    font-weight: 600;
    color: var(--color-muted);
}

/* Colonne « Le plus mangé » */
.alim-tbd-top { display: flex; flex-direction: column; }
.alim-tbd-top-titre {
    display: block;
    font-weight: 600;
    color: var(--color-muted);
    font-size: 0.9rem;
    margin-bottom: 0.6rem;
}
.alim-tbd-vide { margin: 0.25rem 0 0; }
.alim-top-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}
.alim-top-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 4rem 2.8rem;
    align-items: center;
    gap: 0.5rem;
}
.alim-top-nom {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 0.92rem;
}
.alim-top-barre {
    height: 6px;
    border-radius: 999px;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    overflow: hidden;
}
.alim-top-barre-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--color-primary);
}
/* Ligne d'accessoire (Rapport) : barre en gris neutre (nature distincte). */
.alim-top-item--accessoire .alim-top-barre-fill { background: var(--color-accessoire); }
.alim-top-pct {
    font-variant-numeric: tabular-nums;
    color: var(--color-muted);
    text-align: right;
    font-size: 0.9rem;
}

/* Tableau de bord : « Le plus mangé » s'étale sur toute sa moitié de bloc. Le
   gabarit par défaut fige la barre à 4rem, ce qui tassait la liste à gauche en
   laissant du vide ; ici le nom est borné, la barre absorbe TOUT l'espace
   restant de la moitié et le pourcentage garde une colonne fixe. Portée limitée
   au tableau de bord : le module Alimentation conserve son gabarit compact. */
.accueil-alim-bloc .alim-top-item {
    grid-template-columns: minmax(6rem, 10rem) minmax(0, 1fr) 3rem;
    gap: 0.9rem;
}
.accueil-alim-bloc .alim-top-liste { gap: 0.6rem; }
.accueil-alim-bloc .alim-top-barre { height: 8px; }
/* La zone du top 5 occupe toute la place laissée par les anneaux */
.accueil-alim-bloc .alim-tbd-top { padding-right: 0.25rem; }

/* ----- Onglet « Rapport » : fréquence des ingrédients (lecture seule) ----- */
.alim-rapport-horizons { margin-top: 1rem; }
.alim-rapport-base { margin: 0.5rem 0 0.25rem; font-size: 0.9rem; }
.alim-rapport-vide { margin: 1rem 0 0; }

/* Bascule liste / par rubrique, alignée à droite */
.alim-rapport-vues {
    display: flex;
    justify-content: flex-end;
    margin: 0.5rem 0 0.75rem;
}

/* Liste de fréquences : barre neutre large (réutilise .alim-top-*), pleine
   largeur — nom flexible, barre extensible, pourcentage fixe. */
.alim-rapport-liste .alim-top-item {
    grid-template-columns: minmax(6rem, 14rem) 1fr 3rem;
}

/* Vue par rubrique : un bloc par groupe (badge + nombre, puis la liste) */
.alim-rapport-groupe { margin: 0 0 1.1rem; }
/* Section « Accessoires » (bas des deux vues) : filet de séparation au-dessus
   pour marquer sa mise à l'écart du classement principal. */
.alim-rapport-accessoires {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}
.alim-rapport-groupe-tete {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.alim-rapport-groupe-nb {
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

/* Repli sur écran étroit : plus de moitiés côte à côte — les anneaux au-dessus,
   le top 5 en dessous, séparés par un filet horizontal (le filet vertical n'a
   plus lieu d'être) ; la gouttière devient l'écart entre les deux rangées. */
@media (max-width: 820px) {
    .alim-tbd-grille {
        grid-template-columns: minmax(0, 1fr);
        gap: 1rem;
    }
    .alim-tbd-top {
        border-left: none;
        border-top: 1px solid var(--color-border);
        padding-top: 1.25rem;
        margin-top: 0;
    }
}

/* Très petit écran : anneaux réduits pour que les trois tiennent sur la ligne
   (portée limitée au tableau de bord, le module Alimentation n'est pas touché). */
@media (max-width: 480px) {
    .alim-tbd-col { padding: 0.75rem 0.35rem; }
    .accueil-alim-bloc .alim-anneau-wrap,
    .accueil-alim-bloc .alim-anneau { width: 72px; height: 72px; }
    .accueil-alim-bloc .alim-anneau-valeur { font-size: 0.95rem; }
}

/* Colonnes alignées (Finances / Lano) : carte en colonne flex ; le graphique
   (et les KPI qui suivent) sont poussés vers le bas → les deux graphiques au
   même niveau et les trois KPI qui se répondent ligne par ligne. La hauteur des
   deux cellules est égalisée par la grille (align-items: stretch par défaut). */
.accueil-bloc {
    display: flex;
    flex-direction: column;
    /* Espace qu'occupe un sous-titre intermédiaire (« Cette année ») entre le
       graphique et les KPI, sa marge haute comprise. UNE seule valeur, utilisée
       à deux endroits : elle fixe la boîte du sous-titre là où il existe, et
       réserve exactement le même espace dans les cartes qui n'en ont pas. C'est
       ce qui garantit que les trois graphiques se terminent au même niveau
       (axes des mois alignés), sans dépendre des métriques de police. */
    --accueil-sous-titre-espace: 2.5rem;
}
.accueil-bloc .sport-graph { margin-top: auto; }

/* Cartes SANS sous-titre (Finances, Lano) : on réserve au-dessus des KPI la
   place que « Cette année » occupe dans la carte Exercices. */
.accueil-bloc .accueil-kpis {
    margin-top: calc(0.5rem + var(--accueil-sous-titre-espace));
}
/* Carte AVEC sous-titre (Exercices) : celui-ci occupe déjà cette place, les KPI
   retrouvent donc leur marge normale. Règle placée après la précédente : à
   spécificité égale, c'est elle qui s'applique. */
.accueil-sous-titre + .accueil-kpis { margin-top: 0.5rem; }

/* Graphique sport (100 % CSS), partagé accueil (annuel) + module (semaine) :
   barres = pas, ronds = pompes normales, carrés = minutes ; trois échelles
   indépendantes. Hauteurs/positions calculées en PHP (styles inline). */
.sport-graph { margin: 0.5rem 0 1.25rem; }

/* Ligne de lecture (survol, accueil) */
.sport-graph-lecture {
    min-height: 1.3rem;
    margin-bottom: 0.4rem;
    font-size: 0.85rem;
    color: var(--color-text);
}

.sport-graph-legende {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    /* Marge basse élargie : aère l'espace légende ↔ zone pour que les
       étiquettes de valeur au-dessus des barres ne touchent plus la légende */
    margin-bottom: 0.9rem;
    font-size: 0.85rem;
    color: var(--color-muted);
}
.sport-graph-leg { display: inline-flex; align-items: center; gap: 0.4rem; }
.sport-graph-leg-barre {
    width: 12px;
    height: 12px;
    border-radius: 2px;
    background: var(--color-primary);
}
/* Zone : colonnes égales, axes discrets en bas et à gauche */
.sport-graph-zone {
    display: flex;
    align-items: flex-end;
    height: 180px;
    padding: 0 0.25rem;
    border-left: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}
.sport-graph-col {
    position: relative;
    flex: 1;
    height: 100%;
}

/* Barre (pas) ancrée en bas, centrée dans la colonne : large et pleine */
.sport-graph-barre {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    width: 80%;
    background: var(--color-primary);
    border-radius: 2px 2px 0 0;
}

/* Valeur des pas affichée en permanence au-dessus de la barre (accueil) */
.sport-graph-pas {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    padding-bottom: 2px;
    font-size: 0.62rem;
    color: var(--color-muted);
    white-space: nowrap;
}

/* Étiquettes (mois ou jours) alignées sur les colonnes */
.sport-graph-labels {
    display: flex;
    padding: 0 0.25rem;
    margin-top: 0.3rem;
}
.sport-graph-label {
    flex: 1;
    text-align: center;
    font-size: 0.7rem;
    color: var(--color-muted);
}

/* Chiffres permanents sous chaque colonne (version hebdomadaire) */
.sport-graph-chiffres {
    display: flex;
    padding: 0 0.25rem;
    margin-top: 0.15rem;
}
.sport-graph-valeurs {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.05rem;
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
}
.sport-graph-val--pas { color: var(--color-primary); }
.sport-graph-val--pomp { color: var(--color-success); }
.sport-graph-val--min { color: var(--color-graph-minutes); }

.sport-graph-note { font-size: 0.8rem; margin-top: 0.4rem; }

/* =====================================================================
   Module Alimentation (.alim-*) — catalogue d'ingrédients
   Couleurs issues uniquement des variables :root (aucune valeur en dur).
   ===================================================================== */

/* Liste des ingrédients */
.alim-liste {
    list-style: none;
    margin: 0.5rem 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
/* Liste des ingrédients actifs sur TROIS colonnes : la grille remplit de gauche
   à droite puis passe à la ligne, l'ordre de tri du serveur (rubrique puis
   alphabétique) est donc conservé tel quel. align-items: start évite qu'une
   ligne s'étire à la hauteur de sa voisine, et les lignes masquées par la
   recherche (display: none) sortent proprement du flux de la grille. */
.alim-liste--3col {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
    column-gap: 2rem;
}
/* Rubriques : 2 à 3 colonnes selon la largeur disponible */
.alim-liste--rubriques {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    align-items: start;
    column-gap: 2rem;
}
@media (max-width: 1400px) {
    .alim-liste--3col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 1000px) {
    .alim-liste--3col { grid-template-columns: minmax(0, 1fr); }
}

.alim-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--color-border);
}
.alim-item--inactif { opacity: 0.55; }
/* Masquage par la recherche « Mes ingrédients » : l'attribut [hidden] doit
   l'emporter sur le display:flex ci-dessus (sinon la ligne reste visible). */
.alim-item[hidden] { display: none; }

/* Bloc repliable des ingrédients désactivés (<details> natif) */
.alim-desactives { margin-top: 1rem; }
.alim-desactives > summary {
    cursor: pointer;
    padding: 0.5rem 0;
    font-weight: 600;
    color: var(--color-muted);
}
.alim-desactives > summary:hover { color: var(--color-primary); }
.alim-desactives[open] > summary { margin-bottom: 0.25rem; }

.alim-item-infos {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}
/* Point indicatif en tête de ligne : petite pastille ronde, colonne alignée
   (premier élément de la ligne). Vert = aliment, bleu de marque = accessoire. */
.alim-point {
    flex: none;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--color-point-plein);
}
.alim-point--accessoire { background: var(--color-point-accessoire); }
.alim-item-nom { font-weight: 600; }
.alim-saison {
    color: var(--color-muted);
    font-size: 0.9rem;
    font-variant-numeric: tabular-nums;
}

/* Étiquettes d'états : discrètes, secondaires par rapport à la pastille
   de catégorie (ni fond coloré, ni gras). */
.alim-etats {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}
.alim-etat-tag {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    border-radius: 4px;
    font-size: 0.7rem;
    color: var(--color-muted);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    white-space: nowrap;
}

/* Pastilles de catégorie (teintes dérivées des variables de statut) */
.alim-badge {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
    border: 1px solid var(--color-border);
    background: var(--color-surface-2);
    color: var(--color-muted);
}
/* Puce de rubrique sur les lignes du catalogue : largeur fixe + texte centré
   (alignement en colonne) et coins peu arrondis. Les couleurs restent portées
   par les classes .alim-badge--<slug> (variables --color-cat-<slug>). */
.alim-badge--rubrique {
    width: 6.5rem;
    box-sizing: border-box;
    flex: 0 0 auto;
    text-align: center;
    padding-left: 0.4rem;
    padding-right: 0.4rem;
    border-radius: 3px;
}

/* Pastilles par slug de couleur (fond/texte/bordure dérivés par color-mix
   depuis --color-cat-<slug>). La pastille d'un ingrédient porte la couleur de
   sa rubrique. */
.alim-badge--indigo {
    background: color-mix(in srgb, var(--color-cat-indigo) 12%, var(--color-surface));
    color: var(--color-cat-indigo);
    border-color: color-mix(in srgb, var(--color-cat-indigo) 35%, transparent);
}
.alim-badge--bleu {
    background: color-mix(in srgb, var(--color-cat-bleu) 12%, var(--color-surface));
    color: var(--color-cat-bleu);
    border-color: color-mix(in srgb, var(--color-cat-bleu) 35%, transparent);
}
.alim-badge--vert {
    background: color-mix(in srgb, var(--color-cat-vert) 12%, var(--color-surface));
    color: var(--color-cat-vert);
    border-color: color-mix(in srgb, var(--color-cat-vert) 35%, transparent);
}
.alim-badge--teal {
    background: color-mix(in srgb, var(--color-cat-teal) 12%, var(--color-surface));
    color: var(--color-cat-teal);
    border-color: color-mix(in srgb, var(--color-cat-teal) 35%, transparent);
}
.alim-badge--jaune {
    background: color-mix(in srgb, var(--color-cat-jaune) 12%, var(--color-surface));
    color: var(--color-cat-jaune);
    border-color: color-mix(in srgb, var(--color-cat-jaune) 35%, transparent);
}
.alim-badge--ambre {
    background: color-mix(in srgb, var(--color-cat-ambre) 12%, var(--color-surface));
    color: var(--color-cat-ambre);
    border-color: color-mix(in srgb, var(--color-cat-ambre) 35%, transparent);
}
.alim-badge--noisette {
    background: color-mix(in srgb, var(--color-cat-noisette) 12%, var(--color-surface));
    color: var(--color-cat-noisette);
    border-color: color-mix(in srgb, var(--color-cat-noisette) 35%, transparent);
}
.alim-badge--rose {
    background: color-mix(in srgb, var(--color-cat-rose) 12%, var(--color-surface));
    color: var(--color-cat-rose);
    border-color: color-mix(in srgb, var(--color-cat-rose) 35%, transparent);
}
.alim-badge--violet {
    background: color-mix(in srgb, var(--color-cat-violet) 12%, var(--color-surface));
    color: var(--color-cat-violet);
    border-color: color-mix(in srgb, var(--color-cat-violet) 35%, transparent);
}
.alim-badge--gris {
    background: color-mix(in srgb, var(--color-cat-gris) 12%, var(--color-surface));
    color: var(--color-cat-gris);
    border-color: color-mix(in srgb, var(--color-cat-gris) 35%, transparent);
}
.alim-badge--inactif {
    background: var(--color-surface-2);
    color: var(--color-muted);
    border-color: var(--color-border);
}
/* Badge « composé » (discret) sur les lignes du catalogue */
.alim-badge--compose {
    background: color-mix(in srgb, var(--color-cat-violet) 12%, var(--color-surface));
    color: var(--color-cat-violet);
    border-color: color-mix(in srgb, var(--color-cat-violet) 35%, transparent);
    text-transform: lowercase;
}
/* Badge « Accessoires » (en-tête de la section du bas du Rapport) : gris neutre */
.alim-badge--accessoire {
    background: color-mix(in srgb, var(--color-accessoire) 12%, var(--color-surface));
    color: var(--color-accessoire);
    border-color: color-mix(in srgb, var(--color-accessoire) 35%, transparent);
}

/* Recherche instantanée en tête de la liste « Mes ingrédients » */
/* Barre de recherche des ingrédients : l'apparence vient du composant partagé
   .idv-recherche* (module Idées) ; cette classe ne porte plus que l'espacement
   propre à la page, la barre étant désormais en tête de carte. */
/* Double classe : l'emporte sur la marge haute du composant partagé, qui est
   déclaré plus bas dans la feuille. La barre occupe seule sa carte, sans
   retrait superflu (le message « aucun résultat » prend sa marge lui-même). */
.idv-recherche.alim-recherche { margin: 0; }
.alim-recherche-vide { margin: 0.75rem 0 0; }

/* Éditeur « Élément composé » : interrupteur + zone recette par défaut */
.alim-compose-inter { margin-top: 0.25rem; }
.alim-compose-zone {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.25rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface-2);
}
.alim-compose-zone[hidden] { display: none; }
.alim-compose-pastilles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
    min-height: 1.5rem;
}
.alim-compose-pastille {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.5rem;
    border: 1px solid var(--color-border-2);
    border-radius: 3px;
    background: var(--color-surface);
    font-size: 0.9rem;
}
.alim-compose-pastille-x {
    border: none;
    background: transparent;
    color: var(--color-muted);
    cursor: pointer;
    padding: 0;
    font-size: 0.85rem;
    line-height: 1;
}
.alim-compose-pastille-x:hover { color: var(--color-error); }
.alim-compose-ajout {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.alim-compose-ajout .alim-input { max-width: 240px; }

/* Gestionnaire de rubriques : bloc repliable en tête de l'onglet */
.alim-rubriques { margin: 0.5rem 0 1rem; }
/* Dans le bloc « Ajouter un ingrédient », le gestionnaire de rubriques suit le
   formulaire : un filet discret marque la séparation entre les deux. */
.alim-gestion .alim-rubriques {
    margin: 1.5rem 0 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--color-border);
}

/* ----- Bloc repliable « Ajouter un ingrédient » -----
   Carte dont l'en-tête est le résumé cliquable d'un <details> natif : fermé par
   défaut (aucun attribut open), donc la liste des ingrédients reste visible
   d'emblée au chargement. Aucun JS : c'est le navigateur qui gère l'ouverture. */
.alim-gestion { padding: 0; }
.alim-gestion-tete {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1.1rem 2rem;
    cursor: pointer;
    font-weight: 600;
    color: var(--color-text);
    list-style: none; /* pas de triangle natif */
}
.alim-gestion-tete::-webkit-details-marker { display: none; }
.alim-gestion-tete:hover { color: var(--color-primary); }
/* Le « + » d'appel, dans une pastille ronde discrète */
.alim-gestion-plus {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    color: var(--color-primary);
    font-size: 1.1rem;
    line-height: 1;
}
.alim-gestion-titre { flex: 1; min-width: 0; }
/* Chevron : vers le bas fermé, retourné une fois ouvert */
.alim-gestion-chevron {
    display: inline-flex;
    flex-shrink: 0;
    color: var(--color-muted);
    transition: transform 0.15s;
}
.alim-gestion-chevron svg { width: 18px; height: 18px; display: block; }
.alim-gestion[open] .alim-gestion-chevron { transform: rotate(180deg); }
/* Corps révélé : reprend le retrait intérieur habituel des cartes */
.alim-gestion-corps { padding: 0 2rem 1.5rem; }
.alim-rubriques > summary {
    cursor: pointer;
    padding: 0.5rem 0;
    font-weight: 600;
    color: var(--color-muted);
}
.alim-rubriques > summary:hover { color: var(--color-primary); }
.alim-rubriques h4 { margin: 0.75rem 0 0.25rem; }

/* Choix de couleur en pastilles cliquables (boutons radio) */
.alim-couleur-choix {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.alim-couleur-option { display: inline-flex; cursor: pointer; }
.alim-couleur-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.alim-swatch {
    display: inline-block;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 1px solid var(--color-border-2);
    box-sizing: border-box;
}
/* Anneau de sélection visible quand le radio est coché */
.alim-couleur-option input:checked + .alim-swatch {
    box-shadow: 0 0 0 2px var(--color-surface), 0 0 0 4px var(--color-primary);
}
.alim-couleur-option input:focus-visible + .alim-swatch {
    box-shadow: 0 0 0 2px var(--color-surface), 0 0 0 4px var(--color-focus-ring);
}
.alim-swatch--indigo   { background: var(--color-cat-indigo); }
.alim-swatch--bleu     { background: var(--color-cat-bleu); }
.alim-swatch--vert     { background: var(--color-cat-vert); }
.alim-swatch--teal     { background: var(--color-cat-teal); }
.alim-swatch--jaune    { background: var(--color-cat-jaune); }
.alim-swatch--ambre    { background: var(--color-cat-ambre); }
.alim-swatch--noisette { background: var(--color-cat-noisette); }
.alim-swatch--rose     { background: var(--color-cat-rose); }
.alim-swatch--violet   { background: var(--color-cat-violet); }
.alim-swatch--gris     { background: var(--color-cat-gris); }

/* Actions de ligne (icônes) */
.alim-actions { display: flex; align-items: center; gap: 0.3rem; }
.alim-form-en-ligne { margin: 0; }
.alim-lien-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--color-muted);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.alim-lien-action svg { width: 16px; height: 16px; }
.alim-lien-action:hover {
    color: var(--color-primary);
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
}
.alim-lien-action--suppr:hover { color: var(--color-error); }

/* Champs (couvre text/select, non couverts par le style global) */
.alim-input {
    width: 100%;
    padding: 0.5rem 0.6rem;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-size: 0.95rem;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.alim-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Champ « Saison » : en-tête + grille de 12 cases */
.alim-saison-champ {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.alim-saison-tete {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.alim-lien-toute-annee {
    border: 1px solid var(--color-border-2);
    background: var(--color-surface);
    color: var(--color-primary);
    border-radius: 999px;
    padding: 0.1rem 0.6rem;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.alim-lien-toute-annee:hover {
    background: var(--color-accent-soft);
    border-color: var(--color-primary);
}
.alim-mois-grille {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 0.3rem;
}
.alim-mois-case {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.3rem 0.4rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    background: var(--color-surface-2);
    font-size: 0.8rem;
    cursor: pointer;
}
.alim-mois-case input { margin: 0; cursor: pointer; }

/* Grille des 4 états : même modèle que les mois (cases .alim-mois-case) */
.alim-etats-grille {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.3rem;
}

/* Case « Actif » */
.alim-case-actif {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9rem;
}
.alim-case-actif input { margin: 0; cursor: pointer; }

/* Interrupteurs (toggle switches) : « Élément composé », « Accessoire », « Actif ».
   Même case à cocher (name/valeur POST inchangés) redessinée en bascule maison via
   la palette :root. Éteinte = piste neutre ; allumée = accent (--color-primary).
   Le label reste cliquable (bascule l'input natif) ; l'état on/off est porté par
   la couleur ET la position du bouton. */
.alim-switch { cursor: pointer; gap: 0.5rem; }
.alim-switch input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    flex: none;
    position: relative;
    width: 2.25rem;
    height: 1.25rem;
    margin: 0;
    border-radius: 999px;
    background: var(--color-border-2);
    cursor: pointer;
    transition: background 0.15s ease;
}
.alim-switch input[type="checkbox"]::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: calc(1.25rem - 4px);
    height: calc(1.25rem - 4px);
    border-radius: 50%;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    transition: transform 0.15s ease;
}
.alim-switch input[type="checkbox"]:checked { background: var(--color-primary); }
.alim-switch input[type="checkbox"]:checked::after { transform: translateX(1rem); }
.alim-switch input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 2px;
}

/* Interrupteur « Accessoire » : même retrait que « Élément composé ». */
.alim-accessoire-inter { margin-top: 0.25rem; }

/* Formulaire d'ajout */
.alim-form-ajout {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin: 0.75rem 0 0;
}
.alim-form-ajout .field { min-width: 180px; }

/* Variante « ajouter un ingrédient » : le formulaire ne s'étire plus en
   hauteur. Rangée du haut à trois colonnes (Nom / Rubrique / Saison), puis les
   options et le bouton en pleine largeur. Purement visuel : aucun champ n'est
   renommé ni déplacé hors du <form>. */
.alim-form-ajout--grille {
    display: block;
    margin-top: 0.75rem;
}
.alim-form-rangee {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: end;
    gap: 1rem 1.5rem;
}
.alim-form-bas {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.9rem;
    margin-top: 1.25rem;
}
/* Bouton d'envoi sur toute la largeur, en bas du formulaire */
.alim-form-bouton { width: 100%; }

@media (max-width: 900px) {
    .alim-form-rangee { grid-template-columns: minmax(0, 1fr); }
}

/* Mini-formulaire de modification (révélé en JS) */
.alim-modif-form {
    display: none;
    flex-basis: 100%;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin-top: 0.5rem;
    padding: 0.75rem;
    background: var(--color-surface-2);
    border-radius: var(--radius);
}
.alim-modif-form.is-open { display: flex; }
.alim-modif-form .field { min-width: 180px; }

@media (max-width: 900px) {
    .alim-mois-grille { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .alim-etats-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ----- Onglet « Journal » (synthèse mensuelle) : état vide ----- */
.alim-journal-vide { margin-top: 1rem; }

/* =====================================================================
   Onglet « Suivi » FUSIONNÉ — suivi éditable + journal du mois
   ---------------------------------------------------------------------
   Les anciens onglets « Suivi » et « Journal » ne font plus qu'un : le suivi
   éditable occupe la colonne large de gauche, le journal du mois la colonne
   étroite de droite, dont chaque jour est cliquable pour l'ouvrir à l'édition.
   ===================================================================== */

.alim-fusion {
    display: grid;
    grid-template-columns: 3fr 1fr;
    gap: var(--gap);
    align-items: start; /* les deux colonnes démarrent en haut */
}
/* Les cartes peuvent rétrécir dans leur colonne sans déborder */
.alim-fusion > .card { min-width: 0; }
.alim-fusion > .card > * { max-width: 100%; }

/* Sous ~1400px, le journal passe SOUS le suivi : la colonne de droite
   deviendrait trop étroite pour ses barres de score. */
@media (max-width: 1400px) {
    .alim-fusion { grid-template-columns: 1fr; }
}

/* En-tête léger de colonne : jour édité à gauche, mois (et moyenne) à droite.
   Remplace les anciens gros titres et leurs baselines. */
.alim-suivi-entete {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.alim-suivi-jour-label {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--kpi-valeur);
}
.alim-suivi-jour-nav {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}
/* Flèches de jour : navigation SECONDAIRE (le clic dans le journal est le
   moyen principal), donc discrète. */
.alim-suivi-fleche {
    padding: 0.1rem 0.45rem;
    border-radius: 6px;
    color: var(--nav-texte);
    font-size: 0.95rem;
    line-height: 1.4;
    text-decoration: none;
}
.alim-suivi-fleche:hover {
    background: var(--nav-gris);
    color: var(--nav-texte-fort);
    text-decoration: none;
}

/* Colonne de droite : la liste tient sur toute la hauteur utile */
.alim-journal-colonne .alim-jr-liste { margin-top: 0.75rem; }

/* ----- Onglet « Suivi » (repas noté) ----- */

/* Disposition : liste des moments à gauche, fiche du moment à droite. */
.alim-suivi-jour {
    display: grid;
    grid-template-columns: minmax(200px, 260px) 1fr;
    gap: 1rem;
    margin-top: 1rem;
    align-items: start;
}

/* Colonne gauche : quatre moments empilés */
.alim-suivi-moments {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.alim-suivi-moment {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    /* Boutons de moment plus hauts et confortables (padding vertical généreux) */
    padding: 1.05rem 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
}
.alim-suivi-moment:hover {
    border-color: var(--color-border-2);
    background: var(--color-surface-2);
    text-decoration: none;
}
/* Sélection : anneau inséré (n'écrase pas la teinte de qualité éventuelle) */
.alim-suivi-moment.is-active {
    box-shadow: inset 0 0 0 2px var(--color-primary);
}

/* Tuile teintée selon la qualité du moment DÈS QU'IL EST NOTÉ (liseré + fond
   légèrement teinté) ; un moment non noté reste neutre. Seuils/couleurs uniques
   (--color-qualite-*). */
.alim-suivi-moment--haut {
    border-color: var(--color-qualite-haut);
    background: color-mix(in srgb, var(--color-qualite-haut) 10%, var(--color-surface));
}
.alim-suivi-moment--moyen {
    border-color: var(--color-qualite-moyen);
    background: color-mix(in srgb, var(--color-qualite-moyen) 10%, var(--color-surface));
}
.alim-suivi-moment--bas {
    border-color: var(--color-qualite-bas);
    background: color-mix(in srgb, var(--color-qualite-bas) 10%, var(--color-surface));
}
/* Survol : conserver la teinte de qualité (un peu plus soutenue) */
.alim-suivi-moment--haut:hover {
    border-color: var(--color-qualite-haut);
    background: color-mix(in srgb, var(--color-qualite-haut) 16%, var(--color-surface));
}
.alim-suivi-moment--moyen:hover {
    border-color: var(--color-qualite-moyen);
    background: color-mix(in srgb, var(--color-qualite-moyen) 16%, var(--color-surface));
}
.alim-suivi-moment--bas:hover {
    border-color: var(--color-qualite-bas);
    background: color-mix(in srgb, var(--color-qualite-bas) 16%, var(--color-surface));
}
.alim-suivi-moment-icone {
    display: inline-flex;
    color: var(--color-muted);
}
.alim-suivi-moment.is-active .alim-suivi-moment-icone { color: var(--color-primary); }
.alim-suivi-moment-label { flex: 1; font-weight: 600; }

/* Pastille de note à droite du moment (chiffre teinté selon le barème) */
.alim-suivi-note-pastille {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.6rem;
    height: 1.6rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    border: 1px solid transparent;
}
.alim-suivi-note--vide {
    color: var(--color-muted);
    background: var(--color-surface-2);
    border-color: var(--color-border);
    font-weight: 400;
}
/* Pastille d'une pénalité renseignée : monochrome (chiffre sobre sur fond
   neutre). Se distingue du « vide » par un texte plus marqué. */
.alim-suivi-note--valeur {
    color: var(--color-text);
    background: var(--color-surface-2);
    border-color: var(--color-border);
}

/* Score du jour (points retirés) : ligne discrète alignée à droite */
.alim-suivi-score {
    margin-top: 1rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.alim-suivi-score strong { color: var(--color-text); }

/* Panneau droit : fiche du moment */
.alim-suivi-panneau {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem;
    background: var(--color-surface);
}
.alim-suivi-fiche {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    align-items: flex-start;
}
/* En-tête de fiche : titre à gauche, heure calée à droite, sur la même ligne */
.alim-suivi-fiche-tete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
}
.alim-suivi-fiche-titre {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.alim-suivi-fiche-tete h3 { margin: 0; }
.alim-suivi-fiche-icone { display: inline-flex; color: var(--color-primary); }
.alim-suivi-heure { display: inline-flex; }
.alim-suivi-heure .alim-input { width: auto; }

/* Bouton Enregistrer : plus grand et centré horizontalement dans la fiche */
.alim-suivi-enregistrer {
    align-self: center;
    padding: 0.7rem 2.25rem;
    font-size: 1.05rem;
    margin-top: 0.25rem;
}

/* Note : quatre boutons carrés (1 rouge → 4 vert) */
.alim-suivi-note-champ {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    width: 100%;
}
/* Rangée des cinq cases : GRILLE de 5 pistes égales occupant TOUTE la largeur
   de la colonne du détail, donc alignée à gauche et à droite sur les champs de
   services au-dessus (qui sont des blocs pleine largeur). Auparavant en flex
   avec une largeur fixe par case, la rangée restait groupée à gauche. */
.alim-suivi-notes {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: var(--note-gap);
}
.alim-suivi-note-btn {
    /* position: relative pour ancrer le radio masqué à sa propre case */
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    /* La largeur vient de la piste de grille ; min-width: 0 autorise la case à
       se réduire sans déborder, et les cases gardent une hauteur identique
       (étirement par défaut de la grille) même si un libellé passe sur deux
       lignes. */
    min-width: 0;
    padding: 0.5rem 0.35rem;
    border: 2px solid var(--note-bordure);
    border-radius: var(--radius);
    background: var(--note-fond);
    cursor: pointer;
    text-align: center;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.alim-suivi-note-btn input { position: absolute; opacity: 0; width: 0; height: 0; }
.alim-suivi-note-chiffre {
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1;
    color: var(--note-chiffre);
}
/* Libellé : interligne serré pour tenir sur deux lignes sans grandir la case */
.alim-suivi-note-libelle {
    font-size: 0.78rem;
    line-height: 1.15;
    color: var(--note-libelle);
    overflow-wrap: break-word;
    hyphens: auto;
}

/* État sélectionné : bleu clair de la charte — fond, bordure, chiffre et
   libellé. Aucune couleur de barème (le rouge/vert reste aux scores). */
.alim-suivi-note-btn:has(input:checked) {
    border-color: var(--note-actif-bordure);
    background: var(--note-actif-fond);
}
.alim-suivi-note-btn:has(input:checked) .alim-suivi-note-chiffre,
.alim-suivi-note-btn:has(input:checked) .alim-suivi-note-libelle {
    color: var(--note-actif-texte);
}
.alim-suivi-note-btn:hover { border-color: var(--note-actif-bordure); }
.alim-suivi-note-btn:has(input:focus-visible) {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--nav-marque) 25%, transparent);
}

/* Écran étroit : les cinq pistes restent égales, on resserre le texte plutôt
   que de casser la rangée. */
@media (max-width: 620px) {
    .alim-suivi-note-btn { padding: 0.45rem 0.2rem; }
    .alim-suivi-note-chiffre { font-size: 1.15rem; }
    .alim-suivi-note-libelle { font-size: 0.7rem; }
}

/* Lieu du repas : pastilles sobres « segmented » (un seul choix, radios) */
.alim-suivi-lieu-champ {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    width: 100%;
}
.alim-suivi-lieux {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.alim-suivi-lieu-btn {
    display: inline-flex;
    align-items: center;
    padding: 0.35rem 0.75rem;
    border: 1px solid var(--color-border-2);
    border-radius: 999px;
    font-size: 0.9rem;
    color: var(--color-muted);
    background: var(--color-surface);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.alim-suivi-lieu-btn:hover { border-color: var(--color-primary); }
.alim-suivi-lieu-btn input { position: absolute; opacity: 0; width: 0; height: 0; }
.alim-suivi-lieu-btn:has(input:checked) {
    border-color: var(--color-primary);
    background: var(--color-accent-soft);
    color: var(--color-primary);
    font-weight: 600;
}
.alim-suivi-lieu-btn:has(input:focus-visible) {
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Contenu : boutons de service ouvrant le sélecteur */
.alim-suivi-contenu {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    width: 100%;
}
/* Services empilés verticalement, chaque bouton sur toute la largeur */
.alim-suivi-services {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.alim-suivi-service-btn {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius);
    background: var(--color-surface);
    cursor: pointer;
    text-align: left;
    transition: border-color 0.15s, background 0.15s;
}
/* Service RENSEIGNÉ (au moins un ingrédient) : fond vert très léger + bordure
   verte douce, purement indicatif. Un service vide reste neutre. Déclaré avant
   :hover / .is-ouvert pour que le survol et l'ouverture (états actifs) priment. */
.alim-suivi-service-btn.is-rempli {
    background: var(--color-service-rempli-fond);
    border-color: var(--color-service-rempli-bord);
}
.alim-suivi-service-btn:hover { border-color: var(--color-primary); background: var(--color-surface-2); }
.alim-suivi-service-btn.is-ouvert { border-color: var(--color-primary); background: var(--color-accent-soft); }
.alim-suivi-service-titre {
    font-weight: 600;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-muted);
}
.alim-suivi-service-btn.is-rempli .alim-suivi-service-titre { color: var(--color-qualite-haut); }
.alim-suivi-service-resume { font-size: 0.9rem; color: var(--color-text); }

/* Service « Liquide » : petite icône de verre alignée au libellé */
.alim-suivi-service-titre {
    display: flex;
    align-items: center;
    gap: 0.3rem;
}
.alim-suivi-service-icone {
    display: inline-flex;
    color: var(--color-qualite-moyen);
}
.alim-suivi-service-icone svg { width: 0.95rem; height: 0.95rem; }

/* Sélecteur d'aliments (pastilles cliquables) */
.alim-suivi-selecteur {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    padding: 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface-2);
}
.alim-suivi-selecteur[hidden] { display: none; }
.alim-suivi-selecteur-tete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.alim-suivi-selection {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
}
.alim-suivi-ajout-libre {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.alim-suivi-ajout-libre .alim-input { max-width: 220px; }
.alim-suivi-cat-groupe {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.alim-suivi-cat-titre {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-muted);
    font-weight: 600;
}
.alim-suivi-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}
/* Pastille cliquable (catalogue et sélection) */
.alim-suivi-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    /* Padding légèrement augmenté pour équilibrer le texte plus grand */
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--color-border-2);
    /* Coins nettement moins arrondis que des pastilles classiques */
    border-radius: 3px;
    background: var(--color-surface);
    color: var(--color-text);
    /* Texte plus grand (~15px) pour une meilleure lisibilité */
    font-size: 0.95rem;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.alim-suivi-chip:hover { border-color: var(--color-primary); }
.alim-suivi-chip.is-choisi {
    border-color: var(--color-primary);
    background: var(--color-accent-soft);
    color: var(--color-primary);
    font-weight: 600;
}
.alim-suivi-chip--nouveau {
    border-style: dashed;
    border-color: var(--color-warning);
    color: var(--color-warning);
    background: var(--color-warning-soft);
}
/* Croix de retrait dans une pastille de sélection */
.alim-suivi-chip-x {
    border: none;
    background: transparent;
    color: inherit;
    cursor: pointer;
    padding: 0;
    font-size: 0.9rem;
    line-height: 1;
}
/* Libellé interne d'une pastille (isolé du chevron / de la croix) */
.alim-suivi-chip-lib { line-height: 1; }

/* Masquage par la recherche du sélecteur : comme pour .alim-item, l'attribut
   [hidden] doit primer sur le display des pastilles et des groupes. */
.alim-suivi-chip[hidden],
.alim-suivi-cat-groupe[hidden] { display: none; }

/* Petit badge « composé » dans une pastille de catalogue du sélecteur */
.alim-suivi-chip-badge {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.03rem 0.32rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--color-cat-violet) 15%, var(--color-surface));
    color: var(--color-cat-violet);
    border: 1px solid color-mix(in srgb, var(--color-cat-violet) 35%, transparent);
}
/* Chevron d'ouverture de l'ajustement d'un composé sélectionné */
.alim-suivi-chip-chevron {
    border: none;
    background: transparent;
    color: inherit;
    cursor: pointer;
    padding: 0 0.1rem;
    font-size: 0.8rem;
    line-height: 1;
    transition: transform 0.15s;
}
.alim-suivi-chip-chevron.is-ouvert { transform: rotate(180deg); }
/* Pastille légère d'un composé sélectionné (teinte de bord distincte) */
.alim-suivi-chip--compose.is-choisi {
    border-color: color-mix(in srgb, var(--color-cat-violet) 55%, transparent);
}

/* Recherche en tête du sélecteur d'un service (filtre des pastilles) */
.alim-suivi-recherche { margin: 0; }
.alim-suivi-recherche .alim-input { width: 100%; }

/* Panneau d'ajustement des composants d'un composé, DANS ce repas. Occupe une
   ligne pleine sous la pastille (la sélection est en flex-wrap). */
.alim-suivi-ajust {
    flex: 1 1 100%;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin: 0.15rem 0 0.35rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--color-border);
    border-left: 3px solid color-mix(in srgb, var(--color-cat-violet) 45%, transparent);
    border-radius: var(--radius);
    background: var(--color-surface);
}
.alim-suivi-ajust-titre {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-muted);
    font-weight: 600;
}
.alim-suivi-ajust-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
}
.alim-suivi-ajust-ajout {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.alim-suivi-ajust-ajout .alim-input { max-width: 220px; }

@media (max-width: 720px) {
    .alim-suivi-jour { grid-template-columns: 1fr; }
    .alim-suivi-moments {
        flex-direction: row;
        flex-wrap: wrap;
    }
    .alim-suivi-moment { flex: 1 1 45%; }
}

/* ----- Onglet « Journal » : synthèse mensuelle (lecture seule) ----- */
.alim-jr-moyenne { font-weight: 400; font-size: 0.9rem; }

.alim-jr-liste {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
/* Une ligne par jour, CLIQUABLE : date | score | barre. C'est un lien qui
   rouvre ce jour dans le suivi (colonne de gauche). Le jour en cours d'édition
   est surligné en bleu très clair. */
.alim-jr-ligne {
    display: grid;
    grid-template-columns: 4.5rem auto 1fr;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.5rem;
    border-radius: 8px;
    border-bottom: 1px solid var(--color-border);
    color: inherit;
    text-decoration: none;
    transition: background-color 0.12s;
}
.alim-jr-ligne:hover {
    background: var(--nav-gris);
    text-decoration: none;
}
/* Jour actuellement édité dans la colonne de gauche */
.alim-jr-ligne.is-active,
.alim-jr-ligne.is-active:hover {
    background: var(--nav-tuile-accent-fond); /* #e6f5fd */
}
.alim-jr-ligne.is-active .alim-jr-date,
.alim-jr-ligne.is-active .alim-jr-score {
    color: var(--nav-tuile-accent-texte);
}
.alim-jr-ligne:focus-visible {
    outline: 2px solid var(--nav-marque);
    outline-offset: 1px;
}
.alim-jr-date {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--color-muted);
    white-space: nowrap;
}

/* (.alim-jr-moments / .alim-jr-moment* / .alim-jr-pct* sont supprimées : dans la
   colonne étroite du journal fusionné, la ligne se limite à date + score +
   barre, et le détail par moment est passé en infobulle du lien.) */

.alim-jr-score {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.alim-jr-barre {
    flex: 1;
    height: 8px;
    min-width: 4rem;
    border-radius: 999px;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    overflow: hidden;
}
.alim-jr-barre-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
}
.alim-jr-barre--haut  { background: var(--color-qualite-haut); }
.alim-jr-barre--moyen { background: var(--color-qualite-moyen); }
.alim-jr-barre--bas   { background: var(--color-qualite-bas); }

/* Écran étroit : la barre passe sous le couple date + score. (Les anciennes
   zones « moments » et « pct » n'existent plus : le détail par moment du
   journal est désormais en infobulle de la ligne.) */
@media (max-width: 720px) {
    .alim-jr-ligne {
        grid-template-columns: 1fr auto;
        row-gap: 0.4rem;
    }
    .alim-jr-score { text-align: right; }
    .alim-jr-barre { grid-column: 1 / -1; }
}

/* =====================================================================
   Module Gains (.gains-*) — simulateur de revenus « en mode si »
   ===================================================================== */

/* Barre de tête : label « Scénario » + contrôle segmenté.
   Le composant .segmented (rail gris, option retenue en pastille bleue) est
   RÉUTILISÉ tel quel, comme à l'onglet Historique de la Comptabilité : aucune
   de ses règles n'est redéfinie ici, sans quoi les deux pourraient diverger.
   (Les anciennes règles .gains-scenarios a.btn* n'ont plus d'objet : les
   scénarios ne sont plus des boutons pilule.) */
.gains-barre {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: var(--gap);
}
.gains-scenarios-label {
    color: var(--color-muted);
    font-size: 0.9rem;
}

/* ----- Agencement en deux colonnes -----
   Les recettes (le gros tableau à quatre colonnes) prennent la colonne large ;
   les réglages et le résultat s'empilent à droite. align-items: start pour que
   chaque colonne garde sa hauteur propre. */
.gains-grille {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    align-items: start;
    gap: var(--gap);
}
.gains-colonne-droite {
    display: flex;
    flex-direction: column;
    gap: var(--gap);
    min-width: 0;
}

/* Repli en une seule colonne : sous ce seuil, la colonne de gauche deviendrait
   trop étroite pour le tableau des plans et ses trois champs de saisie. */
@media (max-width: 1100px) {
    .gains-grille { grid-template-columns: minmax(0, 1fr); }
}

/* ----- En-tête de carte : celui de l'accueil, réutilisé tel quel -----
   Balisage .accueil-entete-titre > .accueil-pastille + <h2>, donc pastille
   RONDE à filet gris, icône grise et titre sombre, à l'identique des cartes du
   tableau de bord. Cette classe n'ajoute QUE l'espacement sous l'en-tête, le
   même que .accueil-bloc-entete. */
.gains-carte-entete { margin: 0 0 0.75rem; }
.gains-carte-entete h2 { margin: 0; }

/* ----- Tableau des plans : en-tête ADOUCI -----
   Portée au module : .compta-recettes garde son bandeau bleu plein partout
   ailleurs (encaissements de la Comptabilité). Ici, l'en-tête passe en petites
   capitales grises sur fond transparent et la lecture est portée par des filets
   fins, comme les tableaux d'Historique et de Fin de mois. */
#gains-module .compta-recettes thead th {
    background: transparent;
    color: var(--color-muted);
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-bottom: 1px solid var(--color-border);
}
/* Plus de zébrage : les filets suffisent. */
#gains-module .compta-recettes tbody tr:nth-child(even) td { background: transparent; }
#gains-module .compta-recettes tbody td { border-top: 1px solid var(--color-border); }
#gains-module .compta-recettes tbody tr:first-child td { border-top: none; }
#gains-module .compta-recettes tfoot td {
    background: transparent;
    border-top: 1px solid var(--color-border-2);
}

/* Le tableau défile plutôt qu'il ne s'écrase : sur écran étroit, ses quatre
   colonnes (dont deux de saisie) resteraient sinon illisibles. */
.gains-table-enveloppe {
    overflow-x: auto;
    margin-bottom: 0.5rem;
}

/* Cases de saisie resserrées (portée au module, surcharge .exo-input) :
   ~120 px pour prix/abonnés/revenu actuel/taux, ~64 px pour les pourcentages. */
#gains-module .exo-input {
    width: 120px;
    text-align: right;
}
#gains-module .gains-pct {
    width: 64px;
}

/* ----- Zone taux de change, sous le tableau -----
   Le champ et le rappel du taux BCE tiennent sur une ligne tant que la place le
   permet, et se replient proprement sinon. Le bouton reste sur la même ligne
   que le taux qu'il recopie. */
.gains-taux {
    max-width: none;
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 0.6rem 1.25rem;
    margin: 0.75rem 0 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--color-border);
}
.gains-taux .field { margin: 0; }
.gains-taux-jour {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    margin: 0;
}
.gains-taux-jour strong { color: var(--color-text); }

/* Les quatre pourcentages : deux par ligne, plutôt qu'une file qui se replie
   n'importe comment dans une colonne étroite. */
.gains-champs-pct {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: end;
    gap: 0.75rem 1rem;
    margin: 0 0 0.75rem;
}
.gains-champs-pct .field { min-width: 0; }
@media (max-width: 480px) {
    .gains-champs-pct { grid-template-columns: minmax(0, 1fr); }
}

/* ----- Cascade du Détail : lignes à filets fins ----- */
.gains-cascade { margin: 0 0 var(--gap); }
#gains-module .gains-cascade th,
#gains-module .gains-cascade td {
    padding: 0.45rem 0.25rem;
    border-top: 1px solid var(--color-border);
}
#gains-module .gains-cascade tr:first-child th,
#gains-module .gains-cascade tr:first-child td { border-top: none; }
#gains-module .gains-cascade th { color: var(--color-text); font-weight: 500; }
#gains-module .gains-cascade td { font-weight: 600; }
/* Le chiffre d'affaires clôt le premier tiers de la cascade : filet un peu plus
   marqué, comme les lignes de total des relevés de Fin de mois. */
#gains-module .gains-cascade-total th,
#gains-module .gains-cascade-total td {
    border-top-color: var(--color-border-2);
    font-weight: 700;
}

/* Ligne « + Revenu actuel » : NEUTRALISÉE en encre normale. La couleur est
   réservée au rouge fonctionnel des valeurs négatives — on ne colore pas le
   positif. (Cette ligne était auparavant en vert de succès.) */
#gains-module .gains-detail-revenu th,
#gains-module .gains-detail-revenu td {
    color: var(--color-text);
}

/* Le KPI « Salaire net / mois » ferme la carte Détail : mêmes classes .kpi /
   .kpi-label / .kpi-valeur / .kpi-sub que partout ailleurs, aucune redéfinition. */
.gains-kpi { margin-top: var(--gap); }

/* Bouton d'enregistrement, sous les deux colonnes. */
.gains-actions { margin-top: var(--gap); }

/* ============================================================
   Onglet « Fin de mois » (module Comptabilité)
   ============================================================ */

/* En-tête : titre + état de validation */
.fdm-entete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.fdm-etat {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    border: 1px solid var(--color-border);
}
.fdm-etat svg { width: 16px; height: 16px; }
.fdm-etat--valide {
    color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 10%, transparent);
    border-color: color-mix(in srgb, var(--color-success) 35%, transparent);
}
.fdm-etat--brouillon {
    color: var(--color-muted);
    background: var(--color-surface-2);
}
.fdm-etat .muted { font-weight: 400; }

/* Liste « À faire » : lignes en grille [coche] [corps] [%] [€] */
.fdm-liste { display: flex; flex-direction: column; }

.fdm-ligne {
    display: grid;
    grid-template-columns: 2rem 1fr auto auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-top: 1px solid var(--color-border);
}
.fdm-ligne:first-child { border-top: none; }
.fdm-ligne--sous { padding-left: 1.5rem; }
.fdm-apayer { font-size: 0.85rem; }

/* Fond alterné (bleu très clair) réservé aux lignes des sections « à faire »
   (conteneurs .fdm-afaire) : le récapitulatif n'est PAS zébré. Les filets de
   séparation entre lignes restent portés par .fdm-ligne. */
.fdm-afaire .fdm-ligne:nth-child(even) { background: var(--color-fdm-zebra); }

/* Ligne mise en valeur (« Salaire net versé ») : libellé + montant/champ plus
   grands, gras et colorés. N'agit que sur le texte visible → l'alignement à
   droite (.fdm-euros) et la grille .fdm-ligne restent intacts. */
.fdm-ligne--phare .fdm-libelle,
.fdm-ligne--phare .fdm-euros,
.fdm-ligne--phare .fdm-euros-input {
    /* Taille de la ligne mise en valeur — ajuster ici : 1.15rem, 1.25rem… */
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--color-fdm-phare);
}

/* Titre de section léger (remplace les bandeaux bleus pleins) : intitulé en
   gras + simple filet dessous, aucun fond coloré. */
.fdm-section {
    font-weight: 700;
    /* Valeur à modifier pour régler la taille des titres de section (1.35rem). */
    font-size: 1.35rem;
    color: var(--color-text);
    padding-bottom: 0.4rem;
    margin: 1.5rem 0 0.25rem;
    border-bottom: 1px solid var(--color-border-2);
}

/* =====================================================================
   RAPPORT DE FIN DE MOIS EN COLONNES — habillage « document »
   ---------------------------------------------------------------------
   Deux conteneurs, une seule grammaire visuelle :
     .fdm-cloture — la checklist du haut (Déclarations | Lano + Salaires) ;
     .fdm-duo     — les étages suivants (Récapitulatif | Plafond, puis
                    Recettes | Opérations de banque).

   Ils partagent toutes les règles ci-dessous : deux noms plutôt qu'un seul
   parce que la checklist était en place avant les autres étages, et que son
   balisage ne devait pas être retouché pour les accueillir.

   TOUT RESTE SCOPÉ sous ces deux conteneurs. C'est délibéré : .fdm-section,
   .fdm-liste, .fdm-ligne et .fdm-euros servent aussi ailleurs, et aucune règle
   générique n'est modifiée ici.

   Registre visuel : document sobre. Fond opaque neutre, filets fins, titres
   discrets en petites capitales — plus de zébrage bleu, plus de gros titres
   noirs. C'est ce qui prépare l'imprimabilité (la CSS d'impression et le décor
   global, eux, ne sont PAS touchés à cette étape).
   ===================================================================== */

/* La GRANDE CARTE : un en-tête unique, puis deux colonnes. C'est elle qui porte
   désormais la « feuille sobre » — fond opaque (et non le translucide de la
   carte de page), filet fin, coins arrondis. Les colonnes, à l'intérieur, n'ont
   plus de boîte propre : une seule bordure par étage, pas trois. */
.fdm-carte {
    padding: 0.9rem 1.15rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    margin: 1.25rem 0;
}

.fdm-cloture,
.fdm-duo {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* stretch (et non start) : les deux colonnes prennent la hauteur de la
       rangée, ce qui permet au filet vertical ci-dessous de courir sur toute la
       hauteur du contenu de la carte. Les colonnes n'ont ni fond ni cadre : les
       étirer ne change rien d'autre au rendu. */
    align-items: stretch;
    /* Plus de gouttière portée par la grille : l'écart entre les colonnes vient
       désormais du padding de chacune, de part et d'autre du filet vertical. */
    gap: 1.25rem 0;
    margin: 1.25rem 0 0.5rem;
}

/* Dans une grande carte, la grille ne porte plus ses marges : l'espacement
   vient du padding de la carte. */
.fdm-carte .fdm-cloture,
.fdm-carte .fdm-duo { margin: 0; }

/* Repli en une colonne : sous ce seuil, deux colonnes rogneraient les libellés
   et les montants (lignes de déclaration, libellés d'opérations bancaires). */
@media (max-width: 900px) {
    .fdm-cloture,
    .fdm-duo { grid-template-columns: minmax(0, 1fr); }
}

/* Une colonne n'est plus qu'un rail de contenu : ni fond, ni filet, ni rayon —
   c'est la grande carte qui les porte. */
.fdm-cloture-colonne,
.fdm-duo-colonne { min-width: 0; }

/* ----- FILET VERTICAL ENTRE LES DEUX COLONNES -----
   Un trait fin, de la même teinte que les filets de séparation des lignes
   (--color-border), posé sur le bord gauche de la colonne de droite. Comme la
   grille est en align-items: stretch, il court sur toute la hauteur de la zone
   à deux colonnes, sous l'en-tête.

   L'écart de 1.25rem de chaque côté remplace l'ancienne gouttière de 2rem : le
   contenu ne colle jamais au trait, et la largeur totale de la gouttière reste
   du même ordre qu'avant. */
.fdm-cloture > .fdm-cloture-colonne:first-child,
.fdm-duo > .fdm-duo-colonne:first-child { padding-right: 1.25rem; }

.fdm-cloture > .fdm-cloture-colonne + .fdm-cloture-colonne,
.fdm-duo > .fdm-duo-colonne + .fdm-duo-colonne {
    padding-left: 1.25rem;
    border-left: 1px solid var(--color-border);
}
/* 0.5px là où l'écran sait le rendre, 1px ailleurs — même convention que les
   filets fins entre les lignes, plus bas. */
@media (min-resolution: 2dppx) {
    .fdm-cloture > .fdm-cloture-colonne + .fdm-cloture-colonne,
    .fdm-duo > .fdm-duo-colonne + .fdm-duo-colonne { border-left-width: 0.5px; }
}

/* Repli en une colonne (même seuil que la grille ci-dessus) : les colonnes
   passent l'une SOUS l'autre, un filet vertical n'aurait plus de sens. Il
   devient donc un filet HORIZONTAL entre les deux blocs empilés. */
@media (max-width: 900px) {
    .fdm-cloture > .fdm-cloture-colonne:first-child,
    .fdm-duo > .fdm-duo-colonne:first-child { padding-right: 0; }

    .fdm-cloture > .fdm-cloture-colonne + .fdm-cloture-colonne,
    .fdm-duo > .fdm-duo-colonne + .fdm-duo-colonne {
        padding-left: 0;
        border-left: none;
        padding-top: 1.25rem;
        border-top: 1px solid var(--color-border);
    }
}
@media (max-width: 900px) and (min-resolution: 2dppx) {
    .fdm-cloture > .fdm-cloture-colonne + .fdm-cloture-colonne,
    .fdm-duo > .fdm-duo-colonne + .fdm-duo-colonne { border-top-width: 0.5px; }
}

/* ----- EN-TÊTE DE CARTE : celui de l'ACCUEIL, réutilisé tel quel -----
   Les titres de carte de ce rapport n'ont PAS de style propre : ils reprennent
   le composant d'en-tête des cartes de l'accueil (« Finances », « Lano »,
   « Exercices »), c'est-à-dire le balisage .accueil-entete-titre >
   .accueil-pastille + <h2>, et donc, à l'identique, la pastille RONDE à filet
   gris, l'icône grise et le titre <h2> sombre.

   UN SEUL par grande carte : les intitulés des sous-sections, à l'intérieur des
   colonnes, sont de simples .fdm-section (petites capitales grises, sans badge).

   PAS DE FILET SOUS L'EN-TÊTE : ce trait de séparation n'existe nulle part
   ailleurs dans l'application (les cartes « Finances », « Lano », « Exercices »
   de l'accueil n'en ont pas). L'en-tête est donc suivi directement du contenu,
   avec le MÊME espacement que ces cartes-là (.accueil-bloc-entete :
   margin-bottom 0.75rem). Aucune règle de l'accueil n'est redéfinie — sans quoi
   les deux en-têtes pourraient diverger. */
.fdm-carte-entete {
    margin: 0 0 0.75rem;
}
/* Même remise à zéro que .accueil-bloc-entete h2 : le titre ne porte pas sa
   marge basse par défaut, l'espacement vient du padding de l'en-tête. */
.fdm-carte-entete h2 { margin: 0; }

/* Titres de section : petites capitales grises, poids 500, filet fin dessous.
   Remplacent, DANS CES BLOCS SEULEMENT, les gros titres noirs de .fdm-section.
   C'est le registre des SOUS-TITRES internes (« Salaires ») ; les titres de
   carte, eux, passent par le modificateur --carte juste dessous. */
.fdm-cloture .fdm-section,
.fdm-duo .fdm-section {
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-muted);
    padding-bottom: 0.4rem;
    margin: 1.25rem 0 0;
    border-bottom: 1px solid var(--color-border);
}
/* Le premier sous-titre d'une colonne ne porte pas de marge haute : les deux
   colonnes d'une carte démarrent alors exactement sur la même ligne. */
.fdm-cloture .fdm-cloture-colonne > .fdm-section:first-child,
.fdm-duo .fdm-duo-colonne > .fdm-section:first-child { margin-top: 0; }

/* Plus de zébrage : la lecture est portée par les seuls filets de séparation. */
.fdm-cloture .fdm-afaire .fdm-ligne:nth-child(even),
.fdm-duo .fdm-afaire .fdm-ligne:nth-child(even) { background: transparent; }

/* Filets fins entre les lignes. 0.5px là où l'écran sait le rendre (densité
   ≥ 2x), 1px ailleurs — sur un écran standard, 0.5px disparaîtrait. */
.fdm-cloture .fdm-ligne,
.fdm-duo .fdm-ligne {
    padding: 0.45rem 0.25rem;
    border-top: 1px solid var(--color-border);
}
@media (min-resolution: 2dppx) {
    .fdm-cloture .fdm-ligne,
    .fdm-duo .fdm-ligne { border-top-width: 0.5px; }
}
.fdm-cloture .fdm-ligne:first-child,
.fdm-duo .fdm-ligne:first-child { border-top: none; }

/* Sous-lignes (A1 / E2 / 08, YouTube / Amazon / Getresponse) : léger retrait. */
.fdm-cloture .fdm-ligne--sous { padding-left: 1.25rem; }

/* Libellés un cran plus sobres que les titres qu'ils accompagnaient. */
.fdm-cloture .fdm-libelle,
.fdm-duo .fdm-libelle { font-weight: 500; }

/* ----- Étages de lecture (.fdm-duo) : gain de largeur -----
   Ces quatre sections n'ont AUCUNE case à cocher : la gouttière de 2rem que
   .fdm-ligne réserve à la coche ne sert donc à rien et prendrait, dans une
   demi-largeur, la place des libellés d'opérations. Le repère vide est
   simplement retiré du flux (il est déjà aria-hidden, aucun contenu n'est
   perdu), et la colonne des pourcentages ne garde sa largeur minimale que
   lorsqu'elle porte réellement un pourcentage (Plafond). */
.fdm-duo .fdm-ligne { grid-template-columns: 1fr auto auto; }
.fdm-duo .fdm-coche-vide { display: none; }
.fdm-duo .fdm-pct:empty { min-width: 0; }
.fdm-duo .fdm-euros { min-width: 5.5rem; }

/* En-tête de relevé (« Date · Libellé » / « Montant ») : discrète, et détachée
   des lignes par un filet un peu plus marqué. */
.fdm-duo .fdm-ligne-tete {
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
    border-bottom: 1px solid var(--color-border-2);
    font-size: 0.8rem;
}

/* Ligne de total (« Total », « Solde des mouvements ») : détachée par le haut,
   valeur affirmée. */
.fdm-duo .fdm-ligne-total {
    border-top: 1px solid var(--color-border-2);
    margin-top: 0.15rem;
}

/* Montant NÉGATIF d'une opération de banque : rouge FONCTIONNEL (le même que
   celui des KPI en alerte), jamais décoratif — il signale un débit. Le nombre
   affiché, lui, est inchangé. */
.fdm-duo .fdm-euros--negatif { color: var(--kpi-valeur-negatif); }

/* Libellé d'un mouvement : il peut être long et ne doit ni pousser la colonne
   des montants, ni être coupé — il se replie sur plusieurs lignes. */
.fdm-duo .fdm-libelle-detail { overflow-wrap: anywhere; }

/* ----- Cases à cocher unifiées -----
   Carré arrondi neutre au repos ; coché = bleu de marque plein + coche blanche
   dessinée en CSS (aucune image, aucune police d'icônes). L'input reste une
   VRAIE case : seul son rendu est repris, son état et l'envoi du mini-formulaire
   au `change` sont inchangés. */
.fdm-cloture .fdm-coche-case {
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    width: 1.05rem;
    height: 1.05rem;
    margin: 0;
    border: 1px solid var(--color-border-2);
    border-radius: 5px;
    background: var(--color-surface);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.fdm-cloture .fdm-coche-case:hover { border-color: var(--nav-marque); }
.fdm-cloture .fdm-coche-case:checked {
    border-color: var(--nav-marque);
    background: var(--nav-marque);
}
/* La coche : deux traits blancs, dessinés par une bordure en L pivotée. */
.fdm-cloture .fdm-coche-case:checked::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 46%;
    width: 0.28rem;
    height: 0.55rem;
    border: solid var(--nav-blanc);
    border-width: 0 2px 2px 0;
    transform: translate(-50%, -50%) rotate(45deg);
}
.fdm-cloture .fdm-coche-case:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 2px;
}

/* ----- Champs de saisie -----
   Membres Lano (STD / Premium / VIP) et Salaire net versé : même traitement
   d'input sobre. Les trois compteurs restent des champs number ÉDITABLES, avec
   leurs name d'origine — seule leur boîte change. */
.fdm-cloture .fdm-kpi {
    padding: 0.3rem 0.55rem;
    border-color: var(--color-border);
    border-radius: 8px;
    background: var(--color-surface);
}
.fdm-cloture .fdm-kpi-input { font-size: 1.1rem; font-weight: 600; }
.fdm-cloture .fdm-euros-input { border-color: var(--color-border); }

/* Numéros de TVA (IE… / LU… / PL…) : étiquette monospace lisible, trait plein
   plutôt que pointillé, et toujours cliquable pour la copie. */
.fdm-cloture .fdm-code {
    border-style: solid;
    border-color: var(--color-border);
    border-radius: 5px;
    font-size: 0.78rem;
    letter-spacing: 0.01em;
    color: var(--color-text);
    background: var(--color-surface-2);
}

/* Listes de détail (Recettes / Opérations) : en-tête discrète et pied de total,
   au même style de lignes légères que le reste du rapport. */
.fdm-ligne-tete { padding-top: 0.35rem; padding-bottom: 0.35rem; }
.fdm-ligne-tete .fdm-euros { font-weight: 400; }
.fdm-ligne-total .fdm-libelle,
.fdm-ligne-total .fdm-euros { font-weight: 700; }
.fdm-detail-date { font-size: 0.85rem; }
.fdm-detail-sep { color: var(--color-muted); }

.fdm-coche { margin: 0; display: flex; align-items: center; }
.fdm-coche-case { width: 1.1rem; height: 1.1rem; cursor: pointer; accent-color: var(--color-primary); }
.fdm-coche-vide { display: inline-block; width: 2rem; }

.fdm-corps {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    min-width: 0;
}
.fdm-libelle { font-weight: 600; }
.fdm-sous-libelle { color: var(--color-muted); font-size: 0.9rem; }

.fdm-lien { font-size: 0.85rem; text-decoration: underline; }

/* Colonnes alignées à droite : % juste à gauche des € */
.fdm-pct { text-align: right; color: var(--color-muted); font-size: 0.9rem; min-width: 3.5rem; }
.fdm-euros {
    text-align: right;
    font-variant-numeric: tabular-nums;
    min-width: 7rem;
    font-weight: 600;
}

/* Membres Lano : trois petits KPI éditables (libellé court en haut, nombre en
   gros dessous, resté un champ de saisie). */
.fdm-kpis { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.fdm-kpi {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--color-border-2);
    border-radius: 10px;
    background: var(--color-surface);
}
.fdm-kpi-label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-muted);
}
.fdm-kpi-input {
    width: 3.5rem;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--color-text);
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.1;
    -moz-appearance: textfield;
}
.fdm-kpi-input::-webkit-outer-spin-button,
.fdm-kpi-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* Champ de saisie aligné à droite dans la colonne des montants (salaire versé) */
.fdm-euros-input {
    width: 7rem;
    padding: 0.25rem 0.4rem;
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    background: var(--color-surface);
    color: var(--color-text);
    text-align: right;
}
.fdm-kpi-input:focus,
.fdm-euros-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.fdm-kpi:focus-within { border-color: var(--color-primary); }

/* Code d'identification cliquable (copie presse-papier) */
.fdm-code {
    font-family: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
    font-size: 0.8rem;
    padding: 0.15rem 0.45rem;
    border: 1px dashed var(--color-border-2);
    border-radius: 6px;
    background: var(--color-surface-2);
    color: var(--color-muted);
    cursor: pointer;
}
.fdm-code:hover { border-color: var(--color-primary); color: var(--color-primary); }
.fdm-code.is-copie {
    color: var(--color-success);
    border-color: var(--color-success);
    border-style: solid;
}

/* Note + actions */
.fdm-note { margin-top: 1rem; }
.fdm-note textarea {
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--color-border-2);
    border-radius: 8px;
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: 0.95rem;
    resize: vertical;
}
.fdm-note textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.fdm-actions { display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap; }
.fdm-valider-form { margin: 0; }

/* Bloc de gestion des tâches libres */
.fdm-taches-gestion .fdm-tache-form {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    margin: 0;
}
.fdm-taches-gestion .fdm-tache-form .compta-libelle-input { flex: 1; }
.fdm-tache-etat form { margin: 0; }
.fdm-tache-renommer { padding: 0.3rem 0.6rem; font-size: 0.85rem; }

/* ============================================================
   Impression (export PDF du rapport « Fin de mois » via window.print)
   ============================================================
   N'agit qu'à l'impression : l'affichage écran reste strictement identique. */
@media print {
    /* =================================================================
       LEVIER DE DENSITÉ DE L'EXPORT — LA SEULE VALEUR À AJUSTER
       -----------------------------------------------------------------
       Ajuster ICI, et nulle part ailleurs : 9pt confortable, 8.5pt plus
       dense (≈ +12 % de lignes par page), 8pt plancher de lisibilité.

       Une seule valeur suffit parce que TOUT le rapport « Fin de mois »
       est dimensionné en rem — tailles de texte, mais aussi paddings,
       gouttières et largeurs minimales des colonnes de montants. Baisser
       la base les réduit tous dans la même proportion : la mise en page
       se densifie sans se déformer.

       C'est ce réglage qui pilote le nombre de pages. Voir la note sur
       les sauts de page, plus bas : le volume variable, c'est la carte
       « Mouvements du mois ».
       ================================================================= */
    html, body { font-size: 9pt; }

    /* Format de page : A4 PAYSAGE. L'horizontale est ce qui permet de
       garder les deux colonnes de chaque carte (cf. plus bas) : en A4
       portrait, la largeur imprimable (18 cm ≈ 680 px) passe sous le
       seuil de repli de 900 px et les cartes sortiraient sur une seule
       colonne. Marges resserrées : ~2 cm de hauteur utile gagnés. */
    @page { size: A4 landscape; margin: 10mm 12mm; }

    /* Utilitaire : masquer un élément uniquement à l'impression */
    .no-print { display: none !important; }

    /* Symétrique : révéler à l'impression un élément masqué à l'écran. Sert au
       titre de mois du rapport « Fin de mois » : le sélecteur de période porte
       la période à l'écran, mais il ne s'imprime pas (no-print). */
    .print-only { display: block !important; }

    /* Pleine largeur : le rapport occupe toute la feuille, sans décalage menu */
    .app-body { display: block; }
    .main {
        max-width: none;
        padding: 0;
        overflow: visible;
        gap: 0.5rem;
    }

    /* Feuille propre : on retire l'habillage « carte » (ombre/bordure/fond) */
    .card {
        border: none;
        box-shadow: none;
        padding: 0;
        background: transparent;
    }

    /* Les couleurs et fonds (cases cochées, zébrage « à faire », badge d'état,
       mise en valeur du salaire versé) doivent sortir à l'impression. */
    .fdm-etat,
    .fdm-coche-case,
    .fdm-ligne--phare,
    .fdm-afaire .fdm-ligne {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    /* ----- CASE COCHÉE : une VRAIE coche, pas un chevron -----
       Le défaut et sa cause. À l'écran, la coche est dessinée en CSS : une
       boîte de 0.28rem × 0.55rem dont on ne garde que les bordures DROITE et
       BASSE (border-width: 0 2px 2px 0), pivotée de 45°. Les deux bras du ✓
       sont donc en rem… mais leur ÉPAISSEUR est en px absolus (2px), seule
       valeur du dessin à ne pas suivre le levier de densité. À 9pt, le bras
       court tombe à ~3.4px pour une épaisseur restée à 2px : les deux traits
       deviennent quasi aussi longs l'un que l'autre et presque aussi épais que
       longs. Le ✓ dégénère en pointe de flèche — le « ❯ » constaté. Le rayon
       de 5px sur une boîte réduite à ~12.6px arrondissait en prime la case en
       pastille, ce qui accentuait la lecture « flèche dans une pastille ».

       Le correctif. On ne rafistole pas la géométrie : à l'impression, le
       dessin par bordures est neutralisé (content: none) au profit d'un ✓ en
       SVG posé en image de fond. Il se met à l'échelle exactement (background-
       size en %), ne dépend d'aucune rotation, d'aucune unité absolue et
       d'aucune police. print-color-adjust: exact, hérité de la règle
       ci-dessus, garantit que le fond bleu ET le ✓ blanc sortent à l'encre.

       Le rendu ÉCRAN n'est pas touché : tout ceci vit dans @media print. */
    .fdm-cloture .fdm-coche-case { border-radius: 3px; }
    .fdm-cloture .fdm-coche-case:checked {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round' d='M3.6 8.4l3.1 3.1 5.7-6.3'/%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-position: center;
        background-size: 74% 74%;
    }
    .fdm-cloture .fdm-coche-case:checked::after { content: none; }

    /* Champs de saisie allégés : seule la valeur ressort (bordure/fond retirés).
       La couleur/taille de mise en valeur du salaire versé est préservée par
       .fdm-ligne--phare .fdm-euros-input (définie plus haut). */
    .fdm-kpi-input,
    .fdm-euros-input {
        border: none;
        background: transparent;
        padding: 0;
    }
    .fdm-kpi { border: none; padding: 0; background: transparent; }
    /* (Le textarea de la note ne s'imprime plus — voir le paragraphe miroir
       .fdm-note-print juste dessous ; ses règles d'impression sont devenues
       sans objet et ont été retirées d'ici.) */

    /* ----- Note : le TEXTE, et non le champ -----
       Le <textarea rows="3"> ne s'agrandit pas à l'impression : au-delà de
       trois lignes, la fin de la note manquerait au PDF. Il est donc masqué
       (no-print, posé sur son <label>) au profit du paragraphe miroir
       .fdm-note-print, qui se déroule sur autant de lignes qu'il en faut.
       Aucun champ, aucun name : la saisie et son enregistrement sont ailleurs
       et restent inchangés. */
    .fdm-note-print {
        margin-top: 0.75rem;
        break-inside: avoid;
        page-break-inside: avoid;
    }
    .fdm-note-print .field-label { display: block; }
    .fdm-note-print p { margin: 0.15rem 0 0; }

    /* ----- Rattrapages de taille : ce qui n'est PAS en rem -----
       Ces quelques valeurs sont en px ou en em et ne suivraient donc pas le
       levier de densité ci-dessus ; elles sont recalibrées à la main pour
       rester dans la même proportion que le reste. */

    /* Titre du rapport (« Fin de mois — <mois> »), révélé à l'impression :
       c'est le titre du document, un cran au-dessus des titres de carte. */
    .fdm-entete .print-only { font-size: 1.35rem; }

    /* En-tête de carte : la pastille ronde est en px fixes (40 px / SVG 20 px)
       et écraserait un texte réduit. Le <h2>, lui, n'a pas de taille propre —
       il prendrait le 1.5em du navigateur. */
    .fdm-carte-entete { gap: 8px; }
    .fdm-carte-entete h2 { font-size: 1.15rem; }
    .fdm-carte-entete .accueil-pastille {
        width: 22px;
        height: 22px;
        border-width: 1px;
    }
    .fdm-carte-entete .accueil-pastille svg { width: 12px; height: 12px; }

    /* Compteurs Lano : 1.1rem en gras suffit une fois la base réduite. */
    .fdm-cloture .fdm-kpi-input { font-size: 1rem; }

    /* ----- DEUX COLONNES : garanties, pas espérées -----
       Les media queries de largeur sont évaluées à l'impression sur la boîte de
       page. En A4 paysage à 12 mm de marges la largeur imprimable vaut ~27 cm
       (≈ 1030 px), donc au-dessus du seuil de repli de 900 px — mais à 100 px
       près. On ne s'en remet pas à cette marge : la grille à deux colonnes et
       son filet vertical sont réaffirmés ici, ce qui neutralise le repli quelle
       que soit la marge d'impression choisie par l'utilisateur. */
    .fdm-cloture,
    .fdm-duo {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.25rem 0;
    }
    .fdm-cloture > .fdm-cloture-colonne:first-child,
    .fdm-duo > .fdm-duo-colonne:first-child { padding-right: 1rem; }

    .fdm-cloture > .fdm-cloture-colonne + .fdm-cloture-colonne,
    .fdm-duo > .fdm-duo-colonne + .fdm-duo-colonne {
        padding-left: 1rem;
        padding-top: 0;
        border-left: 1px solid var(--color-border);
        border-top: none;
    }

    /* ----- Sauts de page -----
       Règles générales : ne pas couper une ligne en deux, ne jamais laisser un
       titre de section ni un en-tête de carte seul en bas de page. */
    .fdm-section,
    .fdm-carte-entete {
        break-after: avoid;
        page-break-after: avoid;
    }
    .fdm-liste,
    .fdm-ligne,
    .fdm-entete {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    /* Cartes 1 et 2 (« Déclarations & Lano », « Situation du mois ») : volume
       FIXE et modeste — elles doivent rester d'un seul tenant. */
    .fdm-carte {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    /* Carte 3 (« Mouvements du mois ») : la SEULE dont le volume varie d'un
       mois à l'autre, et la seule qui puisse dépasser une page. Lui interdire
       de se couper serait contre-productif — le navigateur ignorerait la règle,
       ou la rejetterait en bloc sur une nouvelle page en laissant la précédente
       à moitié vide. On l'autorise donc explicitement à se poursuivre d'une
       page à l'autre ; la coupe tombe entre deux mouvements, jamais au milieu
       d'un, puisque .fdm-ligne garde son break-inside: avoid ci-dessus.

       Ciblage en CSS pur, sans toucher au balisage : la ligne d'en-tête de
       relevé (« Date · Libellé » / « Montant ») n'existe que dans cette
       carte-là. */
    .fdm-carte:has(.fdm-ligne-tete),
    .fdm-carte:has(.fdm-ligne-tete) .fdm-liste {
        break-inside: auto;
        page-break-inside: auto;
    }

    /* …et elle DÉMARRE en haut de page. Page 1 = « Déclarations & Lano » +
       « Situation du mois » ; page 2 = « Mouvements du mois ».

       Ce n'est pas qu'une question d'allure. Quand cette carte s'amorçait dans
       les quelques centimètres restants de la page 1, sa grille à deux colonnes
       devait se fragmenter dès son premier fragment, avec presque aucune
       hauteur disponible : les en-têtes de relevé sortaient alors seuls, et
       leurs lignes étaient repoussées. En lui donnant une page entière dès le
       départ, le cas courant ne se fragmente plus du tout.

       break-inside reste à auto (règle ci-dessus) : si le mois est chargé, la
       carte a toujours le droit de se poursuivre sur une 3e page, la coupe
       tombant entre deux mouvements — jamais au milieu d'un, .fdm-ligne gardant
       son break-inside: avoid. */
    .fdm-carte:has(.fdm-ligne-tete) {
        break-before: page;
        page-break-before: always;
    }

    /* Les listes fragmentent en BLOC, pas en flex. À l'écran .fdm-liste est un
       conteneur flex en colonne ; à l'impression, la fragmentation d'un flex
       sur plusieurs pages est le point faible connu des moteurs de rendu et
       c'est elle qui produisait les lignes escamotées. En bloc, chaque
       .fdm-ligne (qui est elle-même une grille) reste un bloc empilé pleine
       largeur : l'empilement est visuellement IDENTIQUE, mais il se coupe
       proprement d'une page à l'autre. */
    .fdm-liste { display: block; }
}

/* ============================================================
   Bloc « Lano » du tableau de bord (membres par tier)
   ============================================================ */

.lano-vide { margin: 0.5rem 0; }

/* Indicateur du mois en focus + nouveaux membres, en tête du bloc */
.lano-focus { font-size: 0.85rem; color: var(--color-muted); margin-bottom: 0.5rem; }
.lano-focus #lano-focus-mois { color: var(--color-text); font-weight: 600; }
/* Compteur de nouveaux membres à côté du mois (couleur via .lano-tuile-delta) */
.lano-focus-delta { margin-left: 0.5rem; font-weight: 600; }

/* Légende interactive du bloc Finances : mois + brut / charges / net, en tête,
   sur une ligne (retour à la ligne toléré en écran étroit). */
.fin-focus {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.9rem;
    font-size: 0.85rem;
    color: var(--color-muted);
    margin-bottom: 0.5rem;
}
.fin-focus-mois { color: var(--color-text); font-weight: 600; }
.fin-focus-item strong {
    color: var(--color-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Graphique Finances : barres empilées net (bas) + charges (haut) = brut.
   Calqué sur le graphe empilé de Lano ; couleurs dérivées de --color-primary,
   sans contour. */
.fin-leg-barre { display: inline-block; width: 12px; height: 12px; border-radius: 2px; }
.fin-leg-barre--net     { background: var(--color-primary); }
.fin-leg-barre--charges { background: color-mix(in srgb, var(--color-primary) 25%, white); }

.fin-barre {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    width: 80%;
    display: flex;
    flex-direction: column; /* 1er enfant (charges) en haut, net en bas */
    border-radius: 2px 2px 0 0;
    overflow: hidden;
}
.fin-seg { display: block; width: 100%; }
.fin-seg--net     { background: var(--color-primary); }
.fin-seg--charges { background: color-mix(in srgb, var(--color-primary) 25%, white); }

/* KPI STD / Premium / VIP : cartes réutilisées du bloc Finances (.accueil-kpi).
   La ligne de légende (.accueil-kpi-detail) porte la variation, colorée ici. */
.lano-tuile-delta.is-hausse { color: var(--color-success); font-weight: 600; }
.lano-tuile-delta.is-baisse { color: var(--color-error); font-weight: 600; }

/* Pastilles de légende (mêmes dimensions que .sport-graph-leg-barre) */
.lano-leg-barre { display: inline-block; width: 12px; height: 12px; border-radius: 2px; }
.lano-leg-barre--std     { background: var(--color-tier-std); }
.lano-leg-barre--premium { background: var(--color-tier-premium); }
.lano-leg-barre--vip     { background: var(--color-tier-vip); }

/* Colonne (calquée sur .sport-graph-col) et barre empilée */
.lano-col { position: relative; flex: 1; height: 100%; cursor: pointer; }
.lano-barre {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    width: 80%;
    display: flex;
    flex-direction: column; /* 1er enfant (VIP) en haut, STD en bas */
    border-radius: 2px 2px 0 0;
    overflow: hidden;
}
/* Segments : aplats de couleur pleins, sans aucun contour (comme le graphe
   Finances). Le mois en focus n'est pas encadré : l'indicateur de mois et les
   KPI suffisent à le repérer. */
.lano-seg { display: block; width: 100%; }
.lano-seg--std     { background: var(--color-tier-std); }
.lano-seg--premium { background: var(--color-tier-premium); }
.lano-seg--vip     { background: var(--color-tier-vip); }

/* Les raccourcis « Sites » ne sont plus un bandeau du tableau de bord : ils
   vivent désormais à droite de la barre de navigation principale (cf. les
   règles .topbar-raccourcis / .topbar-tuile plus haut), donc visibles depuis
   toutes les pages. Le bandeau .dash-entete et ses styles ont été retirés. */

/* =====================================================================
   Module Agenda (vue semaine : todo + agenda détaillé)
   ===================================================================== */

/* Le bandeau de titre du module a été retiré (le nom du module vit dans la
   barre de navigation) : .ag-entete n'a plus d'emploi et ses styles sont
   supprimés. La barre d'actions .ag-barre prend la tête de la carte. */
.ag-ajouter { display: inline-flex; align-items: center; gap: 0.4rem; }
.ag-ajouter-icone { display: inline-flex; }
.ag-ajouter-icone svg { width: 18px; height: 18px; }

/* La carte de la semaine peut déborder horizontalement : scroll interne */
.ag-semaine-carte { overflow-x: auto; }

/* Grille des 7 jours */
.ag-semaine {
    display: grid;
    grid-template-columns: repeat(7, minmax(150px, 1fr));
    gap: 0.6rem;
    min-width: 900px;
}

.ag-colonne {
    display: flex;
    flex-direction: column;
    background: var(--color-agenda-jour-fond);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}
.ag-colonne.is-courant {
    border-color: var(--color-agenda-marque);
    box-shadow: 0 0 0 1px var(--color-agenda-marque);
}

/* En-tête de colonne : jour + numéro ; jour courant en bleu de marque */
.ag-colonne-entete {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.5rem;
    background: var(--color-agenda-blanc);
    border-bottom: 1px solid var(--color-border);
}
.ag-colonne-entete.is-courant {
    background: var(--color-agenda-marque);
    color: var(--color-agenda-blanc);
}
.ag-colonne-jour {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-muted);
}
.ag-colonne-entete.is-courant .ag-colonne-jour { color: var(--color-agenda-blanc); }
.ag-colonne-num { font-size: 1.1rem; font-weight: 700; }

/* Intitulé de zone (« À faire », « Agenda ») */
.ag-zone-titre {
    display: block;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-muted);
    margin-bottom: 0.35rem;
}

.ag-vide { margin: 0; color: var(--color-muted); font-size: 0.82rem; }

/* ----- Zone « À faire » (todo cochable) ----- */
.ag-todo {
    padding: 0.55rem 0.55rem 0.65rem;
    border-bottom: 1px dashed var(--color-border-2);
}
.ag-todo-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }

.ag-todo-item { display: flex; align-items: center; gap: 0.2rem; margin: 0; }
.ag-todo-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1.25;
    flex: 1;
    min-width: 0;
}
.ag-todo-label input[type="checkbox"] { flex-shrink: 0; cursor: pointer; }
.ag-todo-puce { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ag-todo-titre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Événement coché : barré et estompé */
.ag-todo-item.est-fait .ag-todo-titre { text-decoration: line-through; color: var(--color-muted); }
.ag-todo-item.est-fait { opacity: 0.7; }
/* Bouton de repli sans JS ; masqué quand le JS auto-soumet le cochage. */
.ag-todo-valider {
    display: none;
    border: 1px solid var(--color-border-2);
    background: var(--color-surface);
    color: var(--color-muted);
    border-radius: 5px;
    font-size: 0.65rem;
    padding: 0.05rem 0.3rem;
    cursor: pointer;
}

/* ----- Zone « Agenda » (événements détaillés) ----- */
.ag-detail {
    padding: 0.55rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex: 1;
}

/* Vignette d'événement : PAS de liseré latéral ; le type = point coloré.
   La hauteur mini est proportionnelle à la durée (style inline). */
.ag-evt {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    width: 100%;
    text-align: left;
    padding: 0.4rem 0.5rem;
    background: var(--color-agenda-blanc);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    cursor: pointer;
    font-family: inherit;
    color: var(--color-text);
    transition: border-color 0.12s, box-shadow 0.12s;
    overflow: hidden;
}
.ag-evt:hover {
    border-color: var(--color-border-2);
    box-shadow: var(--shadow-sm);
}
.ag-evt.est-fait { opacity: 0.6; }
.ag-evt.est-fait .ag-evt-titre { text-decoration: line-through; }

.ag-evt-tete { display: flex; align-items: center; gap: 0.35rem; }
.ag-evt-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ag-evt-heure {
    font-size: 0.72rem;
    color: var(--color-muted);
    font-variant-numeric: tabular-nums;
}
.ag-evt-toutejournee { font-style: italic; }
.ag-evt-titre { font-size: 0.88rem; font-weight: 600; line-height: 1.2; }
.ag-evt-desc {
    font-size: 0.76rem;
    color: var(--color-muted);
    line-height: 1.25;
    overflow: hidden;
}

/* ----- Modale (création / modification) ----- */
.ag-modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.ag-modal[hidden] { display: none; }
.ag-modal-fond {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, var(--color-text) 45%, transparent);
}
.ag-modal-carte {
    position: relative;
    width: 100%;
    max-width: 560px;
    max-height: 90vh;
    overflow-y: auto;
    padding: 1.25rem 1.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}
.ag-modal-carte--petite { max-width: 420px; }
.ag-modal-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}
.ag-modal-entete h3 { margin: 0; }
.ag-modal-croix {
    border: none;
    background: none;
    font-size: 1.35rem;
    line-height: 1;
    color: var(--color-muted);
    cursor: pointer;
}
.ag-modal-croix:hover { color: var(--color-text); }

/* Formulaire : champs pleine largeur empilés + une grille pour jour/heure/durée */
#ag-form, #ag-type-form { display: flex; flex-direction: column; gap: 0.8rem; }
.ag-champ-plein { width: 100%; }
#ag-form input[type="text"],
#ag-form input[type="date"],
#ag-form input[type="time"],
#ag-form input[type="number"],
#ag-form input[type="url"],
#ag-form textarea,
#ag-type-form input[type="text"] {
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-family: inherit;
    font-size: 0.95rem;
    background: var(--color-surface);
    color: var(--color-text);
}
#ag-form textarea { resize: vertical; }

.ag-modal-grille {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 0.75rem 1rem;
}
.ag-color {
    width: 100%;
    height: 2.4rem;
    padding: 0.15rem;
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    background: var(--color-surface);
    cursor: pointer;
}

/* Pastilles de type (radios) */
.ag-types { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.ag-type-option { cursor: pointer; }
.ag-type-option input { position: absolute; opacity: 0; pointer-events: none; }
.ag-type-pastille {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--color-border-2);
    border-radius: 999px;
    font-size: 0.85rem;
    background: var(--color-surface);
    transition: border-color 0.12s, background 0.12s;
}
.ag-type-option input:checked + .ag-type-pastille {
    border-color: var(--color-primary);
    background: var(--color-accent-soft);
    font-weight: 600;
}
.ag-type-option input:focus-visible + .ag-type-pastille {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 1px;
}
.ag-type-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.ag-type-nouveau {
    border: 1px dashed var(--color-border-2);
    background: none;
    color: var(--color-primary);
    border-radius: 999px;
    padding: 0.3rem 0.6rem;
    font-size: 0.85rem;
    cursor: pointer;
}
.ag-type-nouveau:hover { border-color: var(--color-primary); }

/* Segments (récurrence, portée) */
.ag-segment {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 0.25rem;
    background: var(--color-surface-2);
}
.ag-segment-option { cursor: pointer; }
.ag-segment-option input { position: absolute; opacity: 0; pointer-events: none; }
.ag-segment-option span {
    display: inline-block;
    padding: 0.35rem 0.7rem;
    border-radius: 6px;
    font-size: 0.85rem;
    color: var(--color-muted);
}
.ag-segment-option input:checked + span {
    background: var(--color-surface);
    color: var(--color-text);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}
.ag-segment-option input:focus-visible + span { outline: 2px solid var(--color-focus-ring); }

/* Pied de la modale : Supprimer à gauche, Annuler / Valider à droite */
.ag-modal-pied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}
.ag-modal-pied-droite { display: flex; gap: 0.5rem; margin-left: auto; }
.ag-modal-supprimer { color: var(--color-error); }
.ag-modal-supprimer:hover {
    color: var(--color-error);
    border-color: var(--color-error);
    background: var(--color-danger-bg);
}

@media (max-width: 600px) {
    .ag-modal-grille { grid-template-columns: 1fr; }
}

/* =====================================================================
   Module Agenda — évolution : fenêtre 3 jours, chevrons, impératifs,
   fond vert coché, popups (vue semaine, remplacement)
   ===================================================================== */

/* Barre au-dessus des jours : libellé de période à gauche, actions à droite */
.ag-barre {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}
.ag-fenetre-label { font-size: 1.05rem; font-weight: 600; }
.ag-barre-actions { display: flex; gap: 0.5rem; }

/* Temps total de la journée : pastille discrète dans l'en-tête du jour */
.ag-colonne-total {
    margin-left: auto;
    font-size: 0.72rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--color-muted);
    padding: 0.05rem 0.35rem;
    border-radius: 999px;
    background: var(--color-surface-2);
}
.ag-colonne-entete.is-courant .ag-colonne-total {
    color: var(--color-agenda-blanc);
    background: color-mix(in srgb, var(--color-agenda-blanc) 25%, transparent);
}
/* Temps total dans l'en-tête d'un jour du popup semaine */
.ag-semaine-total {
    margin-left: auto;
    font-size: 0.68rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--color-muted);
}

/* Fenêtre : chevron rond | 3 colonnes | chevron rond.
   Items alignés EN HAUT (flex-start) pour que les chevrons restent à une
   position verticale STABLE — calés au niveau des en-têtes de jour — quelle que
   soit la hauteur des colonnes en dessous (plus de déplacement au fil des clics). */
.ag-fenetre { display: flex; align-items: flex-start; gap: 0.5rem; }
.ag-jours {
    flex: 1;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.6rem;
    min-width: 0;
}

/* Chevrons : boutons CARRÉS à coins arrondis (~35px, surface de clic agrandie
   pour le clic répété) calés en HAUT, face à la bande de date. La marge haute
   fixe les centre dans l'en-tête du jour (~40px de haut). */
.ag-chevron.ag-chevron--rond {
    flex-shrink: 0;
    margin-top: 3px;
    width: 35px;
    height: 70px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--color-muted);
    background: var(--color-agenda-blanc);
    border: 1px solid var(--color-border-2);
    border-radius: 8px;
    text-decoration: none;
    box-shadow: var(--shadow-sm);
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.ag-chevron.ag-chevron--rond:hover {
    color: var(--color-agenda-blanc);
    background: var(--color-agenda-marque);
    border-color: var(--color-agenda-marque);
    text-decoration: none;
}

/* ----- Zone « Impératifs » (haut de chaque jour) ----- */
.ag-imp {
    padding: 0.5rem 0.55rem;
    border-bottom: 1px dashed var(--color-border-2);
    transition: background 0.12s, box-shadow 0.12s;
}
.ag-imp.est-survol {
    background: var(--color-agenda-courant-soft);
    box-shadow: inset 0 0 0 2px var(--color-agenda-marque);
}
.ag-imp-titre {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-agenda-marque);
    margin-bottom: 0.4rem;
}
.ag-imp-icone { display: inline-flex; }
.ag-imp-icone svg { width: 15px; height: 15px; }
.ag-imp-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.3rem; }
.ag-imp-slot {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 1.9rem;
    padding: 0.15rem 0.3rem;
    border-radius: 6px;
}
.ag-imp-slot.est-vide {
    border: 1px dashed var(--color-border-2);
    color: var(--color-muted);
}
.ag-imp-slot.est-rempli {
    border: 1px solid color-mix(in srgb, var(--color-agenda-marque) 35%, var(--color-border));
    background: var(--color-agenda-courant-soft);
}
.ag-imp-num {
    flex-shrink: 0;
    width: 1.1rem;
    height: 1.1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--color-agenda-marque);
}
.ag-imp-vide { font-size: 0.75rem; font-style: italic; }
.ag-imp-faits { list-style: none; margin: 0.4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.ag-imp-fait { display: flex; }

/* ----- Mini-formulaire de cochage (todo + impératifs) ----- */
.ag-coche { display: flex; align-items: center; gap: 0.2rem; margin: 0; flex: 1; min-width: 0; }
.ag-coche-label { display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer; flex-shrink: 0; }
.ag-coche-label input[type="checkbox"] { cursor: pointer; }
.ag-coche-puce { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ag-coche-titre {
    border: none;
    background: none;
    padding: 0;
    font-family: inherit;
    font-size: 0.85rem;
    line-height: 1.25;
    color: var(--color-text);
    text-align: left;
    cursor: pointer;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ag-coche-titre:hover { color: var(--color-primary); }
.ag-coche.est-fait .ag-coche-titre { text-decoration: line-through; color: var(--color-muted); }
.ag-coche-valider { display: none; }

/* ----- Zone « À faire » ----- */
.ag-todo { padding: 0.5rem 0.55rem 0.6rem; border-bottom: 1px dashed var(--color-border-2); }
.ag-todo-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.ag-todo-item { display: flex; align-items: center; gap: 0.2rem; margin: 0; border-radius: 6px; }
.ag-todo-item[draggable="true"] { cursor: grab; }
.ag-todo-item.est-glisse, .ag-evt.est-glisse { opacity: 0.4; }

/* ----- Événement d'agenda COCHÉ : fond vert léger (pas de couleur en dur) ----- */
.ag-evt.est-fait {
    opacity: 1;
    background: var(--color-agenda-fait-fond);
    border-color: var(--color-agenda-fait-bord);
}
.ag-evt.est-fait .ag-evt-titre { text-decoration: line-through; color: var(--color-muted); }
/* Événement impératif : petit badge « ! » bleu de marque */
.ag-evt-badge {
    margin-left: auto;
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--color-agenda-blanc);
    background: var(--color-agenda-marque);
    border-radius: 50%;
}

/* ----- Case « Impératif » du popup d'édition ----- */
.ag-case-imperatif {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.45rem;
    cursor: pointer;
    color: var(--color-text);
    font-size: 0.9rem;
}

/* ----- Popup « Vue semaine » (lecture seule) ----- */
.ag-modal-carte--large { max-width: 960px; }
.ag-semaine-note { margin: 0 0 0.75rem; font-size: 0.85rem; }
/* Trois lignes de 3 colonnes : Lun-Mar-Mer / Jeu-Ven-Sam / Dimanche pleine
   largeur (grid-column: 1 / -1). Grille à 3 colonnes → aucun débordement. */
.ag-semaine-grille {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
}
.ag-semaine-jour {
    background: var(--color-agenda-jour-fond);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 0.4rem;
    min-height: 6rem;
    min-width: 0; /* autorise la colonne à se compresser (pas de débordement) */
}
.ag-semaine-jour.is-courant { border-color: var(--color-agenda-marque); box-shadow: 0 0 0 1px var(--color-agenda-marque); }
.ag-semaine-jour-entete {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.3rem;
    padding-bottom: 0.3rem;
    margin-bottom: 0.3rem;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.75rem;
    text-transform: uppercase;
    color: var(--color-muted);
}
.ag-semaine-jour-entete strong { font-size: 0.95rem; color: var(--color-text); }
.ag-semaine-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.ag-semaine-liste li { display: flex; align-items: center; gap: 0.25rem; font-size: 0.78rem; line-height: 1.2; min-width: 0; }
.ag-semaine-liste li.est-fait { color: var(--color-muted); text-decoration: line-through; }
.ag-semaine-puce { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.ag-semaine-imp {
    flex-shrink: 0;
    width: 0.85rem; height: 0.85rem;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.6rem; font-weight: 700;
    color: var(--color-agenda-blanc); background: var(--color-agenda-marque);
    border-radius: 50%;
}
.ag-semaine-heure { color: var(--color-muted); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.ag-semaine-titre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }

/* ----- Nuances suggérées du popup « Nouveau type » (deux familles) ----- */
.ag-nuances { display: flex; flex-wrap: wrap; gap: 0.75rem 1.25rem; }
.ag-nuance-groupe { display: flex; flex-direction: column; gap: 0.3rem; }
.ag-nuance-famille {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-muted);
}
.ag-nuance-liste { display: flex; gap: 0.35rem; }
.ag-nuance {
    width: 22px;
    height: 22px;
    border-radius: 6px;
    border: 1px solid var(--color-border-2);
    padding: 0;
    cursor: pointer;
    transition: transform 0.1s, box-shadow 0.1s;
}
.ag-nuance:hover { transform: scale(1.1); }
.ag-nuance.est-choisie {
    box-shadow: 0 0 0 2px var(--color-surface), 0 0 0 4px var(--color-focus-ring);
}

/* ----- Modale de remplacement (règle des 3 impératifs) ----- */
.ag-remplacer-liste { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.5rem 0 0; }
.ag-remplacer-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--color-border-2);
    border-radius: 8px;
    cursor: pointer;
}
.ag-remplacer-option:hover { border-color: var(--color-primary); background: var(--color-surface-2); }

/* Responsive : sous 720px, une seule colonne de jour + chevrons plus fins */
@media (max-width: 720px) {
    .ag-jours { grid-template-columns: 1fr; }
    .ag-chevron { width: 2rem; font-size: 1.4rem; }
}

/* =====================================================================
   Module Agenda — évolution 2 : temps Repas/Travail, réordonnancement
   des événements libres, événements fixes, popup semaine 3 lignes
   ===================================================================== */

/* ----- Deux totaux (Repas / Travail) sous l'en-tête du jour ----- */
.ag-colonne-temps {
    display: flex;
    justify-content: center;
    gap: 0.6rem;
    padding: 0.25rem 0.4rem;
    background: var(--color-agenda-blanc);
    border-bottom: 1px solid var(--color-border);
    flex-wrap: wrap;
}
.ag-colonne-entete.is-courant + .ag-colonne-temps {
    background: color-mix(in srgb, var(--color-agenda-marque) 8%, var(--color-agenda-blanc));
}
.ag-temps {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.7rem;
    color: var(--color-muted);
}
.ag-temps strong { font-variant-numeric: tabular-nums; color: var(--color-text); }
.ag-temps-pt {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    display: inline-block;
}
.ag-temps--repas .ag-temps-pt,
.ag-temps-pt--repas   { background: var(--color-agenda-repas); }
.ag-temps--travail .ag-temps-pt,
.ag-temps-pt--travail { background: var(--color-agenda-travail); }

/* ----- Vignette d'agenda : poignée grip (libre) + corps ----- */
.ag-evt {
    flex-direction: row;      /* grip à gauche, corps à droite */
    align-items: stretch;
    gap: 0.35rem;
}
.ag-evt-corps {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1;
    min-width: 0;
}
.ag-evt-grip {
    display: flex;
    align-items: flex-start;
    padding-top: 0.1rem;
    color: var(--color-border-2);
    cursor: grab;
    flex-shrink: 0;
}
.ag-evt-grip svg { width: 16px; height: 16px; }
.ag-evt.est-libre { cursor: grab; }
.ag-evt.est-libre:active { cursor: grabbing; }

/* (Plus de distinction fixe/libre : tous les événements sont réordonnables.) */

/* Zone Agenda survolée pendant un réordonnancement */
.ag-detail.est-reorder {
    outline: 2px dashed var(--color-agenda-marque);
    outline-offset: -3px;
    border-radius: 8px;
}

/* ----- Popup vue semaine : 3 lignes, dimanche pleine largeur ----- */
/* La grille reste sur 3 colonnes ; le dimanche s'étale sur toute la largeur. */
.ag-semaine-jour--large { grid-column: 1 / -1; }
/* Événements du dimanche étalés en colonnes internes pour occuper la largeur */
.ag-semaine-liste--colonnes {
    column-width: 12rem;
    column-gap: 1rem;
}
.ag-semaine-liste--colonnes li { break-inside: avoid; }

/* Total du popup : deux durées avec points de couleur (repas · travail) */
.ag-semaine-total {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-size: 0.66rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--color-muted);
}
.ag-semaine-total .ag-temps-pt { width: 7px; height: 7px; }
.ag-semaine-total .ag-temps-pt--travail { margin-left: 0.25rem; }

/* =====================================================================
   Agenda — lien (URL) optionnel d'un événement
   Icône discrète à côté du titre, affichée UNIQUEMENT si l'événement a un
   lien effectif (série ou override d'occurrence). Bleu de marque au repos,
   accent au survol : aucune couleur en dur, tout vient de :root.
   ===================================================================== */

/* Titre + icône sur la même ligne (le titre garde toute la place restante) */
.ag-evt-titre-ligne {
    display: flex;
    align-items: flex-start;
    /* Écart resserré : la zone active de l'icône (18px pour un glyphe de 11px)
       apporte déjà ~3,5px de respiration de chaque côté. */
    gap: 0.15rem;
    min-width: 0;
}
.ag-evt-titre-ligne .ag-evt-titre { flex: 1; min-width: 0; }

/* Icône cliquable de la vignette (vue 3 jours).
   GLYPHE VOLONTAIREMENT PETIT (11px) pour rester discret à côté du titre, mais
   ZONE ACTIVE de 18×18px : la cible de clic reste confortable, l'encombrement
   visuel non. Le padding est porté par la boîte fixe (pas de marge ajoutée). */
.ag-evt-lien {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    padding: 0;
    margin-top: -0.05rem;
    border-radius: 4px;
    color: var(--color-primary);
    line-height: 0;
    cursor: pointer;
    transition: color 0.12s, background 0.12s;
}
.ag-evt-lien svg { width: 11px; height: 11px; }
.ag-evt-lien:hover {
    color: var(--color-agenda-marque);
    background: color-mix(in srgb, var(--color-agenda-marque) 12%, transparent);
    text-decoration: none;
}
.ag-evt-lien:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 1px;
}
/* Un événement coché reste lisible : le lien ne prend pas le barré du titre. */
.ag-evt.est-fait .ag-evt-lien { text-decoration: none; }

/* Même icône dans le popup « Vue semaine » (lecture seule, aucun geste
   concurrent) : même réduction, pour rester cohérent avec la vignette. */
.ag-semaine-lien {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    color: var(--color-primary);
    line-height: 0;
}
.ag-semaine-lien svg { width: 10px; height: 10px; }
.ag-semaine-lien:hover { color: var(--color-agenda-marque); text-decoration: none; }
.ag-semaine-liste li.est-fait .ag-semaine-lien { text-decoration: none; }

/* Libellé « Lien (optionnel) » du popup : petite icône de chaîne */
.ag-label-lien { display: inline-flex; align-items: center; gap: 0.3rem; }
.ag-label-icone { display: inline-flex; color: var(--color-primary); }
.ag-label-icone svg { width: 14px; height: 14px; }

/* =====================================================================
   Module « Idées de vidéo »
   Recherche globale en tête, quatre onglets (Lano / Allô / Autres /
   Externe), listes de fiches cliquables et modale de détail. Toutes les
   teintes viennent de :root (bloc --color-idv-*).
   ===================================================================== */

/* Le bandeau de titre du module a été retiré (le nom du module vit dans la
   barre de navigation) : .idv-entete n'a plus d'emploi. La recherche globale
   prend la tête de la carte. */

/* ----- Recherche globale ----- */
/* Champ nettement plus haut (~60px) : c'est la porte d'entrée du module.
   La hauteur vient du padding vertical + d'un texte un peu plus grand, et
   min-height la garantit quelle que soit la police du navigateur.
   align-items: center centre l'icône, la saisie et la croix sur la même ligne
   médiane ; chaque enfant est un flex item (display: inline-flex sur l'icône),
   donc aucun décalage de ligne de base ne subsiste.

   COMPOSANT PARTAGÉ : l'onglet « Mes ingrédients » du module Alimentation
   réutilise ce composant tel quel (mêmes classes .idv-recherche*), sans rien
   dupliquer ni redéfinir — une seule définition, donc une seule apparence. */
.idv-recherche {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1rem;
    padding: 0.7rem 1rem;
    min-height: 3.6rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border-2);
    border-radius: 999px;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.idv-recherche:focus-within {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.idv-recherche-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-idv-marque);
    flex-shrink: 0;
    line-height: 0;
}
.idv-recherche-icone svg { width: 22px; height: 22px; }
.idv-recherche-champ {
    flex: 1;
    min-width: 0;
    border: none;
    background: transparent;
    color: var(--color-text);
    font-family: inherit;
    font-size: 1.05rem;
    line-height: 1.5;
    padding: 0.35rem 0;
}
.idv-recherche-champ:focus { outline: none; }
.idv-recherche-vider {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.9rem;
    height: 1.9rem;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--color-muted);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}
/* La règle display ci-dessus l'emporterait sur le display:none du navigateur :
   on rétablit explicitement le masquage porté par l'attribut hidden (la croix
   n'apparaît que lorsque le champ contient du texte). */
.idv-recherche-vider[hidden] { display: none; }
.idv-recherche-vider:hover { color: var(--color-text); background: var(--color-surface-2); }

/* ----- Filtres (onglet de recherche, rubrique) ----- */
.idv-filtres {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.75rem;
}
.idv-filtres[hidden] { display: none; }
.idv-filtres-titre { font-size: 0.8rem; color: var(--color-muted); margin-right: 0.2rem; }
.idv-filtre {
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-muted);
    font-family: inherit;
    font-size: 0.82rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.idv-filtre:hover { color: var(--color-primary); border-color: var(--color-border-2); background: var(--color-surface-2); }
.idv-filtre.is-active {
    color: var(--color-primary);
    background: var(--color-accent-soft);
    border-color: var(--color-primary);
    font-weight: 600;
}
/* ----- Filtres de classement : trois menus déroulants sur UNE seule ligne ----- */
.idv-filtres-ligne {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 1.1rem;
    margin: 0 0 0.9rem;
    padding-bottom: 0.8rem;
    border-bottom: 1px solid var(--color-idv-gris-bord);
}
.idv-filtre-champ { display: inline-flex; align-items: center; gap: 0.4rem; }
.idv-filtre-libelle { font-size: 0.8rem; color: var(--color-muted); white-space: nowrap; }
.idv-filtre-select {
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: 0.82rem;
    cursor: pointer;
    max-width: 15rem;
}
.idv-filtre-select:focus-visible {
    outline: none;
    border-color: var(--color-idv-marque);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* ----- Barre d'onglets du module ------------------------------------
   Rendue par le composant partagé App\Lib\SousNav (mode boutons) : le style
   vient des règles .sousnav* de la section « Sous-navigation (niveau 2) ». Les
   pastilles de comptage utilisent .sousnav-compte. Rien de spécifique ici. */

/* ----- En-tête d'un panneau d'onglet ----- */
.idv-panneau-entete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}
.idv-panneau-entete h2 { margin-bottom: 0.15rem; }
.idv-panneau-entete p { margin: 0; font-size: 0.85rem; }
.idv-ajouter { display: inline-flex; align-items: center; gap: 0.4rem; flex-shrink: 0; }
.idv-ajouter-icone { display: inline-flex; }
.idv-ajouter-icone svg { width: 18px; height: 18px; }
.idv-vide { margin: 0; font-size: 0.88rem; }

/* ----- Liste de fiches ----- */
.idv-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}
/* Liste en FILETS : plus d'encadré ni de fond par item — un simple trait gris
   sépare deux fiches, et le dernier n'en porte pas. Nettement plus léger que la
   succession de cartes précédente. */
.idv-item {
    display: flex;
    align-items: stretch;
    gap: 0.35rem;
    border-bottom: 1px solid var(--color-idv-gris-bord);
    transition: background 0.12s;
}
.idv-item:last-child { border-bottom: none; }
.idv-item:hover { background: var(--color-idv-gris); }
.idv-item[hidden] { display: none; }
/* Vidéo PUBLIÉE : la ligne entière (titre + meta) prend un fond vert léger, pour
   repérer d'un coup d'œil ce qui est sorti en balayant la liste. Posé après la
   règle de survol pour que la teinte verte reste celle qui domine. */
.idv-item--publiee { background: var(--color-idv-item-publie-fond); }
.idv-item--publiee:hover { background: var(--color-idv-item-publie-survol); }
/* Une ligne masquée par un filtre ne doit pas laisser le filet de la dernière
   ligne visible : on retire aussi le filet de celle qui précède les masquées. */
.idv-item:has(~ .idv-item:not([hidden]))  { border-bottom: 1px solid var(--color-idv-gris-bord); }
.idv-item:not(:has(~ .idv-item:not([hidden]))) { border-bottom: none; }

/* Toute la ligne est un bouton : clic = ouverture de la fiche.
   UNE SEULE ligne visuelle : titre, classement, mots-clés et statut s'enchaînent
   de gauche à droite, collés, avec un espacement régulier et réduit. Rien n'est
   rejeté à droite (pas de `flex: 1` sur le titre, pas de `space-between`) :
   l'espace libre se retrouve naturellement en fin de ligne. */
.idv-item-btn {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-start;
    gap: 0.3rem;
    padding: 0.55rem 0.25rem;
    border: none;
    background: transparent;
    color: var(--color-text);
    font-family: inherit;
    text-align: left;
    line-height: 1.4;
    overflow: hidden;
    cursor: pointer;
}
.idv-item-btn:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: -2px; }

/* Tout ce qui suit le titre garde sa taille : les pastilles ne se compriment
   jamais, pour rester lisibles même sur une ligne très chargée. */
.idv-item-btn > * { flex: 0 0 auto; }

/* Le TITRE, en tête de l'enchaînement. Seul élément autorisé à rétrécir, et en
   DERNIER RECOURS uniquement (débordement d'une ligne très chargée) : il se
   tronque alors par « … » sans jamais casser l'ordre ni repousser la suite. */
.idv-item-titre {
    flex: 0 1 auto;
    min-width: 0;
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Petit filet gris vertical, posé ENTRE deux groupes réellement présents. */
.idv-meta-sep {
    display: inline-block;
    width: 1px;
    height: 0.95rem;
    margin: 0 0.15rem;
    background: var(--color-idv-gris-bord);
}

/* ----- Badge de STATUT -----
   Base NEUTRE (gris doux) : elle sert telle quelle à « Idée », point de départ
   du pipeline, et à TOUT le jeu de lecture de l'onglet Externe (à regarder / vu
   / à revoir), qui reste volontairement discret.
   Les quatre modificateurs suivants dessinent l'ÉCHELLE DE VERT du pipeline de
   production : plus la vidéo avance, plus la pastille verdit. */
.idv-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--color-idv-statut-texte);
    background: var(--color-idv-statut-fond);
    border: 1px solid var(--color-idv-statut-bord);
}
.idv-badge--a_tourner {
    color: var(--color-idv-vert-texte);
    background: var(--color-idv-statut-atourner-fond);
    border-color: var(--color-idv-statut-atourner-bord);
}
.idv-badge--tournee {
    color: var(--color-idv-vert-texte);
    background: var(--color-idv-statut-tournee-fond);
    border-color: var(--color-idv-statut-tournee-bord);
}
.idv-badge--montage {
    color: var(--color-idv-vert-texte);
    background: var(--color-idv-statut-montage-fond);
    border-color: var(--color-idv-statut-montage-bord);
}
.idv-badge--publiee {
    color: var(--color-idv-statut-publiee-texte);
    background: var(--color-idv-statut-publiee-fond);
    border-color: var(--color-idv-statut-publiee-bord);
    font-weight: 700;
}

/* ----- Étiquette d'ORIGINE : montrée UNIQUEMENT là où les catégories se mêlent
   — la vue « Tout » des idées de vidéos et les résultats de recherche. Sur une
   catégorie isolée, elle n'apprendrait rien : elle disparaît.
   Quatre INTENSITÉS de la même famille : bleu foncé → bleu → bleu pâle → gris. */
.idv-origine { display: none; }
.idv-resultats .idv-origine,
.idv-vue-tout .idv-origine {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
}
.idv-resultats .idv-origine--lano,
.idv-vue-tout .idv-origine--lano    { background: var(--color-idv-lano);    color: var(--color-surface); }
.idv-resultats .idv-origine--allo,
.idv-vue-tout .idv-origine--allo    { background: var(--color-idv-allo);    color: var(--color-surface); }
.idv-resultats .idv-origine--autres,
.idv-vue-tout .idv-origine--autres  { background: var(--color-idv-autres);  color: var(--color-idv-bleu-texte); }
.idv-resultats .idv-origine--externe { background: var(--color-idv-externe); color: var(--color-idv-gris-texte); }
.idv-resultats-info { margin: 0 0 0.6rem; font-size: 0.85rem; }

/* ----- Étiquettes de classement : TROIS niveaux de remplissage, une seule
   famille (le bleu). C'est le remplissage, et non la teinte, qui les sépare —
   aucun vert ici, il est réservé au statut.
     RUBRIQUE  : bleu marque PLEIN ;
     FORMATION : bleu très clair REMPLI ;
     MODULE    : bleu en CONTOUR sur fond blanc. */
.idv-rubrique-tag,
.idv-formation-tag,
.idv-module-tag {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    font-size: 0.7rem;
}
.idv-rubrique-tag {
    color: var(--color-idv-rubrique-texte);
    background: var(--color-idv-rubrique-fond);
    border: 1px solid var(--color-idv-rubrique-fond);
}
.idv-formation-tag {
    color: var(--color-idv-formation-texte);
    background: var(--color-idv-formation-fond);
    border: 1px solid var(--color-idv-formation-fond);
}
.idv-module-tag {
    color: var(--color-idv-module-texte);
    background: var(--color-surface);
    border: 1px solid var(--color-idv-module-bord);
}

/* ----- Mots-clés (pastilles grises) ----- */
.idv-mots { display: flex; flex-wrap: wrap; gap: 0.25rem; }
.idv-mot {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.72rem;
    color: var(--color-idv-mot-texte);
    background: var(--color-idv-mot-fond);
    border: 1px solid transparent;
}
.idv-mot--editable { border-color: var(--color-idv-gris-bord); }
.idv-mot-retirer {
    border: none;
    background: transparent;
    color: var(--color-muted);
    font-size: 0.95rem;
    line-height: 1;
    padding: 0;
    cursor: pointer;
}
.idv-mot-retirer:hover { color: var(--color-error); }

/* ----- Icône de lien d'une fiche (ouverture en nouvel onglet) ----- */
.idv-item-lien {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 34px;
    color: var(--color-primary);
    border-left: 1px solid var(--color-border);
    transition: color 0.12s, background 0.12s;
}
.idv-item-lien svg { width: 14px; height: 14px; }
.idv-item-lien:hover {
    color: var(--color-idv-marque);
    background: color-mix(in srgb, var(--color-idv-marque) 10%, transparent);
    text-decoration: none;
}

/* ----- Modale de détail (calquée sur celle de l'Agenda) ----- */
.idv-modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.idv-modal[hidden] { display: none; }
.idv-modal-fond { position: absolute; inset: 0; background: rgba(15, 23, 42, 0.45); }
.idv-modal-carte {
    position: relative;
    width: 100%;
    max-width: 620px;
    max-height: 90vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 1.1rem 1.2rem 1.2rem;
}
.idv-modal-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}
.idv-modal-entete h3 { margin: 0; }
.idv-modal-croix {
    border: none;
    background: transparent;
    color: var(--color-muted);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.2rem;
}
.idv-modal-croix:hover { color: var(--color-text); }

/* Formulaire de la modale. Ciblé par une CLASSE (et non plus par l'identifiant
   #idv-form) : les DEUX sous-modules de « Idées » — Idées de Cédric et Idées de
   vidéos — portent la même modale, chacun avec ses propres identifiants. */
.idv-form { display: flex; flex-direction: column; gap: 0.8rem; }
.idv-champ-plein { width: 100%; }
.idv-form input[type="text"],
.idv-form input[type="url"],
.idv-form textarea,
.idv-form .idv-select {
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-family: inherit;
    font-size: 0.95rem;
    background: var(--color-surface);
    color: var(--color-text);
}
.idv-form textarea { resize: vertical; }
.idv-form input:focus-visible,
.idv-form textarea:focus-visible,
.idv-form .idv-select:focus-visible {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Statut : pastilles radio (un seul jeu visible à la fois) */
.idv-segment { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.idv-segment-option { cursor: pointer; }
.idv-segment-option input { position: absolute; opacity: 0; pointer-events: none; }
.idv-segment-pastille {
    display: inline-flex;
    align-items: center;
    padding: 0.35rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.85rem;
    color: var(--color-muted);
    background: var(--color-surface);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.idv-segment-option:hover .idv-segment-pastille { border-color: var(--color-idv-bleu-bord); }
.idv-segment-option input:focus-visible + .idv-segment-pastille { outline: 2px solid var(--color-focus-ring); }
/* Statut RETENU : la seule pastille bleue du groupe — un seul jeu de statuts
   étant visible à la fois, une règle unique suffit (plus de nuance par statut). */
.idv-segment-option input:checked + .idv-segment-pastille {
    color: var(--color-idv-bleu-texte);
    border-color: var(--color-idv-bleu-bord);
    background: var(--color-idv-bleu-fond);
    font-weight: 600;
}

/* CORRECTIF : .field porte display:flex, qui l'emporte sur le display:none que
   le navigateur applique à l'attribut hidden — sans cette règle, la modale
   affichait TOUS ses blocs à la fois (les deux jeux de statuts, la rubrique
   partout…). On rétablit explicitement le masquage. */
.idv-form .field[hidden] { display: none; }

/* Champ « Lien » de la modale + icône d'ouverture */
.idv-label-lien { display: inline-flex; align-items: center; gap: 0.3rem; }
.idv-label-icone { display: inline-flex; color: var(--color-primary); }
.idv-label-icone svg { width: 14px; height: 14px; }
.idv-lien-ligne { display: flex; align-items: center; gap: 0.4rem; }
.idv-lien-ouvrir {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    color: var(--color-primary);
}
.idv-lien-ouvrir[hidden] { display: none; }
.idv-lien-ouvrir svg { width: 15px; height: 15px; }
.idv-lien-ouvrir:hover { color: var(--color-idv-marque); border-color: var(--color-idv-marque); text-decoration: none; }

/* Rubrique : liste + création à la volée */
.idv-rubrique-ligne { display: flex; align-items: center; gap: 0.4rem; }
.idv-rubrique-ligne .idv-select { flex: 1; }
.idv-rubrique-nouveau,
.idv-rubrique-annuler,
.idv-mot-ajouter {
    flex-shrink: 0;
    padding: 0.45rem 0.7rem;
    border: 1px dashed var(--color-border-2);
    border-radius: 6px;
    background: var(--color-surface);
    color: var(--color-muted);
    font-family: inherit;
    font-size: 0.85rem;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s;
}
.idv-rubrique-nouveau:hover,
.idv-rubrique-annuler:hover,
.idv-mot-ajouter:hover { border-color: var(--color-idv-marque); color: var(--color-idv-marque); }
.idv-rubrique-creation { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.45rem; }
.idv-rubrique-creation[hidden] { display: none; }
.idv-rubrique-creation input { flex: 1; }

/* Bouton « Ajouter » qui VALIDE la création d'une rubrique / formation / module :
   plein bleu de marque, pour se lire comme l'action principale de la ligne face
   au « Annuler » discret qui l'accompagne. */
.idv-crea-ajouter {
    flex-shrink: 0;
    padding: 0.45rem 0.8rem;
    border: 1px solid var(--color-idv-marque);
    border-radius: 6px;
    background: var(--color-idv-marque);
    color: var(--color-surface);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.idv-crea-ajouter:hover {
    background: var(--color-idv-bleu-texte);
    border-color: var(--color-idv-bleu-texte);
}
.idv-crea-ajouter:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 1px; }

/* Entrée « à créer » injectée dans un select par le bouton « Ajouter » :
   elle part au POST via le champ texte, le serveur fait le find-or-create. */
.idv-select option[data-nouveau] { font-style: italic; }

/* Mots-clés dans la modale */
.idv-mots-saisie { display: flex; align-items: center; gap: 0.4rem; }
.idv-mots-saisie input { flex: 1; }
.idv-mots-liste { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.45rem; }

/* Pied de la modale */
.idv-modal-pied {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--color-border);
}
.idv-modal-pied-droite { display: flex; gap: 0.5rem; margin-left: auto; }
.idv-modal-supprimer { color: var(--color-error); }
.idv-modal-supprimer:hover { background: var(--color-danger-bg); color: var(--color-danger-fg); }
.idv-modal-supprimer[hidden] { display: none; }

/* Écrans étroits : en-têtes et boutons passent à la ligne */
@media (max-width: 720px) {
    .idv-panneau-entete { flex-direction: column; align-items: stretch; }
    .idv-ajouter { justify-content: center; }
}

/* =====================================================================
   Module « Listes » — listes de courses/achats par magasin (préfixe .lst-)
   ---------------------------------------------------------------------
   TOUT est scopé sous des classes .lst-* : aucune règle existante n'est
   modifiée, aucune couleur n'est écrite en dur (la palette :root est la
   seule source). Les briques déjà partagées sont RÉUTILISÉES telles
   quelles plutôt que redéfinies : la grande carte .card, le bouton
   .btn/.btn-primary, et surtout l'en-tête de carte du tableau de bord
   (.accueil-entete-titre > .accueil-pastille + <h2>) — d'où la pastille
   ronde à filet gris, l'icône grise et le titre sombre des cartes de
   magasin, strictement identiques à ceux de « Fin de mois ».
   ===================================================================== */

/* ----- « Nouveau magasin » : dernier bloc de la page -----
   La page n'a plus de bandeau de titre (le nom du module est porté par
   l'onglet actif de la barre principale) et ce bouton en ferme le bas,
   après la section des magasins désactivés.

   Il est enfant DIRECT de .main, une colonne flex : sans align-self il
   s'étirerait sur toute la largeur. flex-start le ramène à sa largeur
   naturelle ET le cale sur le bord gauche de la grille des magasins. */
.lst-ajouter {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
}
.lst-ajouter-icone { display: inline-flex; }
.lst-ajouter-icone svg { width: 18px; height: 18px; }

/* ----- Grille des magasins : 4 cartes par ligne sur grand écran -----
   Colonnes de largeur ÉGALE (minmax(0, 1fr) : le 0 évite qu'un long nom
   d'article élargisse sa colonne), repli progressif à 3 puis 2 puis 1
   colonne. Les cartes d'une même ligne sont étirées à la MÊME hauteur
   (align-items: stretch, le défaut de la grille) : combiné au margin-top
   auto de la réserve, cela aligne les blocs repliables d'une même ligne
   même quand les listes n'ont pas la même longueur. */
.lst-grille {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--gap);
}
@media (max-width: 1500px) { .lst-grille { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 1100px) { .lst-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 720px)  { .lst-grille { grid-template-columns: minmax(0, 1fr); } }

/* Carte d'un magasin : la grande carte .card, en colonne, avec un padding
   un peu resserré (quatre par ligne = colonnes étroites). La réserve est
   poussée en pied de carte. */
.lst-carte {
    display: flex;
    flex-direction: column;
    padding: 1.25rem 1.25rem 1rem;
}
.lst-carte > .lst-reserve { margin-top: auto; }

/* En-tête : le composant de l'accueil (.accueil-entete-titre >
   .accueil-pastille + <h2>) est réutilisé TEL QUEL à l'intérieur. Cette
   classe ne fait que le mettre en ligne avec le compteur « à acheter »,
   rejeté tout à droite, et poser l'espacement sous l'en-tête. */
.lst-carte-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin: 0 0 0.6rem;
}
/* Nom du magasin : MÊME taille et MÊME graisse que les titres de cartes du
   tableau de bord. Aucune font-size n'est posée — comme .accueil-bloc-entete h2
   et .fdm-carte-entete h2, le titre garde celle des <h2> de l'application, et
   la graisse 600 de la règle globale. Seule la marge est remise à zéro. */
.lst-carte-entete h2 { margin: 0; }

/* Nom long : le titre se tronque proprement plutôt que d'élargir sa colonne
   ou de casser la grille à 4 cartes. min-width: 0 est indispensable sur le
   groupe pastille + titre — sans lui, un élément flex refuse de descendre
   sous sa taille de contenu et l'ellipsis ne se déclenche jamais. La règle
   est SCOPÉE au module : .accueil-entete-titre, partagée avec le tableau de
   bord, n'est pas touchée ailleurs. Le nom complet reste en infobulle. */
.lst-carte-entete .accueil-entete-titre { min-width: 0; }
.lst-carte-nom {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Le LOGO du magasin ouvre la modale d'édition : c'est un <button> qui porte
   la classe .accueil-pastille, donc STRICTEMENT le même rendu que la pastille
   des cartes du tableau de bord. On ne remet ici que ce qu'un bouton apporte
   en trop (padding, police) et l'affordance de clic. */
.lst-logo {
    padding: 0;
    font: inherit;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s;
}
.lst-logo:hover {
    border-color: var(--nav-marque);
    color: var(--nav-marque);
}
.lst-logo:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }

/* ----- Glisser-déposer : réorganisation des cartes de magasins -----
   Même vocabulaire d'état que l'Agenda : .est-glisse sur l'élément soulevé,
   .est-reorder sur la zone qui accueille. Sobre : l'élément s'estompe et
   s'affaisse légèrement, la grille prend un liseré pointillé discret.

   Le NOM est la poignée, d'où le curseur de préhension — posé UNIQUEMENT
   au-dessus de 720px, puisque le mécanisme n'est pas installé en dessous :
   pas de curseur qui promette un geste indisponible. */
@media (min-width: 721px) {
    .lst-carte-nom { cursor: grab; }
    .lst-carte.est-glisse .lst-carte-nom { cursor: grabbing; }
}
.lst-carte.est-glisse {
    opacity: 0.5;
    transform: scale(0.99);
}
.lst-grille.est-reorder {
    outline: 1px dashed var(--color-border-2);
    outline-offset: 6px;
    border-radius: var(--radius);
}

/* ----- Pastille compteur (« à acheter » et « Réserve ») -----
   Petit rond compact, MÊME traitement pour les deux compteurs du module.
   Gris neutre par défaut ; le modificateur --bleue passe au bleu de marque
   sur fond bleu très clair (teintes dérivées de --nav-marque = #00aaef). */
.lst-pastille {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    min-width: 1.4rem;
    height: 1.4rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--color-muted);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
}
.lst-pastille--bleue {
    color: var(--nav-marque);
    background: color-mix(in srgb, var(--nav-marque) 12%, var(--color-surface));
    border-color: color-mix(in srgb, var(--nav-marque) 30%, transparent);
}

/* ----- Liste des articles ----- */
.lst-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}
.lst-article {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0;
    border-top: 1px solid var(--color-border);
    font-size: 0.9rem;
}
.lst-article:first-child { border-top: none; }

/* Nom : c'est un BOUTON (il ouvre la modale d'édition de l'article), remis
   à plat pour se lire comme du texte courant. Il occupe la place restante
   et se replie sur plusieurs lignes plutôt que de pousser l'icône de note
   ou le bouton de déplacement. La NOTE n'est pas rendue sous l'article —
   elle est signalée par .lst-note-icone. */
.lst-article-nom {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
    padding: 0;
    background: transparent;
    border: none;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}
.lst-article-nom:hover { color: var(--nav-marque); }
.lst-article-nom:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }

/* Les deux mini-formulaires de la ligne (coche, flèche) ne doivent peser
   sur rien : ils n'existent que pour porter leur POST. */
.lst-coche-form,
.lst-deplacer-form {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    margin: 0;
}

/* Article COCHÉ = déjà dans le panier : nom barré et estompé. L'article
   reste affiché, c'est bien un état de ligne et pas un retrait. */
.lst-article.is-coche .lst-article-nom {
    text-decoration: line-through;
    color: var(--color-muted);
}

/* Case à cocher : même rendu que les cases unifiées de « Fin de mois »
   (carré arrondi neutre, coché = bleu de marque plein + coche blanche
   dessinée en CSS). À l'étape 1 elle est `disabled`, donc sans curseur
   de clic et légèrement estompée. */
.lst-case {
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    flex-shrink: 0;
    width: 1.05rem;
    height: 1.05rem;
    margin: 0.12rem 0 0;
    border: 1px solid var(--color-border-2);
    border-radius: 5px;
    background: var(--color-surface);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.lst-case:hover:not(:disabled) { border-color: var(--nav-marque); }
.lst-case:checked {
    border-color: var(--nav-marque);
    background: var(--nav-marque);
}
.lst-case:checked::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 46%;
    width: 0.28rem;
    height: 0.55rem;
    border: solid var(--nav-blanc);
    border-width: 0 2px 2px 0;
    transform: translate(-50%, -50%) rotate(45deg);
}
.lst-case:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 1px; }
.lst-case:disabled { cursor: default; opacity: 0.75; }

/* Icône de NOTE en fin de ligne : marqueur gris sans cadre, rendu QUE si
   l'article porte une note (le texte est en infobulle) ; un article sans
   note n'affiche rien du tout à cet emplacement — pas de picto pâle qui
   ferait croire à un bouton inactif. C'est un bouton : il ouvre la modale
   de l'article directement sur le champ Note. */
.lst-note-icone {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    padding: 0;
    background: transparent;
    border: none;
    color: var(--color-muted);
    cursor: pointer;
    transition: color 0.15s;
}
.lst-note-icone:hover { color: var(--nav-marque); }
.lst-note-icone:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }
.lst-note-icone svg { width: 15px; height: 15px; }

/* Bouton de DÉPLACEMENT en fin de ligne : vrai bouton carré (~24px), filet
   fin et coins arrondis — flèche BAS en liste active (« envoyer en
   réserve »), flèche HAUT en réserve (« remonter dans la liste »).
   ÉTAPE 2 : rendu mais `disabled`, il sera branché à l'étape 3. */
.lst-deplacer {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    color: var(--color-muted);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.lst-deplacer:hover:not(:disabled) {
    color: var(--nav-marque);
    border-color: var(--nav-marque);
    background: color-mix(in srgb, var(--nav-marque) 8%, var(--color-surface));
}
.lst-deplacer:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 1px; }
.lst-deplacer svg { width: 14px; height: 14px; }
.lst-deplacer:disabled { cursor: default; opacity: 0.55; }

/* Liste vide (active ou réserve) */
.lst-liste-vide { margin: 0.15rem 0 0; font-size: 0.8rem; }
.lst-vide { margin: 0; }

/* ----- « + Nouvel article » : appel discret sous la liste ----- */
.lst-nouvel-article {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    gap: 0.3rem;
    margin: 0.6rem 0 0.9rem;
    padding: 0.25rem 0;
    background: transparent;
    border: none;
    color: var(--nav-marque);
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.15s;
}
.lst-nouvel-article:hover:not(:disabled) { color: var(--color-primary-h); }
.lst-nouvel-article-icone { display: inline-flex; }
.lst-nouvel-article-icone svg { width: 15px; height: 15px; }
.lst-nouvel-article:disabled { cursor: default; opacity: 0.65; }

/* ----- Bloc « Réserve » : <details> natif, FERMÉ par défaut -----
   Résumé cliquable en petites capitales grises, chevron CSS pivotant à
   l'ouverture, sur le modèle des blocs repliables des autres modules. */
.lst-reserve { border-top: 1px solid var(--color-border); }
.lst-reserve-tete {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 0 0.35rem;
    color: var(--color-muted);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    list-style: none;
}
.lst-reserve-tete::-webkit-details-marker { display: none; }
.lst-reserve-tete::marker { content: ""; }
.lst-reserve-tete:hover { color: var(--color-text); }
/* Chevron : pointe à droite fermé, vers le bas ouvert. */
.lst-reserve-tete::after {
    content: "";
    margin-left: auto;
    width: 0.4rem;
    height: 0.4rem;
    border: solid currentColor;
    border-width: 0 1.5px 1.5px 0;
    transform: rotate(-45deg);
    transition: transform 0.15s;
}
.lst-reserve[open] > .lst-reserve-tete::after { transform: rotate(45deg); }

/* Nombre d'articles en réserve : la pastille compteur du module (.lst-pastille),
   dans sa variante grise. Cette classe n'ajoute qu'un léger tassement, le
   résumé étant déjà en petites capitales. */
.lst-reserve-nombre { height: 1.25rem; min-width: 1.25rem; }

/* Articles en réserve : mêmes lignes, sans case à cocher à ce stade — seuls
   le nom, l'éventuelle icône de note et la flèche de remontée y figurent. */
.lst-liste--reserve { padding-bottom: 0.35rem; }
.lst-liste--reserve .lst-article { font-size: 0.85rem; }

/* =====================================================================
   Section « Magasins désactivés » — <details> natif, FERMÉ par défaut
   ---------------------------------------------------------------------
   Calquée sur le bloc « Ingrédients désactivés » d'Alimentation
   (.alim-desactives) : même résumé cliquable gris qui vire au bleu au
   survol, même absence de JS. Chaque ligne rappelle le nombre d'articles
   CONSERVÉS et porte son bouton « Réactiver » (POST + CSRF + PRG).
   ===================================================================== */
.lst-desactives > summary {
    cursor: pointer;
    padding: 0.5rem 0;
    font-weight: 600;
    color: var(--color-muted);
}
.lst-desactives > summary:hover { color: var(--color-primary); }
.lst-desactives[open] > summary { margin-bottom: 0.25rem; }

/* Items EMPILÉS : un magasin désactivé par ligne, sur toute la largeur du
   conteneur — lequel ne fait plus, lui, que deux colonnes de large (cf.
   .lst-desactives-carte plus bas). C'est le CONTENANT qui est rétréci, pas
   le contenu qui est mis en colonnes. */
.lst-desactives-liste { list-style: none; margin: 0; padding: 0; }
.lst-desactive {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.55rem 0;
    border-top: 1px solid var(--color-border);
}
.lst-desactive:first-child { border-top: none; }

/* Logo : la même pastille ronde que les cartes, en plus petit et NON
   cliquable ici (la seule action offerte sur cette ligne est « Réactiver »). */
.lst-desactive-logo {
    width: 30px;
    height: 30px;
}
.lst-desactive-logo svg { width: 16px; height: 16px; }

.lst-desactive-nom { font-weight: 600; overflow-wrap: anywhere; }
/* Élément élastique de la ligne : il occupe la place restante et rejette
   donc le bouton « Réactiver » au bord droit du conteneur. */
.lst-desactive-compte { flex: 1; min-width: 0; font-size: 0.8rem; }
.lst-desactive-form { flex-shrink: 0; margin: 0; }
.lst-reactiver { font-size: 0.85rem; padding: 0.35rem 0.75rem; }

/* ----- Largeur du CONTENANT : deux colonnes de la grille des magasins -----
   La carte est posée dans un conteneur .lst-grille — la MÊME grille que
   celle des magasins actifs, donc rigoureusement les mêmes colonnes, les
   mêmes gouttières et les mêmes points de rupture — et n'en occupe que
   DEUX pistes. Bord gauche et rythme de colonnes sont ainsi alignés sur
   les cartes du dessus par construction, sans largeur calculée à la main ;
   la moitié droite de la rangée reste vide. Même procédé que la rangée
   basse du tableau de bord (.accueil-grille-bas > .accueil-alim-bloc).
   Aux paliers à 3 puis 2 colonnes, « 2 pistes » vaut naturellement les
   deux tiers puis la totalité de la largeur. */
.lst-desactives-carte { grid-column: span 2; }

/* =====================================================================
   Modale « Magasin » (création / édition)
   ---------------------------------------------------------------------
   Calquée sur celle des Idées (elle-même calquée sur celle de l'Agenda) :
   même ossature fond + carte centrée, mêmes boutons de pied, mêmes
   variables de profondeur. Classes propres au module, pour que « Listes »
   ne dépende du CSS d'aucun autre.
   ===================================================================== */
.lst-modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.lst-modal[hidden] { display: none; }
.lst-modal-fond { position: absolute; inset: 0; background: rgba(15, 23, 42, 0.45); }
.lst-modal-carte {
    position: relative;
    width: 100%;
    max-width: 560px;
    max-height: 90vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 1.1rem 1.2rem 1.2rem;
}
.lst-modal-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}
.lst-modal-entete h3 { margin: 0; }
.lst-modal-croix {
    border: none;
    background: transparent;
    color: var(--color-muted);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.2rem;
}
.lst-modal-croix:hover { color: var(--color-text); }

/* Formulaire de modale, partagé par les DEUX modales du module (magasin et
   article) : ciblé par une classe, jamais par un identifiant. */
.lst-form { display: flex; flex-direction: column; gap: 0.9rem; }
.lst-champ-plein { width: 100%; }
.lst-form input[type="text"],
.lst-form textarea {
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--color-border-2);
    border-radius: 6px;
    font-family: inherit;
    font-size: 0.95rem;
    background: var(--color-surface);
    color: var(--color-text);
}
.lst-form textarea { resize: vertical; }
.lst-form input[type="text"]:focus-visible,
.lst-form textarea:focus-visible {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Rappel du magasin d'accueil, en mode CRÉATION d'article uniquement (masqué
   en édition, où l'article ne change pas de magasin). */
.lst-art-magasin-nom { margin: -0.35rem 0 0; font-size: 0.85rem; }
.lst-art-magasin-nom[hidden] { display: none; }

/* ----- Palette d'icônes : grille de boutons radio -----
   Le radio lui-même est masqué (sans display:none, pour rester focusable
   au clavier) : c'est la tuile .lst-icone-choix qui porte tout le rendu.
   Sélection = filet bleu + fond bleu clair, dérivés de --nav-marque. */
.lst-icones {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
    gap: 0.4rem;
}
.lst-icone-option {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    cursor: pointer;
}
.lst-icone-option input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}
.lst-icone-choix {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 0.5rem 0;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface);
    color: var(--color-muted);
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.lst-icone-choix svg { width: 20px; height: 20px; }
.lst-icone-option:hover .lst-icone-choix { border-color: var(--color-border-2); color: var(--color-text); }
.lst-icone-libelle {
    font-size: 0.68rem;
    color: var(--color-muted);
    text-align: center;
    line-height: 1.2;
}
/* Icône SÉLECTIONNÉE : mise en évidence bordure bleue + fond bleu clair. */
.lst-icone-option input:checked + .lst-icone-choix {
    border-color: var(--nav-marque);
    background: color-mix(in srgb, var(--nav-marque) 10%, var(--color-surface));
    color: var(--nav-marque);
}
.lst-icone-option input:checked ~ .lst-icone-libelle {
    color: var(--color-text);
    font-weight: 600;
}
.lst-icone-option input:focus-visible + .lst-icone-choix {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 1px;
}

/* ----- Interrupteur « Actif » (mode ÉDITION seulement) ----- */
.lst-actif-bloc[hidden] { display: none; }
.lst-actif {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.7rem 0.8rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface-2);
    cursor: pointer;
}
.lst-actif input { margin: 0.2rem 0 0; flex-shrink: 0; }
.lst-actif-texte { display: flex; flex-direction: column; gap: 0.15rem; }
.lst-actif-texte .muted { font-size: 0.78rem; line-height: 1.35; }

/* ----- Pied de la modale : suppression à gauche, en rouge ----- */
.lst-modal-pied {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--color-border);
}
.lst-modal-pied-droite { display: flex; gap: 0.5rem; margin-left: auto; }
.lst-modal-supprimer { color: var(--color-error); }
.lst-modal-supprimer:hover { background: var(--color-danger-bg); color: var(--color-danger-fg); }
.lst-modal-supprimer[hidden] { display: none; }

/* Écrans étroits : les lignes de magasins désactivés se replient.
   « Nouveau magasin » n'a rien à y faire : aligné à gauche et à sa largeur
   naturelle, il tient déjà sur un petit écran. */
@media (max-width: 720px) {
    /* La grille n'a plus qu'UNE piste : la carte « Magasins désactivés »
       reprend toute la largeur disponible. Sans ce retour à `auto`, un
       span 2 créerait une seconde colonne implicite et déborderait. */
    .lst-desactives-carte { grid-column: auto; }
    .lst-desactive { flex-wrap: wrap; }
    .lst-desactive-compte { flex-basis: 100%; }
}

/* =====================================================================
   TABLEAUX DE DONNÉES EN CARTES SUR MOBILE — mécanisme « .table-cards »
   ---------------------------------------------------------------------
   UN SEUL mécanisme, réutilisable par tous les tableaux à colonnes
   multiples de l'application. Sous le seuil du burger, chaque <tr>
   devient une CARTE contenant TOUTES ses colonnes ; au-dessus, le
   tableau reste un tableau, au pixel près (rien de ce qui suit ne vit
   hors de la media query, et les classes/attributs posés par le script
   ne sont stylés que là).

   SEUIL : 1000px — le MÊME que le burger. Trois endroits à garder
   synchrones si vous le changez : la variable --nav-seuil-mobile (:root),
   le bloc « NAVIGATION MOBILE », et la media query ci-dessous (une media
   query CSS ne peut pas consommer une variable).

   ---------------------------------------------------------------------
   APPLIQUER LE MÉCANISME À UN NOUVEAU TABLEAU
   ---------------------------------------------------------------------
     1. poser la classe `table-cards` sur le <table> ;
     2. c'est tout : /assets/js/tableaux-cartes.js recopie l'intitulé de
        chaque colonne (dernière ligne du <thead>) sur les cellules, en
        `data-label`, et marque la tête de carte.

     Deux réglages facultatifs, sur le <table> :
       data-cards-labels="Date|Libellé|Montant|"  intitulés à la main,
           pour un tableau SANS <thead> (une entrée par colonne).
       data-cards-montant="4"  numéro (à partir de 1) de la colonne de
           montant hissée en tête de carte. Défaut : la première colonne
           numérique (en-tête portant .compta-cellule-nombre).

     Lignes de TOTAL : les lignes de <tfoot> sont reconnues d'office ;
     une ligne de total logée dans le <tbody> se marque `tc-total`.

   ANATOMIE D'UNE CARTE
     ┌───────────────────────────────────┐
     │ 12/07/2026              450,00 €  │  tête : 1re colonne + montant
     ├───────────────────────────────────┤  filet
     │ N° fact.                 F-2026-7 │  intitulé → valeur
     │ Source                       Lano │
     └───────────────────────────────────┘

   `screen and` est délibéré : l'impression (export PDF de Fin de mois)
   ne doit jamais basculer en cartes, quelle que soit la largeur de page.
   ===================================================================== */
@media screen and (max-width: 1000px) {

    /* ----- Le tableau cesse d'être une grille ----- */
    .table-cards {
        /* Filet LÉGER de séparation entre deux lignes « intitulé → valeur »
           d'une même carte. Nettement plus pâle que --color-border (qui reste
           le trait des cartes et de la tête) : il guide l'œil de gauche à
           droite sans jamais quadriller la carte. Déclaré ICI, en portée
           locale au composant — pas dans :root : il ne sert qu'aux cartes.
           Dérivé de la palette (≈ #eff2f7), donc il suit un changement de
           --color-border sans retouche. */
        --tc-filet: color-mix(in srgb, var(--color-border) 55%, var(--color-surface));

        display: block;
        width: 100%;
        padding: 0;
    }
    .table-cards thead { display: none; }
    .table-cards tbody,
    .table-cards tfoot {
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
    }
    .table-cards tfoot { margin-top: 0.5rem; }

    /* Un tableau logé dans un panneau encadré (.compta-table) ou dans une
       section repliable (.compta-sources) prend un peu d'air : ses cartes ne
       collent pas au filet du panneau. Ailleurs — mini-tableaux logés dans une
       .card — l'hôte fournit déjà son propre padding, d'où le 0 par défaut. */
    .compta-table > .table-cards,
    .compta-sources .table-cards { padding: 0.6rem; }

    /* ----- Une LIGNE = une CARTE ----- */
    .table-cards tbody > tr,
    .table-cards tfoot > tr {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        /* colonne à 0 : les deux cellules de tête se touchent, leur filet
           commun est donc continu. L'écart vertical sépare les lignes. */
        gap: 0.35rem 0;
        padding: 0.7rem 0.85rem;
        background: var(--color-surface);
        border: 1px solid var(--color-border);
        border-radius: 12px;
    }

    /* ----- Une CELLULE = une ligne « intitulé → valeur » -----
       Sélecteur sur [data-label] : l'attribut est posé par le script sur
       chaque cellule traitée, et il donne à ces règles le poids qu'il faut
       pour primer sur les gabarits de bureau (.compta-recettes--liste td…). */
    .table-cards tbody td[data-label],
    .table-cards tfoot td[data-label] {
        display: flex;
        flex: 1 1 100%;
        align-items: baseline;
        justify-content: flex-start;
        gap: 0.75rem;
        width: auto;
        max-width: none;
        padding: 0;
        border: 0;
        background: transparent;
        font-size: 0.9rem;
        text-align: right;
        white-space: normal;
        overflow: visible;
    }

    /* L'intitulé de colonne, à gauche ; `margin-right: auto` repousse la
       valeur (et ses éventuels compagnons : badge, bouton) contre la droite. */
    .table-cards tbody td[data-label]::before,
    .table-cards tfoot td[data-label]::before {
        content: attr(data-label);
        flex: 0 1 auto;
        margin-right: auto;
        color: var(--color-muted);
        font-size: 0.8rem;
        font-weight: 400;
        text-align: left;
        white-space: normal;
    }

    /* Zébrure et filets du tableau : sans objet une fois en cartes. */
    .table-cards tbody tr:nth-child(even) td[data-label] { background: transparent; }
    .table-cards tfoot tr:first-child td[data-label] { border-top: 0; }

    /* Cellule vide : ni intitulé, ni ligne fantôme. */
    .table-cards tbody td[data-label]:empty,
    .table-cards tfoot td[data-label]:empty { display: none; }

    /* Champs de saisie et mini-formulaires en cellule : ils prennent la
       place restante au lieu de réclamer 100 % de la largeur de la carte. */
    .table-cards tbody td[data-label] > input[type="text"],
    .table-cards tbody td[data-label] > select,
    .table-cards tbody td[data-label] > form {
        flex: 1 1 8rem;
        min-width: 0;
        width: auto;
    }

    /* ----- TÊTE DE CARTE : 1re colonne à gauche, montant à droite -----
       Les deux cellules sont remontées (order négatif) sur une même ligne ;
       la première grandit, d'où un filet inférieur continu sous les deux. */
    .table-cards tbody td.tc-tete {
        order: -1;
        flex: 0 0 auto;
        gap: 0;
        padding-bottom: 0.5rem;
        margin-bottom: 0.2rem;
        border-bottom: 1px solid var(--color-border);
        font-size: 0.95rem;
        font-weight: 500;
    }
    .table-cards tbody td.tc-tete::before { display: none; }
    .table-cards tbody td.tc-tete-cle {
        order: -2;
        flex: 1 1 auto;
        /* min-width: 0 — sans quoi un libellé long refuserait de se réduire et
           renverrait le montant à la ligne, cassant la tête de carte. */
        min-width: 0;
        justify-content: flex-start;
        text-align: left;
        overflow-wrap: anywhere;
    }
    .table-cards tbody td.tc-tete-montant {
        justify-content: flex-end;
        padding-left: 0.75rem;
        text-align: right;
        font-weight: 600;
    }

    /* ----- FILETS ENTRE LES LIGNES « intitulé → valeur » -----
       Une carte de Recettes empile jusqu'à neuf lignes : sans repère, l'œil
       perd la correspondance entre l'intitulé de gauche et la valeur de
       droite. Un trait très pâle sous chaque ligne le rétablit.

       Le padding vertical fait respirer le trait des deux côtés ; l'écart
       vertical du conteneur est donc ramené à 0 sur ces lignes, sans quoi le
       filet ne serait plus à mi-chemin entre deux valeurs. Les lignes de
       TOTAL gardent leur écart (et n'ont pas de filet : cf. plus bas). */
    .table-cards tbody > tr:not(.tc-total) { row-gap: 0; }

    .table-cards tbody > tr:not(.tc-total) > td[data-label]:not(.tc-tete) {
        padding-top: 0.3rem;
        padding-bottom: 0.3rem;
        border-bottom: 1px solid var(--tc-filet);
    }

    /* La DERNIÈRE ligne de la carte ne porte pas de filet : la bordure de la
       carte fait déjà la clôture, et un trait de plus la doublerait.
       « Dernière » se lit à rebours en sautant ce qui n'est PAS une ligne de
       données et se trouve en fin de balisage :
         - une cellule de TÊTE (tableaux dont la colonne de montant est la
           dernière : Détail des paiements, plans de Gains) — elle est remontée
           en haut de carte par `order`, elle ne clôt donc rien ;
         - une cellule VIDE, masquée par `display: none` (ex. la colonne de
           suppression d'une source encore rattachée à des encaissements).
       C'est alors l'avant-dernière cellule qui termine visuellement la carte. */
    .table-cards tbody > tr:not(.tc-total) > td[data-label]:not(.tc-tete):last-child,
    .table-cards tbody > tr:not(.tc-total) > td[data-label]:not(.tc-tete):has(+ .tc-tete:last-child),
    .table-cards tbody > tr:not(.tc-total) > td[data-label]:not(.tc-tete):has(+ td[data-label]:empty:last-child) {
        border-bottom: 0;
    }

    /* ----- LIGNES DE TOTAL / SOLDE : visuellement à part -----
       Fond teinté, filet plus marqué, texte gras — et jamais éclatées en
       intitulé → valeur quand il n'y a qu'un seul montant à montrer. */
    .table-cards tfoot > tr,
    .table-cards tbody > tr.tc-total {
        background: var(--color-surface-2);
        border-color: var(--color-border-2);
        font-weight: 600;
    }
    .table-cards tfoot td[data-label],
    .table-cards tbody tr.tc-total td[data-label] { font-weight: 600; }
    .table-cards tr.tc-total > td[data-label]:first-child::before { display: none; }

    /* Cas courant — UN seul montant : libellé à gauche, montant à droite,
       sur une seule ligne (« Total Juillet 2026 », « Cumul HT à déclarer »…). */
    .table-cards tr.tc-solo > td[data-label] { flex: 0 0 auto; gap: 0; }
    .table-cards tr.tc-solo > td[data-label]:first-child {
        flex: 1 1 auto;
        min-width: 0;
        padding-right: 0.75rem;
        text-align: left;
        overflow-wrap: anywhere;
    }
    .table-cards tr.tc-solo > td[data-label]::before { display: none; }

    /* Cas rare — PLUSIEURS montants (total annuel : brut, charges, net) :
       le libellé coiffe la carte, les montants gardent leur intitulé, sans
       quoi trois nombres nus seraient illisibles. */
    .table-cards tr.tc-total:not(.tc-solo) > td[data-label]:first-child {
        flex: 1 1 100%;
        padding-bottom: 0.5rem;
        margin-bottom: 0.2rem;
        border-bottom: 1px solid var(--color-border-2);
        text-align: left;
    }

    /* ----- Ligne « message » (« Aucun mouvement ce mois-ci. ») ----- */
    .table-cards tr.tc-plein > td[data-label] {
        flex: 1 1 100%;
        justify-content: flex-start;
        text-align: left;
    }
    .table-cards tr.tc-plein > td[data-label]::before { display: none; }

    /* ----- Le rouge fonctionnel des négatifs est conservé -----
       Il vit sur la cellule ; l'intitulé, lui, reste en gris (règle ::before
       ci-dessus), de sorte que seule la VALEUR est colorée. */
    .table-cards td[data-label].compta-montant-negatif { color: var(--color-error); }
    .table-cards td[data-label].compta-montant-positif { color: var(--color-success); }

    /* ----- Colonne d'action (crayon, croix) : à droite, sans intitulé ----- */
    .table-cards tbody td[data-label].compta-cellule-action {
        justify-content: flex-end;
        text-align: right;
    }

    /* ----- Gabarits « bureau » neutralisés dans une carte ----- */
    .table-cards .compta-banque-libelle {
        max-width: none;
        overflow: visible;
        text-overflow: clip;
        white-space: normal;
    }
    /* Plus rien ne déborde : l'enveloppe à défilement horizontal du tableau
       des plans n'a plus lieu d'être une fois celui-ci empilé en cartes.
       (Les panneaux .compta-table gardent leur `overflow: hidden` : il borne
       leurs coins arrondis, et une pile de cartes ne le déclenche jamais.) */
    .gains-table-enveloppe:has(> .table-cards) { overflow-x: visible; }
}

/* Filets FINS des cartes : 0.5px là où l'écran sait le rendre, 1px ailleurs —
   même convention que les filets de colonnes de Fin de mois. En pratique, tout
   mobile récent est en 2dppx ou plus : c'est bien le trait fin qui s'affiche. */
@media screen and (max-width: 1000px) and (min-resolution: 2dppx) {
    .table-cards tbody > tr,
    .table-cards tfoot > tr { border-width: 0.5px; }
    .table-cards tbody td.tc-tete,
    .table-cards tr.tc-total:not(.tc-solo) > td[data-label]:first-child {
        border-bottom-width: 0.5px;
    }
    .table-cards tbody > tr:not(.tc-total) > td[data-label]:not(.tc-tete) {
        border-bottom-width: 0.5px;
    }
}
