/* /Components/Grids/HelpGridV3.razor.rz.scp.css */
/* HelpGridV3 — CSS isolé (bundle {App}.styles.css du host).
   Jetons de thème avec valeurs Colibase par défaut : surchargez-les dans un
   sélecteur plus spécifique (.gdg { --c-accent: ... }) pour thématiser.
   E5/G9 (mode sombre) : ce bloc de jetons (les --c-* et --sh-lg) est REDÉFINI plus bas sous
   @media screen and (prefers-color-scheme: dark) (gardé par :root:not([data-theme="light"]) ET par
   l'opt-in gdg-theme-auto — sans lui, la grille reste claire en système sombre, G6)
   et sous @media screen { :root[data-theme="dark"] { ... } } — "screen" (round 1 de revue) pour
   qu'aucun des deux ne déteigne sur @media print, plus bas, qui reste sur CES valeurs claires —
   jamais de couleur en dur ailleurs dans ce fichier
   (ThemeTests.Aucune_couleur_codee_en_dur_hors_des_declarations_de_variables). */

.gdg[b-9kaz8ksd3g] {
    --c-accent: #C8392C;
    --c-accent-700: #AC2E22;
    --c-accent-soft: #FBEBE9;
    --c-accent-soft-2: #F6DAD6;
    --c-border: #E2E6EB;
    --c-border-2: #D2D8DF;
    --c-surface: #FFFFFF;
    --c-surface-2: #EEF1F4;
    --c-surface-3: #E4E8ED;
    --c-row-sel: #D7DEE7;      /* ligne cochée : gris franc, distinct du survol et de l'accent */
    --c-col-active: #ffd9d4;  /* colonne active (E1) : rouge clair, lisible en clair comme en sombre */
    --c-ink: #1A2230;
    --c-ink-2: #4A586B;
    --c-ink-3: #8693A4;
    --c-navy: #16202E;
    --c-on-navy: #EAF0F7;
    --c-info: #2F5FA8;
    --c-info-soft: #E6EDF8;
    --c-warning-soft: #FBF0DC;
    --sh-lg: 0 18px 48px -18px rgba(16,28,45,.28), 0 6px 18px -10px rgba(16,28,45,.12);

    /* Jetons ajoutés en tâche 4 pour éliminer les couleurs en dur restantes (E5) : valeurs claires
       IDENTIQUES à ce qu'elles remplacent (G6, apparence claire inchangée). --c-on-accent, les
       surcouches --ov-*, les ombres --sh-float* et les jetons d'impression n'ont PAS besoin de
       variante sombre (le fond qu'ils accompagnent — accent, marine — reste suffisamment sombre/
       saturé dans les deux thèmes, et l'impression est volontairement figée). --c-danger-soft(-2),
       --c-on-info ET --c-danger-ink, EUX, sont redéfinis dans les deux blocs sombres ci-dessous
       (round 1 et 2 de revue, tâche 4) : la valeur claire d'origine ne suffisait plus une fois
       --c-ink-2/--c-info éclaircis en sombre, ou (--c-danger-ink, round 2) une fois --c-accent
       lui-même redéfini en sombre — voir la table de contraste du rapport. */
    --c-on-accent: #fff;                              /* texte/icône sur un fond --c-accent/--c-navy */
    --c-on-info: #fff;                                /* texte/icône sur un fond --c-info (distinct de on-accent : --c-info s'éclaircit en sombre, contrairement à accent/navy) */
    --ov-12: rgba(255, 255, 255, .12);                /* surcouches blanches sur fond sombre (puces, barres) */
    --ov-16: rgba(255, 255, 255, .16);
    --ov-22: rgba(255, 255, 255, .22);
    --ov-25: rgba(255, 255, 255, .25);
    --ov-28: rgba(255, 255, 255, .28);
    --ov-40: rgba(255, 255, 255, .4);
    --ov-50: rgba(255, 255, 255, .5);
    --sh-float: 0 10px 26px rgba(15, 23, 42, .30), 0 2px 6px rgba(15, 23, 42, .20);   /* barre de sélection */
    --sh-float-2: 0 10px 26px rgba(15, 23, 42, .22), 0 2px 6px rgba(15, 23, 42, .14); /* bandeau d'annulation */
    --c-danger-soft: #FCEBEB;                         /* rapport d'édition massive écartée */
    --c-danger-soft-2: #F0C9C9;
    --c-danger-ink: #C8392C;                          /* round 2 : texte sur --c-danger-soft (titre du rapport) — même valeur que --c-accent en clair (G6), mais un jeton dédié : --c-accent lui-même reste inchangé (décision du contrôleur, round 2), voir sa variante sombre plus bas */
    --c-print-ink: #000;                              /* impression : toujours noir sur blanc, quel que soit le thème écran */
    --c-print-border: #999;
}

/* E5/G9 : mode sombre — préférence système, tant que l'hôte n'a pas figé le thème sur "light".
   OPT-IN (G6, revue finale du jalon 21) : ce bloc ne vaut QUE si l'hôte le demande — classe gdg-theme-auto sur
   <html>, sur un ancêtre de la grille, ou sur la racine .gdg elle-même (paramètre AutoDarkMode). Sans opt-in,
   une grille reste claire même si le système est sombre (comportement 1.1.0 : CoreBlazor.Shared, PalladiumStats
   et toute page claire qui ne gère pas le sombre ne voient pas une grille sombre surgir dans une page claire).
   "screen" (round 1 de revue, tâche 4) : SANS lui, ce bloc s'appliquait aussi à l'impression — un
   navigateur qui imprime avec le thème sombre actif aurait rendu --c-ink-2 (texte des cellules)
   quasi invisible sur le papier blanc de @media print (qui, lui, ne redéfinit QUE color/border,
   pas --c-surface). Restreindre au support écran laisse l'impression sur les jetons clairs, seuls
   déclarés dans .gdg (ligne 9) — la promesse du README (« impression toujours noir sur blanc, quel
   que soit le thème de l'écran ») redevient vraie. */
@media screen and (prefers-color-scheme: dark) {
    :root.gdg-theme-auto:not([data-theme="light"]) .gdg[b-9kaz8ksd3g],
    :root:not([data-theme="light"]) .gdg-theme-auto .gdg[b-9kaz8ksd3g],
    :root:not([data-theme="light"]) .gdg.gdg-theme-auto[b-9kaz8ksd3g] {
        --c-accent: #CC4534;
        --c-accent-700: #B23A2A;
        --c-accent-soft: #331A1C;
        --c-accent-soft-2: #452420;
        --c-border: #3A4454;
        --c-border-2: #4B5768;
        --c-surface: #1C232D;
        --c-surface-2: #242D39;
        --c-surface-3: #2D3745;
        --c-row-sel: #3B4A5C;
        --c-col-active: #4A2420;
        --c-ink: #EDF1F6;
        --c-ink-2: #C7D0DC;
        --c-ink-3: #94A3B8;
        --c-navy: #0E141C;
        --c-on-navy: #EAF0F7;
        --c-info: #6FA8E8;
        --c-info-soft: #1C2A3D;
        --c-warning-soft: #3B341E;
        --sh-lg: 0 18px 48px -18px rgba(0, 0, 0, .65), 0 6px 18px -10px rgba(0, 0, 0, .45);
        --c-on-info: #0E141C;      /* round 1 : --c-info s'éclaircit en sombre (texte lisible sur --c-info-soft) — un texte blanc dessus (fond de puce/bouton) serait quasi invisible (~2,5:1) ; ce quasi-noir donne 7,4:1 */
        --c-danger-soft: #2A1416; /* round 1 : la version claire faisait disparaître --c-ink-2 (texte du rapport, devenu clair en sombre) — voir table de contraste du rapport */
        --c-danger-soft-2: #452420;
        --c-danger-ink: #E86F5B;  /* round 2 : --c-accent sombre (#CC4534) ne dépasse pas 3,7:1 sur --c-danger-soft sombre (ni 4,5:1 sur aucun fond sombre plausible, c'est la couleur elle-même qui plafonne à 4,47:1 contre du noir pur) ; l'éclaircir ici, SANS toucher --c-accent (décision du contrôleur), donne 5,67:1 */
    }
}

/* E5/G9 : mode sombre — forcé par l'hôte (attribut data-theme, contrat rp-theme-auto de RPrinter).
   "screen" (round 1 de revue, tâche 4) : même raison que le bloc @media ci-dessus — data-theme reste
   posé sur <html> pendant l'impression (l'hôte ne l'enlève pas pour imprimer), donc SANS ce garde
   la feuille imprimée aurait hérité des jetons sombres malgré @media print. */
@media screen {
    :root[data-theme="dark"] .gdg[b-9kaz8ksd3g] {
        --c-accent: #CC4534;
        --c-accent-700: #B23A2A;
        --c-accent-soft: #331A1C;
        --c-accent-soft-2: #452420;
        --c-border: #3A4454;
        --c-border-2: #4B5768;
        --c-surface: #1C232D;
        --c-surface-2: #242D39;
        --c-surface-3: #2D3745;
        --c-row-sel: #3B4A5C;
        --c-col-active: #4A2420;
        --c-ink: #EDF1F6;
        --c-ink-2: #C7D0DC;
        --c-ink-3: #94A3B8;
        --c-navy: #0E141C;
        --c-on-navy: #EAF0F7;
        --c-info: #6FA8E8;
        --c-info-soft: #1C2A3D;
        --c-warning-soft: #3B341E;
        --sh-lg: 0 18px 48px -18px rgba(0, 0, 0, .65), 0 6px 18px -10px rgba(0, 0, 0, .45);
        --c-on-info: #0E141C;
        --c-danger-soft: #2A1416;
        --c-danger-soft-2: #452420;
        --c-danger-ink: #E86F5B;
    }
}

/* =========================================================================
   HelpGridV3 (Components/Grids/V3) — préfixe gdg-
   Styles globaux (pas de CSS isolé : l'hôte Uno ne sert pas les bundles scoped).
   ========================================================================= */

/* position: relative → repère des éléments en surimpression (barre de sélection, bandeau d'annulation) */
.gdg[b-9kaz8ksd3g] { position: relative; color: var(--c-ink); font-size: 13.5px; outline: none; }

/* ---- zone de groupage ---- */
.gdg-groupzone[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    min-height: 40px; padding: 6px 12px; margin-bottom: 10px;
    border: 1.5px dashed var(--c-border); border-radius: 10px;
    background: var(--c-surface-2);
    transition: border-color .15s, background .15s;
}
.gdg-groupzone.gdg-dropover[b-9kaz8ksd3g] { border-color: var(--c-accent); background: var(--c-accent-soft); }
.gdg-groupicon[b-9kaz8ksd3g] { color: var(--c-ink-3); font-size: 14px; }
.gdg-grouphint[b-9kaz8ksd3g] { color: var(--c-ink-3); font-size: 12.5px; }
.gdg-groupchip[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 6px 4px 12px; border-radius: 999px;
    background: var(--c-navy); color: var(--c-on-navy);
    font-size: 12.5px; font-weight: 600; cursor: pointer; user-select: none;
}
.gdg-chipdir[b-9kaz8ksd3g] { font-size: 11px; opacity: .9; }
.gdg-chipx[b-9kaz8ksd3g] {
    border: none; background: var(--ov-22); color: var(--c-on-accent);
    width: 18px; height: 18px; border-radius: 50%; cursor: pointer;
    font-size: 13px; line-height: 1; padding: 0;
}
.gdg-chipx:hover[b-9kaz8ksd3g] { background: var(--ov-40); }
.gdg-link[b-9kaz8ksd3g] { border: none; background: none; color: var(--c-accent); font-size: 12px; cursor: pointer; padding: 2px 4px; }
.gdg-link:hover[b-9kaz8ksd3g] { text-decoration: underline; }

