/* =============================================================================
   GESCOL — Direction A « Registre clair » (maquette validée le 6 sept. 2026)
   Chargé APRÈS app.css (socle MecSyf) : redéfinit les tokens et les surfaces
   principales (barre latérale claire, barre de contexte, connexion).
   Palette : papier chaud #F6F4EF, vert profond #1F6F5B, encre #1D1B16.
   Typo : Bricolage Grotesque (titres) + Manrope (interface).
   ============================================================================= */
:root {
    --brand-primary-darkest: #123F35;
    --brand-primary-dark: #174F42;
    --brand-primary: #1F6F5B;
    --brand-primary-light: #2E8A72;
    --brand-primary-lighter: #4FA58E;
    --brand-primary-bg: #E6F2EC;
    --brand-secondary: #8A5A1E;
    --brand-secondary-dark: #6E4715;
    --brand-secondary-light: #C9A24B;
    --brand-secondary-bg: #FBEFD9;
    --brand-action: #1F6F5B;
    --gs-paper: #F6F4EF;
    --gs-surface: #FFFFFF;
    --gs-surface-2: #FBFAF7;
    --gs-ink: #1D1B16;
    --gs-ink-2: #4A463F;
    --gs-muted: #6B6760;
    --gs-line: #E4E0D8;
    --gs-line-2: #EFECE5;
    --gray-50: #FBFAF7; --gray-100: #EFECE5; --gray-200: #E4E0D8; --gray-300: #D5D0C6;
    --gray-400: #9A958B; --gray-500: #6B6760; --gray-600: #4A463F; --gray-700: #33302A;
    --gray-800: #1D1B16; --gray-900: #141310;
    --status-success-bg: #E6F2EC; --status-success-fg: #174F42;
    --status-warning-bg: #FBEFD9; --status-warning-fg: #8A5A1E;
    --status-danger-bg: #FBE4E1; --status-danger-fg: #8E1F17;
    --status-info-bg: #E5EEF6; --status-info-fg: #1F4E79;
    --sidebar-w: 232px;
    --radius-sm: 8px; --radius: 12px;
    --gs-font: 'Manrope', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    --gs-font-display: 'Bricolage Grotesque', 'Avenir Next', 'Segoe UI', Arial, sans-serif;
}
body { font-family: var(--gs-font); color: var(--gs-ink); background: var(--gs-paper); }
h1, h2, h3, .page-title { font-family: var(--gs-font-display); letter-spacing: -0.01em; }
.num, td.num, .gs-kpi-value { font-variant-numeric: tabular-nums; }

