/* =============================================================================
   Careevia — styles globaux de l'app.
   Réalisation des variantes décidées par le système de design local
   (_direction/FD3_applications/careevia/design/). Aucune valeur visuelle n'est inventée ici :
   toute couleur, tout corps, tout espace vient d'un jeton nommé par son rôle.
   Quatre sections ordonnées (edition-css.md) : A petits éléments fonctionnels ·
   B textes · C secondaires · D structurels, animations en fin de D.
   ============================================================================= */

/* --- Jetons -----------------------------------------------------------------
   Les douze premiers sont les fondations COMMUNES (FD2_app-conventions/
   systeme-de-design.md) : nom et valeur recopiés, jamais importés d'une autre
   app (autonomie-applicative.md). Les suivants sont propres à Careevia
   (design/fondations.md). Aucune redéfinition hors de ce :root.            */
:root {
    color-scheme: light;
    /* Fondations communes — surfaces et encre */
    --gbl-color-canvas: #f7f7f5;
    --gbl-color-surface: #ffffff;
    --gbl-color-ink: #171916;
    --gbl-color-muted: #5c625c;
    --gbl-color-line: #d8ddd8;
    --gbl-color-control-boundary: #8f968f;
    /* Fondations communes — états */
    --gbl-color-success: #176b4d;
    --gbl-color-success-surface: #ecfdf3;
    --gbl-color-warning: #7a4a00;
    --gbl-color-warning-surface: #fff7db;
    --gbl-color-danger: #a4262c;
    --gbl-color-danger-surface: #fff1f2;
    /* Careevia — identité de la plateforme */
    --gbl-color-action: #007f73;
    --gbl-color-action-hover: #00675e;
    --gbl-color-electric: #00cbb5;
    --gbl-color-electric-bright: #35f2d4;
    --gbl-color-focus: #007b70;
    --gbl-color-selected-surface: #e0f5f1;
    --gbl-color-on-action: #ffffff;
    --gbl-color-on-electric: #052923;

    /* Palette sombre explicite — inspirée de la référence fournie : canevas
       presque noir, surfaces graphite, limites discrètes, texte ivoire. */
    --gbl-color-dark-canvas: #151515;
    --gbl-color-dark-surface: #212120;
    --gbl-color-dark-surface-raised: #292928;
    --gbl-color-dark-ink: #f4f2ee;
    --gbl-color-dark-muted: #aaa9a4;
    --gbl-color-dark-line: #373735;
    --gbl-color-dark-control-boundary: #5c5c58;
    --gbl-color-dark-action: #2fe3c6;
    --gbl-color-dark-action-hover: #5af0d7;
    --gbl-color-dark-focus: #58f0d8;
    --gbl-color-dark-selected-surface: #163c36;
    --gbl-color-dark-on-action: #06251f;
    --gbl-color-dark-success: #72d7ae;
    --gbl-color-dark-success-surface: #17382b;
    --gbl-color-dark-warning: #f0c36a;
    --gbl-color-dark-warning-surface: #3b301b;
    --gbl-color-dark-danger: #ff9ca3;
    --gbl-color-dark-danger-surface: #422326;

    /* Rôles résolus. Le thème ne redéfinit aucune valeur brute hors :root. */
    --gbl-theme-canvas: light-dark(var(--gbl-color-canvas), var(--gbl-color-dark-canvas));
    --gbl-theme-surface: light-dark(var(--gbl-color-surface), var(--gbl-color-dark-surface));
    --gbl-theme-surface-raised: light-dark(var(--gbl-color-surface), var(--gbl-color-dark-surface-raised));
    --gbl-theme-ink: light-dark(var(--gbl-color-ink), var(--gbl-color-dark-ink));
    --gbl-theme-muted: light-dark(var(--gbl-color-muted), var(--gbl-color-dark-muted));
    --gbl-theme-line: light-dark(var(--gbl-color-line), var(--gbl-color-dark-line));
    --gbl-theme-control-boundary: light-dark(var(--gbl-color-control-boundary), var(--gbl-color-dark-control-boundary));
    --gbl-theme-action: light-dark(var(--gbl-color-action), var(--gbl-color-dark-action));
    --gbl-theme-action-hover: light-dark(var(--gbl-color-action-hover), var(--gbl-color-dark-action-hover));
    --gbl-theme-focus: light-dark(var(--gbl-color-focus), var(--gbl-color-dark-focus));
    --gbl-theme-selected-surface: light-dark(var(--gbl-color-selected-surface), var(--gbl-color-dark-selected-surface));
    --gbl-theme-on-action: light-dark(var(--gbl-color-on-action), var(--gbl-color-dark-on-action));
    --gbl-theme-success: light-dark(var(--gbl-color-success), var(--gbl-color-dark-success));
    --gbl-theme-success-surface: light-dark(var(--gbl-color-success-surface), var(--gbl-color-dark-success-surface));
    --gbl-theme-warning: light-dark(var(--gbl-color-warning), var(--gbl-color-dark-warning));
    --gbl-theme-warning-surface: light-dark(var(--gbl-color-warning-surface), var(--gbl-color-dark-warning-surface));
    --gbl-theme-danger: light-dark(var(--gbl-color-danger), var(--gbl-color-dark-danger));
    --gbl-theme-danger-surface: light-dark(var(--gbl-color-danger-surface), var(--gbl-color-dark-danger-surface));

    /* Typographie : familles, puis couples corps/interligne par rôle */
    --gbl-font-ui: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
    --gbl-font-title: "Inter Tight", "Inter", system-ui, sans-serif;
    --gbl-size-caption: 0.75rem;
    --gbl-leading-caption: 1rem;
    --gbl-size-compact: 0.875rem;
    --gbl-leading-compact: 1.25rem;
    --gbl-size-body: 1rem;
    --gbl-leading-body: 1.5rem;
    --gbl-size-section: 1.25rem;
    --gbl-leading-section: 1.5rem;
    --gbl-size-page: 1.75rem;
    --gbl-leading-page: 2rem;
    --gbl-size-entry: 2.25rem;
    --gbl-leading-entry: 2.5rem;
    --gbl-weight-strong: 600;
    --gbl-weight-title: 650;

    /* Espace : unité 4px, échelle FERMÉE. Une valeur intermédiaire s'ajoute
       ici et dans fondations.md, jamais en local.                          */
    --gbl-space-1: 4px;
    --gbl-space-2: 8px;
    --gbl-space-3: 12px;
    --gbl-space-4: 16px;
    --gbl-space-6: 24px;
    --gbl-space-8: 32px;
    --gbl-space-12: 48px;
    --gbl-space-16: 64px;

    /* Dimensions, formes, mesure de lecture */
    --gbl-control-height: 44px;
    --gbl-control-height-compact: 36px;
    --gbl-icon-target: 40px;
    --gbl-radius-small: 6px;
    --gbl-radius: 10px;
    --gbl-border: 1px;
    --gbl-focus-width: 3px;
    --gbl-focus-offset: 2px;
    --gbl-select-chevron-size: 5px;
    --gbl-select-chevron-stroke: 3px;
    --gbl-shadow-overlay: 0 12px 32px rgb(23 25 22 / 16%);
    --gbl-dropdown-surface-opacity: 88%;
    --gbl-dropdown-backdrop-blur: 13px;
    --gbl-dropdown-backdrop-tint: 8%;
    --gbl-measure: 70ch;

    /* Gabarits de largeur (design/structures-de-page.md) */
    --gbl-layout-narrow: 32rem;
    --gbl-layout-standard: 72rem;
    --gbl-layout-wide: 80rem;

    /* Mouvement */
    --gbl-duration-state: 120ms;
    --gbl-duration-reveal: 180ms;
}