/* ---- barre d'outils ---- */
.gdg-toolbar[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.gdg-spacer[b-9kaz8ksd3g] { flex: 1; }
.gdg-search[b-9kaz8ksd3g] {
    flex: 1; min-width: 200px; max-width: 400px; padding: 8px 12px;
    border: 1px solid var(--c-border); border-radius: 9px;
    background: var(--c-surface); font-size: 13.5px; color: var(--c-ink);
}
.gdg-search:focus[b-9kaz8ksd3g] { outline: 2px solid var(--c-accent); outline-offset: -1px; }
/* Les selecteurs ::deep habillent aussi ce que l'ECRAN place dans ToolbarContent ou dans un
   gabarit de cellule : le CSS a portee ne descend pas dans le balisage venu d'un autre composant,
   et un bouton maison au milieu des boutons de la grille se voyait tout de suite. Un <button
   class="gdg-btn"> ecrit dans une page a donc exactement l'allure des boutons de la barre. */
.gdg-btn[b-9kaz8ksd3g], .gdg-iconbtn[b-9kaz8ksd3g],
.gdg[b-9kaz8ksd3g]  .gdg-btn, .gdg[b-9kaz8ksd3g]  .gdg-iconbtn {
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    border: 1px solid var(--c-border); background: var(--c-surface); color: var(--c-ink-2);
    border-radius: 9px; padding: 7px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.gdg-iconbtn[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-iconbtn { width: 34px; height: 34px; padding: 0; font-size: 15px; }
.gdg-btn:hover[b-9kaz8ksd3g], .gdg-iconbtn:hover[b-9kaz8ksd3g],
.gdg[b-9kaz8ksd3g]  .gdg-btn:hover, .gdg[b-9kaz8ksd3g]  .gdg-iconbtn:hover { border-color: var(--c-accent); color: var(--c-accent); }
.gdg-iconbtn.is-on[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-iconbtn.is-on { background: var(--c-accent-soft); border-color: var(--c-accent); color: var(--c-accent); }

/* ---- sélecteur de colonnes ---- */
.gdg-colmenu-host[b-9kaz8ksd3g] { position: relative; }
.gdg-overlay[b-9kaz8ksd3g] { position: fixed; inset: 0; z-index: 40; }
.gdg-colmenu[b-9kaz8ksd3g] {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: 50;
    min-width: 220px; max-height: 320px; overflow-y: auto; padding: 8px;
    border: 1px solid var(--c-border); border-radius: 12px;
    background: var(--c-surface); box-shadow: var(--sh-lg);
}
.gdg-colmenu-title[b-9kaz8ksd3g] {
    margin: 4px 8px 8px; font-size: 11px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase; color: var(--c-ink-3);
}
.gdg-colopt[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 9px; padding: 7px 8px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.gdg-colopt:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); }

/* ---- barre de sélection ----
   Elle FLOTTE au-dessus de la grille : dans le flux, son apparition décalait tout l'écran de
   ~47 px a chaque coche/decoche — desagreable, et en defilement continu ce saut faisait redemander
   une fenetre a Virtualize. Barre posee en surimpression, ancree en bas et centree, comme les
   barres d'action des listes de fichiers : rien ne bouge, et elle reste a portee du pouce. */
/* Barre de sélection : posée par défaut sur le PIED, pas au milieu des lignes — elle masquait
   justement ce qu'on vient de sélectionner. Déplaçable à la souris (poignée ⠿, voir initSelbar
   dans generic-datagrid.js) et sa place est retenue par grille dans localStorage. */
.gdg-selbar[b-9kaz8ksd3g] {
    position: absolute; z-index: 30;
    left: 14px; bottom: 10px; transform: none;
    display: flex; align-items: center; gap: 12px; flex-wrap: nowrap;
    max-width: calc(100% - 28px); overflow-x: auto;
    margin: 0; padding: 9px 14px; border-radius: 999px;
    background: var(--c-navy); color: var(--c-on-navy);
    box-shadow: var(--sh-float);
    animation: gdg-selrise-b-9kaz8ksd3g .16s ease-out;
    touch-action: none;          /* le glisser passe par les pointer events, pas par le défilement */
}
.gdg-selgrip[b-9kaz8ksd3g] {
    cursor: grab; user-select: none; opacity: .55; font-size: 14px; line-height: 1;
    padding: 0 2px;
}
.gdg-selgrip:active[b-9kaz8ksd3g] { cursor: grabbing; }
.gdg-selbar.is-dragging[b-9kaz8ksd3g] { animation: none; opacity: .92; }
@keyframes gdg-selrise-b-9kaz8ksd3g {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}
/* écran étroit : barre pleine largeur, plus lisible qu'une pastille qui déborde */
@media (max-width: 700px) {
    .gdg-selbar[b-9kaz8ksd3g] { left: 12px; right: 12px; transform: none; max-width: none; border-radius: 12px; animation: none; }
}
@media (prefers-reduced-motion: reduce) {
    .gdg-selbar[b-9kaz8ksd3g] { animation: none; }
}
@media (forced-colors: active) {
    .gdg-selbar[b-9kaz8ksd3g] { border: 1px solid CanvasText; }
}
.gdg-selcount[b-9kaz8ksd3g] { font-weight: 700; font-size: 13px; }
.gdg-seldiv[b-9kaz8ksd3g] { width: 1px; height: 18px; background: var(--ov-25); }
.gdg-selact[b-9kaz8ksd3g] {
    border: none; background: var(--ov-12); color: var(--c-on-accent);
    border-radius: 7px; padding: 5px 11px; font-size: 12.5px; cursor: pointer;
}
.gdg-selact:hover[b-9kaz8ksd3g] { background: var(--ov-25); }

/* ---- tableau ---- */
/* position: relative → repère du filet de chargement, posé sur l'arête haute sans occuper de place */
.gdg-card[b-9kaz8ksd3g] { position: relative; border: 1px solid var(--c-border); border-radius: 12px; background: var(--c-surface); overflow: hidden; }
.gdg-scroll[b-9kaz8ksd3g] { overflow: auto; }
/* user-select: none → Shift+clic sélectionne des LIGNES, pas du texte. Sans cela le navigateur
   étend en même temps sa propre sélection de texte et surligne la moitié du tableau en bleu.
   Copier reste possible et donne un meilleur résultat : Ctrl+C (TSV) ou l'export.
   Les zones de saisie gardent la sélection, sinon on ne pourrait plus corriger une valeur. */
.gdg-table[b-9kaz8ksd3g] { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 13.5px; user-select: none; -webkit-user-select: none; }
.gdg-table input[b-9kaz8ksd3g], .gdg-table textarea[b-9kaz8ksd3g], .gdg-table select[b-9kaz8ksd3g], .gdg-table [contenteditable="true"][b-9kaz8ksd3g] {
    user-select: text; -webkit-user-select: text;
}
.gdg-th[b-9kaz8ksd3g] {
    position: sticky; top: 0; z-index: 2;
    background: var(--c-surface-2); color: var(--c-ink-3);
    padding: 11px 14px; font-size: 11px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; user-select: none;
}
.gdg-table.is-dense .gdg-th[b-9kaz8ksd3g] { padding: 7px 12px; }
.gdg-th.is-sortable[b-9kaz8ksd3g] { cursor: pointer; }
.gdg-th.is-sortable:hover[b-9kaz8ksd3g] { color: var(--c-accent); }
.gdg-th.gdg-dropover[b-9kaz8ksd3g] { box-shadow: inset 3px 0 0 var(--c-accent); background: var(--c-accent-soft); }
.gdg-thlabel[b-9kaz8ksd3g] { display: inline-flex; align-items: center; gap: 5px; vertical-align: middle; }
.gdg-sorticon[b-9kaz8ksd3g] { font-size: 12px; }
.gdg-sortorder[b-9kaz8ksd3g] { font-size: 9px; font-weight: 800; }
.gdg-filteron[b-9kaz8ksd3g] { color: var(--c-accent); display: inline-flex; }
.gdg-resize[b-9kaz8ksd3g] { position: absolute; top: 0; right: -3px; width: 7px; height: 100%; cursor: col-resize; z-index: 3; }
.gdg-resize:hover[b-9kaz8ksd3g] { background: var(--c-accent); opacity: .5; }

/* ligne de filtres */
.gdg-filterrow th[b-9kaz8ksd3g] {
    position: sticky; top: 36px; z-index: 2;
    background: var(--c-surface); padding: 6px 8px;
    border-bottom: 1px solid var(--c-border); font-weight: 400;
}
.gdg-fwrap[b-9kaz8ksd3g] { display: flex; gap: 4px; }
.gdg-fop[b-9kaz8ksd3g] {
    width: 42%; min-width: 0; border: 1px solid var(--c-border); border-radius: 7px;
    background: var(--c-surface-2); font-size: 11.5px; padding: 5px 3px; color: var(--c-ink-2);
}
.gdg-fin[b-9kaz8ksd3g], .gdg-fsel[b-9kaz8ksd3g] {
    flex: 1; width: 100%; min-width: 0; border: 1px solid var(--c-border); border-radius: 7px;
    padding: 5px 8px; font-size: 12.5px; background: var(--c-surface); color: var(--c-ink);
}
.gdg-fin:focus[b-9kaz8ksd3g], .gdg-fsel:focus[b-9kaz8ksd3g], .gdg-fop:focus[b-9kaz8ksd3g] { outline: 2px solid var(--c-accent); outline-offset: -1px; }

/* lignes */
.gdg-datarow[b-9kaz8ksd3g] { border-top: 1px solid var(--c-border); }
.gdg-datarow.is-clickable[b-9kaz8ksd3g] { cursor: pointer; }
.gdg-datarow:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); }
/* Sélection en GRIS, pas dans la couleur d'accent : le rouge tenait déjà un autre rôle sur les
   écrans qui teintent leurs lignes (ticket interne en rose, ligne en anomalie…) et les deux
   messages se confondaient. Le gris ne dit qu'une chose : « cette ligne est cochée ». */
.gdg-datarow.is-selected[b-9kaz8ksd3g] { background: var(--c-row-sel); }
.gdg-datarow.is-focus[b-9kaz8ksd3g] { box-shadow: inset 2px 0 0 var(--c-accent); }
.gdg-datarow.gdg-marquee-hit[b-9kaz8ksd3g] { background: var(--c-row-sel); }

/* Sélection POSSÉDÉE PAR L'HÔTE (E9) : quand la grille n'a pas la sélection (Selectable=false), un
   écran pose ces classes via RowClassFunc plutôt que d'écrire son propre CSS. Même jetons que la
   sélection interne (--c-row-sel/--c-accent) pour rester cohérent visuellement.
   Écrites préfixées par .gdg-datarow (comme .gdg-datarow.is-selected juste au-dessus) : une classe
   seule (.gdg-row-selected) a une spécificité plus faible que .gdg-datarow:hover et perdrait au
   survol, quel que soit l'ordre des règles — round 1 de revue (25/09). Le zébrage (plus bas dans ce
   fichier) et le combo « ligne gelée sélectionnée » ont chacun besoin de leur propre règle, à
   spécificité au moins égale, pour la même raison : voir plus bas. */
.gdg-datarow.gdg-row-selected[b-9kaz8ksd3g] { background: var(--c-row-sel); }
/* .gdg-datarow.gdg-row-current : même spécificité que .gdg-datarow.is-focus (2 classes) juste
   au-dessus, mais des valeurs DIFFÉRENTES (2px vs 3px) — placée après, elle gagne l'égalité et le
   liseré « ligne courante » de l'hôte reste visible même quand la ligne a aussi le focus clavier. */
.gdg-datarow.gdg-row-current[b-9kaz8ksd3g] { box-shadow: inset 3px 0 0 var(--c-accent); }
.gdg-cell[b-9kaz8ksd3g] {
    padding: 11px 14px; color: var(--c-ink-2);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 1px;
}
.gdg-table.is-dense .gdg-cell[b-9kaz8ksd3g] { padding: 7px 12px; font-size: 12.5px; }
.gdg-cell.is-num[b-9kaz8ksd3g] { font-variant-numeric: tabular-nums; }
.gdg-checkcell[b-9kaz8ksd3g] { width: 42px; text-align: center; padding: 8px; }
.gdg-check[b-9kaz8ksd3g] {
    width: 17px; height: 17px; border: 1.5px solid var(--c-ink-3); border-radius: 4px;
    background: var(--c-surface); cursor: pointer; padding: 0;
    font-size: 11px; line-height: 1; color: var(--c-on-accent);
}
.gdg-check.is-all[b-9kaz8ksd3g] { background: var(--c-accent); border-color: var(--c-accent); }
.gdg-check.is-some[b-9kaz8ksd3g] { background: var(--c-accent); border-color: var(--c-accent); position: relative; }
.gdg-check.is-some[b-9kaz8ksd3g]::after { content: ""; position: absolute; inset: 5px 3px; background: var(--c-on-accent); border-radius: 1px; }

/* groupes */
.gdg-grouprow[b-9kaz8ksd3g] { background: var(--c-surface-2); border-top: 1px solid var(--c-border); cursor: pointer; user-select: none; }
.gdg-grouprow td[b-9kaz8ksd3g] { padding: 9px 14px; font-size: 13px; }
.gdg-caret[b-9kaz8ksd3g] { display: inline-block; width: 16px; color: var(--c-ink-3); }
.gdg-grouplabel[b-9kaz8ksd3g] { font-weight: 700; color: var(--c-ink); }
.gdg-groupcount[b-9kaz8ksd3g] { color: var(--c-ink-3); margin-left: 6px; font-size: 12px; }
.gdg-empty[b-9kaz8ksd3g] { padding: 36px 16px; text-align: center; color: var(--c-ink-3); }

/* ---- pied : compteur à gauche, taille de page et navigation à droite ---- */
.gdg-footer[b-9kaz8ksd3g] {
    display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
    margin-top: 10px; padding: 8px 12px;
    border: 1px solid var(--c-border); border-radius: 10px;
    background: var(--c-surface-2);
    font-size: 12.5px; color: var(--c-ink-3);
}
.gdg-count[b-9kaz8ksd3g] { font-weight: 600; color: var(--c-ink-2); }
.gdg-pager[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.gdg-pagesize[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 7px; white-space: nowrap; }
/* Taille de page (1.5.0) : champ numérique et bouton de menu fondus en un seul contrôle ;
   le menu s'ouvre vers le HAUT, le pied étant en bas de la grille. */
.gdg-pscombo[b-9kaz8ksd3g] {
    position: relative; display: inline-flex; align-items: stretch;
    border: 1px solid var(--c-border); border-radius: 7px; background: var(--c-surface);
}
.gdg-pscombo:hover[b-9kaz8ksd3g], .gdg-pscombo:focus-within[b-9kaz8ksd3g] { border-color: var(--c-accent); }
.gdg-pscombo input[b-9kaz8ksd3g] {
    width: 4.2em; padding: 4px 2px 4px 8px; border: 0; border-radius: 7px 0 0 7px;
    background: transparent; color: var(--c-ink-2); font: inherit; font-variant-numeric: tabular-nums;
    outline: none; -moz-appearance: textfield; appearance: textfield;
}
.gdg-pscombo input[b-9kaz8ksd3g]::-webkit-outer-spin-button,
.gdg-pscombo input[b-9kaz8ksd3g]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.gdg-pscombo-auto[b-9kaz8ksd3g] {
    align-self: center; margin-right: 2px; padding: 1px 5px; border-radius: 5px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
    background: var(--c-surface-2); color: var(--c-ink-3);
}
.gdg-pscombo-btn[b-9kaz8ksd3g] {
    padding: 0 7px; border: 0; border-left: 1px solid var(--c-border); border-radius: 0 7px 7px 0;
    background: transparent; color: var(--c-ink-3); cursor: pointer; font-size: 11px; line-height: 1;
}
.gdg-pscombo-btn:hover[b-9kaz8ksd3g] { color: var(--c-accent); background: var(--c-surface-2); }
.gdg-pscombo-menu[b-9kaz8ksd3g] {
    position: absolute; right: 0; bottom: calc(100% + 6px); z-index: 50;
    display: flex; flex-direction: column; min-width: 100%; padding: 4px;
    border: 1px solid var(--c-border); border-radius: 10px;
    background: var(--c-surface); box-shadow: var(--sh-lg);
}
.gdg-pscombo-opt[b-9kaz8ksd3g] {
    padding: 6px 12px; border: 0; border-radius: 7px; background: transparent;
    color: var(--c-ink-2); font: inherit; font-variant-numeric: tabular-nums; text-align: right;
    white-space: nowrap; cursor: pointer;
}
.gdg-pscombo-opt:hover[b-9kaz8ksd3g], .gdg-pscombo-opt:focus-visible[b-9kaz8ksd3g] { background: var(--c-surface-2); outline: none; }
.gdg-pscombo-opt.is-selected[b-9kaz8ksd3g] { color: var(--c-accent); font-weight: 700; }

/* Les numéros et les flèches forment un seul bloc : on lit d'un coup où on est et où aller. */
.gdg-pagenav[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 2px; padding: 2px;
    border: 1px solid var(--c-border); border-radius: 9px; background: var(--c-surface);
}
.gdg-pagebtn[b-9kaz8ksd3g], .gdg-pagenav .gdg-pagenum[b-9kaz8ksd3g] {
    min-width: 30px; height: 28px; padding: 0 7px;
    border: none; background: none; color: var(--c-ink-2);
    border-radius: 7px; cursor: pointer; font-size: 13px; line-height: 1;
    font-variant-numeric: tabular-nums;
}
.gdg-pagebtn[b-9kaz8ksd3g] { font-size: 15px; }
.gdg-pagebtn:disabled[b-9kaz8ksd3g] { opacity: .35; cursor: default; }
.gdg-pagebtn:not(:disabled):hover[b-9kaz8ksd3g], .gdg-pagenav .gdg-pagenum:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); color: var(--c-accent); }