/* ---- Barre latérale claire (spécificité alignée sur app.css : .sidebar-nav .nav-item) ---- */
.sidebar { background: var(--gs-surface-2); color: var(--gs-ink); border-right: 1px solid var(--gs-line); }
.sidebar-header { border-bottom: 1px solid var(--gs-line); }
.sidebar-header .brand h2 { color: var(--gs-ink); font-family: var(--gs-font-display); font-size: 1.05rem; }
.sidebar-header .brand span { color: var(--gs-muted); }
.sidebar-close { color: var(--gs-ink); }
.sidebar-nav .nav-section { color: var(--gray-400); font-size: .68rem; letter-spacing: .08em; font-weight: 700; }
.sidebar-nav .nav-section:hover { color: var(--gs-ink-2); }
.sidebar-nav .nav-item { color: var(--gs-ink-2); font-weight: 500; }
.sidebar-nav .nav-item i { color: #7A756C; }
.sidebar-nav .nav-item:hover { background: var(--gray-100); color: var(--gs-ink); }
.sidebar-nav .nav-item:hover i { color: var(--brand-primary); }
.sidebar-nav .nav-item.active { background: var(--brand-primary-bg); color: var(--brand-primary-dark); font-weight: 700; box-shadow: inset 3px 0 0 var(--brand-primary); }
.sidebar-nav .nav-item.active i { color: var(--brand-primary-dark); }
.sidebar-footer { border-top: 1px solid var(--gs-line); color: var(--gs-ink); }
.sidebar-footer .avatar { background: var(--brand-primary-bg); color: var(--brand-primary-dark); }
.sidebar-footer .user-info .role { opacity: 1; color: var(--gs-muted); }
.sidebar-footer .logout-btn { color: var(--gray-400); }
.sidebar-footer .logout-btn:hover { background: var(--gray-100); }
.gs-mark { width: 36px; height: 36px; border-radius: 10px; background: var(--brand-primary); color: #fff; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }

/* ---- Barre du haut + contexte tenant ------------------------------------- */
.topbar { background: var(--gs-surface); border-bottom: 1px solid var(--gs-line); }
.scope-chip { display: inline-flex; align-items: center; gap: .4rem; height: 32px; padding: 0 .7rem; border: 1px solid var(--gs-line); border-radius: var(--radius-sm); background: var(--gs-surface); font-size: .8rem; color: var(--gs-ink); }
.scope-chip i { color: var(--gray-400); }
.scope-chip.scope-warning { background: var(--status-warning-bg); color: var(--status-warning-fg); border-color: transparent; }
.search-box { background: var(--gs-surface-2); border: 1px solid var(--gs-line); border-radius: var(--radius-sm); }

/* ---- Composants GESCOL ----------------------------------------------------- */
.content { background: var(--gs-paper); }
.gs-card { background: var(--gs-surface); border: 1px solid var(--gs-line); border-radius: var(--radius); padding: 20px; }
.gs-h2 { font-size: 1.05rem; font-weight: 600; margin: 0 0 8px; }
.gs-muted { color: var(--gs-muted); font-size: .9rem; margin: 0; }
.gs-page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 22px; }
.gs-page-header h1 { font-size: 1.75rem; font-weight: 700; margin: 0 0 4px; }
.gs-kpi-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 1100px) { .gs-kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.gs-kpi { display: flex; flex-direction: column; gap: 6px; }
.gs-kpi-label { font-size: .82rem; color: var(--gs-muted); font-weight: 600; }
.gs-kpi-value { font-family: var(--gs-font-display); font-size: 1.9rem; font-weight: 700; }
.gs-kpi-note { font-size: .78rem; color: var(--gs-muted); }
.gs-label { display: block; font-size: .78rem; font-weight: 600; color: var(--gs-muted); margin: 14px 0 6px; }
.gs-input { width: 100%; height: 44px; padding: 0 12px; border: 1px solid var(--gray-300); border-radius: var(--radius-sm); font: inherit; font-size: .95rem; background: var(--gs-surface); box-sizing: border-box; }
.gs-input:focus { outline: none; border-color: var(--brand-primary); box-shadow: 0 0 0 3px var(--brand-primary-bg); }
.gs-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 44px; padding: 0 18px; border-radius: var(--radius-sm); border: 1px solid var(--gray-300); background: var(--gs-surface); font: inherit; font-weight: 600; font-size: .95rem; cursor: pointer; }
.gs-btn-primary { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
.gs-btn-primary:hover { background: var(--brand-primary-dark); }
.gs-btn:disabled { opacity: .6; cursor: default; }
.gs-btn-block { width: 100%; margin-top: 20px; }
.gs-error { margin-top: 12px; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--status-danger-bg); color: var(--status-danger-fg); font-size: .85rem; }
/* Écrans du mot de passe (#223, PR 2) : message de réussite, erreur sous un champ, liens. */
.gs-info { margin-top: 12px; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--status-info-bg); color: var(--status-info-fg); font-size: .85rem; }
.gs-succes { margin-top: 12px; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--status-success-bg, #e8f5ee); color: var(--status-success-fg, #1f6b43); font-size: .85rem; }
.gs-champ-erreur { margin: 4px 0 0; color: var(--status-danger-fg); font-size: .78rem; }
/* École servie par l'hôte (#223) : repère au-dessus de la carte de connexion. */
.gs-login-ecole { display: flex; align-items: center; gap: 10px; margin: 0 0 18px; padding: 10px 12px; background: var(--gs-surface-2); border: 1px solid var(--gs-line); border-radius: 10px; font-size: .9rem; color: var(--gs-ink); }
.gs-login-ecole[hidden] { display: none; }
.gs-login-ecole-mark { flex: none; width: 34px; height: 34px; border-radius: 8px; background: var(--brand-primary); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: .72rem; letter-spacing: .4px; }
.gs-login-ecole-mark--logo { width: 48px; height: 48px; padding: 3px; border: 2px solid var(--gs-line); }
.gs-login-ecole-mark--logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.gs-login-ecole-texte { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.gs-login-ecole-pre { color: var(--gs-muted); font-size: .72rem; }
.gs-login-lien { margin: 14px 0 0; text-align: center; font-size: .85rem; }
.gs-login-lien a { color: var(--brand-primary); font-weight: 600; text-decoration: none; }
.gs-login-lien a:hover { text-decoration: underline; }

/* ---- Connexion ------------------------------------------------------------- */
.gs-login { min-height: 100vh; display: grid; grid-template-columns: minmax(320px, 46%) minmax(0, 1fr); background: var(--gs-paper); }
.gs-login-band { background: var(--brand-primary-darkest); color: #EAF3EE; padding: 40px 48px; display: flex; flex-direction: column; justify-content: space-between; }
.gs-brand { display: flex; align-items: center; gap: 12px; }
.gs-brand-mark { width: 44px; height: 44px; border-radius: 12px; background: var(--brand-primary); display: inline-flex; align-items: center; justify-content: center; color: #fff; }
.gs-brand-name { font-family: var(--gs-font-display); font-size: 1.4rem; font-weight: 700; letter-spacing: .04em; }
.gs-eyebrow { font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; color: var(--brand-primary-lighter); margin: 0 0 12px; font-weight: 700; }
.gs-login-pitch h1 { font-size: 2rem; line-height: 1.15; margin: 0 0 16px; font-weight: 600; color: #fff; text-wrap: pretty; }
.gs-sub { font-size: 1rem; line-height: 1.5; color: #C8DDD3; margin: 0; max-width: 40ch; }
.gs-login-legal { font-size: .78rem; color: #9FBFB2; margin: 0; }
.gs-login-card { align-self: center; justify-self: center; width: min(420px, 90%); background: var(--gs-surface); border: 1px solid var(--gs-line); border-radius: 16px; padding: 36px; }
.gs-login-card h2 { margin: 0 0 6px; font-size: 1.5rem; }
.gs-login-sub { color: var(--gs-muted); font-size: .9rem; margin: 0 0 8px; }
@media (max-width: 860px) { .gs-login { grid-template-columns: 1fr; } .gs-login-band { padding: 28px; gap: 24px; } .gs-login-pitch h1 { font-size: 1.4rem; } }

/* ---- Onglets, barres d'outils, en-têtes de carte (responsive) --------------
   Points de rupture du skill frontend-responsive : 1024 (sidebar), 900, 640 (mobile).
   Le document ne défile jamais horizontalement : ce qui est large défile dans son conteneur. */
/* En-têtes de ligne (<th> dans tbody : Finances, synthèses) : même remplissage et même filet que
   les <td>, sinon le libellé se colle au bord de la carte (app.css ne stylait que thead th / tbody td). */
.data-table tbody th { padding: .75rem 1rem; font-size: .85rem; text-align: left; color: var(--gray-700); border-bottom: 1px solid var(--gray-100); background: transparent; }
.tabs { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
.tabs .tab { white-space: nowrap; flex-shrink: 0; }
.gs-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-bottom: 16px; }
.gs-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; margin-bottom: 12px; }
.gs-card-head > :first-child { min-width: 0; }
.gs-card-actions { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; }
/* Boutons d'une cellule de tableau (Modifier, Mot de passe, Désactiver…) : espacés dans les
   deux sens quand ils passent à la ligne, jamais coupés au milieu d'un libellé (#106). */
.gs-actions { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; }
.gs-actions .btn { white-space: nowrap; }
/* Bouton d'action d'une section de formulaire (« Nouveau tuteur », #110) : sur le bord haut, à droite. */
/* Bloc Renseignements de la fiche élève (#112). */
.gs-dl { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 0; font-size: .9rem; }
.gs-dl dt { color: var(--gray-500); } .gs-dl dd { margin: 0; }
@media (max-width: 640px) { .gs-dl { grid-template-columns: 1fr; } .gs-dl dt { margin-top: 6px; } }
.ff-section { position: relative; }
.ff-section-action { position: absolute; top: -14px; right: 12px; background: var(--white); padding: 0 6px; }
.gs-h2 { flex-wrap: wrap; }
@media (max-width: 640px) {
    /* Barre du haut sur téléphone : le préfixe de fil d'Ariane (« Principal / ») disparaît et le
       titre se tronque plutôt que de pousser la cloche hors de l'écran (5 px de débordement
       horizontal à 360 px, toute la page décalée). */
    .topbar { min-width: 0; }
    .topbar .crumb-section, .topbar .crumb-sep { display: none; }
    .topbar .page-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .scope-chip { display: none; }  /* app.css la masque déjà à cette taille, mais la règle .scope-chip de ce fichier, chargé après, la réaffichait */
    /* Deux tuiles par ligne, valeurs resserrées (#204) : en une colonne, les indicateurs du tableau
       de bord occupaient un écran et demi avant le premier contenu. */
    .gs-kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    /* Nombre impair de tuiles : la dernière prend la ligne entière plutôt que de rester seule
       dans une demi-largeur (revue des écrans, 8 oct. 2026). */
    .gs-kpi-row > :last-child:nth-child(odd) { grid-column: 1 / -1; }
    .gs-kpi-row > .gs-card { padding: 12px; }
    .gs-kpi-value { font-size: 1.15rem; overflow-wrap: anywhere; }
    .gs-kpi-label { font-size: .74rem; }
    .gs-card { padding: 14px; }
    .gs-page-header { flex-direction: column; align-items: flex-start; }
    .gs-card-actions { width: 100%; }
    .gs-card-actions .btn { flex: 1 1 auto; }
    .page-header .actions { width: 100%; flex-wrap: wrap; }
}

/* ---- Connexion : pied de page (sécurité, domaine, version) et mobile ------- */
.gs-login-foot { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--gs-line); font-size: .74rem; line-height: 1.45; color: var(--gs-muted); display: flex; flex-direction: column; gap: 4px; }
.gs-login-foot i { margin-right: .3rem; color: var(--brand-primary); }
.gs-login-foot .gs-login-sig { font-variant-numeric: tabular-nums; }
/* Version sous la signature, sur sa ligne, comme le pied de l'application (#app-version). */
.gs-login-foot #login-version:not(:empty) { display: block; opacity: .75; }
@media (max-width: 640px) {
    .gs-login-band { padding: 20px; gap: 12px; justify-content: flex-start; }
    .gs-login-pitch h1 { font-size: 1.15rem; margin-bottom: 0; }
    /* Le texte d'accroche disparaît : la mention sécurité est reprise dans le pied de la carte. */
    .gs-sub, .gs-login-legal { display: none; }
    .gs-login-card { width: 100%; align-self: start; border-radius: 0; border-left: 0; border-right: 0; padding: 24px 20px; }
}

/* ---- Caisse (maquette Encaissement : élève | échéances | règlement) ---------------- */
.gs-caisse { display: grid; grid-template-columns: 320px minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.gs-caisse-col { min-width: 0; }
.gs-caisse-resultats { list-style: none; margin: 0 0 12px; padding: 0; border: 1px solid var(--gray-200); border-radius: 10px; overflow: hidden; }
.gs-caisse-resultats li + li { border-top: 1px solid var(--gray-200); }
.gs-caisse-resultats button { width: 100%; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 8px 12px; background: none; border: 0; text-align: left; cursor: pointer; font: inherit; }
.gs-caisse-resultats button:hover, .gs-caisse-resultats button:focus { background: var(--brand-primary-bg); outline: none; }
.gs-caisse-eleve { display: flex; gap: 12px; align-items: center; margin-top: 4px; }
.gs-caisse-avatar { width: 52px; height: 52px; border-radius: 50%; background: var(--brand-primary-bg); color: var(--brand-primary-dark); display: grid; place-items: center; font-weight: 700; font-family: var(--gs-font-display); flex: none; }
.gs-caisse-infos { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 14px 0; font-size: .9rem; }
.gs-caisse-infos dt { color: var(--gs-muted); }
.gs-caisse-infos dd { margin: 0; }
.gs-caisse-situation { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.gs-caisse-situation > div { display: flex; flex-direction: column; gap: 4px; padding: 10px; border: 1px solid var(--gray-200); border-radius: 10px; }
.gs-caisse-situation .num { font-weight: 700; }
.gs-caisse-arriere { margin: 12px 0 0; padding: 8px 10px; border-radius: 8px; background: #fef2f2; color: #991b1b; font-size: .85rem; }
.gs-caisse-cochee td { background: var(--brand-primary-bg); }
.gs-caisse-montant { display: flex; align-items: center; gap: 8px; }
.gs-caisse-montant .gs-input { flex: 1; min-width: 0; width: auto; font-size: 1.6rem; font-weight: 700; padding: 8px 12px; text-align: right; font-family: var(--gs-font-display); }
.gs-caisse-montant span { font-weight: 600; color: var(--gs-muted); }
.gs-caisse-selection { margin: 10px 0 0; padding: 8px 12px; border-radius: 8px; background: var(--brand-primary-bg); color: var(--brand-primary-dark); font-size: .9rem; }
.gs-caisse-modes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 6px 0 12px; }
.gs-caisse-mode { padding: 10px; border: 1px solid var(--gray-200); border-radius: 10px; background: var(--gs-surface); font: inherit; cursor: pointer; text-align: left; }
.gs-caisse-mode.active { border-color: var(--brand-primary); background: var(--brand-primary-bg); color: var(--brand-primary-dark); font-weight: 600; }
.gs-caisse-imputation { list-style: none; margin: 6px 0 0; padding: 0; }
.gs-caisse-imputation li { display: flex; justify-content: space-between; gap: 8px; padding: 6px 0; border-bottom: 1px dashed var(--gray-200); font-size: .9rem; }
.gs-caisse-recu { margin: 0 0 12px; padding: 10px 12px; border-radius: 10px; background: var(--brand-primary-bg); color: var(--brand-primary-dark); }
@media (max-width: 1100px) { .gs-caisse { grid-template-columns: 1fr 1fr; } .gs-caisse-col:nth-child(2) { grid-column: 1 / -1; order: 1; } }
/* Téléphone : élève, échéances, règlement — dans l'ordre du geste ; le règlement sans élève
   choisi n'a rien à dire et ne s'affiche pas (revue des écrans, 8 oct. 2026). */
@media (max-width: 720px) {
    .gs-caisse { grid-template-columns: 1fr; } .gs-caisse-situation { grid-template-columns: 1fr; }
    .gs-caisse-col:nth-child(2) { order: 0; }
    .gs-caisse-attente { display: none; }
}

/* ---- Fiche élève (maquette FicheEleve) ---------------------------------------------- */
.gs-breadcrumb { font-size: .85rem; color: var(--gs-muted); margin: 0 0 12px; }
.gs-breadcrumb a { color: inherit; }
.gs-fiche-entete { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 16px; }
.gs-fiche-avatar { width: 72px; height: 72px; border-radius: 50%; background: var(--brand-primary-bg); color: var(--brand-primary-dark); display: grid; place-items: center; font-weight: 700; font-size: 1.4rem; font-family: var(--gs-font-display); flex: none; }
.gs-fiche-identite { flex: 1 1 320px; min-width: 0; }
.gs-fiche-nom { font-family: var(--gs-font-display); font-size: 1.6rem; margin: 0; line-height: 1.2; }
.gs-fiche-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.gs-fiche-identite .btn-link { background: none; border: 0; padding: 0 4px; color: var(--brand-primary-dark); cursor: pointer; font: inherit; font-size: .85rem; }
.gs-fiche-identite .btn-link:hover { text-decoration: underline; }
.gs-fiche-grille { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px; align-items: start; }
.gs-parcours { display: grid; grid-template-columns: repeat(auto-fit, minmax(48px, 1fr)); gap: 6px; }
.gs-parcours-case { height: 44px; border-radius: 8px; display: grid; place-items: center; font-size: .72rem; font-weight: 600; color: #fff; }
.gs-parcours-case.is-payee, .gs-parcours-pastille.is-payee, .gs-parcours-legende .is-payee { background: var(--brand-primary); }
.gs-parcours-case.is-reliquat, .gs-parcours-pastille.is-reliquat, .gs-parcours-legende .is-reliquat { background: #f59e0b; }
.gs-parcours-case.is-echue, .gs-parcours-pastille.is-echue, .gs-parcours-legende .is-echue { background: #dc2626; }
.gs-parcours-case.is-avenir, .gs-parcours-pastille.is-avenir, .gs-parcours-legende .is-avenir { background: var(--gray-300); color: var(--gray-700); }
/* #120 : échéance annulée par un abandon — grisée et barrée, plus rien n'est dû. */
.gs-parcours-case.is-annulee, .gs-parcours-pastille.is-annulee, .gs-parcours-legende .is-annulee { background: var(--gray-100); color: var(--gray-500); border: 1px dashed var(--gray-300); }
.gs-parcours-case.is-annulee span { text-decoration: line-through; }
/* #119 : versement porté par l'organisme payeur — liseré violet, couleur d'état conservée. */
.gs-parcours-case.is-organisme, .gs-parcours-pastille.is-organisme { box-shadow: inset 0 0 0 2px #7c3aed; }
.gs-parcours-legende .is-organisme { background: #fff; border: 2px solid #7c3aed; }
.gs-organisme-versements { display: flex; gap: 4px; flex-wrap: wrap; }
.gs-organisme-total { display: flex; justify-content: space-between; align-items: center; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--gray-200); font-size: 1.05rem; }
.gs-parcours-pastille { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: middle; }
.gs-parcours-legende { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 10px; font-size: .8rem; color: var(--gs-muted); }
.gs-parcours-legende i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-right: 4px; vertical-align: middle; }
.gs-solde-ligne { display: flex; justify-content: space-between; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--gray-200); }
.gs-solde-total { border-bottom: 0; font-weight: 700; font-size: 1.05rem; padding-top: 12px; }
.gs-timeline { list-style: none; margin: 0; padding: 0; }
.gs-timeline li { display: grid; grid-template-columns: 130px 1fr; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--gray-200); }
.gs-journal li { grid-template-columns: 90px 1fr; font-size: .85rem; padding: 6px 0; }
.gs-journal li:last-child { border-bottom: 0; }
.gs-card-head .btn-link { background: none; border: 0; padding: 0; color: var(--brand-primary-dark); cursor: pointer; font: inherit; font-size: .85rem; }
.gs-timeline time { color: var(--gs-muted); font-size: .85rem; }
@media (max-width: 900px) { .gs-fiche-grille { grid-template-columns: 1fr; } .gs-timeline li { grid-template-columns: 1fr; gap: 2px; } }

/* ---- Impayés (maquette Impayes : cellule par échéance) ------------------------------ */
.gs-impaye-cellule { display: inline-block; min-width: 44px; padding: 3px 6px; border-radius: 6px; font-size: .78rem; font-weight: 600; text-align: center; color: #fff; }
.gs-impaye-cellule.is-payee { background: var(--brand-primary); }
.gs-impaye-cellule.is-reliquat { background: #f59e0b; }
.gs-impaye-cellule.is-echue { background: #dc2626; }
.gs-impaye-cellule.is-avenir { background: var(--gray-100); color: var(--gray-400); min-width: 24px; }
/* Tableau élève × échéance sur grand écran (8 oct. 2026 : 1 565 px pour 1 112 disponibles, le nom
   disparaissait au défilement). Cases compactes (reste dû ou coche, l'état en couleur) et colonnes
   case + élève figées à gauche pendant le défilement horizontal. Sur téléphone, cartes (#204). */
.gs-impaye-statut { margin-top: 3px; }
.gs-impaye-statut .badge { white-space: normal; }
#impayesTable td > .gs-impaye-cellule { min-width: 0; width: 100%; padding: 4px 2px; font-size: .74rem; font-variant-numeric: tabular-nums; white-space: nowrap; min-height: 24px; }
#impayesTable td:has(> .gs-impaye-cellule), #impayesTable th:has(> .gs-impaye-mois) { padding-left: 3px; padding-right: 3px; text-align: center; }
.gs-fiche-faits { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px 24px; margin: 10px 0 0; }
.gs-fiche-faits dt { font-size: .72rem; color: var(--gs-muted); margin: 0 0 2px; }
.gs-fiche-faits dd { margin: 0; font-weight: 500; overflow-wrap: break-word; min-width: 0; }
.gs-fiche-faits-bascule { display: none; }
.gs-fait-lieu { display: block; font-weight: 400; }
.gs-fiche-faits .gs-fait-large { grid-column: span 2; }
@media (max-width: 720px) {
    .gs-fiche-faits { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 16px; }
    .gs-fiche-faits:not(.is-ouvert) .gs-fait-plus { display: none; }
    .gs-fiche-faits .gs-fait-large { grid-column: 1 / -1; }
    .gs-fiche-faits-bascule { display: inline-block; margin-top: 6px; }
}
.gs-dash-sous { font-size: .75rem; font-weight: 400; }
.gs-infos-ligne { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 12px; row-gap: 2px; }
.gs-impaye-eleve-infos { font-size: .75rem; display: flex; flex-wrap: wrap; column-gap: 10px; }
.gs-impaye-tel { white-space: nowrap; }
.gs-impaye-eleve-badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.gs-impaye-legende-note { margin-left: auto; }
@media (max-width: 720px) { .gs-impaye-legende-note { display: none; } }   /* les cartes montrent les mois, pas les montants */
@media (min-width: 721px) {
    #impayesTable table { border-collapse: separate; border-spacing: 0; }
    #impayesTable tr > :nth-child(1) { position: sticky; left: 0; z-index: 2; width: 40px; min-width: 40px; max-width: 40px; box-sizing: border-box; }
    #impayesTable tr > :nth-child(2) { position: sticky; left: 40px; z-index: 2; min-width: 190px; box-shadow: 6px 0 6px -6px rgba(0, 0, 0, .25); }
    #impayesTable tbody tr > :nth-child(-n+2) { background: var(--gs-surface); }   /* l'en-tête garde son fond */
    #impayesTable thead tr > :nth-child(-n+2) { z-index: 3; }
}
.gs-impaye-legende { display: flex; gap: 14px; flex-wrap: wrap; margin: 0 0 10px; font-size: .8rem; color: var(--gs-muted); }
.gs-impaye-legende i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-right: 4px; vertical-align: middle; }
.gs-impaye-legende .is-payee { background: var(--brand-primary); } .gs-impaye-legende .is-reliquat { background: #f59e0b; } .gs-impaye-legende .is-echue { background: #dc2626; } .gs-impaye-legende .is-avenir { background: var(--gray-300); }
/* ---- Tableau de bord (maquette Main) ------------------------------------------------- */
.gs-kpi-success { border-left: 4px solid var(--brand-primary); }
.gs-kpi-warning { border-left: 4px solid #f59e0b; }
.gs-kpi-danger { border-left: 4px solid #dc2626; }
.gs-kpi-barre { height: 6px; background: var(--gray-100); border-radius: 3px; overflow: hidden; }
.gs-kpi-barre > div { height: 100%; border-radius: 3px; }
/* Tableau de bord : à gauche une colonne qui empile Encaissements du jour, À faire et Finances
   (elle remplit la hauteur du recouvrement par classe à droite, souvent 20 à 30 classes) ; en
   bas, une grille qui s'adapte au nombre de cartes (Effectifs, Sites) — plus de carte seule sur
   un tiers de ligne. Le conteneur principal accepte de rétrécir sous son contenu minimal
   (min-width: 0), sinon la page déborde de 14 px sur téléphone. */
.main-area { min-width: 0; }
.gs-dash-grille { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 3fr); gap: 16px; margin-top: 16px; align-items: start; }
.gs-dash-colonne { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.gs-dash-grille-auto { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }  /* min() : jamais plus large que le conteneur sur téléphone */
.gs-dash-table td, .gs-dash-table th { padding: 8px 10px; font-size: .86rem; }
.gs-dash-table .gs-dash-objet { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Le conteneur des barres (Charts.hBars) porte un display/gap inline : !important nécessaire. */
/* Deux colonnes de barres quand la CARTE est assez large (requête de conteneur) : sur tablette
   la carte occupe toute la largeur et retrouve ses deux colonnes ; à 1440 px elle fait 3/8. */
.gs-dash-barres { container-type: inline-size; }
.gs-dash-classes-2col .hbar-row > div:first-child { margin-bottom: 2px !important; }
/* Seuil = largeur intérieure de la carte : ~387 px à 1440 px (3/8 du contenu), pleine largeur
   sur tablette ; deux colonnes de ~180 px suffisent aux barres. */
@container (min-width: 380px) { .gs-dash-classes-2col .gs-dash-barres > div { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 20px !important; } }
.gs-afaire { list-style: none; margin: 0; padding: 0; }
.gs-afaire li { display: flex; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--gray-200); }
.gs-afaire li:last-child { border-bottom: 0; }
.gs-afaire a { color: inherit; }
.gs-cycles { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 10px; }
.gs-cycles > div { display: flex; flex-direction: column; gap: 2px; padding: 10px; border: 1px solid var(--gray-200); border-radius: 10px; }
.gs-cycles > .gs-cycle { display: flex; flex-direction: column; gap: 2px; padding: 10px; border: 1px solid var(--gray-200); border-radius: 10px; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.gs-cycles > .gs-cycle:hover, .gs-cycles > .gs-cycle-ouvert { border-color: var(--brand-primary); }
.gs-cycle-classes { list-style: none; margin: 12px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 6px; }
.gs-cycle-classes a { display: flex; align-items: baseline; gap: 8px; padding: 8px 10px; border: 1px solid var(--gray-200); border-radius: 8px; color: inherit; text-decoration: none; }
.gs-cycle-classes a:hover { border-color: var(--brand-primary); }
.gs-cycle-classes a > span:first-child { flex: 1; min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 1100px) { .gs-dash-grille:not(.gs-dash-grille-auto) { grid-template-columns: 1fr; } }  /* la grille du bas garde son auto-adaptation sur tablette */

/* Paie (#72) : cellules éditables de l'état de paie et de la grille d'émargement ; fiche agent. */
.gs-paie-input { padding: 4px 6px; border: 1px solid var(--gray-300); border-radius: 6px; font: inherit; text-align: right; }
.gs-paie-input:focus { outline: 2px solid var(--brand-primary-bg); border-color: var(--brand-primary); }
.gs-fiche-dl { display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; margin: 0; }
.gs-fiche-dl dt { color: var(--gs-muted); }
.gs-fiche-dl dd { margin: 0; }

/* Instance de démonstration (#94) : bandeau dans l'app, comptes en un clic à la connexion. */
.gs-demo-banner { background: var(--brand-secondary-bg); color: var(--brand-secondary-dark); border-bottom: 1px solid var(--brand-secondary-light); padding: 6px 16px; font-size: .82rem; text-align: center; }
.gs-demo-banner a { color: inherit; font-weight: 600; }

/* Bannière d'abonnement suspendu (#134) — même gabarit que celle de la démonstration, en
   registre d'alerte : l'accès va s'arrêter, ce n'est pas une information de courtoisie. */
.gs-abo-banner { background: var(--status-danger-bg); color: var(--status-danger-fg); border-bottom: 1px solid var(--status-danger-fg); padding: 6px 16px; font-size: .82rem; text-align: center; }
.gs-abo-banner a { color: inherit; font-weight: 700; text-decoration: underline; }
.gs-demo { margin: 0 0 14px; padding: 10px 12px; background: var(--brand-secondary-bg); border: 1px solid var(--brand-secondary-light); border-radius: 8px; }
.gs-demo-titre { margin: 0 0 8px; font-size: .8rem; color: var(--brand-secondary-dark); }
.gs-demo-titre code { background: #fff; padding: 1px 5px; border-radius: 4px; }
.gs-demo-comptes { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.gs-demo-compte { text-align: left; padding: 6px 8px; background: #fff; border: 1px solid var(--gs-line); border-radius: 6px; cursor: pointer; font: inherit; line-height: 1.25; }
.gs-demo-compte:hover, .gs-demo-compte:focus { border-color: var(--brand-primary); outline: none; }
.gs-demo-compte strong { display: block; font-size: .82rem; color: var(--gs-ink); }
.gs-demo-compte span { font-size: .72rem; color: var(--gs-muted); }

/* Barre d'outils : les actions (date + boutons de la fiche abonnement, #133) s'enroulent au lieu
   de déborder du document sous 375px ; `min-width: 0` pour que l'item flex puisse rétrécir
   (review Copilot PR #136, /frontend-responsive règle 2). */
.toolbar .toolbar-actions { flex-wrap: wrap; min-width: 0; align-items: center; justify-content: flex-end; }
.toolbar .search-box { flex: 0 1 320px; min-width: 0; }

/* DatePicker dans un formulaire (#137) : même largeur et même hauteur que les autres champs du
   groupe (`.form-group input` impose width:100% et une bordure à l'input interne : neutralisé). */
.form-group .dp { display: block; width: 100%; }
.form-group .dp-field { display: flex; align-items: center; width: 100%; }
.form-group .dp-field .dp-input { flex: 1 1 auto; width: auto; min-width: 0; border: none; box-shadow: none; background: transparent; padding: .625rem .875rem; font-size: inherit; line-height: inherit; color: inherit; }
.form-group .dp-field .dp-input:focus { border: none; box-shadow: none; }
.form-group .dp-field .dp-cal-btn { flex: 0 0 auto; padding: .35rem .75rem; }

/* ---- Fiches et tableaux lisibles, surtout sur téléphone (#204) ------------------------------
   Relevé sur la fiche prospect : actions en vrac, fiche en colonne interminable de « — », tableau
   dans une carte dans une carte dont les actions fuyaient hors écran, état vide d'un écran. */

/* Fiche : paires libellé / valeur compactes (Fiche.render), grille qui s'adapte seule. */
.gs-fiche { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 14px 24px; margin: 0; }
.gs-fiche-item { min-width: 0; }
.gs-fiche-large { grid-column: 1 / -1; }
.gs-fiche dt { font-size: .75rem; font-weight: 600; color: var(--gs-muted); margin: 0 0 2px; }
.gs-fiche dd { margin: 0; font-size: .92rem; overflow-wrap: break-word; }
.gs-fiche-vide { margin: 0; font-size: .9rem; }

/* Un cadre n'en contient pas un autre : dans une section, le DataTable abandonne le sien. */
.gs-card .dt-card, .card-body .dt-card { border: 0; box-shadow: none; border-radius: 0; background: transparent; }

/* Un montant ou un numéro de pièce ne se coupe jamais dans un tableau : « 540 000 / FCFA » ou
   « PF-26- / 000001 » à 900 px. Faute de place, le tableau défile dans son propre cadre. */
.data-table .num { white-space: nowrap; }

/* Filtres d'une barre d'outils : sur grand écran, le conteneur s'efface (les chips restent des
   éléments de la barre, disposition inchangée) et le bouton « Filtres » n'existe pas. */
.toolbar-filtres { display: contents; }
.toolbar-filtres-bouton { display: none; }

/* Chip de filtre : jamais plus large que l'écran. Son libellé de valeur passe à la ligne plutôt
   que de pousser la page — « Recouvrement : Familles (hors organismes payeurs) » débordait de
   48 px à 375 px au tableau de bord. Le menu ouvert reste lui aussi dans l'écran. */
.chip { max-width: 100%; }
.chip-select .dd, .chip-select .dd-trigger { min-width: 0; max-width: 100%; }
.chip-select .dd-label { white-space: normal; overflow-wrap: anywhere; }
.chip-select .dd-menu { max-width: calc(100vw - 32px); }
.chip-select .dd-menu .dd-option { white-space: normal; }

/* Étape vide du pipeline : son en-tête et son « 0 » suffisent. */
.pipeline-colonne-vide { opacity: .7; }

/* Colonne réservée à la carte mobile (`carteSeule`) : absente du tableau sur grand écran. */
.data-table th.dt-carte-seule, .data-table td[data-carte-seule] { display: none; }
/* Pastilles d'échéances : le résumé des impayés dans une carte, une pastille par échéance. */
.gs-pastilles { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 3px; max-width: 100%; }
.gs-pastilles .gs-impaye-cellule { min-width: 0; padding: 1px 5px; border-radius: 4px; font-size: .66rem; font-weight: 600; }

/* Sections d'une fiche : un titre et son contenu, espacées d'un rythme constant. */
.gs-fiche-section { margin-top: 16px; }

/* État vide d'une section : discret, il ne réclame pas un écran. */
.empty-state-compact { padding: 1.25rem 1rem; }
.empty-state-compact > i { font-size: 1.5rem; margin-bottom: .5rem; }
.empty-state-compact .empty-state-action { margin-top: .75rem; }

/* Retour : un lien au-dessus du titre, pas un bouton de plus parmi les actions. */
.page-retour { display: inline-flex; align-items: center; gap: .35rem; margin-bottom: .35rem; font-size: .82rem; color: var(--gs-muted); text-decoration: none; }
.page-retour:hover { color: var(--brand-primary-dark); }

@media (max-width: 640px) {
    .gs-fiche { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
    .gs-fiche-longue { grid-column: 1 / -1; }

    /* Groupes d'actions (en-tête de page, en-tête de fiche, actions de carte) : boutons resserrés en
       lignes pleines, l'action principale sur toute la largeur pour qu'elle se détache. La fiche
       élève alignait six boutons sur cinq lignes. Pas de `order` : l'ordre à l'écran reste celui du
       document, que suit le focus au clavier (review PR #205). */
    .page-header .actions, .gs-fiche-actions, .gs-card-actions { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
    .page-header .actions > .btn, .gs-fiche-actions > .btn, .gs-card-actions > .btn { flex: 1 1 auto; justify-content: center; padding: .55rem .75rem; font-size: .84rem; }
    /* Dès trois boutons, deux par ligne (le dernier, seul, prend la ligne) : un par ligne, quatre
       boutons d'une carte d'établissement occupaient un écran (revue du 8 oct. 2026). */
    .page-header .actions:has(> .btn:nth-of-type(3)), .gs-fiche-actions:has(> .btn:nth-of-type(3)), .gs-card-actions:has(> .btn:nth-of-type(3)) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    :is(.page-header .actions, .gs-fiche-actions, .gs-card-actions):has(> .btn:nth-of-type(3)) > .btn { white-space: normal; text-align: center; line-height: 1.25; }
    :is(.page-header .actions, .gs-fiche-actions, .gs-card-actions):has(> .btn:nth-of-type(3)) > .btn:last-child:nth-child(odd) { grid-column: 1 / -1; }

    /* Barre d'outils (téléphone) : la recherche sur toute la largeur ; dessous, « Filtres » et
       les boutons partagent une ligne (boutons compacts, poussés à droite, qui s'enroulent). */
    .toolbar { gap: .5rem; }
    .toolbar .search-box { flex: 1 1 100%; }
    .toolbar .search-input { width: 100%; }
    .toolbar .toolbar-actions { flex: 1 1 auto; margin-left: auto; gap: .5rem; }
    .toolbar .toolbar-actions > .btn { padding: .5rem .75rem; font-size: .84rem; }

    /* Onglets : tous visibles, sur deux lignes s'il le faut, plutôt qu'un défilement horizontal
       qui cachait « Historique » sans autre indice qu'une fine barre. Les icônes s'effacent. */
    /* row-gap : le soulignement (margin-bottom -2px) d'une ligne d'onglets ne mord pas sur la
       suivante (mesure de chevauchement, smoke du 3 oct. 2026). */
    .tabs { flex-wrap: wrap; overflow-x: visible; row-gap: 4px; }
    .tabs .tab, .tabs .tab-btn { flex: 1 1 auto; justify-content: center; padding: .6rem .75rem; font-size: .84rem; }
    .tabs .tab > i, .tabs .tab-btn > i { display: none; }

    /* Tableau en cartes : une ligne = une carte. La 1re colonne en est le titre, chaque autre
       cellule porte son libellé (data-label) à gauche et sa valeur à droite ; la colonne
       d'actions (libellé vide) prend toute la largeur. Flottant plutôt que flex : le contenu
       d'une cellule (badge + motif) garde son propre flux. */
    .data-table-cartes thead { display: none; }
    .data-table-cartes, .data-table-cartes tbody, .data-table-cartes tr { display: block; width: 100%; }
    .data-table-cartes tbody tr { padding: 12px 14px; border-bottom: 1px solid var(--gs-line); }
    .data-table-cartes tbody tr:last-child { border-bottom: 0; }
    .gs-card .data-table-cartes tbody tr { padding-left: 0; padding-right: 0; }  /* la section porte déjà la marge */
    .data-table-cartes tbody td { display: block; width: auto; padding: 3px 0; border: 0; text-align: right; overflow-wrap: anywhere; }
    .data-table-cartes tbody td::before { content: attr(data-label); float: left; margin-right: 12px; max-width: 45%; text-align: left; font-size: .75rem; font-weight: 600; line-height: 1.7; color: var(--gs-muted); }
    .data-table-cartes tbody td::after { content: ""; display: table; clear: both; }
    .data-table-cartes tbody td:first-child { text-align: left; font-size: .95rem; padding-bottom: 6px; }
    .data-table-cartes tbody td:first-child::before, .data-table-cartes tbody td[data-label=""]::before { content: none; }
    /* Titre désigné (colonne `titre: true`) : il passe en tête de la carte, la première colonne
       redevient une ligne libellée comme les autres. */
    .dt-titre-explicite tbody tr { display: flex; flex-direction: column; }
    .dt-titre-explicite tbody td[data-titre] { order: -1; text-align: left; font-size: .95rem; padding-bottom: 6px; }
    .dt-titre-explicite tbody td[data-titre]::before { content: none; }
    /* `:not([data-coin])` : une case de coin en première colonne garde son rendu de coin, sans
       libellé — plus spécifique, cette règle lui rendait « Active » tassé contre la case (#176). */
    .dt-titre-explicite tbody td:first-child:not([data-titre]):not([data-coin]) { text-align: right; font-size: inherit; padding-bottom: 3px; }
    .dt-titre-explicite tbody td:first-child:not([data-titre]):not([data-coin])::before { content: attr(data-label); }
    .data-table-cartes tbody td[data-label=""] { text-align: left; padding-top: 8px; }
    /* Texte long (table.js, `TEXTE_LONG`) : le libellé au-dessus, la valeur à gauche sur toute la
       largeur — à droite, une mention fiscale se coupait en escalier (smoke du 8 oct. 2026). */
    .data-table-cartes tbody td[data-texte] { text-align: left; }
    .data-table-cartes tbody td[data-texte]::before { float: none; display: block; max-width: none; margin: 0 0 1px; }
    /* Même rendu quand la cellule longue est la 1re colonne d'un tableau à titre désigné (la
       règle de cette 1re colonne, plus spécifique, la remettait à droite). */
    .dt-titre-explicite tbody td[data-texte]:first-child:not([data-titre]):not([data-coin]) { text-align: left; }
    /* Fiche élève, onglet Notes (#178) : les pastilles d'une matière s'alignent à droite, face
       à leur libellé, comme les autres valeurs d'une carte. */
    .notes-fiche .notes-fiche-pastilles { justify-content: flex-end; }
    .data-table-cartes tbody td:empty { display: none; }
    /* Ligne de total (tfoot) des tableaux écrits à la main — échéances de la caisse et de
       l'élève (smoke de la démo, 8 oct. 2026) : une carte de plus, libellés comme les autres. */
    .data-table-cartes tfoot { display: block; }
    .data-table-cartes tfoot tr { padding: 12px 14px; border-top: 2px solid var(--gs-line); }
    .gs-card .data-table-cartes tfoot tr { padding-left: 0; padding-right: 0; }
    .data-table-cartes tfoot :is(th, td) { display: block; padding: 3px 0; border: 0; text-align: right; }
    .data-table-cartes tfoot :is(th, td):first-child, .data-table-cartes tfoot :is(th, td):not([data-label]):not(:empty) { text-align: left; font-size: .95rem; }
    .data-table-cartes tfoot :is(th, td)[data-label]::before { content: attr(data-label); float: left; margin-right: 12px; text-align: left; font-size: .75rem; font-weight: 600; line-height: 1.7; color: var(--gs-muted); }
    .data-table-cartes tfoot :is(th, td):empty { display: none; }
    .data-table-cartes tfoot :is(th, td)::after { content: ""; display: table; clear: both; }
    .data-table-cartes tfoot :is(th, td)[data-label] { font-size: .85rem; }
    /* Tableau croisé (Finances : catégorie × mois) : en carte, l'en-tête de ligne est le titre,
       un mois par ligne, le total en bas, détaché (demande du 8 oct. 2026). */
    .data-table-cartes tbody th[scope="row"] { display: block; text-align: left; font-size: .95rem; padding: 0 0 6px; border: 0; white-space: normal !important; }
    /* Carte repliable (table.js, colonne `resume` ; tableaux croisés de Finances) : repliée, le
       titre et le résumé sur une ligne ; dépliée, le reste dessous. Base 0 pour le titre : un
       libellé long (« Matériels didactiques et consommables ») se coupe dans la place que laisse
       le résumé au lieu de le pousser à la ligne. Tout le titre est la zone d'appui du bouton ;
       un lien du titre (nom de l'élève → fiche) passe au-dessus et reste cliquable. */
    /* `row` : un tableau à titre désigné (`dt-titre-explicite`) met sa carte en colonne. */
    .data-table-cartes tbody tr.gs-repli { display: flex; flex-direction: row; flex-wrap: wrap; align-items: flex-start; }
    .data-table-cartes tbody tr.gs-repli > [data-repli-titre] { position: relative; display: flex; align-items: flex-start; flex: 1 1 0; min-width: 0; order: 0; padding: 0; text-align: left; }
    .data-table-cartes tbody tr.gs-repli > [data-repli-titre]::before { content: none; }
    .data-table-cartes tbody tr.gs-repli > td:not([data-repli-titre]):not([data-resume]):not([data-coin]) { display: none; flex: 0 0 100%; order: 2; }
    .data-table-cartes tbody tr.gs-repli.ouverte > td:not([data-repli-titre]):not([data-resume]):not([data-coin]):not(:empty):not([data-hors-carte]) { display: block; }
    /* Le résumé garde sa ligne courte ; un détail sous le montant (« − 8 000 FCFA de remise ») se
       coupe au lieu d'écraser le titre. */
    .data-table-cartes tbody tr.gs-repli > [data-resume] { flex: 0 1 auto; max-width: 55%; order: 1; margin: 0; padding: 0 0 0 12px; border: 0; font-size: .95rem; white-space: normal !important; text-align: right; }
    .data-table-cartes tbody tr.gs-repli > [data-resume]::before { content: none; }
    /* Repère d'état dans le résumé d'une carte repliée (proposition « à valider ») : affiché en
       carte seulement, la colonne Statut le porte déjà sur grand écran (smoke du 10 oct. 2026). */
    .data-table-cartes tbody tr.gs-repli > [data-resume] .gs-resume-carte { display: block; margin-top: 2px; }
    /* Case de sélection dans le coin (impayés) : le résumé lui laisse la place. */
    .data-table-cartes tbody tr.gs-repli:has(> [data-coin]) > [data-resume] { margin-right: 30px; }
    .data-table-cartes tbody tr.gs-repli:has(> [data-coin]) > [data-repli-titre] { padding-right: 0; }
    .data-table-cartes tbody tr.gs-repli.ouverte > [data-repli-titre] { padding-bottom: 6px; }
    .gs-repli-libelle { min-width: 0; overflow-wrap: anywhere; }
    .gs-repli-libelle a, .gs-repli-libelle button { position: relative; z-index: 1; }
    .gs-repli-bascule { align-items: center; justify-content: center; flex: 0 0 20px; width: 20px; height: 1.5em; margin-right: 4px; padding: 0; border: 0; background: none; color: var(--gs-muted); cursor: pointer; }
    .gs-repli-bascule::after { content: ""; position: absolute; inset: -12px 0; }
    .gs-repli-bascule i { transition: transform .15s ease; }
    .gs-repli.ouverte .gs-repli-bascule i { transform: rotate(90deg); }
    @media (prefers-reduced-motion: reduce) { .gs-repli-bascule i { transition: none; } }
    .gs-repli-bascule:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
    /* L'objet du reçu est tronqué à 180 px dans le tableau ; en carte, la cellule reprend toute la
       largeur, sinon sa valeur s'aligne au milieu (smoke de la démo, 6 oct. 2026). */
    .data-table-cartes.gs-dash-table .gs-dash-objet { max-width: none; white-space: normal; }
    .data-table-cartes tbody td[data-hors-carte] { display: none; }
    .data-table-cartes tbody td[data-carte-seule] { display: block; }
    .data-table-cartes tbody tr { position: relative; }
    .data-table-cartes tbody td[data-coin] { position: absolute; top: 12px; right: 0; padding: 0; }
    .data-table-cartes tbody td[data-coin]::before { content: none; }
    .data-table-cartes:not(.gs-card *) tbody td[data-coin] { right: 14px; }
    .data-table-cartes tbody tr:has(td[data-coin]) td[data-titre],
    .data-table-cartes:not(.dt-titre-explicite) tbody tr:has(td[data-coin]) td:first-child { padding-right: 32px; }

    /* Filtres repliés derrière un bouton ; ouverts, ils se rangent sur toute la largeur. */
    .toolbar-filtres-bouton { display: inline-flex; }
    .toolbar-filtres { display: none; }
    .toolbar-filtres.ouverts {
        display: flex; flex-wrap: wrap; gap: .5rem; width: 100%; order: 10;
        padding: .625rem; background: var(--white); border: 1px solid var(--gray-100); border-radius: var(--radius-sm);
    }
}

/* Affectations (#177) : les sélecteurs d'enseignant d'une grille ont tous la même largeur,
   quel que soit le nom choisi — sinon la colonne se décale à chaque changement. */
#aff-grille .dd { width: min(100%, 280px); }
#aff-grille .dd-trigger { width: 100%; min-width: 0; }

/* Saisie des notes (#178) : grille au clavier. Elle défile dans son cadre, jamais la page ; la
   colonne des élèves reste visible quand on défile vers les évaluations de droite. */
.notes-grille-cadre { border: 1px solid var(--gray-200); border-radius: var(--radius-sm); background: var(--gs-surface); width: fit-content; max-width: 100%; }
/* Largeur naturelle (9 oct. 2026) : étirée à 100 %, une grille de deux évaluations écartait l'en-tête
   (à gauche) de sa note (à droite) de 400 px. En-tête et note centrés dans leur colonne. */
.notes-grille { border-collapse: collapse; width: auto; max-width: 100%; font-size: .9rem; }
.notes-grille th, .notes-grille td { padding: 6px 8px; border-bottom: 1px solid var(--gray-200); vertical-align: middle; }
.notes-grille thead th { text-align: left; font-weight: 600; background: var(--gray-50, var(--gs-surface)); vertical-align: bottom; }
.notes-grille .notes-eleve { position: sticky; left: 0; z-index: 1; background: var(--gs-surface); text-align: left; font-weight: 500; min-width: 200px; max-width: 260px; }
.notes-grille .notes-rang { display: inline-block; min-width: 1.6em; color: var(--gray-500); font-variant-numeric: tabular-nums; }
.notes-grille .notes-eval { min-width: 96px; max-width: 140px; text-align: center; }
.notes-eval-titre { overflow-wrap: break-word; }
.notes-eval-sous { font-size: .75rem; font-weight: 400; white-space: nowrap; }
.notes-eval-actions { display: grid; grid-template-columns: repeat(2, max-content); justify-content: center; gap: 4px; margin-top: 4px; }
.notes-grille .notes-case { text-align: center; }
.notes-grille .notes-moyenne { text-align: right; white-space: nowrap; }
.notes-input { height: 36px; width: 68px; text-align: right; }
.notes-input.invalide { border-color: var(--status-danger-fg); background: var(--status-danger-bg); }
/* Téléphone : la grille devient une liste (9 oct. 2026) — une carte par élève, une ligne par
   évaluation (libellé à gauche, note à droite), la moyenne en dernier ; les évaluations et leurs
   actions restent au-dessus, en liste elles aussi. La navigation au clavier (data-r / data-c) est
   inchangée. */
@media (max-width: 720px) {
    .notes-grille-cadre { border: 0; background: none; width: auto; }
    .notes-grille, .notes-grille thead, .notes-grille tbody, .notes-grille tr, .notes-grille th, .notes-grille td { display: block; width: auto; }
    .notes-grille thead tr { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
    .notes-grille thead th:first-child, .notes-grille thead th.notes-moyenne { display: none; }
    .notes-grille thead th.notes-eval { max-width: none; border: 1px solid var(--gray-200); border-radius: var(--radius-sm); background: var(--gs-surface); }
    .notes-grille tbody tr { border: 1px solid var(--gray-200); border-radius: var(--radius-sm); background: var(--gs-surface); margin-bottom: 10px; padding: 4px 0; }
    .notes-grille .notes-eleve { position: static; max-width: none; white-space: normal; border-bottom: 1px solid var(--gray-200); }
    .notes-grille td.notes-case, .notes-grille td.notes-moyenne { display: flex; align-items: center; justify-content: space-between; gap: 12px; border-bottom: 0; }
    .notes-grille td.notes-case::before, .notes-grille td.notes-moyenne::before { content: attr(data-label); color: var(--gs-muted); font-size: .85rem; text-align: left; }
    .notes-grille td.notes-moyenne { border-top: 1px solid var(--gray-200); }
    .notes-grille .tbl-wrap, .notes-grille-cadre .tbl-wrap { overflow: visible; }
}
.notes-barre { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px 12px; margin-top: 12px; }
/* Onglet « Notes » de la fiche élève (#178) : une pastille par évaluation, qui s'enroule. */
.notes-fiche-periode + .notes-fiche-periode { margin-top: 16px; }
.notes-fiche-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; cursor: pointer; list-style: none; }
.notes-fiche-tete::-webkit-details-marker { display: none; }
.notes-fiche-tete::before { content: '›'; font-size: 1.1rem; line-height: 1; color: var(--gs-muted); transition: transform .15s; }
details[open] > .notes-fiche-tete::before { transform: rotate(90deg); }
.notes-fiche-tete .gs-h2 { margin: 0; }
.notes-fiche-tete .gs-muted { font-size: .85rem; }
.notes-fiche-corps { margin-top: 10px; }
.notes-fiche .notes-fiche-matiere { font-weight: 500; }
.notes-fiche-sous { font-size: .75rem; font-weight: 400; }
.notes-fiche-pastilles { display: flex; flex-wrap: wrap; gap: 6px; }
.note-fiche { display: inline-flex; flex-direction: column; align-items: center; min-width: 64px; padding: 3px 8px; border: 1px solid var(--gray-200); border-radius: var(--radius-sm); font-variant-numeric: tabular-nums; }
.note-fiche small { font-size: .7rem; color: var(--gray-500); white-space: nowrap; }
.note-fiche small.note-fiche-detail { white-space: normal; max-width: 16ch; text-align: center; overflow-wrap: anywhere; }
.note-fiche-absent strong, .note-fiche-vide strong { color: var(--gray-500); font-weight: 500; }
.notes-fiche td.num { white-space: nowrap; }

/* Écoles de l'éditeur (#218) : une carte par école, en grille ; une colonne sur téléphone. */
.gs-ecoles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 360px), 1fr)); gap: 16px; align-items: start; }
.gs-ecole { display: flex; flex-direction: column; gap: 10px; padding: 16px 18px; min-width: 0; }
.gs-ecole-tete { display: flex; align-items: flex-start; gap: 10px; }
.gs-ecole-pastille { flex: none; width: 14px; height: 14px; border-radius: 4px; margin-top: 4px; }
.gs-ecole-nom { min-width: 0; overflow-wrap: anywhere; }
.gs-ecole-nom strong { font-size: 1rem; }
.gs-ecole .gs-muted { font-size: .8rem; overflow-wrap: anywhere; }
.gs-ecole-adresse { font-size: .85rem; overflow-wrap: anywhere; }
.gs-ecole-titre { font-size: .72rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--gs-muted); margin: 4px 0 0; padding-top: 10px; border-top: 1px solid var(--gs-line); }
.gs-ecole-admins { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.gs-ecole-admin { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; }
.gs-ecole-admin-qui { min-width: 0; }
.gs-ecole-etabs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.gs-ecole-etab { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.gs-ecole-etab-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.gs-ecole-etab-qui { min-width: 0; overflow-wrap: anywhere; }
.gs-ecole-pied { padding-top: 10px; border-top: 1px solid var(--gs-line); }
/* Formulaires de mise en service et d'invitation : champs resserrés (l'espacement du socle, prévu
   pour des formulaires de quelques champs, étalait ces treize champs sur trois écrans). */
#ecole-form .ff-section > [class^="grid-"] { row-gap: 14px; margin-bottom: 0; }
#ecole-form .form-group { margin-bottom: 0; }
#ecole-form .ff-section + .ff-section { margin-top: 14px; }
.gs-ecole-pied { display: flex; gap: 8px; flex-wrap: wrap; }
/* Identité visuelle d'une école (#218) : couleur et logos. */
.gs-identite-bloc { margin-bottom: 12px; }
.gs-identite-couleur { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.gs-identite-champ { flex: 1; min-width: 0; }
.gs-identite-couleurs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 14px; }
.gs-identite-proposees { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; padding: 10px 12px; margin-bottom: 12px; border: 1px dashed var(--gs-line); border-radius: 8px; font-size: .88rem; }
.gs-identite-proposee { display: inline-flex; align-items: center; gap: 6px; }
.gs-identite-temoin.gs-identite-temoin--petit { width: 18px; height: 18px; border-radius: 4px; }
.gs-identite-champ .form-group { margin: 0; }
.gs-identite-temoin { flex: none; width: 44px; height: 44px; border-radius: 10px; border: 1px solid var(--gs-line); }
.gs-identite-apercu { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; margin: 8px 0; }
.gs-identite-logo.gs-identite-logo--couleur { border-color: transparent; }
.gs-identite-logo { max-height: 90px; max-width: 220px; object-fit: contain; background: repeating-conic-gradient(#eee 0 25%, #fff 0 50%) 0 0/16px 16px; border: 1px solid #e5e7eb; border-radius: 6px; padding: 4px; }

/* Accès support ouvert par l'école (#223) : rappel permanent, sobre, au-dessus de la barre. */
.gs-support-banner { background: var(--status-info-bg); color: var(--status-info-fg); border-bottom: 1px solid var(--status-info-fg); padding: 6px 16px; font-size: .82rem; text-align: center; overflow-wrap: anywhere; }
.gs-support-banner i { margin-right: 6px; }
.gs-support { margin-top: 16px; }
.gs-support-tete { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; }
.gs-support-tete h2 { font-size: 1rem; margin: 0; }
.gs-support-liste { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.gs-support-acces { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; }
.gs-support-acces-qui { min-width: 0; overflow-wrap: anywhere; }

/* Objectifs et rémunération (8 oct. 2026) : une carte par commercial, tuiles du socle, blocs
   espacés régulièrement ; en-tête et boutons qui passent à la ligne sur téléphone. */
.remu-aide { margin: 0 0 12px; font-size: .85rem; }
.remu-aide > p { margin: 0 0 6px; }
.remu-carte { padding: 16px 18px; }
.remu-entete { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px 12px; margin-bottom: 16px; }
.remu-entete .gs-h2 { margin: 0; }
.remu-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.remu-note { margin: 0 0 12px; font-size: .85rem; }
.remu-releve { margin: 0 0 12px; flex-wrap: wrap; gap: 6px 10px; }
.remu-carte .kpi-tiles { margin: 0 0 4px; }
.remu-bloc { margin-top: 20px; }
.remu-titre { font-size: .95rem; font-weight: 600; margin: 0 0 8px; }
.remu-titre .gs-muted { font-weight: 400; font-size: .8rem; }
@media (max-width: 768px) {
    .remu-carte { padding: 12px; }
}

/* =============================================================================
   Groupes d'actions et de filtres — règle UNIQUE pour toute l'application (8 oct. 2026)
   -----------------------------------------------------------------------------
   En-tête de page (`.page-header .actions`), en-tête d'état (`.glhead-filters`), barre
   d'outils (`.toolbar-actions`), fiche et carte (`.gs-fiche-actions`, `.gs-card-actions`) :
   filtres et boutons partagent une ligne TANT QU'ILS Y TIENNENT, et passent à la ligne
   seulement faute de place — jamais une ligne imposée par écran (« Octobre 2026 » et
   « Nouvelle charge » empilés sur téléphone alors qu'ils tenaient côte à côte). Chaque élément
   garde sa largeur naturelle (libellé sur une ligne) puis grandit pour remplir la ligne.
   ============================================================================= */
.page-header .actions, .glhead-filters, .toolbar .toolbar-actions, .gs-fiche-actions, .gs-card-actions, .remu-actions {
    display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; min-width: 0;
}
/* L'en-tête d'état (écrans de l'éditeur) est posé sur la page comme la barre d'outils : ni
   retrait latéral ni filet, aligné sur le contenu. */
.glhead { padding: 0; border-bottom: 0; margin: 0 0 1rem; gap: .5rem .75rem; }
@media (max-width: 768px) {
    .page-header .actions, .glhead-filters, .gs-fiche-actions, .gs-card-actions, .remu-actions {
        width: 100%; flex-wrap: wrap;
    }
    /* Dans la barre d'outils, les boutons prennent la place laissée par les filtres sur la même
       ligne, et passent dessous seulement s'il n'en reste pas. */
    .toolbar .toolbar-actions { width: auto; flex: 1 1 auto; }
    /* Tuiles d'indicateurs en nombre impair : la dernière occupe toute la ligne plutôt que
       de rester seule dans une demi-ligne vide. */
    .kpi-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
    .kpi-tile { padding: .6rem .7rem; min-width: 0; }
    .kpi-tile-value { font-size: 1.02rem; overflow-wrap: anywhere; }
    .kpi-tiles > .kpi-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }
    :is(.page-header .actions, .glhead-filters, .toolbar .toolbar-actions, .gs-fiche-actions, .gs-card-actions, .remu-actions) > :is(.btn, .dd, .dp, .chip) {
        flex: 1 1 auto; min-width: 0;
    }
    :is(.page-header .actions, .glhead-filters, .toolbar .toolbar-actions, .gs-fiche-actions, .gs-card-actions, .remu-actions) > .btn {
        justify-content: center; white-space: nowrap; padding: .5rem .75rem; font-size: .84rem;
    }
    :is(.page-header .actions, .glhead-filters, .toolbar .toolbar-actions) > .dd .dd-trigger { width: 100%; }
    /* Une SEULE action de carte reste un petit bouton dans l'en-tête, à côté du titre : en
       pleine largeur, « État journalier » et « Ouvrir un accès » tombaient entre le titre et le
       texte de la carte (revue des écrans, 8 oct. 2026). Dès deux actions, la règle ci-dessus. */
    .gs-card-head > .gs-card-actions:not(:has(> :nth-child(2))) { width: auto; margin-left: auto; }
    .gs-card-head > .gs-card-actions:not(:has(> :nth-child(2))) > .btn { flex: 0 0 auto; }
}


/* Repli des cartes : le bouton n'existe qu'en carte (téléphone) ; sur grand écran, le titre
   garde son rendu de cellule. */
.gs-repli-bascule { display: none; }
.gs-repli-libelle { display: contents; }
@media (max-width: 640px) {
    .data-table-cartes .gs-repli-bascule { display: inline-flex; }
    .data-table-cartes .gs-repli-libelle { display: block; }
}

/* Pastilles (components/pastilles.js, 8 oct. 2026) : une courte liste de valeurs de référence —
   chaque élément reste entier, la liste passe à la ligne entre deux éléments. */
.gs-liste-pastilles { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.gs-liste-pastille { display: inline-flex; align-items: baseline; gap: 6px; max-width: 100%; padding: 2px 10px; border: 1px solid var(--gs-line, #E4E0D8); border-radius: 999px; background: var(--surface, #fff); font-size: .8rem; line-height: 1.6; overflow-wrap: anywhere; }
.gs-liste-pastille > span { color: var(--gs-muted, #6b7280); }
.gs-fiche-options { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; font-size: .85rem; }
/* En carte (téléphone), des pastilles à droite d'un libellé s'alignent à droite comme les
   autres valeurs ; sous un libellé (texte long), à gauche. */
@media (max-width: 640px) {
    .data-table-cartes tbody td:not([data-texte]):not(:first-child) .gs-liste-pastilles { justify-content: flex-end; }
}

/* Titre répété (layout.js, `_marquerTitreRepete`) : sur téléphone, la barre du haut porte déjà
   le titre de la page ; l'en-tête garde son sous-titre et ses actions. Masqué à l'œil seulement :
   le h1 reste le titre de la page pour un lecteur d'écran et la navigation par titres. */
@media (max-width: 768px) {
    .gs-titre-repete { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
}

/* ---- Grille des tarifs (GrilleTarifs, 8 oct. 2026) ---------------------------------------
   Une carte par formule : cible, mensuel en grand, supplément par site, mise en service. Trois
   colonnes sur grand écran, une sous 720 px ; la formule retenue est soulignée. */
.gs-tarifs { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.gs-tarif { display: flex; flex-direction: column; gap: 6px; padding: 16px; border: 1px solid var(--gs-line); border-radius: var(--radius); background: var(--gs-surface); min-width: 0; }
.gs-tarif-retenue { border-color: var(--brand-primary); box-shadow: 0 0 0 1px var(--brand-primary); background: var(--brand-primary-bg); }
.gs-tarif-tete { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.gs-tarif-nom { margin: 0; font-family: var(--gs-font-display); font-size: 1.05rem; }
.gs-tarif-cible { margin: 0; color: var(--gs-muted); font-size: .82rem; }
.gs-tarif-prix { margin: 6px 0 0; font-size: .9rem; color: var(--gs-muted); }
.gs-tarif-prix strong { font-family: var(--gs-font-display); font-size: 1.6rem; color: var(--gs-ink); font-variant-numeric: tabular-nums; }
.gs-tarif-site { margin: 0; font-size: .82rem; color: var(--gs-muted); }
.gs-tarif-montant { white-space: nowrap; font-weight: 600; color: var(--gs-ink); font-variant-numeric: tabular-nums; }
.gs-tarif-mes { margin-top: auto; padding-top: 10px; border-top: 1px dashed var(--gs-line); display: flex; flex-direction: column; gap: 2px; }
.gs-tarif-mes p { margin: 0; font-size: .9rem; }
.gs-tarif-mes-titre { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--gs-muted); }
.gs-tarifs-compact { gap: 8px; }
.gs-tarifs-compact .gs-tarif { padding: 10px 12px; gap: 4px; }
.gs-tarifs-compact .gs-tarif-prix strong { font-size: 1.25rem; }
@media (max-width: 720px) { .gs-tarifs { grid-template-columns: 1fr; } }
.gs-tarif-action { padding-top: 8px; }
.gs-tarif-action .btn { width: 100%; justify-content: center; }
/* Import : un seul espacement entre les champs — la grille, sans la marge propre à chaque champ
   (44 px entre deux listes, 24 px avant le classeur : revue des écrans, 8 oct. 2026). */
.gs-import-form { gap: 16px 24px; }
.gs-import-form > .form-group { margin-bottom: 0; }
/* Pied de tableau (DataTable `pied`, 8 oct. 2026) : la ligne de total se détache du corps. */
.data-table tfoot .dt-pied > * { border-top: 2px solid var(--gs-line); background: var(--gs-surface-2); font-weight: 600; text-align: left; }
/* Colonnes de montants (DataTable `num`) : à droite, en-tête et total compris, comme dans les
   cartes repliables du téléphone (retour du 8 oct. 2026). */
.data-table :is(th, td)[data-num] { text-align: right; white-space: nowrap; }
/* ---- ListeValeurs (8 oct. 2026) : libellé à gauche, valeur à droite, une ligne chacune ---- */
.gs-valeurs { margin: 0; display: flex; flex-direction: column; }
.gs-valeur { display: flex; align-items: baseline; justify-content: space-between; gap: 6px 16px; padding: 6px 0; border-bottom: 1px dashed var(--gs-line); flex-wrap: wrap; }
.gs-valeur:last-child { border-bottom: 0; }
.gs-valeur dt { color: var(--gs-muted); font-size: .85rem; min-width: 0; }
.gs-valeur dd { margin: 0 0 0 auto; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.gs-valeur-forte dt { color: var(--gs-ink); font-weight: 600; }
.gs-valeur-forte dd { font-weight: 700; }
.gs-valeur-danger dd { color: var(--status-danger-fg); }
.gs-valeur-success dd { color: var(--status-success-fg); }
.gs-valeur-warning dd { color: var(--status-warning-fg, #92400e); }
.gs-valeurs-compact .gs-valeur { padding: 3px 0; }
/* Couverture du forfait (fiche abonnement de l'éditeur) : titre puis une ligne par critère. */
.gs-forfait { margin-top: 12px; padding: 10px 12px; border-radius: 10px; background: var(--gs-surface-2); }
.gs-forfait-depasse { background: var(--status-warning-bg); }
.gs-forfait-titre { margin: 0 0 4px; font-weight: 600; font-size: .9rem; }
.gs-forfait .btn { margin-top: 8px; }
.gs-valeur-detail { font-size: .78rem; font-weight: 400; white-space: normal; }
/* Caisse : reste dû et « Tout solder » sur une ligne, sous le montant reçu. */
.gs-caisse-reste { display: flex; align-items: center; gap: 12px; margin: 6px 0 12px; }
.gs-caisse-reste .gs-valeurs { flex: 1; }
.gs-card-resume { white-space: nowrap; }

/* Hors carte repliée : le repère du résumé reste caché (voir la règle des cartes). */
.gs-resume-carte { display: none; }

/* Liste de classe : choix des colonnes en plus (12 oct. 2026) — cases serrées, pied visible au
   téléphone. */
.gs-liste-colonnes > p { margin: 0 0 6px; }
.gs-liste-colonnes-cases { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0 12px; margin-bottom: 10px; }
.gs-liste-colonnes-cases .form-group { margin-bottom: 4px; }
.gs-liste-colonnes .grid-3 { gap: 0 12px; margin-bottom: 0; }

/* Paie : lignes à recalculer (#278) — bandeau au-dessus du tableau, détail sous la base. */
.gs-paie-bandeau { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; padding: 10px 12px; margin-bottom: 12px; border-radius: 8px; background: var(--status-warning-bg); color: var(--status-warning-fg); }
.gs-paie-ecarts { margin: 4px 0 0; padding-left: 16px; font-size: .75rem; color: var(--status-warning-fg); }