html[data-theme="dark"] { color-scheme: dark; }

@font-face {
    font-family: "Inter";
    src: url("/assets/fonts/Inter-VariableFont_opsz,wght.ttf") format("truetype-variations");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Inter";
    src: url("/assets/fonts/Inter-Italic-VariableFont_opsz,wght.ttf") format("truetype-variations");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: "Inter Tight";
    src: url("/assets/fonts/InterTight-VariableFont_wght.ttf") format("truetype-variations");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Inter Tight";
    src: url("/assets/fonts/InterTight-Italic-VariableFont_wght.ttf") format("truetype-variations");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

/* =============================================================================
   A — PETITS ÉLÉMENTS FONCTIONNELS
   ========================================================================== */

/* Absence à l'écran : `hidden` est le SEUL porteur du fait « non affiché »,
   et il vaut au niveau AUTEUR. La règle du navigateur est d'origine
   user-agent : la moindre classe posant un `display` la bat sans conflit
   apparent — or bannières, résumés, états vides, panneaux et pieds d'actions
   en posent tous un. Sans cette ligne, un écran affiche « Page indisponible »
   ou « Informations à corriger » en permanence, titres sans message.
   La portée est l'attribut, jamais une liste de classes : une famille ajoutée
   demain est couverte sans qu'on y pense (fondations.md).                  */
[hidden] { display: none !important; }

/* Focus : jeton dédié, sur TOUT contrôle, y compris dans un bouton sombre.
   Il ne dépend ni du survol ni de la bordure de repos (fondations.md).     */
/* Le contour de focus se pose sur le contrôle que l'œil voit. Les saisies logées
   DANS une boîte qui est elle-même le contrôle en sont donc écartées — non pour
   le leur RETIRER, mais parce que c'est leur boîte qui le porte
   (`:focus-within`) : deux contours imbriqués se liraient comme deux contrôles.
   Toute exclusion inscrite ici doit avoir sa compensation, et le harnais l'exige.
   L'exclusion passe par un `:where` pour ne pas peser sur la cascade.          */
:where(a, button, input, select, textarea, summary, [tabindex]):where(:not(.field-composite-saisie, .field-termes-saisie)):focus-visible {
    outline: var(--gbl-focus-width) solid var(--gbl-theme-focus);
    outline-offset: var(--gbl-focus-offset);
}

/* Boutons — DEUX classes obligatoires (edition-css.md) : la structure dit la
   dimension, le style dit la couleur. Elles restent orthogonales : aucune
   variante de style ne fixe une hauteur, aucune structure ne fixe un fond. */
.buttonstructure-default,
.buttonstructure-compact,
.buttonstructure-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--gbl-space-2);
    border: var(--gbl-border) solid transparent;
    border-radius: var(--gbl-radius);
    font-family: var(--gbl-font-ui);
    font-weight: var(--gbl-weight-strong);
    cursor: pointer;
    text-decoration: none;
}
.buttonstructure-default {
    min-height: var(--gbl-control-height);
    padding: 0 var(--gbl-space-4);
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
}
.buttonstructure-compact {
    min-height: var(--gbl-control-height-compact);
    padding: 0 var(--gbl-space-3);
    font-size: var(--gbl-size-compact);
    line-height: var(--gbl-leading-compact);
}
.buttonstructure-icon {
    width: var(--gbl-icon-target);
    height: var(--gbl-icon-target);
    padding: 0;
    border-radius: var(--gbl-radius-small);
}

.buttonstyle-primary {
    background: var(--gbl-theme-action);
    color: var(--gbl-theme-on-action);
    transition: background-color var(--gbl-duration-state) ease;
}
.buttonstyle-primary:hover { background: var(--gbl-theme-action-hover); }

.buttonstyle-secondary {
    background: transparent;
    color: var(--gbl-theme-action);
    border-color: var(--gbl-theme-action);
    transition: background-color var(--gbl-duration-state) ease;
}
.buttonstyle-secondary:hover { background: var(--gbl-theme-selected-surface); }

.buttonstyle-generator {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: var(--gbl-color-electric);
    color: var(--gbl-color-on-electric);
    box-shadow: 0 0 0 0 var(--gbl-color-electric-bright);
    transition: background-color var(--gbl-duration-state) ease,
        box-shadow var(--gbl-duration-reveal) ease;
    animation: generator-breathe 3.6s ease-in-out infinite;
}
.buttonstyle-generator::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(110deg, transparent 25%, var(--gbl-color-electric-bright) 48%, transparent 70%);
    transform: translateX(-120%);
}
.buttonstyle-generator:hover {
    background: var(--gbl-color-electric-bright);
    box-shadow: 0 0 0 3px var(--gbl-theme-selected-surface);
}
.buttonstyle-generator:hover::after { animation: generator-sheen 700ms ease-out; }
.buttonstyle-generator:hover .generator-icon { transform: rotate(18deg) scale(1.08); }
.generator-icon { transition: transform var(--gbl-duration-reveal) ease; }
.buttonstyle-generator:disabled {
    animation: none;
    background: var(--gbl-theme-control-boundary);
    color: var(--gbl-theme-on-action);
}

.buttonstyle-quiet {
    background: transparent;
    color: var(--gbl-theme-ink);
    transition: background-color var(--gbl-duration-state) ease;
}
.buttonstyle-quiet:hover { background: var(--gbl-theme-selected-surface); }

.buttonstyle-danger {
    background: var(--gbl-theme-danger);
    color: var(--gbl-theme-surface);
    transition: opacity var(--gbl-duration-state) ease;
}

.buttonstyle-toggle {
    background: var(--gbl-theme-surface);
    color: var(--gbl-theme-ink);
    border-color: var(--gbl-theme-control-boundary);
    transition: background-color var(--gbl-duration-state) ease,
        border-color var(--gbl-duration-state) ease;
}
.buttonstyle-toggle[aria-pressed="true"] {
    background: var(--gbl-theme-selected-surface);
    border-color: var(--gbl-theme-action);
}

.theme-toggle-symbol {
    width: 18px;
    height: 18px;
    border: 2px solid currentColor;
    border-radius: 50%;
    transition: transform var(--gbl-duration-reveal) ease, background-color var(--gbl-duration-state) ease;
}
.buttonstyle-toggle[aria-pressed="true"] .theme-toggle-symbol {
    background: currentColor;
    transform: scale(.62);
    box-shadow: 0 0 0 4px var(--gbl-theme-selected-surface);
}

/* Attente : la géométrie ne bouge pas, le libellé passe au présent d'action et
   la double activation est bloquée par l'attribut natif (actions.md).      */
.buttonstructure-default[aria-busy="true"],
.buttonstructure-compact[aria-busy="true"] { cursor: progress; }
button:disabled { cursor: not-allowed; color: var(--gbl-theme-muted); }
.buttonstyle-primary:disabled { background: var(--gbl-theme-control-boundary); color: var(--gbl-theme-on-action); }