/* Page courante : contraste franc, pas seulement une nuance — repérable au premier coup d'œil. */
.gdg-pagenav .gdg-pagenum.is-current[b-9kaz8ksd3g] {
    background: var(--c-accent); color: var(--c-on-accent); font-weight: 700;
}
.gdg-pagenav .gdg-pagenum.is-current:hover[b-9kaz8ksd3g] { background: var(--c-accent-700); color: var(--c-on-accent); }
.gdg-pagegap[b-9kaz8ksd3g] { padding: 0 2px; color: var(--c-ink-3); user-select: none; }

@media (forced-colors: active) {
    .gdg-pagenav .gdg-pagenum.is-current[b-9kaz8ksd3g] { outline: 2px solid Highlight; outline-offset: -2px; }
}

/* ---- HelpGridV3 v2 : popup de filtre, menu contextuel, agrégats, drag pointer ---- */

.gdg-th[b-9kaz8ksd3g] { touch-action: none; }

.gdg-fbtn[b-9kaz8ksd3g] {
    border: none; background: none; padding: 2px 5px; margin-left: 2px;
    cursor: pointer; color: var(--c-ink-3); display: inline-flex;
    vertical-align: middle; border-radius: 5px;
}
.gdg-fbtn:hover[b-9kaz8ksd3g] { color: var(--c-accent); background: var(--c-accent-soft); }
.gdg-fbtn.is-on[b-9kaz8ksd3g] { color: var(--c-accent); }

.gdg-fpopup[b-9kaz8ksd3g] {
    position: fixed; z-index: 70; min-width: 250px; max-width: 300px; padding: 12px;
    border: 1px solid var(--c-border); border-radius: 12px;
    background: var(--c-surface); box-shadow: var(--sh-lg);
}
.gdg-fpopup-title[b-9kaz8ksd3g] {
    margin: 0 0 10px; font-size: 11px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase; color: var(--c-ink-3);
}
.gdg-fpopup .gdg-fwrap[b-9kaz8ksd3g], .gdg-fpopup .gdg-fsel[b-9kaz8ksd3g] { margin-bottom: 10px; }
.gdg-fpopup-actions[b-9kaz8ksd3g] { display: flex; justify-content: flex-end; gap: 8px; }

.gdg-ctxmenu[b-9kaz8ksd3g] {
    position: fixed; z-index: 70; min-width: 180px; padding: 6px;
    border: 1px solid var(--c-border); border-radius: 12px;
    background: var(--c-surface); box-shadow: var(--sh-lg);
}
.gdg-mi[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
    border: none; background: none; padding: 8px 10px; border-radius: 8px;
    font-size: 13.5px; color: var(--c-ink); cursor: pointer;
}
.gdg-mi:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); }
.gdg-mi.is-danger[b-9kaz8ksd3g] { color: var(--c-accent); }
.gdg-mi.is-danger:hover[b-9kaz8ksd3g] { background: var(--c-accent-soft); }

.gdg-aggrow td[b-9kaz8ksd3g] {
    background: var(--c-surface-2); border-top: 2px solid var(--c-border-2);
    padding: 8px 14px; font-size: 12px; font-weight: 700; color: var(--c-ink-2);
    font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gdg-aggrow.is-sel td[b-9kaz8ksd3g] { background: var(--c-accent-soft); color: var(--c-accent-700); border-top: 1px solid var(--c-accent-soft-2); }

.gdg-groupfoot td[b-9kaz8ksd3g] {
    background: var(--c-surface-2); border-top: 1px dashed var(--c-border);
    padding: 6px 14px; font-size: 12px; font-weight: 600; color: var(--c-ink-2);
    font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.gdg-groupagg[b-9kaz8ksd3g] { margin-left: 10px; font-weight: 600; font-size: 12px; color: var(--c-ink-3); }

/* ---- HelpGridV3 v3 : drag inter-grilles, saisie page size ---- */

.gdg-draghandle[b-9kaz8ksd3g] {
    width: 30px; text-align: center; cursor: grab; color: var(--c-ink-3);
    font-size: 13px; user-select: none; touch-action: none; padding: 8px 4px;
}
.gdg-draghandle:hover[b-9kaz8ksd3g] { color: var(--c-accent); }
.gdg-draghandle-h[b-9kaz8ksd3g] { width: 30px; position: sticky; top: 0; z-index: 2; background: var(--c-surface-2); }

.gdg.gdg-droptarget .gdg-card[b-9kaz8ksd3g] {
    outline: 2px dashed var(--c-accent);
    outline-offset: 2px;
    background: var(--c-accent-soft);
}

/* (l'ancienne saisie libre du nombre de lignes par page a été retirée : le menu de taille de
   page suffit, deux commandes pour la même chose prêtaient à confusion.) */
.gdg-pagenum:focus-visible[b-9kaz8ksd3g] { outline: 2px solid var(--c-accent); outline-offset: -2px; }

/* ---- HelpGridV3 v4 : colonnes gelées, pied collant, comparaisons A/B ---- */

/* toutes les cellules d'en-tête (y compris poignée/cases) collent en haut */
.gdg-headrow th[b-9kaz8ksd3g] { position: sticky; top: 0; z-index: 2; background: var(--c-surface-2); }

/* cadenas d'épinglage */
.gdg-pinbtn[b-9kaz8ksd3g] {
    border: none; background: none; padding: 2px 4px; margin-left: 1px;
    cursor: pointer; color: var(--c-ink-3); opacity: .45;
    display: inline-flex; vertical-align: middle; border-radius: 5px;
}
.gdg-th:hover .gdg-pinbtn[b-9kaz8ksd3g] { opacity: 1; }
.gdg-pinbtn:hover[b-9kaz8ksd3g] { color: var(--c-accent); background: var(--c-accent-soft); }
.gdg-pinbtn.is-on[b-9kaz8ksd3g] { opacity: 1; color: var(--c-accent); }

/* Colonnes gelées : un fond OPAQUE est obligatoire, le reste de la table glisse dessous.
   Mais l'opacité ne doit pas écraser la couleur de la ligne : une ligne colorée par une règle
   (ou par une classe de l'écran) doit l'être de bout en bout, colonnes gelées comprises.
   D'où : la LIGNE porte le fond, les cellules gelées l'héritent. */

/* Teinte de ligne : --row-bg est le point d'entrée des écrans (GridRowRules, style inline).
   Une classe utilitaire (bg-red-100…) ne suffisait pas — cette règle-ci, portée par le CSS isolé,
   gagne en spécificité et repeignait la ligne en blanc. Passer par une variable laisse en place le
   survol et la sélection, qui ont leurs propres jetons, et n'écrase pas le fond des cases à cocher. */
.gdg-datarow[b-9kaz8ksd3g] { background: var(--row-bg, var(--c-surface)); }
.gdg-th.is-pinned[b-9kaz8ksd3g] { z-index: 4; box-shadow: 1px 0 0 var(--c-border-2); }

/* Colonnes utilitaires (détail, poignée, case « tout sélectionner ») : gelées à gauche par
   construction, donc AU-DESSUS des en-têtes libres (2) ET des en-têtes gelés (4). Sans cela le
   défilement horizontal faisait glisser le libellé d'une colonne libre par-dessus la case à cocher
   d'en-tête, qui devenait illisible. Les cellules de corps, elles, sont déjà couvertes par is-pinned. */
.gdg-headrow th.gdg-utilth[b-9kaz8ksd3g],
.gdg-headrow th.gdg-expcell-h[b-9kaz8ksd3g],
.gdg-headrow th.gdg-draghandle-h[b-9kaz8ksd3g],
.gdg-filterrow th.gdg-utilth[b-9kaz8ksd3g] { z-index: 5; }
.gdg-filterrow th.is-pinned[b-9kaz8ksd3g] { z-index: 4; background: var(--c-surface); box-shadow: 1px 0 0 var(--c-border-2); }
.gdg-cell.is-pinned[b-9kaz8ksd3g], .gdg-checkcell.is-pinned[b-9kaz8ksd3g], .gdg-draghandle.is-pinned[b-9kaz8ksd3g] {
    z-index: 1; background-color: inherit; box-shadow: 1px 0 0 var(--c-border-2);
}
.gdg-groupfoot td.is-pinned[b-9kaz8ksd3g] { background: var(--c-surface-2); z-index: 1; }

/* E10 — colonnes virtualisées : la position de chaque colonne est CALCULÉE à partir des largeurs
   déclarées. La largeur rendue doit donc être exactement la largeur déclarée, marge intérieure
   comprise (border-box), sinon l'écart d'une colonne s'accumulerait sur des centaines d'autres.
   Les entretoises (gauche/droite) tiennent la place des colonnes non rendues : aucune marge,
   aucun contenu, rien à cliquer. */
.gdg-table.is-colvirt th[b-9kaz8ksd3g], .gdg-table.is-colvirt td[b-9kaz8ksd3g] { box-sizing: border-box; }
.gdg-colspacer[b-9kaz8ksd3g] { padding: 0 !important; pointer-events: none; }

/* pied d'agrégats collant : les lignes (max 4 : total, sélection, A, B) s'empilent depuis le bas */
.gdg-table.is-stickyfoot tfoot td[b-9kaz8ksd3g] { position: sticky; z-index: 3; height: 34px; box-sizing: border-box; }
.gdg-table.is-stickyfoot tfoot tr:nth-last-child(1) td[b-9kaz8ksd3g] { bottom: 0; }
.gdg-table.is-stickyfoot tfoot tr:nth-last-child(2) td[b-9kaz8ksd3g] { bottom: 34px; }
.gdg-table.is-stickyfoot tfoot tr:nth-last-child(3) td[b-9kaz8ksd3g] { bottom: 68px; }
.gdg-table.is-stickyfoot tfoot tr:nth-last-child(4) td[b-9kaz8ksd3g] { bottom: 102px; }

/* chips et ligne comparatives des groupes de sélection */
.gdg-cmpchip[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 6px 4px 12px; border-radius: 999px;
    background: var(--ov-16); color: var(--c-on-accent);
    font-size: 12.5px; font-weight: 700; cursor: pointer; user-select: none;
}
.gdg-cmpchip:hover[b-9kaz8ksd3g] { background: var(--ov-28); }
.gdg-aggrow.is-cmp td[b-9kaz8ksd3g] { background: var(--c-info-soft); color: var(--c-info); border-top: 1px solid var(--c-border); }

/* ---- HelpGridV3 v5 : master-detail, groupes illimités au pied ---- */

.gdg-expcell[b-9kaz8ksd3g] { width: 34px; text-align: center; padding: 6px 2px; }
.gdg-expcell-h[b-9kaz8ksd3g] { width: 34px; }
.gdg-expbtn[b-9kaz8ksd3g] {
    border: none; background: none; cursor: pointer; color: var(--c-ink-3);
    font-size: 13px; line-height: 1; padding: 4px 6px; border-radius: 6px;
    transition: transform .15s;
    display: inline-block;
}
.gdg-expbtn:hover[b-9kaz8ksd3g] { color: var(--c-accent); background: var(--c-accent-soft); }
.gdg-expbtn.is-open[b-9kaz8ksd3g] { transform: rotate(90deg); color: var(--c-accent); }

.gdg-detailrow > td[b-9kaz8ksd3g] {
    background: var(--c-surface-2);
    border-top: 1px dashed var(--c-border);
    padding: 0;
}
.gdg-detail[b-9kaz8ksd3g] { padding: 14px 18px 16px; }
/* grille imbriquée dans un détail : carte plus discrète */
.gdg-detail .gdg-card[b-9kaz8ksd3g] { box-shadow: none; }
.gdg-detail .gdg[b-9kaz8ksd3g] { font-size: 13px; }

/* étiquette + croix des groupes comparatifs dans le pied */
.gdg-cmptag[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; gap: 5px; margin-right: 8px;
    padding: 1px 6px 1px 9px; border-radius: 999px;
    background: var(--c-info); color: var(--c-on-info); font-size: 10.5px; font-weight: 800;
}
.gdg-cmpx[b-9kaz8ksd3g] {
    border: none; background: var(--ov-25); color: var(--c-on-accent);
    width: 14px; height: 14px; border-radius: 50%; cursor: pointer;
    font-size: 11px; line-height: 1; padding: 0;
}
.gdg-cmpx:hover[b-9kaz8ksd3g] { background: var(--ov-50); }

/* onglets de la démo master-detail */
.gdg-demo-tabs[b-9kaz8ksd3g] { display: flex; gap: 4px; margin-bottom: 12px; border-bottom: 1px solid var(--c-border); }
.gdg-demo-tab[b-9kaz8ksd3g] {
    border: none; background: none; cursor: pointer; padding: 8px 16px;
    font-size: 13px; font-weight: 600; color: var(--c-ink-3);
    border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.gdg-demo-tab:hover[b-9kaz8ksd3g] { color: var(--c-ink); }
.gdg-demo-tab.is-active[b-9kaz8ksd3g] { color: var(--c-accent); border-bottom-color: var(--c-accent); }

/* ---- HelpGridV3 a11y ---- */

/* texte uniquement pour les lecteurs d'écran (région aria-live) */
.gdg-sronly[b-9kaz8ksd3g] {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* le caret de groupe est désormais un vrai bouton focalisable */
button.gdg-caret[b-9kaz8ksd3g] {
    border: none; background: none; cursor: pointer; padding: 0;
    display: inline-block; width: 16px; color: var(--c-ink-3); font-size: inherit;
}
button.gdg-caret:focus-visible[b-9kaz8ksd3g] { outline: 2px solid var(--c-accent); outline-offset: 1px; border-radius: 4px; }

/* focus visible cohérent sur les contrôles internes de la grille */
.gdg button:focus-visible[b-9kaz8ksd3g], .gdg input:focus-visible[b-9kaz8ksd3g], .gdg select:focus-visible[b-9kaz8ksd3g] {
    outline: 2px solid var(--c-accent); outline-offset: 1px;
}

/* ---- HelpGridV3 v8 : édition inline, vues nommées, undo, divers ---- */

.gdg-editin[b-9kaz8ksd3g] {
    width: 100%; min-width: 0; border: 1px solid var(--c-accent); border-radius: 6px;
    padding: 4px 8px; font-size: inherit; font-family: inherit;
    background: var(--c-surface); color: var(--c-ink);
}

/* même traitement que la barre de sélection : en surimpression, l'écran ne saute pas.
   Les deux ne coexistent jamais — « Nettoyer » vide la sélection avant d'afficher l'annulation. */
.gdg-undobar[b-9kaz8ksd3g] {
    position: absolute; z-index: 30;
    left: 50%; bottom: 62px; transform: translateX(-50%);
    display: flex; align-items: center; gap: 10px;
    max-width: calc(100% - 24px);
    margin: 0; padding: 8px 14px; border-radius: 999px;
    background: var(--c-info-soft); color: var(--c-info); font-size: 13px;
    border: 1px solid var(--c-border);
    box-shadow: var(--sh-float-2);
    animation: gdg-selrise-b-9kaz8ksd3g .16s ease-out;
}
@media (max-width: 700px) {
    .gdg-undobar[b-9kaz8ksd3g] { left: 12px; right: 12px; transform: none; max-width: none; border-radius: 12px; animation: none; }
}
@media (prefers-reduced-motion: reduce) {
    .gdg-undobar[b-9kaz8ksd3g] { animation: none; }
}
.gdg-undobar .gdg-chipx[b-9kaz8ksd3g] { background: var(--c-info); color: var(--c-on-info); margin-left: auto; }

.gdg-viewrow[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 6px; padding: 2px 4px; }
/* La croix de suppression d une vue heritait du style « chip sombre » : blanche sur fond clair,
   donc invisible. Meme correction que pour les regles. */
.gdg-viewrow .gdg-chipx[b-9kaz8ksd3g] {
    background: none; color: var(--c-ink-3);
    width: 22px; height: 22px; border-radius: 6px;
}
.gdg-viewrow .gdg-chipx:hover[b-9kaz8ksd3g] { background: var(--c-accent-soft); color: var(--c-accent); }

.gdg-viewapply[b-9kaz8ksd3g] {
    flex: 1; text-align: left; border: none; background: none; cursor: pointer;
    padding: 7px 8px; border-radius: 8px; font-size: 13px; color: var(--c-ink);
}
.gdg-viewapply:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); }
.gdg-viewrow .gdg-chipx[b-9kaz8ksd3g] { background: var(--c-surface-3); color: var(--c-ink-2); }
.gdg-viewrow .gdg-chipx:hover[b-9kaz8ksd3g] { background: var(--c-accent); color: var(--c-on-accent); }
.gdg-viewsave[b-9kaz8ksd3g] { display: flex; gap: 6px; padding: 8px 4px 2px; border-top: 1px solid var(--c-border); margin-top: 6px; }

.gdg-exploading[b-9kaz8ksd3g] { color: var(--c-ink-3); font-weight: 700; }

.gdg mark[b-9kaz8ksd3g] { background: var(--c-warning-soft); color: inherit; border-radius: 3px; padding: 0 1px; }

/* contraste AA des en-têtes (ink-3 était à ~3.5:1) */
.gdg-th[b-9kaz8ksd3g] { color: var(--c-ink-2); }

/* cible tactile du redimensionnement élargie sur écrans tactiles */
@media (pointer: coarse) {
    .gdg-resize[b-9kaz8ksd3g] { width: 16px; right: -8px; }
}

/* animations neutralisées si l'utilisateur le demande */
@media (prefers-reduced-motion: reduce) {
    .gdg *[b-9kaz8ksd3g], .gdg *[b-9kaz8ksd3g]::before, .gdg *[b-9kaz8ksd3g]::after { transition: none !important; animation: none !important; }
}

/* ---- HelpGridV3 v9 : densités (3 niveaux), zébré, multiligne ---- */

/* Compacte (ex is-dense) */
.gdg-table.density-compact .gdg-th[b-9kaz8ksd3g] { padding: 7px 12px; }
.gdg-table.density-compact .gdg-cell[b-9kaz8ksd3g] { padding: 7px 12px; font-size: 12.5px; }
.gdg-table.density-compact .gdg-checkcell[b-9kaz8ksd3g], .gdg-table.density-compact .gdg-expcell[b-9kaz8ksd3g] { padding: 5px 4px; }

/* Ultra-compacte : densité maximale type tableur/Omnis */
.gdg-table.density-ultra .gdg-th[b-9kaz8ksd3g] { padding: 5px 9px; font-size: 10px; }
.gdg-table.density-ultra .gdg-cell[b-9kaz8ksd3g] { padding: 3px 9px; font-size: 11.5px; }
.gdg-table.density-ultra .gdg-checkcell[b-9kaz8ksd3g], .gdg-table.density-ultra .gdg-expcell[b-9kaz8ksd3g] { padding: 2px 4px; }
.gdg-table.density-ultra .gdg-grouprow td[b-9kaz8ksd3g] { padding: 4px 9px; font-size: 11.5px; }
.gdg-table.density-ultra .gdg-groupfoot td[b-9kaz8ksd3g] { padding: 3px 9px; font-size: 11px; }
.gdg-table.density-ultra .gdg-filterrow th[b-9kaz8ksd3g] { top: 26px; }

/* Lignes zébrées — le survol et la sélection gardent la priorité (règles plus bas = gagnantes) */
/* --row-bg d'abord : une ligne teintee par une regle d'ecran garde sa couleur, sinon le zebre
   l'effacait une ligne sur deux (et la teinte ne voulait plus rien dire). */
.gdg-table.is-zebra tbody .gdg-datarow:nth-child(even)[b-9kaz8ksd3g] { background: var(--row-bg, var(--c-surface-2)); }
/* (les cellules gelees heritent du fond de la ligne : plus besoin de les repeindre) */
.gdg-table.is-zebra tbody .gdg-datarow:hover[b-9kaz8ksd3g] { background: var(--c-surface-3); }
.gdg-table.is-zebra tbody .gdg-datarow.is-selected[b-9kaz8ksd3g],
.gdg-table.is-zebra tbody .gdg-datarow.gdg-marquee-hit[b-9kaz8ksd3g] { background: var(--c-row-sel); }
/* E9, round 1 : même besoin que .is-selected juste au-dessus — sans cette règle zébrée, une ligne
   paire (fond du zébrage) ou survolée écraserait le fond posé par l'hôte via gdg-row-selected. */
.gdg-table.is-zebra tbody .gdg-datarow.gdg-row-selected[b-9kaz8ksd3g] { background: var(--c-row-sel); }

/* Texte multiligne : enlève l'ellipse, les lignes prennent la hauteur du contenu */
.gdg-table.is-wrap .gdg-cell[b-9kaz8ksd3g] { white-space: normal; overflow: visible; text-overflow: clip; max-width: none; }

/* Ultra-compacte : jamais de repli, même si le multiligne (is-wrap) est actif — la ligne reste
   à hauteur fixe (E6) ; l'infobulle porte le texte complet (voir title dans HelpGridV3.razor).
   Même spécificité que la règle is-wrap ci-dessus : celle-ci gagne parce qu'elle vient après. */
.gdg-table.density-ultra .gdg-cell[b-9kaz8ksd3g] { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Le <mark> du surlignage est injecté via MarkupString : il ne porte pas l'attribut de scope,
   d'où ::deep (la cellule parente, elle, le porte). */
.gdg-cell[b-9kaz8ksd3g]  mark { background: var(--c-warning-soft); color: inherit; border-radius: 3px; padding: 0 1px; }
/* =========================================================================
   Édition : ligne en cours, actions, dialogues (« Remplacer », confirmation)
   Ajout de la V3 CoreBlazor — même préfixe gdg-, portable tel quel vers
   la grille SrvColibase (aucun token nouveau, aucune dépendance).
   ========================================================================= */

/* Variantes de bouton utilisées par les actions d'écriture */
/* variantes (dont ::deep, pour les boutons places par l'ecran dans la barre) */
.gdg-btn.is-primary[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-btn.is-primary {
    background: var(--c-accent); border-color: var(--c-accent); color: var(--c-on-accent);
}
.gdg-btn.is-primary:hover[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-btn.is-primary:hover { background: var(--c-accent-700); border-color: var(--c-accent-700); color: var(--c-on-accent); }
.gdg-btn.is-danger[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-btn.is-danger { color: var(--c-accent); border-color: var(--c-accent-soft-2); }
.gdg-btn.is-danger:hover[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-btn.is-danger:hover { background: var(--c-accent-soft); border-color: var(--c-accent); }
.gdg-btn:disabled[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-btn:disabled { opacity: .45; cursor: not-allowed; }
.gdg-btn:disabled:hover[b-9kaz8ksd3g], .gdg[b-9kaz8ksd3g]  .gdg-btn:disabled:hover { border-color: var(--c-border); color: var(--c-ink-2); background: var(--c-surface); }

/* Ligne en édition : liseré d'accent à gauche, fond légèrement teinté */
.gdg-table tbody .gdg-datarow.is-editing[b-9kaz8ksd3g],
.gdg-table tbody .gdg-datarow.is-editing .gdg-cell:first-child[b-9kaz8ksd3g] { box-shadow: inset 3px 0 0 var(--c-accent); }
/* E9, round 1 : cette règle est plus spécifique que .gdg-datarow.gdg-row-current et gagnerait le
   box-shadow d'une ligne à la fois en édition ET courante côté hôte — mais la valeur posée est
   IDENTIQUE (inset 3px 0 0 var(--c-accent)) : aucune différence visible, donc aucune règle combinée
   n'est ajoutée ici (contrairement à is-frozenrow, dont le fond diffère de la sélection). Si l'une
   des deux valeurs change un jour, revoir cette note. */

/* Barre d'actions sous la ligne en édition */
.gdg-editrow td[b-9kaz8ksd3g] { padding: 0; background: var(--c-accent-soft); border-bottom: 1px solid var(--c-border); }
.gdg-editactions[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 8px 12px; box-shadow: inset 3px 0 0 var(--c-accent);
}
.gdg-edithint[b-9kaz8ksd3g] { font-size: 11.5px; color: var(--c-ink-3); }
.gdg-editerr[b-9kaz8ksd3g] { font-size: 12.5px; font-weight: 600; color: var(--c-accent); }

/* Dialogues centrés (édition massive, confirmation) */
.gdg-dialog[b-9kaz8ksd3g] {
    position: fixed; z-index: 71; left: 50%; top: 50%; transform: translate(-50%, -50%);
    width: min(560px, calc(100vw - 32px)); max-height: min(76vh, 720px);
    display: flex; flex-direction: column;
    background: var(--c-surface); border: 1px solid var(--c-border-2); border-radius: 12px;
    box-shadow: var(--sh-lg); padding: 16px;
}
.gdg-dialog.is-narrow[b-9kaz8ksd3g] { width: min(420px, calc(100vw - 32px)); }
.gdg-dialog-title[b-9kaz8ksd3g] { margin: 0 0 4px; font-size: 14px; font-weight: 700; color: var(--c-ink); }
.gdg-dialog-hint[b-9kaz8ksd3g] { margin: 0 0 10px; font-size: 12px; color: var(--c-ink-3); }
.gdg-dialog-body[b-9kaz8ksd3g] { overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding-right: 2px; }
.gdg-dialog-actions[b-9kaz8ksd3g] { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }

/* Une ligne = un champ à remplacer : case « appliquer » + éditeur typé */
.gdg-bulkrow[b-9kaz8ksd3g] {
    display: grid; grid-template-columns: minmax(120px, 40%) 1fr; align-items: center; gap: 10px;
    padding: 6px 8px; border-radius: 8px;
}
.gdg-bulkrow:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); }
.gdg-bulklabel[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--c-ink-2); cursor: pointer; }
.gdg-bulkfield[b-9kaz8ksd3g] { min-width: 0; }
.gdg-bulkfield .gdg-editin[b-9kaz8ksd3g] { position: static; width: 100%; }

/* Lignes ecartees : le lot continue apres un refus, donc le dialogue doit pouvoir en montrer
   plusieurs sans repousser ses propres boutons hors de l ecran. */
.gdg-bulkreport[b-9kaz8ksd3g] {
    margin: 10px 0 0; padding: 8px 10px; border-radius: 8px;
    background: var(--c-danger-soft); border: 1px solid var(--c-danger-soft-2);
}
.gdg-bulkreport-title[b-9kaz8ksd3g] { margin: 0 0 6px; font-size: 12.5px; font-weight: 600; color: var(--c-danger-ink); }
.gdg-bulkreport-list[b-9kaz8ksd3g] {
    margin: 0; padding-left: 18px; max-height: 140px; overflow-y: auto;
    font-size: 12px; color: var(--c-ink-2); line-height: 1.55;
}

/* =========================================================================
   Colonnes : débordement, en-têtes empilés, menu de colonne
   ========================================================================= */

.gdg-cell.is-clip[b-9kaz8ksd3g] { white-space: nowrap; overflow: hidden; text-overflow: clip; }
.gdg-cell.is-wrapcell[b-9kaz8ksd3g] { white-space: normal; overflow: visible; text-overflow: clip; max-width: none; }

/* En-tête groupé (stacked headers) : une ligne au-dessus des colonnes */
.gdg-headgrouprow .gdg-thgroup[b-9kaz8ksd3g] {
    padding: 6px 12px; text-align: center; font-size: 11px; font-weight: 700;
    letter-spacing: .04em; text-transform: uppercase; color: var(--c-ink-3);
    background: var(--c-surface-2); border-bottom: 1px solid var(--c-border);
    border-right: 1px solid var(--c-border);
}
.gdg-headgrouprow .gdg-thgroup.is-empty[b-9kaz8ksd3g] { background: var(--c-surface); border-right-color: transparent; }

/* Bouton du menu de colonne : discret, révélé au survol ou au focus clavier */
.gdg-colmenubtn[b-9kaz8ksd3g] {
    border: none; background: none; cursor: pointer; color: var(--c-ink-3);
    font-size: 14px; line-height: 1; padding: 2px 4px; border-radius: 5px;
    opacity: 0; transition: opacity .12s ease;
}
.gdg-th:hover .gdg-colmenubtn[b-9kaz8ksd3g],
.gdg-th:focus-within .gdg-colmenubtn[b-9kaz8ksd3g],
.gdg-colmenubtn:focus-visible[b-9kaz8ksd3g] { opacity: 1; }
.gdg-colmenubtn:hover[b-9kaz8ksd3g] { background: var(--c-surface-3); color: var(--c-accent); }

/* =========================================================================
   Cellules actives et colonne de commandes
   ========================================================================= */

/* Enveloppe d'un contrôle interactif dans une cellule : la grille y neutralise
   le clic de ligne, la sélection et le déclencheur d'édition. */
.gdg-cellaction[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 6px; min-width: 0; }
.gdg-cellaction > select[b-9kaz8ksd3g],
.gdg-cellaction > input:not([type="checkbox"])[b-9kaz8ksd3g] {
    width: 100%; min-width: 0; padding: 3px 6px; font: inherit; color: var(--c-ink);
    background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 6px;
}
.gdg-cellaction > select:hover[b-9kaz8ksd3g] { border-color: var(--c-accent); }

/* E7 : enveloppe purement événementielle du gabarit de cellule (Template/ChildContent d'un écran) —
   seul @onkeydown:stopPropagation (HelpGridV3.razor) en fait usage. display:contents ne change QUE
   la mise en page (l'enveloppe ne génère pas de boîte : dans une cellule en flex/grid, ses enfants
   participent comme s'ils étaient directement dans le <td>). Elle reste un vrai nœud du DOM pour le
   reste — round 1 de revue, tâche 4 : un sélecteur CSS d'écran de la forme `td > x` (combinateur
   « enfant direct ») ne matche donc PLUS x une fois enveloppé (son parent réel est ce <span>) ; un
   sélecteur descendant `td x` ou une règle héritée (`color`, `font`…) continue de fonctionner. */
.gdg-celltemplate[b-9kaz8ksd3g] { display: contents; }

.gdg-cmds[b-9kaz8ksd3g] { display: flex; align-items: center; justify-content: center; gap: 4px; }
.gdg-cmd[b-9kaz8ksd3g] {
    border: 1px solid transparent; background: none; cursor: pointer; color: var(--c-ink-2);
    border-radius: 6px; padding: 3px 7px; font-size: 13px; line-height: 1.1;
    min-width: 28px; min-height: 28px;
}
.gdg-cmd:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); border-color: var(--c-border); color: var(--c-accent); }
.gdg-cmd.is-primary[b-9kaz8ksd3g] { color: var(--c-on-accent); background: var(--c-accent); border-color: var(--c-accent); }
.gdg-cmd.is-primary:hover[b-9kaz8ksd3g] { background: var(--c-accent-700); }
.gdg-cmd.is-danger:hover[b-9kaz8ksd3g] { background: var(--c-accent-soft); border-color: var(--c-accent); color: var(--c-accent); }

/* Cellule modifiée non enregistrée (mode lot) : coin replié — un repère de forme,
   pas seulement de couleur, pour rester lisible en contraste forcé. */
.gdg-cell.is-dirty[b-9kaz8ksd3g] { position: relative; font-weight: 600; }
.gdg-cell.is-dirty[b-9kaz8ksd3g]::after {
    content: ""; position: absolute; top: 0; inset-inline-start: 0;
    border-width: 5px 5px 0 0; border-style: solid;
    border-color: var(--c-accent) transparent transparent transparent;
}

/* =========================================================================
   Filtre multi-liste (façon tableur)
   ========================================================================= */

.gdg-fmulti[b-9kaz8ksd3g] { display: flex; flex-direction: column; gap: 6px; min-width: 220px; }
.gdg-fmulti-actions[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 10px; }
.gdg-fmulti-count[b-9kaz8ksd3g] {
    margin-inline-start: auto; font-size: 11px; font-weight: 700; color: var(--c-accent);
    background: var(--c-accent-soft); border-radius: 999px; padding: 1px 7px;
}
.gdg-fmulti-list[b-9kaz8ksd3g] { max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.gdg-fmulti-item[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 6px;
    font-size: 12.5px; color: var(--c-ink-2); cursor: pointer;
}
.gdg-fmulti-item:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); }

/* =========================================================================
   Formulaire d'édition en dialogue
   ========================================================================= */

.gdg-formrow[b-9kaz8ksd3g] {
    display: grid; grid-template-columns: minmax(120px, 34%) 1fr; align-items: center; gap: 10px;
    padding: 5px 2px;
}
.gdg-formlabel[b-9kaz8ksd3g] { font-size: 13px; color: var(--c-ink-2); }
.gdg-req[b-9kaz8ksd3g] { color: var(--c-accent); margin-inline-start: 3px; }
.gdg-formfield[b-9kaz8ksd3g] { min-width: 0; }
.gdg-formfield .gdg-editin[b-9kaz8ksd3g] { position: static; width: 100%; }

/* =========================================================================
   Lignes gelées et espace réservé de la virtualisation
   ========================================================================= */

.gdg-datarow.is-frozenrow[b-9kaz8ksd3g] { background: var(--c-surface); box-shadow: 0 1px 0 var(--c-border); }
/* E9, round 1 : même spécificité (2 classes) que la règle juste au-dessus — sans ce combo à 3
   classes, une ligne gelée ET sélectionnée par l'hôte perdrait sa teinte de sélection (le fond
   « gelé » l'emporterait selon l'ordre du fichier, alors qu'une ligne sélectionnée doit le rester
   même gelée). */
.gdg-datarow.is-frozenrow.gdg-row-selected[b-9kaz8ksd3g] { background: var(--c-row-sel); }
.gdg-datarow.is-placeholder td[b-9kaz8ksd3g] { color: var(--c-ink-3); font-style: italic; }

/* =========================================================================
   Accessibilité
   ========================================================================= */

/* Anneau de focus visible partout. :focus-visible seulement : rien au clic
   souris, toujours au clavier. */
.gdg :focus-visible[b-9kaz8ksd3g],
.gdg-th:focus-visible[b-9kaz8ksd3g],
.gdg-cell:focus-visible[b-9kaz8ksd3g] {
    outline: 2px solid var(--c-accent); outline-offset: -2px; border-radius: 4px;
}

/* La ligne focalisée au clavier reste identifiable sans dépendre de la couleur */
.gdg-table tbody .gdg-datarow.is-focus[b-9kaz8ksd3g] { outline: 2px solid var(--c-info); outline-offset: -2px; }

/* (La zone d'annonce aria-live utilise .gdg-sronly, déjà défini plus haut.) */

/* Pointeur grossier (tactile) : cibles de 44 px, recommandation WCAG 2.5.5 */
@media (pointer: coarse) {
    .gdg-btn[b-9kaz8ksd3g], .gdg-iconbtn[b-9kaz8ksd3g], .gdg-cmd[b-9kaz8ksd3g], .gdg-pagebtn[b-9kaz8ksd3g] { min-height: 44px; min-width: 44px; }
    .gdg-check[b-9kaz8ksd3g], .gdg-checkcell input[type="checkbox"][b-9kaz8ksd3g] { transform: scale(1.25); }
    .gdg-fmulti-item[b-9kaz8ksd3g] { padding: 10px 6px; }
}

/* Mouvement réduit : transitions coupées, changements d'état conservés */
@media (prefers-reduced-motion: reduce) {
    .gdg *[b-9kaz8ksd3g], .gdg *[b-9kaz8ksd3g]::before, .gdg *[b-9kaz8ksd3g]::after {
        transition-duration: 0.01ms;
        animation-duration: 0.01ms;
        animation-iteration-count: 1;
        scroll-behavior: auto;
    }
}

/* Contraste forcé (Windows) : bordures au système, et les repères qui ne
   tenaient qu'à la couleur passent en formes. */
@media (forced-colors: active) {
    .gdg-table[b-9kaz8ksd3g], .gdg-th[b-9kaz8ksd3g], .gdg-cell[b-9kaz8ksd3g] { border-color: CanvasText; }
    .gdg-table tbody .gdg-datarow.is-selected[b-9kaz8ksd3g] { outline: 2px solid Highlight; outline-offset: -2px; }
    .gdg-cell.is-dirty[b-9kaz8ksd3g]::after { border-top-color: CanvasText; }
    .gdg-btn[b-9kaz8ksd3g], .gdg-iconbtn[b-9kaz8ksd3g], .gdg-cmd[b-9kaz8ksd3g] { border-color: CanvasText; }
    .gdg-sorticon[b-9kaz8ksd3g], .gdg-filteron[b-9kaz8ksd3g] { forced-color-adjust: none; }
}

/* =========================================================================
   Droite-à-gauche
   ========================================================================= */

.gdg[dir="rtl"] .gdg-resize[b-9kaz8ksd3g] { inset-inline-end: auto; inset-inline-start: 0; }
.gdg[dir="rtl"] .gdg-editactions[b-9kaz8ksd3g] { box-shadow: inset -3px 0 0 var(--c-accent); }

/* =========================================================================
   Impression : la grille à plat, sans commandes, en-têtes répétés.
   C'est aussi le chemin PDF — le navigateur sait enregistrer en PDF et le rendu
   reste fidèle à ce que l'utilisateur voit.
   ========================================================================= */

@media print {
    .gdg-toolbar[b-9kaz8ksd3g], .gdg-grouppanel[b-9kaz8ksd3g], .gdg-selbar[b-9kaz8ksd3g], .gdg-footer[b-9kaz8ksd3g], .gdg-undobar[b-9kaz8ksd3g], .gdg-loadbar[b-9kaz8ksd3g],
    .gdg-resize[b-9kaz8ksd3g], .gdg-pinbtn[b-9kaz8ksd3g], .gdg-colmenubtn[b-9kaz8ksd3g], .gdg-fbtn[b-9kaz8ksd3g], .gdg-filterrow[b-9kaz8ksd3g],
    .gdg-cmds[b-9kaz8ksd3g], .gdg-checkcell[b-9kaz8ksd3g], .gdg-draghandle[b-9kaz8ksd3g], .gdg-expcell[b-9kaz8ksd3g] { display: none; }

    .gdg[b-9kaz8ksd3g] { color: var(--c-print-ink); font-size: 10.5pt; }
    .gdg-scroll[b-9kaz8ksd3g] { max-height: none; overflow: visible; }
    .gdg-table[b-9kaz8ksd3g] { table-layout: auto; width: 100%; }
    .gdg-table thead[b-9kaz8ksd3g] { display: table-header-group; }
    .gdg-table tfoot[b-9kaz8ksd3g] { display: table-footer-group; }
    .gdg-datarow[b-9kaz8ksd3g] { break-inside: avoid; page-break-inside: avoid; }
    .gdg-th[b-9kaz8ksd3g], .gdg-cell[b-9kaz8ksd3g] {
        position: static; white-space: normal; max-width: none;
        border: 1px solid var(--c-print-border); padding: 4px 6px;
    }
    .gdg-table tbody .gdg-datarow.is-selected[b-9kaz8ksd3g] { background: none; font-weight: 700; }
}

/* Cellule active du clavier : contour net, visible aussi en contraste force */
.gdg-cell.is-focuscell[b-9kaz8ksd3g] { outline: 2px solid var(--c-accent); outline-offset: -2px; }
@media (forced-colors: active) {
    .gdg-cell.is-focuscell[b-9kaz8ksd3g] { outline: 2px solid Highlight; }
}

/* Colonne active (E1) : en-tête + chaque cellule. Fond posé directement sur le <th>/<td> (pas sur
   la <tr>) : il couvre donc toujours le zébrage (fond posé sur la <tr>, une autre boîte) sans
   !important. Écrit avec deux classes pour l'emporter, à égalité de source, sur .gdg-th.is-pinned /
   .gdg-cell.is-pinned quand la colonne active est aussi gelée (cette règle vient après). */
.gdg-th.gdg-col-active[b-9kaz8ksd3g] { background: var(--c-col-active); }
.gdg-cell.gdg-col-active[b-9kaz8ksd3g] { background: var(--c-col-active); }

/* =========================================================================
   Ligne de filtres : tenir dans la largeur de la colonne, sans grandir en hauteur
   ========================================================================= */

/* Le selecteur d'operateur garde une largeur lisible ("Contient" ne doit pas
   devenir "Contie") ; c'est la saisie qui cede la place, pas l'etiquette. */
.gdg-filterrow .gdg-fop[b-9kaz8ksd3g] {
    flex: 0 0 auto; width: auto; min-width: 74px; max-width: 96px;
    padding: 5px 2px; font-size: 11px;
}
.gdg-filterrow .gdg-fin[b-9kaz8ksd3g], .gdg-filterrow .gdg-fsel[b-9kaz8ksd3g] { flex: 1 1 auto; min-width: 0; }
.gdg-filterrow .gdg-fwrap[b-9kaz8ksd3g] { gap: 3px; min-width: 0; }

/* Une hauteur de ligne stable : aucun controle de filtre ne depasse. */
.gdg-filterrow th[b-9kaz8ksd3g] { vertical-align: middle; }

/* Filtre multi-liste dans la ligne : un bouton compact, la liste s'ouvre en popup.
   Rendre la liste ici ferait une ligne de 300 px de haut. */
.gdg-fmulti-btn[b-9kaz8ksd3g] {
    display: flex; align-items: center; justify-content: space-between; gap: 4px;
    width: 100%; min-width: 0; padding: 5px 8px;
    border: 1px solid var(--c-border); border-radius: 7px;
    background: var(--c-surface); color: var(--c-ink-2);
    font-size: 12.5px; cursor: pointer;
}
.gdg-fmulti-btn:hover[b-9kaz8ksd3g] { border-color: var(--c-accent); color: var(--c-accent); }
.gdg-fmulti-btn.is-on[b-9kaz8ksd3g] { border-color: var(--c-accent); background: var(--c-accent-soft); color: var(--c-accent); font-weight: 600; }
.gdg-fmulti-btnlabel[b-9kaz8ksd3g] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gdg-fmulti-caret[b-9kaz8ksd3g] { flex: 0 0 auto; font-size: 10px; opacity: .7; }

/* Dans le popup, la liste retrouve sa place */
.gdg-fpopup .gdg-fmulti[b-9kaz8ksd3g] { min-width: 240px; }

/* Puce d'un filtre sans valeur (Vide / Non vide) dans la ligne de filtres : clic = effacer */
.gdg-fchip[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
    padding: 4px 9px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--c-accent); background: var(--c-accent-soft);
    color: var(--c-accent); font-size: 12px; font-weight: 600;
}
.gdg-fchip:hover[b-9kaz8ksd3g] { background: var(--c-accent-soft-2); }
.gdg-fchip-label[b-9kaz8ksd3g] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* =========================================================================
   Combobox de filtre : saisie + panneau de valeurs, au theme de la grille
   (le datalist natif n'est ni stylable ni pilotable au clavier de facon sure)
   ========================================================================= */

.gdg-fcombo[b-9kaz8ksd3g] { position: relative; display: flex; align-items: center; flex: 1 1 auto; min-width: 0; }
.gdg-fcombo .gdg-fin[b-9kaz8ksd3g] { padding-right: 22px; }
.gdg-fcombo-caret[b-9kaz8ksd3g] {
    position: absolute; inset-inline-end: 4px; border: none; background: none;
    color: var(--c-ink-3); cursor: pointer; font-size: 10px; line-height: 1; padding: 2px;
}
.gdg-fcombo-caret:hover[b-9kaz8ksd3g] { color: var(--c-accent); }

.gdg-combolist[b-9kaz8ksd3g] {
    position: fixed; z-index: 79; max-height: 280px; overflow-y: auto;
    min-width: 200px; padding: 4px;
    border: 1px solid var(--c-border-2); border-radius: 10px;
    background: var(--c-surface); box-shadow: var(--sh-lg);
}
.gdg-combo-opt[b-9kaz8ksd3g] {
    display: block; width: 100%; text-align: start;
    border: none; background: none; color: var(--c-ink-2);
    padding: 6px 9px; border-radius: 7px; cursor: pointer;
    font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gdg-combo-opt:hover[b-9kaz8ksd3g], .gdg-combo-opt.is-active[b-9kaz8ksd3g] { background: var(--c-accent-soft); color: var(--c-accent); }
.gdg-combo-empty[b-9kaz8ksd3g], .gdg-combo-more[b-9kaz8ksd3g] {
    margin: 0; padding: 7px 9px; font-size: 12px; color: var(--c-ink-3); font-style: italic;
}

/* =========================================================================
   Chargement : bandeau discret pendant un rechargement, lignes fantomes au
   premier affichage. Jamais de voile sur des donnees deja lisibles.
   ========================================================================= */

/* Rechargement : filet anime sur l'arete haute de la carte, HORS FLUX. En bandeau, son
   apparition et sa disparition decalaient le tableau de ~27 px a chaque frappe dans un
   filtre — insupportable a l'usage. Ici rien ne bouge et rien n'est recouvert. */
.gdg-loadbar[b-9kaz8ksd3g] {
    position: absolute; top: 0; left: 0; right: 0; height: 3px; z-index: 5;
    overflow: hidden; background: var(--c-accent-soft);
    border-top-left-radius: 12px; border-top-right-radius: 12px;
    pointer-events: none;
}
.gdg-loadbar[b-9kaz8ksd3g]::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: -40%; width: 40%;
    background: var(--c-accent);
    animation: gdg-loadslide-b-9kaz8ksd3g 1.1s ease-in-out infinite;
}
@keyframes gdg-loadslide-b-9kaz8ksd3g { from { left: -40%; } to { left: 100%; } }
/* sans animation : un filet plein et atténué dit « en cours » sans bouger */
@media (prefers-reduced-motion: reduce) {
    .gdg-loadbar[b-9kaz8ksd3g]::after { animation: none; left: 0; width: 100%; opacity: .55; }
}
@media (forced-colors: active) {
    .gdg-loadbar[b-9kaz8ksd3g]::after { background: Highlight; }
}

.gdg-spinner[b-9kaz8ksd3g] {
    width: 13px; height: 13px; flex: 0 0 auto; border-radius: 50%;
    border: 2px solid var(--c-accent-soft-2); border-top-color: var(--c-accent);
    animation: gdg-spin-b-9kaz8ksd3g .7s linear infinite;
}
@keyframes gdg-spin-b-9kaz8ksd3g { to { transform: rotate(360deg); } }

.gdg-empty .gdg-spinner[b-9kaz8ksd3g] { display: inline-block; vertical-align: -2px; margin-inline-end: 8px; }

/* Lignes fantomes : la forme du tableau apparait avant les donnees */
.gdg-skelrow td[b-9kaz8ksd3g] { padding: 11px 14px; border-top: 1px solid var(--c-border); }
.gdg-skel[b-9kaz8ksd3g] {
    display: block; height: 11px; border-radius: 6px;
    background: linear-gradient(90deg, var(--c-surface-2) 25%, var(--c-surface-3) 37%, var(--c-surface-2) 63%);
    background-size: 400% 100%;
    animation: gdg-shimmer-b-9kaz8ksd3g 1.3s ease-in-out infinite;
}
@keyframes gdg-shimmer-b-9kaz8ksd3g { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* Mouvement reduit : on garde le repere, on enleve l'animation */
@media (prefers-reduced-motion: reduce) {
    .gdg-spinner[b-9kaz8ksd3g] { animation: none; border-top-color: var(--c-accent); }
    .gdg-skel[b-9kaz8ksd3g] { animation: none; background: var(--c-surface-2); }
}

/* Erreur de chargement de la source : visible, avec un bouton pour reessayer */
.gdg-loaderr[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 12px; font-size: 12.5px; font-weight: 600;
    color: var(--c-accent); background: var(--c-accent-soft);
    border-bottom: 1px solid var(--c-accent-soft-2);
}
.gdg-loaderr-msg[b-9kaz8ksd3g] { flex: 1 1 auto; min-width: 0; font-weight: 400; color: var(--c-ink-2); }

/* =========================================================================
   Mise en forme conditionnelle — panneau de règles (HelpGridV3.Rules.cs)
   Une carte par règle : en-tête (pastille, nom, œil, croix), « Quand »
   (conditions + puces ET/OU), « Faire » (couleurs, gras, portée).
   ========================================================================= */

.gdg-rulecount[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 17px; height: 17px; margin-left: 6px; padding: 0 4px;
    border-radius: 999px; background: var(--c-accent); color: var(--c-on-accent);
    font-size: 10.5px; font-weight: 800;
}

/* Dialogue centre : plus de place que le popover, et il ne depend pas de la position du bouton.
   Trois zones fixes — titre, corps qui defile, pied avec les actions — pour que la liste des regles
   puisse grandir sans pousser le bouton d ajout hors de vue. */
.gdg-dialog.is-wide[b-9kaz8ksd3g] { width: min(720px, calc(100vw - 32px)); max-height: min(82vh, 820px); }
.gdg-dialog-head[b-9kaz8ksd3g] {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding-bottom: 10px; margin-bottom: 12px; border-bottom: 1px solid var(--c-border);
}
.gdg-dialog-head .gdg-dialog-title[b-9kaz8ksd3g] { margin: 0; font-size: 15px; }
.gdg-dialogx[b-9kaz8ksd3g] {
    border: none; background: none; color: var(--c-ink-3); cursor: pointer;
    width: 28px; height: 28px; border-radius: 8px; font-size: 20px; line-height: 1; padding: 0;
}
.gdg-dialogx:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); color: var(--c-ink); }
.gdg-dialog-foot[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding-top: 12px; margin-top: 12px; border-top: 1px solid var(--c-border);
}
.gdg-dialog-foot .gdg-rulehint[b-9kaz8ksd3g] { flex: 1 1 240px; margin: 0; border: none; padding: 0; }
.gdg-rules-empty[b-9kaz8ksd3g], .gdg-rulehint[b-9kaz8ksd3g] {
    margin: 6px 2px 0; font-size: 12px; line-height: 1.45; color: var(--c-ink-3);
}
.gdg-rulehint[b-9kaz8ksd3g] { border-top: 1px dashed var(--c-border); padding-top: 8px; }

.gdg-rulecard[b-9kaz8ksd3g] {
    border: 1px solid var(--c-border); border-radius: 10px;
    padding: 10px; margin-bottom: 10px; background: var(--c-surface);
}
.gdg-rulecard.is-off[b-9kaz8ksd3g] { opacity: .55; }
.gdg-rulecard-head[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 6px; }

.gdg-ruleswatch[b-9kaz8ksd3g] {
    width: 16px; height: 16px; border-radius: 5px; flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--c-border-2); cursor: pointer; padding: 0;
    font-size: 10px; color: var(--c-ink-3);
}
.gdg-ruleswatch.is-none[b-9kaz8ksd3g] { background: var(--c-surface); }