/* Champs — anatomie unique : label → aide → contrôle → erreur. */
.field {
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-1);
}
/* Quand plusieurs contrôles répondent à UNE question — radios, parts d'un
   composé —, le champ est un `fieldset` nommé par sa légende
   (`controles-de-selection.md`). Il ne peut alors pas être une boîte flex : la
   légende d'un `fieldset` est rendue dans sa bordure et non comme un enfant,
   l'ordre label → aide → contrôle → erreur s'y perdrait. L'écart vient donc des
   marges, et il vaut la même valeur.                                          */
fieldset.field {
    display: block;
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}
fieldset.field > .field-label { display: block; padding: 0; }
fieldset.field > * + * { margin-block-start: var(--gbl-space-1); }
.field-label {
    font-size: var(--gbl-size-compact);
    line-height: var(--gbl-leading-compact);
    font-weight: var(--gbl-weight-strong);
    color: var(--gbl-theme-ink);
}
.field-hint {
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
    color: var(--gbl-theme-muted);
}
.field-standard,
.field-search,
.field-date,
.field-long,
.field-select,
.field-readonly {
    font-family: var(--gbl-font-ui);
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
    color: var(--gbl-theme-ink);
    background: var(--gbl-theme-surface);
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: var(--gbl-radius);
    padding: 0 var(--gbl-space-3);
    min-height: var(--gbl-control-height);
    transition: border-color var(--gbl-duration-state) ease;
}
.field-readonly {
    border-color: var(--gbl-theme-line);
    color: var(--gbl-theme-muted);
}
/* Champ de fichier : le contrôle natif est conservé — le remplacer par un
   bouton déguisé perdrait le nom du fichier choisi, l'accès clavier et le
   glisser-déposer du système. Seule sa boîte est alignée sur les autres
   champs (champs.md).                                                       */
.field-file {
    font: inherit;
    color: var(--gbl-theme-ink);
    padding: var(--gbl-space-2) 0;
}
.field-file::file-selector-button {
    font: inherit;
    margin-inline-end: var(--gbl-space-3);
    padding: var(--gbl-space-2) var(--gbl-space-3);
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: var(--gbl-radius);
    background: var(--gbl-theme-surface);
    color: var(--gbl-theme-ink);
    cursor: pointer;
}
.field-file::file-selector-button:hover { background: var(--gbl-theme-surface-raised); }

.field-long {
    min-height: calc(3 * var(--gbl-leading-body) + var(--gbl-space-4));
    padding: var(--gbl-space-2) var(--gbl-space-3);
    resize: vertical;
}
.field-compact { min-height: var(--gbl-control-height-compact); font-size: var(--gbl-size-compact); }
:where(.field-standard, .field-search, .field-date, .field-long, .field-select):hover { border-color: var(--gbl-theme-ink); }
:where(.field-standard, .field-search, .field-date, .field-long, .field-select):focus { border-color: var(--gbl-theme-action); }
:where(.field-standard, .field-search, .field-date, .field-long, .field-select)[aria-invalid="true"] {
    border-color: var(--gbl-theme-danger);
    background: var(--gbl-theme-danger-surface);
}
:where(.field-standard, .field-search, .field-date, .field-long, .field-select)::placeholder { color: var(--gbl-theme-muted); }
:where(.field-standard, .field-search, .field-date, .field-long, .field-select):disabled {
    color: var(--gbl-theme-muted);
    background: var(--gbl-theme-surface-raised);
    cursor: not-allowed;
}
:where(.field-standard, .field-search, .field-long)[readonly] {
    border-color: var(--gbl-theme-line);
    background: var(--gbl-theme-surface);
}

/* Champ composé — une valeur dont une part est constante (`@`, `https://`) ou
   déjà connue d'un autre champ (l'indicatif, qui appartient au pays). Les parts
   partagent UNE boîte : une bordure, un focus, un état invalide. Le contour de
   focus se pose sur le composé et non sur la part active, parce que le contrôle
   que l'œil voit est le composé (champs.md).                                  */
.field-composite {
    display: flex;
    align-items: stretch;
    gap: var(--gbl-space-1);
    padding: 0 var(--gbl-space-3);
    background: var(--gbl-theme-surface);
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: var(--gbl-radius);
    min-height: var(--gbl-control-height);
    transition: border-color var(--gbl-duration-state) ease;
}
.field-composite:hover { border-color: var(--gbl-theme-ink); }
.field-composite:focus-within {
    border-color: var(--gbl-theme-action);
    outline: var(--gbl-focus-width) solid var(--gbl-theme-focus);
    outline-offset: var(--gbl-focus-offset);
}
.field-composite[aria-invalid="true"] {
    border-color: var(--gbl-theme-danger);
    background: var(--gbl-theme-danger-surface);
}
.field-composite-saisie {
    flex: 1 1 0;
    min-width: 0;
    font-family: var(--gbl-font-ui);
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
    color: var(--gbl-theme-ink);
    background: transparent;
    border: 0;
    padding: 0;
}
.field-composite-saisie::placeholder { color: var(--gbl-theme-muted); }
/* Une part fixe se montre et ne se saisit pas ; en attente, elle dit qu'elle
   attend un autre champ au lieu de deviner une valeur de départ. */
.field-composite-fixe {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
    color: var(--gbl-theme-ink);
    white-space: nowrap;
}
.field-composite-fixe[data-attente="true"] { color: var(--gbl-theme-muted); }

/* Champ à termes — plusieurs valeurs courtes, indépendantes, sans vocabulaire
   fermé. Un terme se valide seul et se retire seul ; la boîte est UNE, comme
   pour le composé, et c'est elle qui porte le focus. Elle enveloppe : un candidat
   qui saisit quinze mots-clés ne doit pas défiler horizontalement (champs.md). */
.field-termes {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gbl-space-1);
    padding: var(--gbl-space-1) var(--gbl-space-3);
    background: var(--gbl-theme-surface);
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: var(--gbl-radius);
    min-height: var(--gbl-control-height);
    transition: border-color var(--gbl-duration-state) ease;
}
.field-termes:hover { border-color: var(--gbl-theme-ink); }
.field-termes:focus-within {
    border-color: var(--gbl-theme-action);
    outline: var(--gbl-focus-width) solid var(--gbl-theme-focus);
    outline-offset: var(--gbl-focus-offset);
}
.field-termes[aria-invalid="true"] {
    border-color: var(--gbl-theme-danger);
    background: var(--gbl-theme-danger-surface);
}
/* La saisie garde toujours une largeur utile, mais cède la ligne aux termes
   déjà posés : `flex-basis` la fait passer à la ligne au lieu de se réduire. */
.field-termes-saisie {
    flex: 1 1 12ch;
    min-width: 12ch;
    font-family: var(--gbl-font-ui);
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
    color: var(--gbl-theme-ink);
    background: transparent;
    border: 0;
    padding: 0;
}
.field-termes-saisie::placeholder { color: var(--gbl-theme-muted); }
.field-terme {
    display: inline-flex;
    align-items: center;
    gap: var(--gbl-space-1);
    padding: 0 var(--gbl-space-1) 0 var(--gbl-space-2);
    background: var(--gbl-theme-selected-surface);
    border-radius: var(--gbl-radius-small);
    font-size: var(--gbl-size-compact);
    line-height: var(--gbl-leading-compact);
    color: var(--gbl-theme-ink);
}
/* Le retrait est une cible à part entière : il porte son propre nom accessible
   et son propre contour de focus, que la règle générale lui accorde. */