.gdg-rulename[b-9kaz8ksd3g] {
    flex: 1 1 auto; min-width: 0; border: 1px solid transparent; border-radius: 6px;
    padding: 3px 6px; font-size: 13px; font-weight: 700; color: var(--c-ink);
    background: transparent;
}
.gdg-rulename:hover[b-9kaz8ksd3g] { border-color: var(--c-border); }
.gdg-rulename:focus[b-9kaz8ksd3g] { border-color: var(--c-accent); outline: none; background: var(--c-surface); }
.gdg-rulename.is-locked[b-9kaz8ksd3g] { padding: 3px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.gdg-ruleicon[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 26px; height: 26px; padding: 0 6px;
    border: 1px solid var(--c-border); background: var(--c-surface); color: var(--c-ink-2);
    border-radius: 6px; font-size: 12px; cursor: pointer; line-height: 1;
}
.gdg-ruleicon:hover:not(:disabled)[b-9kaz8ksd3g] { border-color: var(--c-accent); color: var(--c-accent); }
.gdg-ruleicon.is-on[b-9kaz8ksd3g] { border-color: var(--c-accent); color: var(--c-accent); background: var(--c-accent-soft); }
.gdg-ruleicon:disabled[b-9kaz8ksd3g] { opacity: .4; cursor: default; }

.gdg-rulelocked[b-9kaz8ksd3g] { margin: 8px 2px 0; font-size: 12px; color: var(--c-ink-3); line-height: 1.45; }

.gdg-rulesection[b-9kaz8ksd3g] { margin-top: 10px; }
.gdg-rulesection-head[b-9kaz8ksd3g] {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    margin: 0 0 6px; font-size: 11px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--c-ink-3);
}

.gdg-rulechips[b-9kaz8ksd3g] { display: inline-flex; gap: 4px; }
.gdg-rulechip[b-9kaz8ksd3g] {
    border: 1px solid var(--c-border); background: var(--c-surface); color: var(--c-ink-2);
    border-radius: 999px; padding: 3px 10px; font-size: 11.5px; font-weight: 700; cursor: pointer;
}
.gdg-rulechip:hover[b-9kaz8ksd3g] { border-color: var(--c-accent); color: var(--c-accent); }
.gdg-rulechip.is-on[b-9kaz8ksd3g] { border-color: var(--c-accent); background: var(--c-accent-soft); color: var(--c-accent); }

/* une condition = colonne + opérateur + valeur(s), sur une ligne qui se replie si besoin */
.gdg-rulecond[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-bottom: 5px; }
.gdg-rulecond .gdg-fsel[b-9kaz8ksd3g], .gdg-rulecond .gdg-fin[b-9kaz8ksd3g] { flex: 1 1 120px; min-width: 0; }
.gdg-rulecond .gdg-fop[b-9kaz8ksd3g] { flex: 0 0 130px; width: auto; }

/* Encadré de groupe : les conditions d un même groupe sont visuellement ensemble, et le OU entre
   deux encadrés se lit d un coup — ce qu une liste plate ne montrait pas. */