.field-terme-retrait {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: var(--gbl-radius-small);
    background: transparent;
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-compact);
    cursor: pointer;
}
.field-terme-retrait:hover { color: var(--gbl-theme-danger); }
/* UNE PROPOSITION N'EST PAS UNE RÉPONSE, et elle ne se lit pas comme une.
   La distinction ne repose PAS sur la seule couleur : le jeton porte aussi un
   mot (`field-terme-origine`), sans quoi un candidat qui ne perçoit pas la
   nuance ne saurait pas qu'on lui demande quelque chose. */
.field-terme-propose {
    background: var(--gbl-theme-warning-surface);
    border: var(--gbl-border) dashed var(--gbl-theme-warning);
    padding-left: var(--gbl-space-1);
}
.field-terme-origine {
    padding: 0 var(--gbl-space-1);
    border-radius: var(--gbl-radius-small);
    background: var(--gbl-theme-warning);
    color: var(--gbl-theme-surface);
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-compact);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
/* L'accord est la décision positive : il porte la couleur d'un état valide,
   là où le retrait garde celle du danger. Les deux sont des cibles à part
   entière et reçoivent leur contour de focus de la règle générale. */
.field-terme-accord {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: var(--gbl-radius-small);
    background: transparent;
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-compact);
    cursor: pointer;
}
.field-terme-accord:hover { color: var(--gbl-theme-success); }

/* Sélections natives habillées. Le contrôle reste dans le DOM et porte
   réellement checked/disabled ; la forme visuelle ne remplace pas l'état. */
.selection-switch,
.selection-dot,
.selection-choice { position: relative; }

.selection-radio-group {
    border: 0;
    padding: 0;
    margin: 0;
    display: grid;
    gap: var(--gbl-space-3);
}
.selection-radio {
    min-height: var(--gbl-control-target-min);
    display: flex;
    align-items: center;
    gap: var(--gbl-space-2);
    cursor: pointer;
}
.selection-radio input {
    width: 20px;
    height: 20px;
    margin: 0;
    accent-color: var(--gbl-theme-action);
}

.selection-switch {
    display: inline-flex;
    align-items: center;
    gap: var(--gbl-space-3);
    min-height: var(--gbl-icon-target);
    cursor: pointer;
}
.selection-switch input,
.selection-dot input,
.selection-choice input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    clip-path: inset(50%);
}
.selection-switch-track {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    width: 44px;
    height: 24px;
    padding: 2px;
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: 999px;
    background: var(--gbl-theme-surface-raised);
    transition: background-color var(--gbl-duration-state) ease,
        border-color var(--gbl-duration-state) ease;
}
.selection-switch-track::after {
    content: "";
    display: block;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--gbl-theme-muted);
    transition: transform var(--gbl-duration-reveal) cubic-bezier(.2, .8, .2, 1),
        background-color var(--gbl-duration-state) ease;
}
.selection-switch input:checked + .selection-switch-track {
    background: var(--gbl-theme-action);
    border-color: var(--gbl-theme-action);
}
.selection-switch input:checked + .selection-switch-track::after {
    background: var(--gbl-theme-on-action);
    transform: translateX(20px);
}
.selection-switch input:focus-visible + .selection-switch-track,
.selection-dot input:focus-visible + .selection-dot-mark,
.selection-choice input:focus-visible + span {
    outline: var(--gbl-focus-width) solid var(--gbl-theme-focus);
    outline-offset: var(--gbl-focus-offset);
}

.selection-choice-group {
    position: relative;
    display: inline-grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding: var(--gbl-space-1);
    border: var(--gbl-border) solid var(--gbl-theme-line);
    border-radius: var(--gbl-radius);
    background: var(--gbl-theme-surface-raised);
}
.selection-choice-group::before {
    content: "";
    position: absolute;
    inset: var(--gbl-space-1) auto var(--gbl-space-1) var(--gbl-space-1);
    width: calc((100% - (2 * var(--gbl-space-1))) / 2);
    border-radius: var(--gbl-radius-small);
    background: var(--gbl-theme-surface);
    box-shadow: 0 1px 3px var(--gbl-theme-line);
    transition: transform var(--gbl-duration-reveal) cubic-bezier(.2, .8, .2, 1);
}
.selection-choice-group:has(.selection-choice:nth-child(2) input:checked)::before {
    transform: translateX(100%);
}
.selection-choice {
    z-index: 1;
    min-width: 8rem;
    cursor: pointer;
}
.selection-choice span {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: var(--gbl-control-height-compact);
    padding: 0 var(--gbl-space-3);
    border-radius: var(--gbl-radius-small);
    color: var(--gbl-theme-muted);
    transition: color var(--gbl-duration-state) ease,
        background-color var(--gbl-duration-reveal) ease;
}
.selection-choice input:checked + span {
    color: var(--gbl-theme-ink);
}

/* `check-consent` : une condition acceptée dans un formulaire — binaire, effet
   au SUBMIT et non à l'activation (controles-de-selection.md). D'où une case et
   non un interrupteur : l'interrupteur promet un effet immédiat qu'un
   formulaire ne tient pas. La case NATIVE est conservée — la remplacer par un
   carré dessiné coûterait l'état indéterminé, le clavier et la restitution
   correcte par les technologies d'assistance, pour un gain d'apparence.       */
.check-consent {
    display: flex;
    align-items: flex-start;
    gap: var(--gbl-space-3);
    min-height: var(--gbl-icon-target);
    cursor: pointer;
    font-size: var(--gbl-size-compact);
    line-height: var(--gbl-leading-compact);
    color: var(--gbl-theme-ink);
}
.check-consent > input[type="checkbox"] {
    flex: 0 0 auto;
    margin-block-start: 0.15em;
    accent-color: var(--gbl-theme-action);
    inline-size: 1.05em;
    block-size: 1.05em;
}

.selection-dot {
    display: inline-flex;
    align-items: center;
    gap: var(--gbl-space-2);
    min-height: var(--gbl-icon-target);
    cursor: pointer;
}
.selection-dot-mark {
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: 50%;
    background: var(--gbl-theme-surface);
    transition: border-color var(--gbl-duration-state) ease;
}
.selection-dot-mark::after {
    content: "";
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--gbl-theme-action);
    transform: scale(0);
    transition: transform var(--gbl-duration-reveal) cubic-bezier(.2, .8, .2, 1);
}
.selection-dot input:checked + .selection-dot-mark { border-color: var(--gbl-theme-action); }
.selection-dot input:checked + .selection-dot-mark::after { transform: scale(1); }

/* Selects augmentés : apparence commune du contrôle, de l'indicateur et des
   surfaces superposées. Les fichiers sgbl ne portent que leur placement. */