.gdg-rulegroup[b-9kaz8ksd3g] {
    border: 1px solid var(--c-border); border-radius: 9px;
    padding: 8px; background: var(--c-surface-2);
}
.gdg-rulegroup-head[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 6px; min-height: 22px; margin-bottom: 6px; }

/* opérateur ENTRE deux encadrés, centré sur un filet : la hiérarchie se voit sans lire */
.gdg-rulejoin[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 8px; margin: 8px 0; }
.gdg-rulejoin-line[b-9kaz8ksd3g] { flex: 1; height: 1px; background: var(--c-border-2); }

/* Supprimer (condition, groupe, règle) : trait monochrome, rouge au survol. .gdg-chipx ne pouvait
   pas servir ici — il est blanc sur fond sombre, donc invisible sur une carte claire. */
.gdg-ruledel[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
    width: 26px; height: 26px; padding: 0; border-radius: 7px;
    border: 1px solid transparent; background: none; color: var(--c-ink-3); cursor: pointer;
}
.gdg-ruledel:hover[b-9kaz8ksd3g] { border-color: var(--c-accent); color: var(--c-accent); background: var(--c-accent-soft); }

/* icônes en ligne (cadenas du titre) alignées sur le texte */
.gdg-ruleic[b-9kaz8ksd3g] { display: inline-flex; vertical-align: -2px; color: var(--c-ink-3); }

.gdg-rulelink[b-9kaz8ksd3g] {
    border: none; background: none; padding: 2px 0; cursor: pointer;
    font-size: 12px; font-weight: 600; color: var(--c-accent);
}
.gdg-rulelink:hover[b-9kaz8ksd3g] { text-decoration: underline; }

.gdg-ruleactions[b-9kaz8ksd3g] { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.gdg-rulecolor[b-9kaz8ksd3g] {
    display: inline-flex; align-items: center; gap: 6px;
    border: 1px solid var(--c-border); background: var(--c-surface); color: var(--c-ink-2);
    border-radius: 7px; padding: 3px 8px; font-size: 12px; cursor: pointer;
}
.gdg-rulecolor:hover[b-9kaz8ksd3g] { border-color: var(--c-accent); color: var(--c-accent); }

.gdg-rulepalette[b-9kaz8ksd3g] {
    display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
    margin-top: 7px; padding: 7px; border: 1px solid var(--c-border); border-radius: 8px;
    background: var(--c-surface-2);
}
.gdg-rulepalette .gdg-ruleswatch[b-9kaz8ksd3g] { width: 20px; height: 20px; }
.gdg-rulecustom[b-9kaz8ksd3g] { width: 26px; height: 22px; border: 1px solid var(--c-border-2); border-radius: 5px; padding: 0; cursor: pointer; }

.gdg-rulecols[b-9kaz8ksd3g] {
    display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 6px;
    max-height: 132px; overflow-y: auto;
}
.gdg-rulecol[b-9kaz8ksd3g] { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--c-ink-2); }


.gdg-viewhint[b-9kaz8ksd3g] {
    margin: 8px 8px 6px; padding-top: 8px; border-top: 1px dashed var(--c-border);
    font-size: 11.5px; line-height: 1.45; color: var(--c-ink-3);
}

/* Menu « Options du tableau » (engrenage) : plus large que le simple choix de colonnes, il porte
   aussi une explication. Sans un peu de largeur, la phrase sur la memoire se lit en colonne. */
.gdg-colmenu.is-wide[b-9kaz8ksd3g] { min-width: 300px; max-width: 340px; }
.gdg-menuhint[b-9kaz8ksd3g] {
    margin: 2px 8px 8px; font-size: 11.5px; line-height: 1.45; color: var(--c-ink-3);
}
.gdg-colmenu .gdg-mi[b-9kaz8ksd3g] {
    width: 100%; margin-top: 6px; padding-top: 8px;
    border-top: 1px solid var(--c-border); border-radius: 0 0 8px 8px;
}

/* Une ligne = un reglage a plusieurs valeurs : libelle a gauche, selecteur a droite. Les cases a
   cocher gardent .gdg-colopt ; melanger les deux formes brouillerait la lecture du menu. */
.gdg-optrow[b-9kaz8ksd3g] {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 5px 8px; border-radius: 8px; cursor: pointer;
}
.gdg-optrow:hover[b-9kaz8ksd3g] { background: var(--c-surface-2); }
.gdg-optlabel[b-9kaz8ksd3g] { font-size: 13px; color: var(--c-ink-2); white-space: nowrap; }
.gdg-optrow .gdg-fsel[b-9kaz8ksd3g] { flex: 0 1 165px; min-width: 0; }
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
/* Blazor's reconnect dialog, in this product's clothes. The markup and the state classes are
   Blazor's own (ReconnectModal.razor.js toggles them); only the look is ours - the tokens from
   app.css, which this scoped sheet reads through the cascade. Motion is opt-in: the dialog has to
   be readable with animations off, so its resting state is fully visible and the fades and the
   ripple only exist for people who have not asked their machine for less movement. */

.components-reconnect-first-attempt-visible[b-frnewygcvr],
.components-reconnect-repeated-attempt-visible[b-frnewygcvr],
.components-reconnect-failed-visible[b-frnewygcvr],
.components-pause-visible[b-frnewygcvr],
.components-resume-failed-visible[b-frnewygcvr],
.components-rejoining-animation[b-frnewygcvr] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-retrying[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-failed[b-frnewygcvr],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-frnewygcvr] {
    display: block;
}

#components-reconnect-modal[b-frnewygcvr] {
    background-color: var(--paper-raised);
    color: var(--ink);
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 1px solid var(--line-control);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

/* The veil behind it, the same as .modal-veil in app.css. A literal rather than a token: the
   backdrop pseudo-element does not inherit custom properties in every browser still in use. */
#components-reconnect-modal[b-frnewygcvr]::backdrop {
    background-color: rgba(24, 26, 27, .45);
}

.components-reconnect-container[b-frnewygcvr] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-frnewygcvr] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-frnewygcvr] {
    border: 0;
    background-color: var(--seal);
    color: var(--on-seal);
    padding: .5rem 1.4rem;
    border-radius: var(--radius-sm);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

#components-reconnect-modal button:hover[b-frnewygcvr] {
    background-color: var(--seal-hover);
}

#components-reconnect-modal button:focus-visible[b-frnewygcvr] {
    outline: 2px solid var(--seal);
    outline-offset: 2px;
}

/* At rest: one still ring in the accent. The ripple below turns it into two expanding ones. */
.components-rejoining-animation[b-frnewygcvr] {
    position: relative;
    width: 80px;
    height: 80px;
}

.components-rejoining-animation div[b-frnewygcvr] {
    position: absolute;
    top: 0;
    left: 0;
    width: 80px;
    height: 80px;
    border: 3px solid var(--seal);
    border-radius: 50%;
    opacity: .6;
}

@media (prefers-reduced-motion: no-preference) {
    #components-reconnect-modal[b-frnewygcvr] {
        opacity: 0;
        transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
        animation: components-reconnect-modal-fadeOutOpacity-b-frnewygcvr 0.5s both;
    }

    #components-reconnect-modal[open][b-frnewygcvr] {
        animation: components-reconnect-modal-slideUp-b-frnewygcvr 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s,
                   components-reconnect-modal-fadeInOpacity-b-frnewygcvr 0.5s ease-in-out 0.3s;
        animation-fill-mode: both;
    }

    #components-reconnect-modal[b-frnewygcvr]::backdrop {
        animation: components-reconnect-modal-fadeInOpacity-b-frnewygcvr 0.5s ease-in-out;
    }

    .components-rejoining-animation div[b-frnewygcvr] {
        opacity: 1;
        animation: components-rejoining-animation-b-frnewygcvr 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

    .components-rejoining-animation div:nth-child(2)[b-frnewygcvr] {
        animation-delay: -0.5s;
    }

    @keyframes components-reconnect-modal-slideUp-b-frnewygcvr {
        0% { transform: translateY(30px) scale(0.95); }
        100% { transform: translateY(0); }
    }

    @keyframes components-reconnect-modal-fadeInOpacity-b-frnewygcvr {
        0% { opacity: 0; }
        100% { opacity: 1; }
    }

    @keyframes components-reconnect-modal-fadeOutOpacity-b-frnewygcvr {
        0% { opacity: 1; }
        100% { opacity: 0; }
    }

    @keyframes components-rejoining-animation-b-frnewygcvr {
        0% { top: 40px; left: 40px; width: 0; height: 0; opacity: 0; }
        4.9% { top: 40px; left: 40px; width: 0; height: 0; opacity: 0; }
        5% { top: 40px; left: 40px; width: 0; height: 0; opacity: 1; }
        100% { top: 0; left: 0; width: 80px; height: 80px; opacity: 0; }
    }
}
/* /Components/Localization/LocalizationEditor.razor.rz.scp.css */
/* CoreBlazor.Localization.Editor — styles isolés (bundle {App}.styles.css).
   Mêmes jetons et mêmes valeurs que HelpGridV3 (--c-*, corail Colibase #C8392C, encre #1A2230, bordures #E2E6EB) :
   l'éditeur se fond dans une page ColibaseApp — interface claire, minimale, sans aplat sombre.
   Sombre UNIQUEMENT sur opt-in, exactement comme la grille (G6) : data-theme="dark" sur <html>, ou prefers-color-scheme
   avec la classe gdg-theme-auto sur la racine / un ancêtre — jamais d'office sur la préférence système. */