.custom-select-trigger,
.custom-tree-select-trigger {
    position: relative;
    width: 100%;
    min-height: var(--gbl-control-height);
    padding: 0 var(--gbl-space-8) 0 var(--gbl-space-3);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gbl-space-3);
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: var(--gbl-radius);
    background: var(--gbl-theme-surface);
    color: var(--gbl-theme-ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--gbl-duration-state) ease;
}
.custom-select-trigger:hover,
.custom-tree-select-trigger:hover { border-color: var(--gbl-theme-ink); }
.custom-select-trigger:focus,
.custom-tree-select-trigger:focus,
.custom-select-trigger[aria-expanded="true"],
.custom-tree-select-trigger[aria-expanded="true"] {
    border-color: var(--gbl-theme-action);
    outline: var(--gbl-focus-width) solid var(--gbl-theme-focus);
    outline-offset: var(--gbl-focus-offset);
}

/* Même chevron courbe que la référence Virædiès : deux bords arrondis et une
   rotation d'état, sans glyphe dépendant d'une police. */
.custom-select-trigger::after,
.custom-tree-select-trigger::after {
    position: absolute;
    content: "";
    top: 50%;
    right: var(--gbl-space-3);
    width: var(--gbl-select-chevron-size);
    height: var(--gbl-select-chevron-size);
    border: var(--gbl-select-chevron-stroke) solid transparent;
    border-color: currentColor currentColor transparent transparent;
    border-radius: 50%;
    transform: translateY(-70%) rotate(135deg);
    transition: transform var(--gbl-duration-reveal) ease;
}
.custom-select-trigger[aria-expanded="true"]::after,
.custom-tree-select-trigger[aria-expanded="true"]::after {
    transform: translateY(-110%) rotate(-45deg);
}

.custom-select-options,
.custom-tree-select-main,
.custom-tree-select-group {
    border: var(--gbl-border) solid var(--gbl-theme-line);
    border-radius: var(--gbl-radius);
    background: var(--gbl-theme-surface);
    box-shadow: var(--gbl-shadow-overlay);
}
.custom-select-options { padding: var(--gbl-space-1); }
.custom-select-option,
.custom-tree-select-item {
    width: 100%;
    min-height: var(--gbl-icon-target);
    padding: var(--gbl-space-2) var(--gbl-space-3);
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--gbl-space-1) var(--gbl-space-3);
    border: 0;
    border-radius: var(--gbl-radius-small);
    background: transparent;
    color: var(--gbl-theme-ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.custom-select-option:hover,
.custom-select-option[data-active="true"],
.custom-tree-select-item:hover,
.custom-tree-select-item[data-active="true"] { background: var(--gbl-theme-selected-surface); }
.custom-select-option[aria-selected="true"],
.custom-tree-select-item[aria-selected="true"] {
    box-shadow: inset 3px 0 0 var(--gbl-theme-action);
    font-weight: var(--gbl-weight-strong);
}
.custom-select-option:disabled {
    color: var(--gbl-theme-muted);
    cursor: not-allowed;
}
.custom-tree-select-item-title { grid-column: 1; }
.custom-tree-select-item-description {
    grid-column: 1;
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
}
.custom-tree-select-item-meta {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-caption);
}
.custom-tree-select-branch > .custom-tree-select-item-title { font-weight: var(--gbl-weight-strong); }
.custom-tree-select-branch-chevron { transition: transform var(--gbl-duration-reveal) ease; }
.custom-tree-select-branch[aria-expanded="true"] .custom-tree-select-branch-chevron { transform: rotate(90deg); }

/* Badge : qualifie un objet, jamais par la couleur seule — le libellé porte
   déjà le fait (conteneurs-et-donnees.md).                                 */
.data-badge {
    display: inline-block;
    padding: var(--gbl-space-1) var(--gbl-space-2);
    border-radius: 999px;
    border: var(--gbl-border) solid var(--gbl-theme-line);
    background: var(--gbl-theme-surface);
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
    font-weight: var(--gbl-weight-strong);
    white-space: nowrap;
}
.data-badge-success { color: var(--gbl-theme-success); background: var(--gbl-theme-success-surface); border-color: var(--gbl-theme-success); }
.data-badge-warning { color: var(--gbl-theme-warning); background: var(--gbl-theme-warning-surface); border-color: var(--gbl-theme-warning); }
.data-badge-danger { color: var(--gbl-theme-danger); background: var(--gbl-theme-danger-surface); border-color: var(--gbl-theme-danger); }

/* Qualification épistémique d'une VALEUR — variante `data-qualified-value`.
   Le badge qualifie un OBJET ; ici c'est la valeur elle-même qui porte son
   état de connaissance (« 1 relance, au moins ce nombre »). Décidée en même
   temps que ce code, cf. design/conteneurs-et-donnees.md.                  */
.data-qualified-value {
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-1);
}
.data-qualified-value > .value {
    font-variant-numeric: tabular-nums;
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
}
.data-qualified-value > .value-unknown { color: var(--gbl-theme-muted); font-style: italic; }
.data-qualified-value > .qualifier {
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
    color: var(--gbl-theme-muted);
}

/* =============================================================================
   B — TEXTES
   ========================================================================== */

body {
    margin: 0;
    background: var(--gbl-theme-canvas);
    color: var(--gbl-theme-ink);
    font-family: var(--gbl-font-ui);
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
    -webkit-font-smoothing: antialiased;
}

/* Le flou porte sur toute la page sous le header, pas seulement sur le
   rectangle translucide du menu. Le voile reste non interactif. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 10;
    pointer-events: none;
    opacity: 0;
    background: color-mix(in srgb, var(--gbl-theme-canvas) var(--gbl-dropdown-backdrop-tint), transparent);
    transition: opacity var(--gbl-duration-reveal) ease;
}
body[data-header-overlay="true"]::before {
    opacity: 1;
    -webkit-backdrop-filter: blur(var(--gbl-dropdown-backdrop-blur));
    backdrop-filter: blur(var(--gbl-dropdown-backdrop-blur));
}

.title-entry, .title-page, .title-section {
    font-family: var(--gbl-font-title);
    font-weight: var(--gbl-weight-title);
    margin: 0;
    text-wrap: balance;
}
.title-entry { font-size: var(--gbl-size-entry); line-height: var(--gbl-leading-entry); }
.title-page { font-size: var(--gbl-size-page); line-height: var(--gbl-leading-page); }
.title-section { font-size: var(--gbl-size-section); line-height: var(--gbl-leading-section); }

/* Prose : mesure bornée, alignée à gauche (composition-visuelle.md). */
.prose {
    max-width: var(--gbl-measure);
    text-align: left;
    margin: 0;
}
.text-muted { color: var(--gbl-theme-muted); }
.text-caption { font-size: var(--gbl-size-caption); line-height: var(--gbl-leading-caption); }
.text-compact { font-size: var(--gbl-size-compact); line-height: var(--gbl-leading-compact); }
.text-numeric { font-variant-numeric: tabular-nums; }

a { color: var(--gbl-theme-action); }
.link-standard,
.link-subtle {
    text-underline-offset: .18em;
    text-decoration-thickness: .08em;
    transition: color var(--gbl-duration-state) ease,
        text-decoration-thickness var(--gbl-duration-state) ease;
}
.link-standard { color: var(--gbl-theme-action); font-weight: var(--gbl-weight-strong); }
.link-subtle { color: var(--gbl-theme-muted); }
.link-standard:hover,
.link-subtle:hover { color: var(--gbl-theme-action-hover); text-decoration-thickness: .14em; }
.prose a { text-decoration: underline; }

/* Onglets de vue (navigation.md). CE SONT DES LIENS, pas un tablist : la vue
   est adressable par l'URL et son contenu vient du serveur, donc le modèle
   clavier natif du lien est le bon — un tablist ici piègerait des flèches sur
   des destinations réelles. L'onglet courant se marque par `aria-current`, la
   graisse ET un trait : la couleur seule ne porte jamais une position.
   Le dénombrement appartient à l'onglet — il dit ce que l'AUTRE vue contient,
   sans quoi il faudrait y aller pour l'apprendre.                          */
.nav-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gbl-space-1);
    border-bottom: 1px solid var(--gbl-theme-line);
}
.nav-tab {
    display: inline-flex;
    align-items: center;
    gap: var(--gbl-space-2);
    min-height: 40px;
    padding: 0 var(--gbl-space-3);
    color: var(--gbl-theme-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color var(--gbl-duration-state) ease,
        border-color var(--gbl-duration-state) ease;
}
.nav-tab:hover { color: var(--gbl-theme-action-hover); }
.nav-tab[aria-current="page"] {
    color: var(--gbl-theme-ink);
    font-weight: var(--gbl-weight-strong);
    border-bottom-color: var(--gbl-theme-action);
}
.nav-tab-count {
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
    font-variant-numeric: tabular-nums;
    color: var(--gbl-theme-muted);
}

/* Nom accessible sans rendu visuel — jamais employé pour cacher une
   information nécessaire (retours-etats.md).                               */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
}

/* =============================================================================
   C — SECONDAIRES (conteneurs, retours, états)
   ========================================================================== */

.container-section { display: flex; flex-direction: column; gap: var(--gbl-space-4); }

.container-panel {
    background: var(--gbl-theme-surface);
    border: var(--gbl-border) solid var(--gbl-theme-line);
    border-radius: var(--gbl-radius);
    padding: var(--gbl-space-6);
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-4);
}

/* Liste de ressources autonomes : l'ordre interne reste stable et l'action
   demeure dans la ligne qu'elle concerne (conteneurs-et-donnees.md). */
.data-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}
.data-list > li {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--gbl-space-4);
    padding: var(--gbl-space-4) 0;
    border-bottom: var(--gbl-border) solid var(--gbl-theme-line);
}
.data-list > li:last-child { border-bottom: 0; }

/* Le titre d'une ligne et ses actions servent toute liste qui les porte — les coordonnées, les
   pièces de la vitrine : ils vivent donc ici, non dans la feuille d'une page. Le titre porte sa
   taille, celle du texte standard : posé sur un `h3` — la vitrine, qui le titre —, il prendrait
   sinon la taille du navigateur, hors de l'échelle (fondations.md, § Typographie). */
.data-item-title {
    margin: 0;
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
    font-weight: var(--gbl-weight-strong);
    overflow-wrap: anywhere;
}

/* Les actions d'un objet vivent dans sa ligne, jamais remontées dans l'en-tête de page
   (structures-de-page.md). Sur espace étroit elles passent sous le contenu sans changer de nature. */
.data-item-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gbl-space-2);
    flex: 0 0 auto;
}

/* Le cadre d'un document média — l'aperçu que le titulaire juge, et la page d'une pièce de la
   vitrine, qui en sert le rendu figé : un seul cadre, parce que ce que le visiteur reçoit est, octet
   pour octet, ce que le titulaire regardait.

   IL A UNE GÉOMÉTRIE FIXE, et c'est une décision, pas un défaut de style. Un cadre qui se
   redimensionne au contenu ferait sauter la page à chaque relecture — et sans script, il ne le
   pourrait pas —, et la mise en page qu'on juge dépend précisément de la largeur où on la juge : une
   proportion de page A4 la rend comparable d'une relecture à l'autre. */
.media-apercu {
    display: block;
    /* La bordure entre dans la largeur : sans quoi le cadre dépasse sa colonne de deux pixels. */
    box-sizing: border-box;
    width: 100%;
    /* 1 / 1,414 — la proportion d'une page A4, qui est le support visé. */
    aspect-ratio: 1 / 1.414;
    max-height: 80vh;
    border: var(--gbl-border) solid var(--gbl-theme-control-boundary);
    border-radius: var(--gbl-radius);
    /* AUCUNE COULEUR N'EST POSÉE ICI. Le fond du cadre est celui du DOCUMENT : son papier est une
       variable qu'il déclare, et en peindre un second par-dessus ferait juger la mise en page sur
       une couleur que l'employeur ne verra jamais. */
    margin-block-start: var(--gbl-space-4);
}

/* Saisie numérique bornée — variante `field-number`. Les chiffres s'alignent
   en colonne (`tabular-nums`) pour qu'un rayon de 30 et un de 300 se comparent
   d'un coup d'oeil ; la largeur suit la borne, pas la largeur du formulaire,
   parce qu'un champ long promet une valeur longue (champs.md).            */
.field-number {
    inline-size: 100%;
    max-inline-size: 12rem;
    font-variant-numeric: tabular-nums;
}

/* Objets autonomes portant PLUSIEURS actions ou un aperçu riche — variante
   `data-card-list`. La différence avec `data-list` n'est pas décorative : une
   ligne sépare des objets d'un même ordre, une carte porte un objet qui a ses
   propres destinations. La carte entière n'est cliquable que si elle a UNE
   destination unique ; ici les ensembles de contexte en ont deux — compléter,
   consulter —, donc rien n'est cliquable au-delà des liens eux-mêmes
   (conteneurs-et-donnees.md).                                              */
.data-card-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--gbl-space-4);
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
}
.data-card-list > li {
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-3);
    padding: var(--gbl-space-5);
    border: var(--gbl-border) solid var(--gbl-theme-line);
    border-radius: var(--gbl-radius);
    background: var(--gbl-theme-surface);
}
/* Le titre et son état se lisent ensemble ; sur espace étroit l'état passe
   dessous sans changer de nature.                                          */
.data-card-list .card-heading {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gbl-space-2);
}
/* Les actions ferment la carte, après l'état : on lit ce qui est, puis ce
   qu'on peut faire. `margin-top: auto` les aligne d'une carte à l'autre quand
   leurs contenus n'ont pas la même hauteur.                                */
.data-card-list .card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gbl-space-4);
    margin-top: auto;
    padding-top: var(--gbl-space-1);
}
/* Une carte RATTACHÉE : la même variante, imbriquée dans sa carte mère. Elle
   fait partie de l'objet parent sans se fondre en lui — elle garde son titre,
   son état et sa destination. Une seule colonne, un retrait, une ligne de
   séparation : on lit « dans », pas « à côté ».                            */
.data-card-list .data-card-list {
    grid-template-columns: 1fr;
    gap: var(--gbl-space-3);
}
.data-card-list .data-card-list > li {
    padding: var(--gbl-space-4);
    border-width: 0 0 0 var(--gbl-border);
    border-radius: 0;
    background: transparent;
}

/* Série stable de libellés et valeurs : le couple reste lisible sans prendre
   l'apparence d'un tableau de comparaison. */
.data-description-list {
    margin: 0;
    display: grid;
    grid-template-columns: minmax(9rem, max-content) minmax(0, 1fr);
    gap: var(--gbl-space-3) var(--gbl-space-6);
}
.data-description-list dt {
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-compact);
    line-height: var(--gbl-leading-compact);
}
.data-description-list dd { margin: 0; overflow-wrap: anywhere; }