.loc-editor[b-s64ov019w2] {
    --c-accent: #C8392C;
    --c-accent-700: #AC2E22;
    --c-accent-soft: #FBEBE9;
    --c-accent-soft-2: #F6DAD6;
    --c-border: #E2E6EB;
    --c-border-2: #D2D8DF;
    --c-surface: #FFFFFF;
    --c-surface-2: #EEF1F4;
    --c-surface-3: #E4E8ED;
    --c-ink: #1A2230;
    --c-ink-2: #4A586B;
    --c-ink-3: #8693A4;
    --c-on-accent: #fff;
    --c-info: #2F5FA8;
    --c-info-soft: #E6EDF8;
    --c-warning-soft: #FBF0DC;
    --c-danger-soft: #FCEBEB;
    --c-danger-ink: #C8392C;

    color: var(--c-ink);
    background: transparent;
    font-size: 13px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* ---- barre du haut ---- */
.loc-bar[b-s64ov019w2] { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: flex-end; }
.loc-field[b-s64ov019w2] { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--c-ink-3); }
.loc-field > span[b-s64ov019w2] { font-weight: 600; letter-spacing: .02em; text-transform: uppercase; font-size: 10.5px; }
.loc-field select[b-s64ov019w2], .loc-field input[b-s64ov019w2], .loc-field textarea[b-s64ov019w2] {
    font: inherit; font-size: 13px; color: var(--c-ink); padding: 6px 9px; min-width: 180px;
    border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface);
}
.loc-field select:focus[b-s64ov019w2], .loc-field input:focus[b-s64ov019w2], .loc-field textarea:focus[b-s64ov019w2] { outline: none; border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-soft); }
.loc-grow[b-s64ov019w2] { flex: 1 1 auto; }
.loc-span2[b-s64ov019w2] { grid-column: span 2; }
.loc-inline[b-s64ov019w2] { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }

/* cultures : pastilles claires, coche fine, pas d'aplat */
.loc-cultures[b-s64ov019w2] { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.loc-chip[b-s64ov019w2] {
    display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; cursor: pointer; user-select: none;
    border: 1px solid var(--c-border); border-radius: 999px; background: var(--c-surface); color: var(--c-ink-2);
}
.loc-chip:hover[b-s64ov019w2] { border-color: var(--c-border-2); }
.loc-chip.is-on[b-s64ov019w2] { background: var(--c-surface-2); color: var(--c-ink); }
.loc-chip.is-neutral.is-on[b-s64ov019w2] { font-weight: 600; }
.loc-chip input[b-s64ov019w2] { margin: 0; accent-color: var(--c-accent); }
.loc-chip > label[b-s64ov019w2] { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.loc-chip-x[b-s64ov019w2] { display: inline-flex; align-items: center; border: 0; background: transparent; cursor: pointer; color: var(--c-ink-3); padding: 1px; margin: 0 -4px 0 0; border-radius: 999px; }
.loc-chip-x:hover[b-s64ov019w2] { color: var(--c-accent); background: var(--c-accent-soft); }
.loc-chip-add[b-s64ov019w2] { font: inherit; font-size: 13px; color: var(--c-ink-2); border-style: dashed; }
.loc-chip-add:hover[b-s64ov019w2] { color: var(--c-accent); border-color: var(--c-accent); }
.loc-badge[b-s64ov019w2] { background: var(--c-accent-soft); color: var(--c-accent); border-radius: 999px; padding: 0 7px; font-size: 10.5px; font-weight: 700; line-height: 17px; }
.loc-badge.is-override[b-s64ov019w2] { background: var(--c-info-soft); color: var(--c-info); }

.loc-check[b-s64ov019w2] { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; color: var(--c-ink-2); padding-bottom: 6px; }
.loc-check input[b-s64ov019w2] { accent-color: var(--c-accent); }
.loc-actions[b-s64ov019w2] { display: flex; gap: 6px; align-items: flex-end; flex-wrap: wrap; margin-left: auto; }

/* icônes SVG en ligne (LocIcons) : alignées sur le texte, couleur du bouton */
.loc-editor[b-s64ov019w2]  .loc-ic, .loc-editor .loc-ic[b-s64ov019w2] { width: 15px; height: 15px; flex: 0 0 auto; vertical-align: -2px; }
.loc-mini .loc-ic[b-s64ov019w2], .loc-x .loc-ic[b-s64ov019w2], .loc-term-x .loc-ic[b-s64ov019w2] { width: 13px; height: 13px; }

/* termes protégés : pastilles + saisie avec bouton « + » (Entrée ajoute aussi) */
.loc-terms[b-s64ov019w2] { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 6px; border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface); }
.loc-term[b-s64ov019w2] { display: inline-flex; align-items: center; gap: 4px; padding: 3px 6px 3px 10px; border-radius: 999px; background: var(--c-surface-2); color: var(--c-ink); font-size: 12.5px; }
.loc-term-x[b-s64ov019w2] { display: inline-flex; align-items: center; border: 0; background: transparent; cursor: pointer; color: var(--c-ink-3); padding: 2px; border-radius: 999px; }
.loc-term-x:hover[b-s64ov019w2] { color: var(--c-accent); background: var(--c-accent-soft); }
.loc-term-add[b-s64ov019w2] { display: inline-flex; align-items: center; gap: 4px; }
.loc-term-add input[b-s64ov019w2] { font: inherit; font-size: 13px; padding: 4px 8px; border: 1px solid var(--c-border); border-radius: 6px; min-width: 160px; background: var(--c-surface); color: var(--c-ink); }
.loc-term-add input:focus[b-s64ov019w2] { outline: none; border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-soft); }

/* boutons : même allure que .gdg-btn (blanc, bordure fine, accent au survol) */
.loc-btn[b-s64ov019w2] {
    display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 13px; padding: 7px 12px; white-space: nowrap; cursor: pointer;
    border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface); color: var(--c-ink);
}
.loc-btn:hover:not(:disabled)[b-s64ov019w2] { border-color: var(--c-accent); color: var(--c-accent); }
.loc-btn:disabled[b-s64ov019w2] { opacity: .45; cursor: not-allowed; }
.loc-btn.is-on[b-s64ov019w2] { background: var(--c-accent-soft); border-color: var(--c-accent); color: var(--c-accent); }
.loc-btn-primary[b-s64ov019w2] { background: var(--c-accent); border-color: var(--c-accent); color: var(--c-on-accent); }
.loc-btn-primary:hover:not(:disabled)[b-s64ov019w2] { background: var(--c-accent-700); border-color: var(--c-accent-700); color: var(--c-on-accent); }
.loc-btn-sm[b-s64ov019w2] { padding: 4px 8px; }
.loc-x[b-s64ov019w2] { font: inherit; font-size: 18px; line-height: 1; border: 0; background: transparent; cursor: pointer; color: var(--c-ink-3); }
.loc-x:hover[b-s64ov019w2] { color: var(--c-accent); }

.loc-menu[b-s64ov019w2] { position: relative; }
.loc-menu-pop[b-s64ov019w2] {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; min-width: 220px; padding: 6px;
    background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 10px; box-shadow: 0 10px 30px rgba(26, 34, 48, .12);
    display: flex; flex-direction: column;
}
.loc-menu-item[b-s64ov019w2] { font: inherit; font-size: 13px; text-align: left; padding: 7px 10px; border: 0; background: transparent; cursor: pointer; border-radius: 6px; color: var(--c-ink); }
.loc-menu-item:hover[b-s64ov019w2] { background: var(--c-surface-2); }

/* messages et panneaux */
.loc-message[b-s64ov019w2] { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 8px; border: 1px solid var(--c-border); background: var(--c-info-soft); color: var(--c-ink); }
.loc-message.is-error[b-s64ov019w2] { background: var(--c-danger-soft); color: var(--c-danger-ink); }
.loc-message .loc-x[b-s64ov019w2] { margin-left: auto; }

.loc-panel[b-s64ov019w2] { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; padding: 10px 14px; border: 1px solid var(--c-border); border-radius: 10px; background: var(--c-surface-2); }
.loc-panel-confirm[b-s64ov019w2] { background: var(--c-warning-soft); }
.loc-hint[b-s64ov019w2] { color: var(--c-ink-3); font-size: 12px; }
.loc-job-head[b-s64ov019w2] { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
.loc-progress[b-s64ov019w2] { width: 100%; height: 6px; margin-top: 6px; accent-color: var(--c-accent); }
.loc-errors[b-s64ov019w2] { margin-top: 6px; font-size: 12px; color: var(--c-danger-ink); }
.loc-errors ul[b-s64ov019w2] { margin: 4px 0 0; padding-left: 18px; max-height: 140px; overflow: auto; }
.loc-settings-grid[b-s64ov019w2] { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px 16px; width: 100%; }
.loc-panel-settings[b-s64ov019w2] { flex-direction: column; align-items: stretch; background: var(--c-surface); }
.loc-preview[b-s64ov019w2] { margin-left: 8px; }

/* cellules : zone de saisie discrète, outils au survol */
.loc-cell[b-s64ov019w2] { display: flex; align-items: flex-start; gap: 4px; width: 100%; }
.loc-cell-input[b-s64ov019w2] {
    flex: 1 1 auto; width: 100%; min-height: 26px; resize: vertical; font: inherit; font-size: 13px; padding: 3px 6px;
    border: 1px solid transparent; border-radius: 6px; background: transparent; color: inherit;
}
.loc-cell-input:hover[b-s64ov019w2] { border-color: var(--c-border); }
.loc-cell-input:focus[b-s64ov019w2] { border-color: var(--c-accent); background: var(--c-surface); outline: none; box-shadow: 0 0 0 3px var(--c-accent-soft); }
.loc-cell-input[b-s64ov019w2]::placeholder { color: var(--c-ink-3); font-style: italic; }
.loc-cell-text[b-s64ov019w2] { white-space: pre-wrap; }
.loc-cell-tools[b-s64ov019w2] { display: inline-flex; gap: 2px; opacity: 0; transition: opacity .12s; }
.loc-cell:hover .loc-cell-tools[b-s64ov019w2], .loc-cell:focus-within .loc-cell-tools[b-s64ov019w2] { opacity: 1; }
.loc-mini[b-s64ov019w2] { font: inherit; font-size: 12px; line-height: 1; padding: 3px 5px; border: 1px solid var(--c-border); border-radius: 6px; background: var(--c-surface); cursor: pointer; color: var(--c-ink-2); }
.loc-mini:hover[b-s64ov019w2] { border-color: var(--c-accent); color: var(--c-accent); }

/* origine du texte : surcharge = liseré accent (comme la ligne en édition de la grille), manquant = teinte avertissement */
[b-s64ov019w2] td.loc-origin-missing { background: var(--c-warning-soft); }
[b-s64ov019w2] td.loc-origin-override { box-shadow: inset 3px 0 0 var(--c-accent); }
[b-s64ov019w2] tr.loc-row-missing td:first-of-type { color: var(--c-accent); }

.loc-legend[b-s64ov019w2] { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; font-size: 12px; color: var(--c-ink-3); }
.loc-dot[b-s64ov019w2] { display: inline-block; width: 12px; height: 12px; border-radius: 3px; border: 1px solid var(--c-border); vertical-align: -2px; margin-right: 4px; background: var(--c-surface); }
.loc-dot.is-override[b-s64ov019w2] { box-shadow: inset 3px 0 0 var(--c-accent); }
.loc-dot.is-missing[b-s64ov019w2] { background: var(--c-warning-soft); }

/* ---- sombre : opt-in seulement, mêmes valeurs que HelpGridV3 ---- */
@media (prefers-color-scheme: dark) {
    :root.gdg-theme-auto:not([data-theme="light"]) .loc-editor[b-s64ov019w2],
    :root:not([data-theme="light"]) .gdg-theme-auto .loc-editor[b-s64ov019w2],
    :root:not([data-theme="light"]) .loc-editor.gdg-theme-auto[b-s64ov019w2] {
        --c-accent: #CC4534; --c-accent-700: #B23A2A; --c-accent-soft: #331A1C; --c-accent-soft-2: #452420;
        --c-border: #3A4454; --c-border-2: #4B5768; --c-surface: #1C232D; --c-surface-2: #242D39; --c-surface-3: #2D3745;
        --c-ink: #EDF1F6; --c-ink-2: #C7D0DC; --c-ink-3: #94A3B8;
        --c-info-soft: #1E2F4A; --c-warning-soft: #3A3120; --c-danger-soft: #3F1D1D; --c-danger-ink: #F5A3A3;
    }
}
:root[data-theme="dark"] .loc-editor[b-s64ov019w2] {
    --c-accent: #CC4534; --c-accent-700: #B23A2A; --c-accent-soft: #331A1C; --c-accent-soft-2: #452420;
    --c-border: #3A4454; --c-border-2: #4B5768; --c-surface: #1C232D; --c-surface-2: #242D39; --c-surface-3: #2D3745;
    --c-ink: #EDF1F6; --c-ink-2: #C7D0DC; --c-ink-3: #94A3B8;
    --c-info-soft: #1E2F4A; --c-warning-soft: #3A3120; --c-danger-soft: #3F1D1D; --c-danger-ink: #F5A3A3;
}