/* Tableau : la région défile, jamais la page (structures-de-page.md). */
.data-table-region { overflow-x: auto; }
.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--gbl-theme-surface);
    font-size: var(--gbl-size-compact);
    line-height: var(--gbl-leading-compact);
}
.data-table caption {
    text-align: left;
    padding-bottom: var(--gbl-space-2);
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
}
.data-table th, .data-table td {
    text-align: left;
    padding: var(--gbl-space-3);
    border-bottom: var(--gbl-border) solid var(--gbl-theme-line);
    vertical-align: top;
}
.data-table thead th {
    font-weight: var(--gbl-weight-strong);
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
    border-bottom-color: var(--gbl-theme-control-boundary);
}
.data-table tbody tr:last-child td { border-bottom: none; }

/* Retours — la couleur ne porte jamais seule le fait : chaque variante a un
   titre ou un intitulé explicite (retours-etats.md).                       */
.feedback-page-banner,
.feedback-submit-error,
.feedback-error-summary {
    border: var(--gbl-border) solid var(--gbl-theme-danger);
    background: var(--gbl-theme-danger-surface);
    color: var(--gbl-theme-ink);
    border-radius: var(--gbl-radius);
    padding: var(--gbl-space-4);
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-2);
}
.feedback-page-banner > .banner-title,
.feedback-submit-error > .banner-title,
.feedback-error-summary > .summary-title {
    font-weight: var(--gbl-weight-strong);
    color: var(--gbl-theme-danger);
}
.feedback-status { font-size: var(--gbl-size-compact); line-height: var(--gbl-leading-compact); color: var(--gbl-theme-muted); }
.feedback-field-error {
    font-size: var(--gbl-size-caption);
    line-height: var(--gbl-leading-caption);
    color: var(--gbl-theme-danger);
}
.feedback-empty {
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-3);
    align-items: flex-start;
    padding: var(--gbl-space-8) var(--gbl-space-4);
    color: var(--gbl-theme-muted);
}
/* Squelette : réserve la géométrie connue, sans simuler ni texte ni
   progression chiffrée (retours-etats.md).                                 */
.feedback-skeleton > .skeleton-line {
    height: var(--gbl-leading-body);
    margin-bottom: var(--gbl-space-3);
    border-radius: var(--gbl-radius-small);
    background: var(--gbl-theme-line);
}

/* Progression : une LISTE d'étapes nommées, non une barre chiffrée. Seules les
   étapes que le SERVEUR a confirmées portent l'état « franchie » — l'écran ne
   déduit rien d'une durée écoulée (retours-etats.md ; `etape-affichee-doit-
   etre-franchie`). L'étape courante est marquée, celles à venir restent en
   attente sans promettre de délai.                                          */
.feedback-progress {
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-2);
    list-style: none;
    margin: 0;
    padding: 0;
}
.feedback-progress > li {
    display: flex;
    align-items: baseline;
    gap: var(--gbl-space-3);
    color: var(--gbl-theme-muted);
}
/* La pastille est DÉCORATIVE : l'état est porté par le texte de l'étape et par
   `aria-current`, jamais par la seule couleur.                              */
.feedback-progress > li::before {
    content: "";
    flex: 0 0 auto;
    inline-size: var(--gbl-space-3);
    block-size: var(--gbl-space-3);
    border-radius: 50%;
    border: var(--gbl-border) solid var(--gbl-theme-line);
}
.feedback-progress > li[data-etat="franchie"] { color: var(--gbl-theme-ink); }
.feedback-progress > li[data-etat="franchie"]::before {
    background: var(--gbl-theme-action);
    border-color: var(--gbl-theme-action);
}
.feedback-progress > li[data-etat="courante"] {
    color: var(--gbl-theme-ink);
    font-weight: var(--gbl-weight-strong);
}
.feedback-progress > li[data-etat="courante"]::before { border-color: var(--gbl-theme-action); }

/* Une chaîne ÉLIMINATOIRE s'arrête au premier contrôle qui ferme : les suivants ne seront jamais
   joués. « En attente » affirmerait qu'ils viennent. Le mot est porté par le texte — la pastille
   barrée n'est qu'un rappel, et la couleur seule ne dirait rien à qui ne la voit pas.          */
.feedback-progress > li[data-etat="non-jouee"] { color: var(--gbl-theme-muted); }
.feedback-progress > li[data-etat="non-jouee"]::before {
    border-style: dashed;
    background: none;
}
.feedback-progress .progress-non-jouee {
    color: var(--gbl-theme-muted);
    font-size: var(--gbl-size-caption);
}

/* =============================================================================
   D — STRUCTURELS (layout, en-tête global, gabarits)
   ========================================================================== */

/* Famille `page-workflow` : les régions se suivent dans l'ordre imposé par
   `structures-de-page.md`. Une région déclarée obligatoire l'est par sa
   POSITION, pas par sa présence — celles qui n'ont rien à dire restent
   masquées, elles ne se remplissent pas de vide.                            */
.page-workflow {
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-6);
}
.page-workflow > .workflow-back { margin-bottom: calc(var(--gbl-space-4) * -1); }

/* Famille détail : retour, en-tête, contenu principal, contexte secondaire. */
.page-detail > nav { margin-bottom: calc(var(--gbl-space-4) * -1); }

.gbl-header {
    position: relative;
    z-index: 20;
    background: var(--gbl-theme-surface);
    border-bottom: var(--gbl-border) solid var(--gbl-theme-line);
}
.gbl-header-inner {
    max-width: var(--gbl-layout-wide);
    margin: 0 auto;
    padding: var(--gbl-space-3) var(--gbl-space-4);
    display: flex;
    align-items: center;
    gap: var(--gbl-space-6);
}
.gbl-header-brand { display: inline-flex; align-items: center; gap: var(--gbl-space-2); text-decoration: none; }
.gbl-header-brand img { height: 28px; width: auto; display: block; }
.gbl-header-menu { display: none; margin-left: auto; }
.gbl-header-nav { display: flex; align-items: center; gap: var(--gbl-space-2); }
.gbl-header-nav-trigger { border-radius: var(--gbl-radius-small); }
/* La section courante ou ouverte combine graisse, surface et marqueur
   structurel — jamais la couleur seule. */
.gbl-header-nav-trigger[data-current="true"],
.gbl-header-nav-trigger[aria-expanded="true"] {
    font-weight: var(--gbl-weight-strong);
    background: var(--gbl-theme-selected-surface);
    box-shadow: inset 0 -2px 0 0 var(--gbl-theme-action);
}

/* Un panneau unique change de contenu selon le déclencheur. Sa hauteur reste
   `auto` : une section courte ne garde pas la hauteur de la précédente. */
.gbl-navigation-panel {
    position: absolute;
    inset: 100% 0 auto;
    z-index: 10;
    overflow: hidden;
    background: var(--gbl-theme-surface);
    background: color-mix(in srgb, var(--gbl-theme-surface) var(--gbl-dropdown-surface-opacity), transparent);
    border-bottom: var(--gbl-border) solid var(--gbl-theme-line);
}
.gbl-navigation-panel-inner {
    max-width: var(--gbl-layout-wide);
    margin: 0 auto;
    padding: var(--gbl-space-6) var(--gbl-space-4) var(--gbl-space-8);
}
.gbl-navigation-title {
    margin: 0 0 var(--gbl-space-4);
    font-family: var(--gbl-font-title);
    font-size: var(--gbl-size-section);
    line-height: var(--gbl-leading-section);
    font-weight: var(--gbl-weight-title);
}
.gbl-navigation-links,
.gbl-navigation-groups {
    margin: 0;
    padding: 0;
    list-style: none;
}
.gbl-navigation-links { display: grid; gap: var(--gbl-space-2); }
.gbl-navigation-links a,
.gbl-profile-menu a {
    min-height: var(--gbl-icon-target);
    display: flex;
    align-items: center;
    padding-inline: var(--gbl-space-3);
    border-radius: var(--gbl-radius-small);
    color: var(--gbl-theme-ink);
    text-decoration: none;
    font-size: var(--gbl-size-compact);
    line-height: var(--gbl-leading-compact);
}
.gbl-navigation-links a:hover,
.gbl-profile-menu a:hover { background: var(--gbl-theme-selected-surface); }
.gbl-navigation-links a[aria-current="page"],
.gbl-profile-menu a[aria-current="page"] {
    font-weight: var(--gbl-weight-strong);
    box-shadow: inset 2px 0 0 var(--gbl-theme-action);
}
.gbl-navigation-groups {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--gbl-space-6);
}
.gbl-navigation-groups h3 {
    margin: 0 0 var(--gbl-space-2);
    padding-inline: var(--gbl-space-3);
    font-family: var(--gbl-font-title);
    font-size: var(--gbl-size-body);
    line-height: var(--gbl-leading-body);
    font-weight: var(--gbl-weight-strong);
}

/* Le profil est une navigation distincte du panneau métier. */
.gbl-header-profile { position: relative; margin-left: auto; }
.gbl-profile-trigger[data-current="true"],
.gbl-profile-trigger[aria-expanded="true"] { background: var(--gbl-theme-selected-surface); }
.gbl-profile-icon,
.gbl-profile-menu-icon {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    background: currentColor;
    -webkit-mask: center / contain no-repeat;
    mask: center / contain no-repeat;
}
.gbl-icon-profile {
    -webkit-mask-image: url("/assets/icons/circle-user-round.svg");
    mask-image: url("/assets/icons/circle-user-round.svg");
}
.gbl-icon-settings {
    -webkit-mask-image: url("/assets/icons/cog.svg");
    mask-image: url("/assets/icons/cog.svg");
}
.gbl-icon-context {
    -webkit-mask-image: url("/assets/icons/message-square-quote.svg");
    mask-image: url("/assets/icons/message-square-quote.svg");
}
.gbl-profile-menu {
    position: absolute;
    top: calc(100% + var(--gbl-space-2));
    right: 0;
    z-index: 20;
    width: 18rem;
    padding: var(--gbl-space-2);
    border: var(--gbl-border) solid var(--gbl-theme-line);
    border-radius: var(--gbl-radius);
    background: var(--gbl-theme-surface);
    background: color-mix(in srgb, var(--gbl-theme-surface) var(--gbl-dropdown-surface-opacity), transparent);
}
.gbl-profile-identity { margin: 0; padding: var(--gbl-space-2) var(--gbl-space-3); }
.gbl-profile-menu .divider-horizontal { margin-block: var(--gbl-space-2); }
.gbl-profile-menu a { gap: var(--gbl-space-3); }
.gbl-profile-action { width: 100%; justify-content: flex-start; }

/* Footer de plateforme : la zone haute réserve les futurs groupes de liens sans
   leur inventer de contenu. Le diviseur est la primitive fonctionnelle qui la
   sépare de la bande basse compacte. */
.gbl-footer {
    background: var(--gbl-theme-surface);
}
.gbl-footer-inner {
    max-width: var(--gbl-layout-wide);
    margin: 0 auto;
    padding-inline: var(--gbl-space-4);
}
.gbl-footer-links {
    min-height: var(--gbl-space-12);
    padding-block: var(--gbl-space-6);
}
.gbl-footer-group {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--gbl-space-2);
}
.gbl-footer-group h2 { margin: 0; }
.divider-horizontal {
    margin: 0;
    border: 0;
    border-top: var(--gbl-border) solid var(--gbl-theme-line);
}
.gbl-footer-meta {
    min-height: var(--gbl-control-height);
    padding-block: var(--gbl-space-2);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gbl-space-4);
}

.layout-narrow, .layout-standard, .layout-wide {
    margin: 0 auto;
    padding: var(--gbl-space-8) var(--gbl-space-4) var(--gbl-space-16);
    display: flex;
    flex-direction: column;
    gap: var(--gbl-space-6);
}
.layout-narrow { max-width: var(--gbl-layout-narrow); }
.layout-standard { max-width: var(--gbl-layout-standard); }
.layout-wide { max-width: var(--gbl-layout-wide); }

/* En-tête de page : l'action globale suit le titre et l'état ; sur espace
   étroit elle passe DESSOUS sans changer de variante fonctionnelle.        */
.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--gbl-space-4);
    flex-wrap: wrap;
}
.page-header > .page-header-actions { display: flex; gap: var(--gbl-space-2); }

/* Pied d'actions d'un formulaire : le principal est DERNIER au clavier, et
   `row-reverse` le place en fin de flux visuel (actions.md).               */
.form-footer {
    display: flex;
    flex-direction: row-reverse;
    justify-content: flex-start;
    gap: var(--gbl-space-3);
}
.form-footer-block { flex-direction: column-reverse; }
.form-footer-block > * { width: 100%; }

.filter-bar {
    display: flex;
    gap: var(--gbl-space-3);
    flex-wrap: wrap;
    align-items: flex-end;
}
.filter-bar > .field { flex: 1 1 12rem; }

@keyframes generator-breathe {
    0%, 100% { box-shadow: 0 0 0 0 var(--gbl-color-electric-bright); }
    50% { box-shadow: 0 0 0 3px var(--gbl-theme-selected-surface); }
}

@keyframes generator-sheen {
    from { transform: translateX(-120%); }
    to { transform: translateX(120%); }
}

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

/* Le seuil correspond au premier espace où marque, navigation et profil ne
   gardent plus leurs cibles minimales. Le profil reste indépendant. */
@media (max-width: 48rem) {
    .gbl-header-inner { gap: var(--gbl-space-3); flex-wrap: wrap; }
    .gbl-header-menu { display: inline-flex; }
    .gbl-header-profile { margin-left: 0; }
    .gbl-header-nav { flex: 1 0 100%; order: 4; align-items: stretch; }
    .gbl-header-nav-trigger { flex: 1 1 0; }
    .gbl-header-inner[data-menu-open="false"] .gbl-header-nav { display: none; }
    .gbl-navigation-panel-inner { padding-block: var(--gbl-space-4) var(--gbl-space-6); }
    .gbl-navigation-groups { grid-template-columns: 1fr; gap: var(--gbl-space-4); }
    .gbl-profile-menu { width: min(18rem, calc(100vw - (2 * var(--gbl-space-4)))); }
    .data-description-list { grid-template-columns: 1fr; gap: var(--gbl-space-1); }
    .data-description-list dd { margin-bottom: var(--gbl-space-3); }
}
