/* ==========================================================================
   Design System — Back-Office Tressol-Chabrier
   Refonte UI/UX 2026
   --------------------------------------------------------------------------
   - Polices auto-hébergées (RGPD) : Space Grotesk (titres) + Inter (corps)
   - Couleurs : navy logo #222A51, fond chaud #F5F5F3,
                orange #FE8D00 = ACTION, bleu #0260E7 = INFO / liens
   - Un seul rôle par couleur pour une hiérarchie d'action sans ambiguïté.
   ========================================================================== */

/* ------------------------------------------------------------------ */
/* 1. Polices auto-hébergées                                           */
/* ------------------------------------------------------------------ */

/* Plages Unicode :
   latin     -> U+0000-00FF (couvre la quasi-totalité du français)
   latin-ext -> caractères étendus (œ, Ÿ, accents rares) */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-400.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-ext-400.woff2') format('woff2');
  unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/inter-500.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/inter-ext-500.woff2') format('woff2');
  unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/inter-600.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/inter-ext-600.woff2') format('woff2');
  unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/fonts/inter-700.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/fonts/inter-ext-700.woff2') format('woff2');
  unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/space-grotesk-500.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/space-grotesk-ext-500.woff2') format('woff2');
  unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/space-grotesk-600.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/space-grotesk-ext-600.woff2') format('woff2');
  unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/fonts/space-grotesk-700.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/fonts/space-grotesk-ext-700.woff2') format('woff2');
  unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ------------------------------------------------------------------ */
/* 2. Tokens de design (variables)                                     */
/* ------------------------------------------------------------------ */
:root {
  /* --- Couleurs de marque --- */
  --c-navy:         #222A51;   /* navy du logo — couleur structurante */
  --c-navy-light:   #344153;   /* navy clair — surfaces secondaires */
  --c-navy-700:     #2c365f;
  --c-bg:           #F5F5F3;   /* fond chaud (repos visuel) */
  --c-white:        #FFFFFF;
  --c-card:         #FFFFFF;

  /* Action (orange) — un seul rôle : agir */
  --c-accent:       #FE8D00;
  --c-accent-hover: #E07D00;
  --c-accent-soft:  #FFF1DE;   /* fond teinté pour états/sélection */

  /* Information / liens (bleu) — jamais une action principale */
  --c-blue:         #0260E7;
  --c-blue-hover:   #0150C0;
  --c-blue-soft:    #E5EFFD;

  /* Texte */
  --c-text:         #1A1A2E;
  --c-text-soft:    #3a3a4d;
  --c-muted:        #6B7280;
  --c-on-navy:      #EEF1F8;   /* texte sur fond navy */
  --c-on-navy-soft: rgba(238,241,248,0.66);
  --c-heading:      #222A51;   /* couleur des titres (bascule en clair en dark) */
  --c-chip:         #ECECE8;   /* fond badge neutre */
  --c-sidebar-from: #222A51;   /* dégradé de la barre latérale */
  --c-sidebar-to:   #344153;

  /* Bordures & surfaces */
  --c-border:       #E2E2DE;
  --c-border-strong:#D2D2CC;

  /* États sémantiques */
  --c-success:      #16A34A;  --c-success-soft: #E6F4EA;
  --c-warning:      #D97706;  --c-warning-soft: #FCEFD9;
  --c-danger:       #DC2626;  --c-danger-soft:  #FBE7E7;

  /* --- Typographie --- */
  --font-display: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
  --font-body:    'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* Échelle typographique (ratio ~1.2 — Minor Third) */
  --fs-xs:   0.75rem;   /* 12px */
  --fs-sm:   0.8125rem; /* 13px */
  --fs-base: 0.9375rem; /* 15px — corps confortable en back-office */
  --fs-md:   1rem;      /* 16px */
  --fs-lg:   1.1875rem; /* 19px */
  --fs-xl:   1.5rem;    /* 24px */
  --fs-2xl:  1.875rem;  /* 30px */
  --fs-3xl:  2.375rem;  /* 38px */

  --lh-tight:  1.15;
  --lh-snug:   1.35;
  --lh-normal: 1.6;

  /* --- Espacements (base 4px) --- */
  --space-1: 0.25rem; --space-2: 0.5rem;  --space-3: 0.75rem; --space-4: 1rem;
  --space-5: 1.25rem; --space-6: 1.5rem;  --space-8: 2rem;    --space-10: 2.5rem;
  --space-12: 3rem;   --space-16: 4rem;

  /* --- Rayons --- */
  --radius-sm:  6px;
  --radius-md:  10px;
  --radius-lg:  16px;
  --radius-xl:  22px;
  --radius-full: 999px;

  /* --- Ombres (teintées navy pour la cohérence de marque) --- */
  --shadow-xs: 0 1px 2px rgba(34,42,81,0.06);
  --shadow-sm: 0 2px 6px rgba(34,42,81,0.07);
  --shadow-md: 0 8px 24px rgba(34,42,81,0.09);
  --shadow-lg: 0 18px 45px rgba(34,42,81,0.12);
  --shadow-xl: 0 30px 60px rgba(34,42,81,0.16);
  --shadow-accent: 0 10px 24px rgba(254,141,0,0.28);

  /* --- Transitions --- */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast: 0.15s var(--ease);
  --t-base: 0.25s var(--ease);

  /* --- Couches --- */
  --z-nav: 100; --z-dropdown: 200; --z-modal: 1000; --z-toast: 1100; --z-tooltip: 1200;
}

/* ------------------------------------------------------------------ */
/* 2bis. Thème sombre (Dark mode)                                      */
/* Activé via <html data-theme="dark"> — bascule par JS + localStorage */
/* ------------------------------------------------------------------ */
[data-theme="dark"] {
  --c-bg:           #14161C;
  --c-card:         #1C2029;
  --c-white:        #1C2029;
  --c-border:       #2A2F3A;
  --c-border-strong:#3A4150;
  --c-text:         #E7E9EE;
  --c-text-soft:    #C2C6D0;
  --c-muted:        #8B92A1;
  --c-heading:      #F2F4F8;
  --c-chip:         #2A2F3A;
  --c-navy-light:   #2C3344;
  --c-sidebar-from: #181B22;
  --c-sidebar-to:   #20252F;

  /* Bleu info/liens : éclairci pour rester lisible en texte sur fond sombre.
     Les fonds pleins bleu+texte blanc (.btn--info, .okta-btn) sont rétablis
     en bleu saturé plus bas pour conserver le contraste. */
  --c-blue:         #6AA8FF;
  --c-blue-hover:   #8FC0FF;

  /* Teintes d'état translucides (lisibles sur fond sombre) */
  --c-accent-soft:  rgba(254,141,0,0.16);
  --c-blue-soft:    rgba(2,96,231,0.20);
  --c-success-soft: rgba(22,163,74,0.18);
  --c-warning-soft: rgba(217,119,6,0.20);
  --c-danger-soft:  rgba(220,38,38,0.20);

  /* Ombres plus profondes */
  --shadow-xs: 0 1px 2px rgba(0,0,0,0.40);
  --shadow-sm: 0 2px 6px rgba(0,0,0,0.45);
  --shadow-md: 0 8px 24px rgba(0,0,0,0.50);
  --shadow-lg: 0 18px 45px rgba(0,0,0,0.55);
  --shadow-xl: 0 30px 60px rgba(0,0,0,0.62);
}
[data-theme="dark"] body {
  background-image:
    radial-gradient(900px circle at 12% -5%, rgba(255,255,255,0.03), transparent 45%),
    radial-gradient(700px circle at 100% 0%, rgba(254,141,0,0.07), transparent 40%);
}
/* Lisibilité des badges & alertes en sombre */
[data-theme="dark"] .badge--accent  { color: #FFB14D; }
[data-theme="dark"] .badge--info    { color: #6AA8FF; }
[data-theme="dark"] .badge--success { color: #4ADE80; }
[data-theme="dark"] .badge--warning { color: #FBBF24; }
[data-theme="dark"] .badge--danger  { color: #F87171; }
[data-theme="dark"] .alert          { color: var(--c-text); }

/* Fonds pleins bleus : on garde un bleu saturé (le token --c-blue éclairci
   servirait de fond illisible sous le texte blanc). */
[data-theme="dark"] .btn--info        { --btn-bg: #2D6FE0; }
[data-theme="dark"] .btn--info:hover  { --btn-bg: #1F5FD4; }
/* Bannières & lignes de diff : le texte foncé codé en dur devient clair. */
[data-theme="dark"] .banner--info     { color: var(--c-text); }
[data-theme="dark"] .banner--success  { color: #4ADE80; }
[data-theme="dark"] .banner--warn     { color: #FBBF24; }
[data-theme="dark"] .banner--danger   { color: #F87171; }
[data-theme="dark"] .diff__line--add  { color: #4ADE80; }
[data-theme="dark"] .diff__line--del  { color: #F87171; text-decoration-color: rgba(248,113,113,0.5); }
/* Plaque (variante hybride) : texte/bord navy → lisibles sur carte sombre. */
[data-theme="dark"] .plate            { color: var(--c-heading); border-color: var(--c-border-strong); }

/* Bouton-icône circulaire — primitive partagée (toolbar, theme-toggle, etc.).
   Défini ici (DS) pour être disponible sur toute page, y compris celles
   qui ne chargent pas app-shell.css (login, reset-password…). */
.icon-btn {
  width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--c-border);
  background: var(--c-card); color: var(--c-text-soft); display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; position: relative; transition: all var(--t-fast);
}
.icon-btn:hover { border-color: var(--c-border-strong); color: var(--c-heading); }
.icon-btn svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.icon-btn .dot { position: absolute; top: 8px; right: 9px; width: 8px; height: 8px; border-radius: 50%; background: var(--c-accent); border: 2px solid var(--c-card); }
/* Variante compacte, pour une action posée dans une barre au milieu de champs
   de 42 px plutôt que dans la topbar. */
.icon-btn--sm { width: 34px; height: 34px; }
.icon-btn--sm svg { width: 16px; height: 16px; }

/* Variante « guide » : bouton à libellé et contour accent, pensé pour ressortir
   du groupe d'icônes neutres de la topbar (l'entrée vers l'aide doit se voir).
   Conserve la hauteur 40px de .icon-btn pour rester aligné. */
.icon-btn--guide {
  width: auto; border-radius: var(--radius-full);
  gap: 7px; padding: 0 15px 0 11px;
  border-color: var(--c-accent); color: var(--c-accent-hover);
  font-weight: 600; font-size: var(--fs-sm); white-space: nowrap;
}
.icon-btn--guide:hover {
  border-color: var(--c-accent); color: var(--c-accent-hover);
  background: var(--c-accent-soft);
}
.icon-btn--guide:focus-visible { box-shadow: 0 0 0 3px var(--c-accent-soft); outline: none; }
.icon-btn--guide .icon-btn__label { line-height: 1; }
/* Sur petite largeur : on retombe sur une pastille icône seule pour préserver
   la place dans la topbar. */
@media (max-width: 640px) {
  .icon-btn--guide { width: 40px; padding: 0; border-radius: 50%; }
  .icon-btn--guide .icon-btn__label { display: none; }
}

/* Bouton de bascule de thème : lune en clair, soleil en sombre.
   Défini ici (DS partagé) pour fonctionner sur toute page, y compris
   celles qui ne chargent pas app-shell.css (login, reset-password…). */
.theme-toggle .sun  { display: none; }
.theme-toggle .moon { display: block; }
[data-theme="dark"] .theme-toggle .sun  { display: block; }
[data-theme="dark"] .theme-toggle .moon { display: none; }

/* Transition douce lors de la bascule de thème */
body, .card, .input, .select, .textarea, .table-wrap, .badge, .alert {
  transition: background-color var(--t-base), border-color var(--t-base), color var(--t-base);
}

/* ------------------------------------------------------------------ */
/* 3. Reset & base                                                     */
/* ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

/* overflow-x: hidden ici (racine), pas sur un conteneur interne : les infobulles ::after
 * ([data-tooltip], cf. plus bas) restent volontairement non clippées par leurs ancêtres pour
 * s'afficher entières au survol, mais gonflent le scrollWidth du document quand un ⓘ proche
 * d'un bord les positionne partiellement hors viewport - invisibles (opacity:0 au repos) mais
 * provoquant quand même une scrollbar horizontale fantôme sur toute la page. Le clip au niveau
 * html ne rogne que la portion déjà hors écran, jamais une infobulle visible au survol. */
html { -webkit-text-size-adjust: 100%; overflow-x: hidden; }

body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--c-text);
  background-color: var(--c-bg);
  /* Atmosphère : halos diffus très légers, navy + orange */
  background-image:
    radial-gradient(900px circle at 12% -5%, rgba(34,42,81,0.05), transparent 45%),
    radial-gradient(700px circle at 100% 0%, rgba(254,141,0,0.06), transparent 40%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-tight);
  color: var(--c-heading);
  letter-spacing: -0.015em;
}
h1 { font-size: var(--fs-3xl); font-weight: 700; }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); }
h4 { font-size: var(--fs-lg); }

p { line-height: var(--lh-normal); }

a { color: var(--c-blue); text-decoration: none; transition: color var(--t-fast); }
a:hover { color: var(--c-blue-hover); text-decoration: underline; }
/* Les ancres stylées en bouton ne doivent pas hériter du bleu souligné de
   a:hover (spécificité (0,1,1) > .btn) : on rétablit le rendu bouton. */
a.btn:hover { color: var(--btn-fg); text-decoration: none; }

img, svg { display: block; max-width: 100%; }

/* Cible de focus accessible et homogène partout */
:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

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

/* Tableaux : chiffres alignés (essentiel back-office) */
.tabular, td.num, th.num { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ */
/* 4. Utilitaires de mise en page                                      */
/* ------------------------------------------------------------------ */
.ds-container { max-width: 1240px; margin: 0 auto; padding: 0 var(--space-6); }
.ds-stack > * + * { margin-top: var(--space-4); }
.ds-muted { color: var(--c-muted); }
.ds-eyebrow {
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-accent);
}

/* ------------------------------------------------------------------ */
/* 5. Boutons                                                          */
/* ------------------------------------------------------------------ */
.btn {
  --btn-bg: var(--c-navy);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: 1;
  padding: 0.7rem 1.3rem;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  white-space: nowrap;
  transition: transform var(--t-fast), box-shadow var(--t-base), background var(--t-base), border-color var(--t-base);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
/* Le `display: inline-flex` ci-dessus bat le `display: none` que le navigateur
   donne à [hidden] : sans cette reprise, `bouton.hidden = true` ne masque rien.
   Même piège que .badge, .field, .toolbar, .filter-accordion et .active-chips.
   Repéré sur « Réinitialiser » de WEPO, qui restait affiché à côté du bandeau
   de vue qui portait déjà « Quitter la vue ». */
.btn[hidden] { display: none; }

/* PRIMAIRE = action = orange (le seul vrai bouton "agir") */
.btn--primary { --btn-bg: var(--c-accent); --btn-fg: #fff; box-shadow: var(--shadow-accent); }
.btn--primary:hover { --btn-bg: var(--c-accent-hover); box-shadow: 0 14px 30px rgba(254,141,0,0.34); }

/* SECONDAIRE = contour neutre */
.btn--secondary {
  --btn-bg: transparent; --btn-fg: var(--c-heading);
  border-color: var(--c-border-strong);
}
.btn--secondary:hover { --btn-bg: var(--c-navy); --btn-fg: #fff; border-color: var(--c-navy); }

/* GHOST = discret */
.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--c-text-soft);
  border-color: var(--c-border-strong);
}
.btn--ghost:hover { --btn-bg: var(--c-card); box-shadow: var(--shadow-sm); }

/* LIEN/INFO = bleu (actions informatives, jamais le CTA principal) */
.btn--info { --btn-bg: var(--c-blue); --btn-fg: #fff; }
.btn--info:hover { --btn-bg: var(--c-blue-hover); box-shadow: 0 10px 24px rgba(2,96,231,0.25); }

/* DANGER */
.btn--danger { --btn-bg: var(--c-danger); --btn-fg: #fff; }
.btn--danger:hover { --btn-bg: #b91c1c; }

/* Tailles */
.btn--sm { padding: 0.45rem 0.9rem; font-size: var(--fs-sm); }
.btn--lg { padding: 0.9rem 1.8rem; font-size: var(--fs-md); }
.btn--block { width: 100%; }

/* ------------------------------------------------------------------ */
/* 6. Cartes                                                           */
/* ------------------------------------------------------------------ */
.card {
  background: var(--c-card);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.card--raised { box-shadow: var(--shadow-md); }
.card--interactive { transition: transform var(--t-base), box-shadow var(--t-base), border-color var(--t-base); cursor: pointer; }
.card--interactive:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--c-border-strong); }
.card__title { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--c-heading); }

/* ------------------------------------------------------------------ */
/* 7. Badges & tags                                                    */
/* ------------------------------------------------------------------ */
.badge {
  display: inline-flex; align-items: center; gap: 0.35em;
  padding: 0.25rem 0.7rem;
  font-size: var(--fs-xs); font-weight: 600;
  border-radius: var(--radius-full);
  background: var(--c-navy); color: #fff;
  letter-spacing: 0.01em;
}
/* Même piège que .field, .toolbar et .filter-accordion : le display ci-dessus
   écraserait le display:none de l'attribut « hidden », et un badge de comptage
   se masque justement quand il tombe à zéro. */
.badge[hidden] { display: none; }
.badge--accent  { background: var(--c-accent-soft);  color: var(--c-accent-hover); }
.badge--info    { background: var(--c-blue-soft);    color: var(--c-blue-hover); }
.badge--success { background: var(--c-success-soft); color: var(--c-success); }
.badge--warning { background: var(--c-warning-soft); color: var(--c-warning); }
.badge--danger  { background: var(--c-danger-soft);  color: var(--c-danger); }
.badge--neutral { background: var(--c-chip);         color: var(--c-text-soft); }

/* ------------------------------------------------------------------ */
/* 8. Formulaires                                                      */
/* ------------------------------------------------------------------ */
.field { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-4); }
/* Le display:flex ci-dessus écraserait le display:none de l'attribut « hidden » :
   même piège que .toolbar et .filter-accordion, et les formulaires masquent
   volontiers un champ selon le contexte. */
.field[hidden] { display: none; }
.field label { font-size: var(--fs-sm); font-weight: 600; color: var(--c-heading); }
.input, .select, .textarea {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  color: var(--c-text);
  width: 100%;
  padding: 0.65rem 0.85rem;
  background: var(--c-card);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-md);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.input::placeholder, .textarea::placeholder { color: var(--c-muted); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px rgba(254,141,0,0.16);
}
.field__hint { font-size: var(--fs-xs); color: var(--c-muted); }
.field--error .input { border-color: var(--c-danger); }
.field--error .field__hint { color: var(--c-danger); }
/* Marqueur d'obligation. Il double `required` sur le champ, qui porte la
   sémantique : l'astérisque est donc `aria-hidden`, un lecteur d'écran
   annonçant déjà « requis » sans avoir besoin d'entendre « étoile ». */
.field__label .req { color: var(--c-danger); margin-left: 2px; font-weight: 400; }

/* ─── Select filtrable (.combo — piloté par TCSelectSearch) ────────────
   Le <select> d'origine reste dans le DOM (source de vérité) mais masqué :
   l'utilisateur voit un champ de recherche + un panneau de résultats.
   À réserver aux listes longues (référentiels), un <select> natif restant
   préférable en dessous d'une vingtaine d'options. */
.combo { position: relative; }
/* Le <select> natif reste dans le DOM (il est la source de vérité) mais ne doit
   plus se voir. Il n'est pas `display: none` pour autant : masqué ainsi, un
   select `required` cesse d'être focusable et `reportValidity()` échoue alors
   en silence — le formulaire refuse de partir sans qu'aucun message
   n'apparaisse. En calque transparent posé sur le champ, il reste focusable :
   la bulle de validation du navigateur s'ancre donc pile sur le champ visible.
   `pointer-events: none` laisse tous les clics à l'input. */
.combo__native {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  margin: 0; padding: 0; border: 0; opacity: 0; pointer-events: none;
}
.combo__control { position: relative; display: flex; align-items: stretch; }
.combo__input { padding-left: 2.3rem; padding-right: 2.2rem; text-overflow: ellipsis; cursor: pointer; }
.combo.is-open .combo__input { cursor: text; border-color: var(--c-accent); box-shadow: 0 0 0 3px rgba(254,141,0,0.16); }
.combo__ico { position: absolute; top: 50%; left: 11px; transform: translateY(-50%); width: 16px; height: 16px; color: var(--c-muted); pointer-events: none; }
.combo__arrow { position: absolute; top: 50%; right: 4px; transform: translateY(-50%); display: grid; place-items: center; width: 26px; height: 26px; padding: 0; background: none; border: none; border-radius: 6px; color: var(--c-muted); cursor: pointer; }
.combo__arrow svg { width: 16px; height: 16px; transition: transform var(--t-fast); }
.combo.is-open .combo__arrow svg { transform: rotate(180deg); }
/* Bouton d'effacement : la saisie n'étant plus présélectionnée au clic (on
   peut corriger « KIA CARCA » en « KIA PERPI » sans tout retaper), il faut une
   action explicite pour repartir d'un champ vide. */
.combo__clear { position: absolute; top: 50%; right: 30px; transform: translateY(-50%); display: none; place-items: center; width: 22px; height: 22px; padding: 0; background: none; border: none; border-radius: 6px; color: var(--c-muted); cursor: pointer; }
.combo__clear svg { width: 14px; height: 14px; }
.combo.is-open.has-value .combo__clear { display: grid; }
.combo.is-open.has-value .combo__input { padding-right: 3.4rem; }
.combo__clear:hover, .combo__arrow:hover { color: var(--c-heading); background: var(--c-bg); }

/* Panneau en `position: fixed` — comme .popover, et pour la même raison : en
   `absolute` il resterait prisonnier du contexte d'empilement créé par un
   ancêtre transformé (une .card.ds-reveal, un .modal…), et le bloc suivant du
   DOM passerait par-dessus quel que soit son z-index. Le placement (left/top/
   width, bascule vers le haut) est calculé par TCSelectSearch.place(). */
.combo__panel {
  position: fixed; z-index: calc(var(--z-modal) + 1);
  display: flex; flex-direction: column;
  background: var(--c-card); border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg); overflow: hidden;
}
/* display:flex écraserait le display:none de l'attribut [hidden] — piège connu. */
.combo__panel[hidden] { display: none; }
.combo__count { flex: 0 0 auto; padding: 7px 12px; border-bottom: 1px solid var(--c-border); background: var(--c-bg); font-size: var(--fs-xs); font-weight: 600; color: var(--c-muted); }
.combo__list { position: relative; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 4px; overscroll-behavior: contain; }
.combo__group { padding: 8px 10px 4px; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--c-muted); }
.combo__opt { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 6px; font-size: var(--fs-sm); color: var(--c-text); cursor: pointer; }
.combo__opt-label { flex: 1; min-width: 0; }
.combo__opt.is-active { background: var(--c-chip); color: var(--c-heading); }
.combo__opt[aria-selected="true"] { font-weight: 600; color: var(--c-heading); }
.combo__opt.is-disabled { color: var(--c-muted); cursor: not-allowed; }
.combo__check { width: 15px; height: 15px; flex-shrink: 0; color: var(--c-accent); }
/* Remise à zéro : proposée en tête de liste seulement si une valeur est choisie. */
.combo__opt--reset { color: var(--c-muted); border-bottom: 1px solid var(--c-border); border-radius: 6px 6px 0 0; margin-bottom: 3px; }
.combo__opt--reset svg { width: 13px; height: 13px; flex-shrink: 0; }
/* Action épinglée (« Ajouter une marque… ») : un geste, pas une valeur — donc
   l'accent et un trait de séparation, pour ne pas se lire comme une option. */
.combo__opt--action { color: var(--c-accent-hover); font-weight: 600; border-bottom: 1px solid var(--c-border); border-radius: 6px 6px 0 0; margin-bottom: 3px; }
.combo__opt--action:hover, .combo__opt--action.is-active { background: var(--c-accent-soft); }
.combo__opt--action svg { width: 14px; height: 14px; flex-shrink: 0; }
[data-theme="dark"] .combo__opt--action { color: #FFB14D; }
.combo__opt mark { background: var(--c-accent-soft); color: var(--c-accent-hover); border-radius: 3px; padding: 0 1px; font-weight: 700; }
.combo__group mark { background: none; color: var(--c-accent-hover); }
.combo__empty { padding: 18px 12px; text-align: center; font-size: var(--fs-sm); color: var(--c-muted); }
/* Sombre : l'orange « hover » (#E07D00) manque de contraste sur fond foncé —
   même correctif que les badges accent. */
[data-theme="dark"] .combo__opt mark,
[data-theme="dark"] .combo__group mark { color: #FFB14D; }

/* ------------------------------------------------------------------ */
/* 9. Tableaux de données                                              */
/* ------------------------------------------------------------------ */
.table-wrap { overflow-x: auto; border: 1px solid var(--c-border); border-radius: var(--radius-lg); background: var(--c-card); box-shadow: var(--shadow-sm); }
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table thead th {
  text-align: left;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--c-on-navy);
  background: var(--c-navy);
  padding: 0.85rem 1rem;
  white-space: nowrap;
}
.table tbody td { padding: 0.8rem 1rem; border-bottom: 1px solid var(--c-border); color: var(--c-text-soft); }
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr { transition: background var(--t-fast); }
.table tbody tr:hover { background: var(--c-accent-soft); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ */
/* 10. Alertes                                                         */
/* ------------------------------------------------------------------ */
.alert {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  border-left: 4px solid;
  font-size: var(--fs-sm);
}
.alert--info    { background: var(--c-blue-soft);    border-color: var(--c-blue);    color: var(--c-navy); }
.alert--success { background: var(--c-success-soft); border-color: var(--c-success); color: #14532d; }
.alert--warning { background: var(--c-warning-soft); border-color: var(--c-warning); color: #7c2d12; }
.alert--danger  { background: var(--c-danger-soft);  border-color: var(--c-danger);  color: #7f1d1d; }

/* ------------------------------------------------------------------ */
/* 11. Animations d'apparition (chargement de page)                    */
/* ------------------------------------------------------------------ */
/* Animation d'apparition — IMPORTANT :
   on n'écrit PAS `transform: translateY(0)` dans la frame `to`. Sans transform résiduel,
   l'élément ne crée pas de stacking context ni de containing block après l'animation
   — ce qui évite que `position: fixed` (modal) et les z-index élevés (tooltip) soient
   bridés à l'intérieur de la section. */
@keyframes ds-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; }
}
.ds-reveal { opacity: 0; animation: ds-rise 0.6s var(--ease) forwards; }
.ds-reveal[data-delay="1"] { animation-delay: 0.06s; }
.ds-reveal[data-delay="2"] { animation-delay: 0.12s; }
.ds-reveal[data-delay="3"] { animation-delay: 0.18s; }
.ds-reveal[data-delay="4"] { animation-delay: 0.24s; }
.ds-reveal[data-delay="5"] { animation-delay: 0.30s; }

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

/* ============================================================== */
/* Composants partagés — issus des maquettes (toast, popover, ...) */
/* ============================================================== */

/* ─── Toast (notifications) ─────────────────────────────────────── */
.toast-stack { position: fixed; bottom: 20px; right: 20px; z-index: calc(var(--z-modal) + 2); display: flex; flex-direction: column; gap: 8px; pointer-events: none; max-width: calc(100vw - 40px); }
.toast { background: var(--c-card); border: 1px solid var(--c-border); border-left: 4px solid var(--c-success); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: 12px 16px; min-width: 240px; max-width: 360px; font-size: var(--fs-sm); color: var(--c-text); display: flex; align-items: center; gap: 10px; opacity: 0; transform: translateX(20px); transition: opacity var(--t-base), transform var(--t-base); pointer-events: auto; }
.toast.show { opacity: 1; transform: translateX(0); }
.toast--info    { border-left-color: var(--c-blue); }
.toast--warn    { border-left-color: var(--c-warning, #f59e0b); }
.toast--danger  { border-left-color: var(--c-danger); }
.toast > svg { width: 18px; height: 18px; stroke: var(--c-success); stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.toast--info > svg   { stroke: var(--c-blue); }
.toast--warn > svg   { stroke: var(--c-warning, #f59e0b); }
.toast--danger > svg { stroke: var(--c-danger); }
/* La croix de fermeture, indispensable depuis qu'un message d'echec n'a plus de
   minuterie : sans elle, la pile masquerait le bas de l'ecran. La couleur ne
   suit pas celle du toast — `.toast > svg` ne vise que l'icone de tete, et une
   croix rouge se lirait comme un second signal. */
.toast__close { margin-left: auto; flex-shrink: 0; background: none; border: none; cursor: pointer; color: var(--c-muted); width: 22px; height: 22px; border-radius: var(--radius-sm); display: grid; place-items: center; padding: 0; transition: background var(--t-fast), color var(--t-fast); }
.toast__close:hover { background: var(--c-chip); color: var(--c-heading); }
.toast__close svg { width: 12px; height: 12px; stroke: currentColor; fill: none; }
@media (max-width: 480px) {
  .toast-stack { bottom: 12px; right: 12px; left: 12px; max-width: none; }
  .toast { min-width: 0; max-width: none; }
}

/* ─── Popover (menus contextuels ⋯) ─────────────────────────────── */
.popover { position: fixed; z-index: var(--z-modal); background: var(--c-card); border: 1px solid var(--c-border); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); min-width: 210px; padding: 4px; opacity: 0; transform: translateY(-4px); transition: opacity var(--t-fast), transform var(--t-fast); pointer-events: none; }
.popover.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.popover button { display: flex; align-items: center; gap: 10px; width: 100%; background: none; border: none; padding: 8px 12px; border-radius: 6px; cursor: pointer; text-align: left; font: inherit; color: var(--c-text); font-size: var(--fs-sm); }
.popover button:hover, .popover button:focus-visible { background: var(--c-bg); outline: none; }
.popover button.danger { color: var(--c-danger); }
.popover button.danger:hover, .popover button.danger:focus-visible { background: color-mix(in srgb, var(--c-danger) 10%, transparent); }
.popover button svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.popover hr { border: none; border-top: 1px solid var(--c-border); margin: 4px 0; }

/* Bouton ⋯ déclenchant un popover */
.menu-btn { background: none; border: none; cursor: pointer; color: var(--c-muted); width: 28px; height: 28px; border-radius: 7px; display: grid; place-items: center; flex-shrink: 0; transition: background var(--t-fast), color var(--t-fast); }
.menu-btn:hover, .menu-btn[aria-expanded="true"] { background: var(--c-chip); color: var(--c-heading); }
.menu-btn svg { width: 16px; height: 16px; fill: currentColor; }

/* ─── Filter chips (filtres actifs retirables) ──────────────────── */
.filter-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--c-accent-soft); color: var(--c-heading); border: 1px solid var(--c-accent); border-radius: var(--radius-full); padding: 3px 4px 3px 10px; font-size: var(--fs-xs); font-weight: 600; }
.filter-chip > span { line-height: 1; }
.filter-chip button { background: none; border: none; cursor: pointer; color: inherit; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; padding: 0; transition: background var(--t-fast); }
.filter-chip button:hover { background: rgba(0,0,0,0.08); }
.filter-chip button svg { width: 11px; height: 11px; stroke: currentColor; stroke-width: 2.5; fill: none; stroke-linecap: round; }
.filter-chip--info    { background: var(--c-blue-soft); border-color: var(--c-blue); }
.filter-chip--neutral { background: var(--c-chip); border-color: var(--c-border); color: var(--c-text-soft); }

/* ─── Skeleton (chargement) ─────────────────────────────────────── */
.skeleton { background: linear-gradient(90deg, var(--c-chip) 0%, color-mix(in srgb, var(--c-chip) 50%, var(--c-card)) 50%, var(--c-chip) 100%); background-size: 200% 100%; animation: ds-skeleton 1.4s linear infinite; border-radius: var(--radius-sm); display: block; }
.skeleton--line { height: 12px; }
.skeleton--title { height: 22px; width: 60%; }
.skeleton--block { height: 80px; }
@keyframes ds-skeleton { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

/* ─── États vides (empty states) ────────────────────────────────── */
.empty-state { text-align: center; padding: var(--space-10) var(--space-6); }
.empty-state .empty-ico { width: 54px; height: 54px; border-radius: 14px; background: var(--c-chip); color: var(--c-muted); display: grid; place-items: center; margin: 0 auto var(--space-4); }
.empty-state .empty-ico svg { width: 26px; height: 26px; stroke: currentColor; stroke-width: 1.6; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.empty-state h4 { font-family: var(--font-display); color: var(--c-heading); margin-bottom: var(--space-2); }
.empty-state p { color: var(--c-muted); font-size: var(--fs-sm); margin-bottom: var(--space-5); max-width: 42ch; margin-left: auto; margin-right: auto; }

/* ─── Visually hidden (accessibilité) ───────────────────────────── */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* ─── Skip-link (« Aller au contenu ») — 1er élément focusable, masqué
   jusqu'au focus clavier. Injecté globalement par app-shell.js. ─────── */
.skip-link {
  position: fixed; top: var(--space-2); left: var(--space-2);
  z-index: calc(var(--z-modal, 1000) + 100);
  background: var(--c-accent); color: #fff;
  padding: 0.6rem 1rem; border-radius: var(--radius-md);
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-sm);
  text-decoration: none; box-shadow: var(--shadow-lg);
  transform: translateY(-150%); transition: transform var(--t-fast);
}
.skip-link:focus { transform: translateY(0); outline: 2px solid #fff; outline-offset: 2px; }

/* ─── Bouton en chargement : masque le libellé, affiche un spinner.
   Utiliser via le helper global setBtnLoading(btn, true/false). ─────── */
@keyframes tc-spin { to { transform: rotate(360deg); } }
.btn.is-loading { color: transparent !important; pointer-events: none; position: relative; }
.btn.is-loading::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 1.05em; height: 1.05em; margin: -0.525em 0 0 -0.525em;
  border: 2px solid var(--btn-fg); border-right-color: transparent; border-radius: 50%;
  animation: tc-spin 0.6s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .btn.is-loading::after { animation-duration: 1.4s; } }

/* ─── Préférences d'accessibilité (panneau TCA11y) ─────────────────────
   Pilotées par des attributs sur <html> : data-fontscale / data-contrast /
   data-motion (posés tôt par theme.js). ─────────────────────────────── */

/* Taille du texte : on agit sur la racine (rem) → toute l'UI suit. */
html[data-fontscale="large"]  { font-size: 18px; }
html[data-fontscale="xlarge"] { font-size: 20px; }

/* Contraste élevé : bordures et textes secondaires renforcés. */
[data-contrast="high"] {
  --c-border: #6b6b75; --c-border-strong: #2a2a32;
  --c-muted: #45454f; --c-text-soft: var(--c-text);
}
[data-contrast="high"][data-theme="dark"] {
  --c-border: #9aa3b4; --c-border-strong: #c2cad8;
  --c-muted: #c8d0dc; --c-text-soft: var(--c-text);
}
[data-contrast="high"] :focus-visible { outline-width: 3px; }
[data-contrast="high"] .table tbody td { border-bottom-color: var(--c-border); }

/* Réduction des animations (équivalent manuel de prefers-reduced-motion). */
[data-motion="reduce"] *, [data-motion="reduce"] *::before, [data-motion="reduce"] *::after {
  animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important; scroll-behavior: auto !important;
}

/* Panneau Accessibilité */
.a11y__scrim {
  position: fixed; inset: 0; z-index: calc(var(--z-modal, 1000) + 50);
  background: rgba(15, 23, 42, 0.5);
  display: flex; align-items: center; justify-content: center; padding: var(--space-4);
  opacity: 0; transition: opacity var(--t-base);
}
.a11y__scrim.open { opacity: 1; }
.a11y {
  width: 100%; max-width: 420px;
  background: var(--c-card); color: var(--c-text);
  border: 1px solid var(--c-border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl); overflow: hidden;
  transform: translateY(10px) scale(0.98); transition: transform var(--t-base);
}
.a11y__scrim.open .a11y { transform: none; }
.a11y__head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--c-border); }
.a11y__title { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--c-heading); margin: 0; }
.a11y__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-5); }
.a11y__row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin: 0; }
.a11y__label { font-size: var(--fs-sm); font-weight: 600; color: var(--c-heading); }
.a11y__seg { display: inline-flex; gap: 4px; background: var(--c-chip); border-radius: var(--radius-full); padding: 4px; }
.a11y__seg button { border: none; background: none; cursor: pointer; font: inherit; font-weight: 700; color: var(--c-text-soft); padding: 6px 14px; border-radius: var(--radius-full); line-height: 1; transition: background var(--t-fast), color var(--t-fast); }
.a11y__seg button:nth-child(2) { font-size: 1.05em; }
.a11y__seg button:nth-child(3) { font-size: 1.2em; }
.a11y__seg button[aria-pressed="true"] { background: var(--c-card); color: var(--c-accent-hover); box-shadow: var(--shadow-xs); }
.a11y__hint { font-size: var(--fs-xs); color: var(--c-muted); line-height: 1.5; margin: 0; }
@media (prefers-reduced-motion: reduce) { .a11y__scrim, .a11y { transition: none; } .a11y { transform: none; } }

/* ─── Modale de confirmation (TCConfirm) ────────────────────────────── */
.tc-confirm__scrim {
  position: fixed; inset: 0; z-index: calc(var(--z-modal, 1000) + 50);
  background: rgba(15, 23, 42, 0.5);
  display: flex; align-items: center; justify-content: center; padding: var(--space-4);
  opacity: 0; transition: opacity var(--t-base);
}
.tc-confirm__scrim.open { opacity: 1; }
.tc-confirm {
  width: 100%; max-width: 440px;
  background: var(--c-card); color: var(--c-text);
  border: 1px solid var(--c-border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl); padding: var(--space-6);
  transform: translateY(10px) scale(0.98); transition: transform var(--t-base);
}
.tc-confirm__scrim.open .tc-confirm { transform: none; }
.tc-confirm__title { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--c-heading); margin: 0 0 var(--space-3); }
.tc-confirm__msg { font-size: var(--fs-sm); color: var(--c-text-soft); line-height: 1.55; white-space: pre-line; margin: 0 0 var(--space-6); }
.tc-confirm__actions { display: flex; justify-content: flex-end; gap: var(--space-3); }
@media (prefers-reduced-motion: reduce) {
  .tc-confirm__scrim, .tc-confirm { transition: none; }
  .tc-confirm { transform: none; }
}

/* ─── Visite guidée (TCTour) ────────────────────────────────────────── */
/* Couche au-dessus des modales/panneaux (a11y, confirm) pour rester visible
   par-dessus toute l'interface. Le « spotlight » crée le voile via un
   box-shadow géant ; un calque transparent dessous capte les clics afin que
   la page reste inerte pendant la visite. */
.tc-tour-overlay {
  position: fixed; inset: 0; z-index: calc(var(--z-modal, 1000) + 60);
  background: transparent; opacity: 0; transition: opacity var(--t-base);
}
.tc-tour-overlay.open { opacity: 1; }
/* Étape centrée (intro) : pas de cible, le voile vient de l'overlay. */
.tc-tour-overlay--dim { background: rgba(15, 18, 32, 0.62); }

.tc-tour-spot {
  position: fixed; top: 0; left: 0; width: 0; height: 0;
  z-index: calc(var(--z-modal, 1000) + 61);
  border-radius: var(--radius-md); pointer-events: none; opacity: 0;
  box-shadow:
    0 0 0 3px var(--c-accent),
    0 0 0 6px var(--c-accent-soft),
    0 0 0 9999px rgba(15, 18, 32, 0.62);
  transition: top var(--t-base), left var(--t-base), width var(--t-base),
              height var(--t-base), opacity var(--t-base);
}
.tc-tour-spot.open { opacity: 1; }

.tc-tour-pop {
  position: fixed; top: 0; left: 0; z-index: calc(var(--z-modal, 1000) + 62);
  width: min(360px, calc(100vw - 32px));
  background: var(--c-card); color: var(--c-text);
  border: 1px solid var(--c-border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl); padding: var(--space-5);
  opacity: 0; transform: translateY(6px) scale(0.98);
  transition: opacity var(--t-base), transform var(--t-base);
}
.tc-tour-pop.open { opacity: 1; transform: none; }
.tc-tour-pop--center {
  top: 50% !important; left: 50% !important;
  transform: translate(-50%, -48%) scale(0.98);
}
.tc-tour-pop--center.open { transform: translate(-50%, -50%); }

/* Caret pointant vers la cible (masqué sur les étapes centrées). */
.tc-tour-pop__caret {
  position: absolute; width: 12px; height: 12px;
  background: var(--c-card); border: 1px solid var(--c-border);
  transform: rotate(45deg); border-radius: 2px;
}
.tc-tour-pop[data-side="bottom"] .tc-tour-pop__caret { top: -7px; border-right: 0; border-bottom: 0; margin-left: -6px; }
.tc-tour-pop[data-side="top"]    .tc-tour-pop__caret { bottom: -7px; border-left: 0; border-top: 0; margin-left: -6px; }
.tc-tour-pop[data-side="right"]  .tc-tour-pop__caret { left: -7px; border-top: 0; border-right: 0; margin-top: -6px; }
.tc-tour-pop[data-side="left"]   .tc-tour-pop__caret { right: -7px; border-bottom: 0; border-left: 0; margin-top: -6px; }
.tc-tour-pop--center .tc-tour-pop__caret { display: none; }

.tc-tour-pop__head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.tc-tour-pop__step {
  font-family: var(--font-display); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--c-accent);
}
.tc-tour-pop__skip {
  margin-left: auto; border: 0; background: none; cursor: pointer; font: inherit;
  font-size: var(--fs-xs); color: var(--c-muted); padding: 4px 6px; border-radius: var(--radius-sm);
  transition: color var(--t-fast), background var(--t-fast);
}
.tc-tour-pop__skip:hover { color: var(--c-text); background: var(--c-chip); }
.tc-tour-pop__close { width: 28px; height: 28px; flex: 0 0 auto; }
.tc-tour-pop__close svg { width: 16px; height: 16px; }

.tc-tour-pop__title { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--c-heading); margin: 0 0 var(--space-2); line-height: 1.25; }
.tc-tour-pop__body { font-size: var(--fs-sm); color: var(--c-text-soft); line-height: 1.55; margin: 0 0 var(--space-5); }

.tc-tour-pop__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.tc-tour-pop__dots { display: inline-flex; gap: 6px; }
.tc-tour-pop__dot { width: 7px; height: 7px; border-radius: var(--radius-full); background: var(--c-border-strong); transition: background var(--t-fast), transform var(--t-fast); }
.tc-tour-pop__dot.is-active { background: var(--c-accent); transform: scale(1.25); }
.tc-tour-pop__nav { display: inline-flex; gap: var(--space-2); }

@media (max-width: 600px) {
  /* Sur mobile, la bulle s'ancre en bas de l'écran pour rester lisible. */
  .tc-tour-pop {
    left: 16px !important; right: 16px !important;
    top: auto !important; bottom: 16px !important;
    width: auto; transform: translateY(8px);
  }
  .tc-tour-pop.open { transform: none; }
  .tc-tour-pop--center { top: auto !important; }
  .tc-tour-pop--center.open { transform: none; }
  .tc-tour-pop__caret { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tc-tour-overlay, .tc-tour-spot, .tc-tour-pop, .tc-tour-pop__dot { transition: none; }
  .tc-tour-pop { transform: none; }
}

/* ─── Container responsive standard ─────────────────────────────── */
.ds-container { width: 100%; max-width: 1400px; margin: 0 auto; padding: 0 var(--space-6); }
@media (max-width: 720px) { .ds-container { padding: 0 var(--space-4); } }

/* ============================================================== */
/* 12. Formulaires — composants individuels                        */
/* ============================================================== */

/* Marqueur "requis" sur les labels */
.field--required > label::after { content: ' *'; color: var(--c-danger); font-weight: 700; }

/* Search-box : input de recherche avec icône loupe à gauche
   Usage :
     <div class="search-box">
       <svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
       <input class="search-input" type="text" placeholder="…">
     </div>
*/
.search-box { position: relative; max-width: 500px; flex: 1; }
.search-box svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; stroke: var(--c-muted); stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.search-input { width: 100%; padding: 0.6rem 0.9rem 0.6rem 2.3rem; border: 1px solid var(--c-border-strong); border-radius: var(--radius-md); font-size: var(--fs-sm); font-family: inherit; background: var(--c-card); color: var(--c-text); transition: border-color var(--t-fast), box-shadow var(--t-fast); }
.search-input:focus { outline: none; border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-soft); }

/* Champ + icône préfixe/suffixe */
.input-affix { position: relative; display: flex; align-items: stretch; width: 100%; }
.input-affix .input { flex: 1; min-width: 0; padding-left: 2.4rem; }
.input-affix .input--suffix { padding-left: 0.85rem; padding-right: 2.4rem; }
.input-affix__icon { position: absolute; top: 50%; transform: translateY(-50%); left: 12px; width: 16px; height: 16px; color: var(--c-muted); pointer-events: none; }
.input-affix__icon--suffix { left: auto; right: 12px; }
.input-affix__icon svg { width: 100%; height: 100%; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.input-affix__btn { position: absolute; top: 50%; right: 6px; transform: translateY(-50%); background: none; border: none; cursor: pointer; padding: 6px; border-radius: 6px; color: var(--c-muted); }
.input-affix__btn:hover { background: var(--c-chip); color: var(--c-heading); }

/* Checkbox stylée */
.check { display: inline-flex; align-items: flex-start; gap: var(--space-2); cursor: pointer; font-size: var(--fs-sm); color: var(--c-text); user-select: none; }
.check input[type="checkbox"] { position: absolute; opacity: 0; pointer-events: none; }
.check__box { width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--c-border-strong); background: var(--c-card); display: grid; place-items: center; flex-shrink: 0; transition: all var(--t-fast); margin-top: 1px; }
.check__box svg { width: 12px; height: 12px; stroke: #fff; stroke-width: 3; fill: none; stroke-linecap: round; stroke-linejoin: round; opacity: 0; transform: scale(0.6); transition: opacity var(--t-fast), transform var(--t-fast); }
.check input:checked ~ .check__box { background: var(--c-accent); border-color: var(--c-accent); }
.check input:checked ~ .check__box svg { opacity: 1; transform: scale(1); }
.check input:indeterminate ~ .check__box { background: var(--c-accent); border-color: var(--c-accent); }
.check input:indeterminate ~ .check__box::after { content: ''; width: 10px; height: 2px; background: #fff; border-radius: 1px; }
.check input:focus-visible ~ .check__box { box-shadow: 0 0 0 3px var(--c-accent-soft); }
.check input:disabled ~ .check__box { opacity: 0.5; cursor: not-allowed; }
.check__label { line-height: 1.4; }

/* Radio stylé */
.radio { display: inline-flex; align-items: flex-start; gap: var(--space-2); cursor: pointer; font-size: var(--fs-sm); color: var(--c-text); user-select: none; }
.radio input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.radio__dot { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--c-border-strong); background: var(--c-card); display: grid; place-items: center; flex-shrink: 0; transition: all var(--t-fast); margin-top: 1px; }
.radio__dot::after { content: ''; width: 8px; height: 8px; border-radius: 50%; background: #fff; opacity: 0; transform: scale(0.5); transition: opacity var(--t-fast), transform var(--t-fast); }
.radio input:checked ~ .radio__dot { background: var(--c-accent); border-color: var(--c-accent); }
.radio input:checked ~ .radio__dot::after { opacity: 1; transform: scale(1); }
.radio input:focus-visible ~ .radio__dot { box-shadow: 0 0 0 3px var(--c-accent-soft); }
.radio input:disabled ~ .radio__dot { opacity: 0.5; cursor: not-allowed; }

/* Switch (toggle) standalone */
.switch { display: inline-flex; align-items: center; gap: var(--space-3); cursor: pointer; font-size: var(--fs-sm); color: var(--c-text); user-select: none; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch__track { width: 38px; height: 22px; border-radius: 999px; background: var(--c-border-strong); position: relative; flex-shrink: 0; transition: background var(--t-base); }
.switch__track::after { content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: var(--shadow-xs); transition: transform var(--t-base); }
.switch input:checked ~ .switch__track { background: var(--c-accent); }
.switch input:checked ~ .switch__track::after { transform: translateX(16px); }
.switch input:focus-visible ~ .switch__track { box-shadow: 0 0 0 3px var(--c-accent-soft); }
.switch input:disabled ~ .switch__track { opacity: 0.5; cursor: not-allowed; }

/* File drop (upload) */
.file-drop { display: block; position: relative; border: 2px dashed var(--c-border-strong); border-radius: var(--radius-md); padding: var(--space-6); text-align: center; background: var(--c-bg); transition: all var(--t-fast); cursor: pointer; }
.file-drop:hover, .file-drop.is-drag { border-color: var(--c-accent); background: var(--c-accent-soft); }
.file-drop input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.file-drop__icon { width: 44px; height: 44px; border-radius: 12px; background: var(--c-card); color: var(--c-accent); display: grid; place-items: center; margin: 0 auto var(--space-3); }
.file-drop__icon svg { width: 22px; height: 22px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.file-drop__title { font-weight: 600; color: var(--c-heading); font-size: var(--fs-sm); }
.file-drop__hint { color: var(--c-muted); font-size: var(--fs-xs); margin-top: 2px; }

/* Compteur de caractères */
.field__counter { font-size: var(--fs-xs); color: var(--c-muted); text-align: right; font-variant-numeric: tabular-nums; }
.field__counter--warn { color: var(--c-warning); }
.field__counter--limit { color: var(--c-danger); font-weight: 700; }

/* Fieldset / legend */
.fieldset { border: 1px solid var(--c-border); border-radius: var(--radius-md); padding: var(--space-5); margin: 0 0 var(--space-5); }
.fieldset__legend { font-family: var(--font-display); font-size: var(--fs-sm); font-weight: 600; color: var(--c-heading); padding: 0 var(--space-2); margin-left: var(--space-3); }

/* Field-row : labels en colonne pour grands formulaires */
.field-row { display: grid; grid-template-columns: 180px 1fr; gap: var(--space-4); align-items: start; margin-bottom: var(--space-4); }
.field-row > label { padding-top: 0.65rem; font-size: var(--fs-sm); font-weight: 600; color: var(--c-heading); }
@media (max-width: 720px) { .field-row { grid-template-columns: 1fr; } .field-row > label { padding-top: 0; } }

/* Form-grid : grille 2 colonnes pour formulaires denses */
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4) var(--space-5); }
.form-grid .col-2 { grid-column: span 2; }
@media (max-width: 680px) { .form-grid { grid-template-columns: 1fr; } .form-grid .col-2 { grid-column: span 1; } }

/* Input-group : préfixe textuel collé au champ (ex. FR pour TVA) */
.input-group { display: flex; align-items: stretch; }
.input-group__addon { display: inline-flex; align-items: center; padding: 0 0.85rem; background: var(--c-chip); border: 1px solid var(--c-border-strong); border-right: none; border-radius: var(--radius-md) 0 0 var(--radius-md); font-size: var(--fs-sm); font-weight: 600; color: var(--c-muted); }
.input-group .input { border-radius: 0 var(--radius-md) var(--radius-md) 0; flex: 1; min-width: 0; }

/* Toggle (variante "switch" historique des maquettes — alias léger de .switch) */
.toggle { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: var(--fs-sm); font-weight: 600; color: var(--c-text-soft); position: relative; }
.toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle__track { width: 42px; height: 24px; border-radius: 999px; background: var(--c-border-strong); position: relative; transition: background var(--t-fast); flex-shrink: 0; }
.toggle__track::after { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform var(--t-fast); box-shadow: var(--shadow-xs); }
.toggle input:checked + .toggle__track { background: var(--c-success); }
.toggle input:checked + .toggle__track::after { transform: translateX(18px); }
.toggle input:focus-visible + .toggle__track { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* Barre Enregistrer (sticky footer) */
.form-footer { position: sticky; bottom: 0; display: flex; justify-content: flex-end; gap: var(--space-3); padding: var(--space-4) var(--space-5); background: color-mix(in srgb, var(--c-card) 92%, transparent); backdrop-filter: blur(10px); border-top: 1px solid var(--c-border); margin-top: var(--space-6); }
.form-footer__left { margin-right: auto; color: var(--c-muted); font-size: var(--fs-sm); display: flex; align-items: center; gap: var(--space-2); }

/* ============================================================== */
/* 13. Navigation                                                  */
/* ============================================================== */

/* Tabs — variante "underline" */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--c-border); position: relative; }
.tabs__item { padding: var(--space-3) var(--space-4); background: none; border: none; cursor: pointer; font: inherit; font-size: var(--fs-sm); font-weight: 600; color: var(--c-muted); border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color var(--t-fast), border-color var(--t-fast); display: inline-flex; align-items: center; gap: var(--space-2); }
.tabs__item:hover { color: var(--c-heading); }
.tabs__item.is-active { color: var(--c-accent-hover); border-bottom-color: var(--c-accent); }
.tabs__item .tab-count { background: var(--c-chip); color: var(--c-text-soft); border-radius: var(--radius-full); padding: 1px 8px; font-size: 0.68rem; font-weight: 700; }
.tabs__item.is-active .tab-count { background: var(--c-accent-soft); color: var(--c-accent-hover); }

/* Tabs — variante "pills" */
.tabs--pills { border-bottom: none; gap: var(--space-2); padding: 4px; background: var(--c-chip); border-radius: var(--radius-full); align-self: flex-start; }
.tabs--pills .tabs__item { border-radius: var(--radius-full); padding: 6px 14px; border-bottom: none; margin-bottom: 0; }
.tabs--pills .tabs__item.is-active { background: var(--c-card); color: var(--c-heading); box-shadow: var(--shadow-xs); }
.tabs--pills .tabs__item:hover:not(.is-active) { color: var(--c-heading); }

/* Segmented control (toggle group) */
.segmented { display: inline-flex; border: 1px solid var(--c-border); border-radius: var(--radius-full); overflow: hidden; background: var(--c-card); }
.segmented__item { padding: 7px 16px; background: none; border: none; cursor: pointer; font: inherit; font-size: var(--fs-xs); font-weight: 700; color: var(--c-muted); transition: all var(--t-fast); text-decoration: none; }
.segmented__item:hover { color: var(--c-heading); }
.segmented__item.is-active { background: var(--c-accent); color: #fff; }
.segmented__item + .segmented__item { border-left: 1px solid var(--c-border); }
.segmented__item.is-active + .segmented__item { border-left-color: var(--c-accent); }
/* Un contrôle sans effet se désactive, il ne se masque pas : disparaître se lit
   comme un bug ou comme une perte de droits, jamais comme une explication. */
.segmented__item:disabled { cursor: not-allowed; opacity: 0.45; }
.segmented__item:disabled:hover { color: var(--c-muted); }

/* Breadcrumb */
.breadcrumb { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); font-size: var(--fs-sm); color: var(--c-muted); }
.breadcrumb a { color: var(--c-muted); text-decoration: none; transition: color var(--t-fast); }
.breadcrumb a:hover { color: var(--c-heading); text-decoration: underline; }
.breadcrumb__sep { color: var(--c-border-strong); user-select: none; }
.breadcrumb__current { color: var(--c-heading); font-weight: 600; }

/* Pagination */
.pagination { display: inline-flex; gap: 2px; align-items: center; }
.pagination button, .pagination a { min-width: 36px; height: 36px; padding: 0 10px; border: 1px solid var(--c-border); background: var(--c-card); color: var(--c-text-soft); border-radius: var(--radius-md); cursor: pointer; font: inherit; font-size: var(--fs-sm); font-weight: 600; display: inline-flex; align-items: center; justify-content: center; transition: all var(--t-fast); text-decoration: none; }
.pagination button:hover:not(:disabled), .pagination a:hover { border-color: var(--c-border-strong); color: var(--c-heading); }
.pagination .is-active { background: var(--c-accent); border-color: var(--c-accent); color: #fff; }
.pagination button:disabled { opacity: 0.4; cursor: not-allowed; }
.pagination__ellipsis { padding: 0 6px; color: var(--c-muted); }
.pagination svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* Anchor menu (table of contents) */
.anchor-menu { position: sticky; top: calc(66px + var(--space-4)); padding-left: var(--space-4); border-left: 2px solid var(--c-border); display: flex; flex-direction: column; gap: var(--space-2); }
.anchor-menu a { font-size: var(--fs-sm); color: var(--c-muted); text-decoration: none; padding: 3px 0; transition: color var(--t-fast); border-left: 2px solid transparent; margin-left: -18px; padding-left: 16px; }
.anchor-menu a:hover, .anchor-menu a.is-active { color: var(--c-accent-hover); border-left-color: var(--c-accent); text-decoration: none; }

/* ============================================================== */
/* 14. Feedback & progress                                         */
/* ============================================================== */

/* Spinner */
.spinner { display: inline-block; width: 20px; height: 20px; border: 2px solid var(--c-border); border-top-color: var(--c-accent); border-radius: 50%; animation: ds-spin 0.7s linear infinite; }
.spinner--sm { width: 14px; height: 14px; border-width: 1.5px; }
.spinner--lg { width: 36px; height: 36px; border-width: 3px; }
.spinner--on-accent { border-color: rgba(255,255,255,0.4); border-top-color: #fff; }
@keyframes ds-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2s; } }

/* Progress bar linéaire */
.progress { width: 100%; height: 8px; background: var(--c-chip); border-radius: var(--radius-full); overflow: hidden; position: relative; }
.progress__bar { height: 100%; background: var(--c-accent); border-radius: inherit; transition: width var(--t-base); }
.progress--success .progress__bar { background: var(--c-success); }
.progress--danger .progress__bar  { background: var(--c-danger); }
.progress--indeterminate .progress__bar { width: 30% !important; animation: ds-progress-ind 1.4s var(--ease) infinite; }
@keyframes ds-progress-ind { 0% { transform: translateX(-100%); } 100% { transform: translateX(333%); } }

/* Progress circulaire (CSS pure — précision suffisante pour affichage) */
.progress-ring { --pct: 0; --size: 64px; --thickness: 6px; width: var(--size); height: var(--size); border-radius: 50%; background: conic-gradient(var(--c-accent) calc(var(--pct) * 1%), var(--c-chip) 0); display: grid; place-items: center; position: relative; }
.progress-ring::before { content: ''; position: absolute; inset: var(--thickness); border-radius: 50%; background: var(--c-card); }
.progress-ring__value { position: relative; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-sm); color: var(--c-heading); font-variant-numeric: tabular-nums; }

/* Tooltip CSS-only — data-tooltip="…"
   `:where()` met la spécificité à 0 pour que tout `position: absolute/fixed/sticky`
   appliqué sur l'élément déclencheur l'emporte (sinon conflits sur boutons en .input-affix, etc.).
   Les pseudo-éléments fonctionnent quel que soit le type de positioning, à condition que l'élément
   crée un containing block — c'est le cas dès qu'il a un position non-static. */
:where([data-tooltip]:not([data-tooltip=""])) { position: relative; }
[data-tooltip]:not([data-tooltip=""])::after { content: attr(data-tooltip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(4px); background: var(--c-navy); color: #fff; padding: 5px 10px; border-radius: 6px; font-size: var(--fs-xs); font-weight: 500; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity var(--t-fast), transform var(--t-fast); z-index: var(--z-tooltip, 1200); box-shadow: var(--shadow-md); }
[data-tooltip]:not([data-tooltip=""])::before { content: ''; position: absolute; bottom: calc(100% + 2px); left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--c-navy); opacity: 0; transition: opacity var(--t-fast); pointer-events: none; }
[data-tooltip]:not([data-tooltip=""]):hover::after, [data-tooltip]:not([data-tooltip=""]):focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }
[data-tooltip]:not([data-tooltip=""]):hover::before, [data-tooltip]:not([data-tooltip=""]):focus-visible::before { opacity: 1; }
/* :not([data-tooltip=""]) répété ici : sans lui, ces overrides (0,1,1) perdent contre la règle de
   base ci-dessus (0,2,1) - `bottom`/`left` restaient donc écrasés, top+bottom actifs en même temps
   écrasant la hauteur de la bulle à quasi 0 (constaté sur les ⓘ d'en-tête de nps_qualite). */
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="bottom"]::after { bottom: auto; top: calc(100% + 8px); transform: translateX(-50%) translateY(-4px); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="bottom"]::before { bottom: auto; top: calc(100% + 2px); border-top-color: transparent; border-bottom-color: var(--c-navy); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="bottom"]:hover::after { transform: translateX(-50%) translateY(0); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="right"]::after { bottom: 50%; left: calc(100% + 8px); transform: translate(4px, 50%); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="right"]::before { bottom: 50%; left: 100%; transform: translate(-3px, 50%); border-top-color: transparent; border-right-color: var(--c-navy); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="right"]:hover::after { transform: translate(0, 50%); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="left"]::after { bottom: 50%; right: calc(100% + 8px); left: auto; transform: translate(-4px, 50%); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="left"]::before { bottom: 50%; right: 100%; left: auto; transform: translate(3px, 50%); border-top-color: transparent; border-left-color: var(--c-navy); }
[data-tooltip]:not([data-tooltip=""])[data-tooltip-pos="left"]:hover::after { transform: translate(0, 50%); }

/* Banner persistant (haut de page) */
.banner { display: flex; align-items: center; gap: var(--space-3); padding: 10px var(--space-5); font-size: var(--fs-sm); border-bottom: 1px solid var(--c-border); }
.banner--info    { background: var(--c-blue-soft);    color: var(--c-navy); border-bottom-color: var(--c-blue); }
.banner--success { background: var(--c-success-soft); color: #14532d;       border-bottom-color: var(--c-success); }
.banner--warn    { background: var(--c-warning-soft); color: #7c2d12;       border-bottom-color: var(--c-warning); }
.banner--danger  { background: var(--c-danger-soft);  color: #7f1d1d;       border-bottom-color: var(--c-danger); }
.banner svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; flex-shrink: 0; }
.banner__close { margin-left: auto; background: none; border: none; cursor: pointer; padding: 6px; color: inherit; opacity: 0.7; border-radius: 6px; }
.banner__close:hover { opacity: 1; background: rgba(0,0,0,0.06); }

/* Status dot animé */
.status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--c-muted); position: relative; vertical-align: middle; flex-shrink: 0; }
.status-dot--success { background: var(--c-success); }
.status-dot--warn    { background: var(--c-warning); }
.status-dot--danger  { background: var(--c-danger); }
.status-dot--info    { background: var(--c-blue); }
.status-dot--pulse::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: inherit; animation: ds-pulse 1.6s var(--ease) infinite; }
@keyframes ds-pulse { 0% { transform: scale(1); opacity: 0.6; } 100% { transform: scale(2.4); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .status-dot--pulse::after { animation: none; } }

/* ============================================================== */
/* 15. Affichage de données                                        */
/* ============================================================== */

/* Tags (à différencier des badges : plus textuels, retirables) */
.tag { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--c-chip); color: var(--c-text-soft); border-radius: var(--radius-sm); font-size: var(--fs-xs); font-weight: 500; }
.tag--accent  { background: var(--c-accent-soft); color: var(--c-accent-hover); }
.tag--info    { background: var(--c-blue-soft);   color: var(--c-blue-hover); }
.tag--success { background: var(--c-success-soft); color: var(--c-success); }
.tag--warn    { background: var(--c-warning-soft); color: var(--c-warning); }
.tag--danger  { background: var(--c-danger-soft);  color: var(--c-danger); }
.tag__remove { background: none; border: none; cursor: pointer; padding: 0; color: inherit; opacity: 0.6; border-radius: 50%; display: inline-grid; place-items: center; width: 14px; height: 14px; transition: opacity var(--t-fast); }
.tag__remove:hover { opacity: 1; background: rgba(0,0,0,0.1); }
.tag__remove svg { width: 9px; height: 9px; stroke: currentColor; stroke-width: 2.5; fill: none; }

/* Liste / row pattern */
.list { display: flex; flex-direction: column; }
.list__item { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--c-border); }
.list__item:last-child { border-bottom: none; }
.list__item--interactive { cursor: pointer; transition: background var(--t-fast); }
.list__item--interactive:hover { background: var(--c-bg); }
.list__title { font-weight: 600; color: var(--c-heading); font-size: var(--fs-sm); }
.list__sub { font-size: var(--fs-xs); color: var(--c-muted); margin-top: 2px; }
.list__body { flex: 1; min-width: 0; }
.list__aside { color: var(--c-muted); font-size: var(--fs-xs); margin-left: auto; }

/* Definition list */
.dl { display: grid; grid-template-columns: minmax(120px, auto) 1fr; gap: var(--space-2) var(--space-5); font-size: var(--fs-sm); }
.dl dt { color: var(--c-muted); font-weight: 600; }
.dl dd { color: var(--c-text); font-variant-numeric: tabular-nums; }
.dl--inline { display: inline-flex; gap: var(--space-4); }
.dl--inline > div { display: inline-flex; gap: 6px; }

/* Code */
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.85em; background: var(--c-chip); padding: 1px 6px; border-radius: 5px; color: var(--c-text-soft); }
.code-block { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: var(--fs-sm); background: var(--c-chip); padding: var(--space-4); border-radius: var(--radius-md); border: 1px solid var(--c-border); overflow-x: auto; color: var(--c-text); line-height: 1.5; white-space: pre; }
[data-theme="dark"] code, [data-theme="dark"] .code-block { background: rgba(255,255,255,0.04); }

/* Kbd — raccourcis clavier */
kbd, .kbd { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 6px; background: var(--c-card); color: var(--c-text-soft); border: 1px solid var(--c-border); border-bottom-width: 2px; border-radius: 5px; font-family: ui-monospace, monospace; font-size: 0.72rem; font-weight: 600; box-shadow: var(--shadow-xs); }

/* Avatar (initiales sur dégradé orange) */
.avatar { width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; background: linear-gradient(135deg, var(--c-accent), #ffb24d); color: #fff; font-family: var(--font-display); font-weight: 600; font-size: var(--fs-sm); letter-spacing: 0.02em; }
.avatar--sm { width: 28px; height: 28px; font-size: var(--fs-xs); }
.avatar--lg { width: 56px; height: 56px; font-size: var(--fs-md); }

/* Avatar group (empilés avec léger overlap) */
.avatar-group { display: inline-flex; }
.avatar-group .avatar { margin-left: -10px; border: 2px solid var(--c-card); width: 32px; height: 32px; font-size: var(--fs-xs); }
.avatar-group .avatar:first-child { margin-left: 0; }
.avatar-group .avatar--more { background: var(--c-chip); color: var(--c-text-soft); font-weight: 700; }

/* Module-icon (carré arrondi, fond teinté — pour cards modules, en-têtes…) */
.mod-ico { display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px; border-radius: 13px; background: var(--c-accent-soft); color: var(--c-accent-hover); flex-shrink: 0; }
.mod-ico svg { width: 24px; height: 24px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.mod-ico--blue { background: var(--c-blue-soft); color: var(--c-blue-hover); }
.mod-ico--navy { background: rgba(34,42,81,0.08); color: var(--c-navy); }
[data-theme="dark"] .mod-ico { color: #FFB14D; }
[data-theme="dark"] .mod-ico--blue { color: #6AA8FF; }
[data-theme="dark"] .mod-ico--navy { background: rgba(255,255,255,0.08); color: var(--c-on-navy); }

/* Stat / Metric card (formalisation de .kpi) */
.stat { background: var(--c-card); border: 1px solid var(--c-border); border-radius: var(--radius-lg); padding: var(--space-5); box-shadow: var(--shadow-sm); }
.stat__label { font-size: var(--fs-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--c-muted); display: flex; align-items: center; gap: var(--space-2); }
.stat__value { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xl); color: var(--c-heading); margin-top: var(--space-2); font-variant-numeric: tabular-nums; line-height: 1; }
.stat__trend { font-size: var(--fs-xs); font-weight: 600; margin-top: var(--space-2); display: inline-flex; align-items: center; gap: 4px; }
.stat__trend--up   { color: var(--c-success); }
.stat__trend--down { color: var(--c-danger); }
.stat__trend--flat { color: var(--c-muted); }
.stat__spark { margin-top: var(--space-3); height: 32px; }

/* Diff */
.diff { font-family: ui-monospace, monospace; font-size: var(--fs-xs); }
.diff__line { padding: 2px 10px; border-radius: 4px; }
.diff__line--add { background: var(--c-success-soft); color: #14532d; }
.diff__line--del { background: var(--c-danger-soft); color: #7f1d1d; text-decoration: line-through; text-decoration-color: rgba(127,29,29,0.4); }

/* ============================================================== */
/* 16. Overlays (modal centré, confirm, bottom-sheet)              */
/* ============================================================== */

.modal-scrim { position: fixed; inset: 0; background: rgba(15,18,32,0.55); backdrop-filter: blur(3px); z-index: var(--z-modal); opacity: 0; pointer-events: none; transition: opacity var(--t-base); }
.modal-scrim.open { opacity: 1; pointer-events: auto; }
.modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -46%) scale(0.96); width: min(540px, 94vw); max-height: 88vh; background: var(--c-card); border: 1px solid var(--c-border); border-radius: var(--radius-xl); box-shadow: var(--shadow-xl); z-index: calc(var(--z-modal) + 1); display: flex; flex-direction: column; opacity: 0; pointer-events: none; transition: opacity var(--t-base), transform var(--t-base); overflow: hidden; }
.modal.open { opacity: 1; transform: translate(-50%, -50%) scale(1); pointer-events: auto; }
.modal__head { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-5) var(--space-6) 0; }
.modal__head h3 { font-size: var(--fs-lg); margin-bottom: var(--space-2); }
.modal__head .sub { color: var(--c-muted); font-size: var(--fs-sm); }
.modal__close { margin-left: auto; background: none; border: none; cursor: pointer; color: var(--c-muted); width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; flex-shrink: 0; }
.modal__close:hover { background: var(--c-chip); color: var(--c-heading); }
.modal__close svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; }
.modal__body { padding: var(--space-5) var(--space-6); overflow-y: auto; flex: 1; }
.modal__foot { display: flex; gap: var(--space-3); justify-content: flex-end; padding: var(--space-4) var(--space-6); border-top: 1px solid var(--c-border); background: color-mix(in srgb, var(--c-bg) 50%, transparent); }
.modal--sm { width: min(420px, 94vw); }
.modal--lg { width: min(780px, 94vw); }
/* Modale ouverte DEPUIS un drawer : elle et son voile doivent dépasser le
   panneau qui l'a ouverte (même z-index par défaut, 1001). Sans cela le voile
   s'arrête au bord du drawer, qui reste vif, et la modale paraît flotter à
   moitié dessus. Même parti pris que .tc-confirm__scrim. */
.modal-scrim--over-drawer { z-index: calc(var(--z-modal) + 40); }
.modal--over-drawer { z-index: calc(var(--z-modal) + 41); }

/* Confirm dialog — variante du modal avec icône */
.modal__hero-ico { width: 48px; height: 48px; border-radius: 14px; background: var(--c-accent-soft); color: var(--c-accent-hover); display: grid; place-items: center; flex-shrink: 0; }
.modal__hero-ico--danger  { background: var(--c-danger-soft);  color: var(--c-danger); }
.modal__hero-ico--warning { background: var(--c-warning-soft); color: var(--c-warning); }
.modal__hero-ico--success { background: var(--c-success-soft); color: var(--c-success); }
.modal__hero-ico svg { width: 22px; height: 22px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* Bottom sheet (mobile-first) */
.sheet { position: fixed; left: 0; right: 0; bottom: 0; background: var(--c-card); border-top-left-radius: var(--radius-xl); border-top-right-radius: var(--radius-xl); box-shadow: var(--shadow-xl); z-index: calc(var(--z-modal) + 1); transform: translateY(100%); transition: transform var(--t-base); max-height: 88vh; display: flex; flex-direction: column; }
.sheet.open { transform: translateY(0); }
.sheet__handle { width: 40px; height: 4px; border-radius: 2px; background: var(--c-border-strong); margin: 8px auto; }
.sheet__head { padding: 0 var(--space-5) var(--space-3); display: flex; align-items: center; }
.sheet__body { padding: var(--space-3) var(--space-5) var(--space-6); overflow-y: auto; flex: 1; }

/* Scrim générique (pour drawer / overlays personnalisés) */
.scrim { position: fixed; inset: 0; background: rgba(16,18,24,0.5); backdrop-filter: blur(2px); opacity: 0; visibility: hidden; transition: opacity var(--t-base), visibility var(--t-base); z-index: var(--z-modal); }
.scrim.open { opacity: 1; visibility: visible; }

/* Drawer (slide-over depuis la droite) — pour CRUD inline d'une entité */
.drawer { position: fixed; top: 0; right: 0; bottom: 0; width: 600px; max-width: 94vw; background: var(--c-bg); box-shadow: var(--shadow-xl); transform: translateX(100%); transition: transform var(--t-base); z-index: calc(var(--z-modal) + 1); display: flex; flex-direction: column; }
.drawer.open { transform: translateX(0); }
.drawer__head { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-5) var(--space-6); border-bottom: 1px solid var(--c-border); }
.drawer__head h2 { font-size: var(--fs-lg); }
.drawer__head .eyebrow { font-size: var(--fs-xs); color: var(--c-muted); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; }
.drawer__close { margin-left: auto; }
.drawer__body { padding: var(--space-6); overflow-y: auto; flex: 1; }
.drawer__foot { display: flex; gap: var(--space-3); justify-content: flex-end; padding: var(--space-4) var(--space-6); border-top: 1px solid var(--c-border); background: var(--c-card); }

/* ============================================================== */
/* 17. Layout & patterns                                           */
/* ============================================================== */

/* Cluster (flex horizontal aligné) */
.ds-cluster { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
.ds-cluster--sm { gap: var(--space-2); }
.ds-cluster--lg { gap: var(--space-5); }
.ds-cluster--between { justify-content: space-between; }

/* Divider */
.ds-divider { border: none; border-top: 1px solid var(--c-border); margin: var(--space-6) 0; }
.ds-divider--label { display: flex; align-items: center; gap: var(--space-3); color: var(--c-muted); font-size: var(--fs-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; margin: var(--space-6) 0; }
.ds-divider--label::before, .ds-divider--label::after { content: ''; flex: 1; height: 1px; background: var(--c-border); }
.ds-divider--vertical { width: 1px; align-self: stretch; background: var(--c-border); margin: 0 var(--space-3); }

/* Page-head pattern (formalisé) */
.page-head { display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: var(--space-4); margin-bottom: var(--space-6); }
.page-head h1 { font-size: var(--fs-2xl); }
.page-head p { color: var(--c-muted); margin-top: 4px; font-size: var(--fs-sm); max-width: 60ch; }
.page-head .actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
/* Sans bloc d'actions à droite, le titre n'a plus à tenir la hauteur d'une
   rangée de boutons : ce qui suit peut se rapprocher. */
.page-head--simple { margin-bottom: var(--space-4); }

/* Toolbar */
.toolbar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--c-card); border: 1px solid var(--c-border); border-radius: var(--radius-md); margin-bottom: var(--space-4); flex-wrap: wrap; }
.toolbar__sep { width: 1px; height: 20px; background: var(--c-border); }
/* Le display:flex ci-dessus écraserait le display:none de l'attribut [hidden] —
   piège connu, et plusieurs écrans posent « hidden » sur leur toolbar le temps
   du chargement. */
.toolbar[hidden] { display: none; }

/* Filter accordion — panneau de filtres déployable EN FLUX sous une toolbar
   (alternative responsive au popover flottant). Hauteur animée via l'astuce
   grid-template-rows 0fr → 1fr. Générique : réutilisable par n'importe quel module. */
.filter-accordion { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--t-base); margin-bottom: var(--space-4); }
.filter-accordion.open { grid-template-rows: 1fr; }
/* Replié, le panneau ne coûte plus sa marge : elle laissait 16 px de vide entre
   la barre d'outils et la liste, sur les quatre écrans qui posent ce panneau
   (WEPO, IT Manager, FVA, Référentiel), pour séparer deux blocs dont l'un
   n'était pas là. Les 2 px qui restent sont les bordures de `__inner`, que la
   piste à `0fr` ne peut pas comprimer. */
.filter-accordion:not(.open) { margin-bottom: 0; }
.filter-accordion[hidden] { display: none; }
.filter-accordion__inner { overflow: hidden; min-height: 0; background: var(--c-card); border: 1px solid var(--c-border); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }
.filter-accordion__head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--c-border); font-family: var(--font-display); font-size: var(--fs-sm); color: var(--c-heading); }
.filter-accordion__body { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--space-4); padding: var(--space-4); }
.filter-accordion__body .field { margin-bottom: 0; }
/* Chrome impose au <select> natif une hauteur de contenu de 2 px supérieure à
   celle d'un <input> — `line-height` n'y change rien. Dans une rangée de
   filtres où voisinent des selects natifs et des combos TCSelectSearch (qui
   sont des <input>), ces 2 px se voient. On les reprend sur le rembourrage
   vertical, du seul endroit où le mélange se produit. */
.filter-accordion__body .select { padding-top: calc(0.65rem - 1px); padding-bottom: calc(0.65rem - 1px); }
/* Le repli s'anime par grid-template-rows : rien à animer si on n'en veut pas. */
@media (prefers-reduced-motion: reduce) { .filter-accordion { transition: none; } }

/* Badge compteur sur le bouton « Filtres ». */
.filter-badge {
  display: inline-grid; place-items: center; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: var(--radius-full);
  background: var(--c-accent); color: #fff;
  font-size: var(--fs-xs); font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
}
/* Même piège que .toolbar et .filter-accordion : le `display` ci-dessus bat le
   `display: none` que le navigateur donne à [hidden], et la pastille restait
   affichée à « 0 ». Elle est posée avec `hidden` par IT Manager, FVA et WEPO. */
.filter-badge[hidden] { display: none; }

/* Chips de filtres actifs (rangée sous la toolbar) : ce que le panneau replié
   masquerait reste énoncé ici, avec de quoi le retirer d'un clic. */
.active-chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--c-bg); border: 1px solid var(--c-border); border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}
/* Sans cette ligne, `display: flex` bat le `display: none` de [hidden] et la
   rangée « Actifs : » reste affichée, vide. */
.active-chips[hidden] { display: none; }
.active-chips__label { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--c-muted); }
.active-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 4px 3px 10px; background: var(--c-accent-soft);
  color: var(--c-accent-hover); border: 1px solid color-mix(in srgb, var(--c-accent) 30%, transparent);
  border-radius: var(--radius-full);
  font-size: var(--fs-xs); font-weight: 600;
}
.active-chip__remove {
  width: 18px; height: 18px; padding: 0; border: none; background: transparent;
  color: inherit; opacity: 0.7; cursor: pointer; border-radius: 50%;
  display: grid; place-items: center; transition: opacity var(--t-fast), background var(--t-fast);
}
.active-chip__remove:hover { opacity: 1; background: rgba(0,0,0,0.08); }
.active-chips__reset {
  margin-left: auto;
  background: var(--c-blue);
  border: none;
  cursor: pointer;
  color: var(--c-white);
  font-size: var(--fs-xs);
  font-weight: 600;
  transition: color var(--t-fast);
}
.active-chips__reset:hover { color: var(--c-white); background: var(--c-blue-hover); }

/* Bouton qui se lit comme un lien : une action posée au fil d'une phrase
   (« voir toute la marque »), là où un vrai bouton couperait la lecture. */
.btn-lien {
  background: none; border: none; padding: 0; font: inherit; cursor: pointer;
  color: var(--c-blue); text-decoration: underline; text-underline-offset: 2px;
  transition: color var(--t-fast);
}
.btn-lien:hover { color: var(--c-blue-hover); }

/* Sticky-section helper */
.ds-sticky { position: sticky; top: calc(66px + var(--space-3)); z-index: 5; background: var(--c-bg); padding-top: var(--space-3); }

/* Two-pane (master / détail) */
.two-pane { display: grid; grid-template-columns: 320px 1fr; gap: var(--space-6); align-items: start; }
@media (max-width: 960px) { .two-pane { grid-template-columns: 1fr; } }

/* Aspect-ratio */
.aspect-1 { aspect-ratio: 1 / 1; }
.aspect-4-3 { aspect-ratio: 4 / 3; }
.aspect-16-9 { aspect-ratio: 16 / 9; }

/* Scroll shadows (indicateurs visuels de défilement horizontal) */
.scroll-x { overflow-x: auto; background:
    linear-gradient(to right, var(--c-card) 30%, transparent),
    linear-gradient(to right, transparent, var(--c-card) 70%) 0 100%,
    radial-gradient(ellipse at left, rgba(34,42,81,0.10), transparent 70%),
    radial-gradient(ellipse at right, rgba(34,42,81,0.10), transparent 70%);
  background-repeat: no-repeat;
  background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
  background-position: 0 0, 100% 0, 0 0, 100% 0;
  background-attachment: local, local, scroll, scroll;
}

/* ============================================================== */
/* 18. Accessibilité, print, prefs utilisateur                     */
/* ============================================================== */

/* Sélection texte cohérente */
::selection { background: var(--c-accent-soft); color: var(--c-heading); }

/* Désactiver les transitions à la bascule de thème pour éviter le flash multi-couleur */
.no-transitions, .no-transitions * { transition: none !important; }

/* High contrast (Windows / forced-colors) */
@media (forced-colors: active) {
  .btn, .input, .select, .card, .badge { border: 1px solid CanvasText; }
  .btn--primary { background: Highlight; color: HighlightText; }
}

/* Réduction des données / images de bg */
@media (prefers-reduced-data: reduce) {
  body { background-image: none; }
  [data-theme="dark"] body { background-image: none; }
}

/* ============================================================== */
/* 19. Patterns métier — secteur automobile / spécifiques FR        */
/* (Réutilisables hors TC : volontairement génériques.)             */
/* ============================================================== */

/* ─── Plaque d'immatriculation (variante "hybride" charte-friendly) */
.plate {
  display: inline-flex; align-items: stretch; overflow: hidden;
  font-family: var(--font-display);
  font-weight: 700; font-size: var(--fs-sm); letter-spacing: 0.08em;
  color: var(--c-navy); background: var(--c-card);
  border: 1.5px solid var(--c-navy); border-radius: 5px;
  box-shadow: var(--shadow-xs);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  line-height: 1; user-select: all;
}
.plate__band { width: 12px; background: var(--c-accent); flex-shrink: 0; }
.plate__num  { padding: 5px 10px 5px 8px; }
.plate--sm { font-size: var(--fs-xs); }
.plate--sm .plate__band { width: 9px; }
.plate--sm .plate__num  { padding: 4px 8px 4px 6px; }
.plate--lg { font-size: var(--fs-md); letter-spacing: 0.08em; }
.plate--lg .plate__band { width: 16px; }
.plate--lg .plate__num  { padding: 8px 14px 8px 10px; }

/* Bandeau coloré = sémantique d'état du véhicule (réutilise les couleurs sémantiques) */
.plate--info    .plate__band { background: var(--c-blue); }
.plate--success .plate__band { background: var(--c-success); }
.plate--warn    .plate__band { background: var(--c-warning); }
.plate--danger  .plate__band { background: var(--c-danger); }
.plate--neutral .plate__band { background: var(--c-muted); }
[data-theme="dark"] .plate { color: var(--c-heading); background: var(--c-chip); border-color: var(--c-border-strong); }

/* Variante "officielle" jaune réglementaire — usage ponctuel (fiche véhicule, impression) */
.plate--official { background: #F5D000; border-color: #1a1a1a; color: #1a1a1a; }
.plate--official .plate__band { background: #003399; color: #F5D000; width: 22px; display: grid; place-items: center; font-size: 0.62rem; font-weight: 700; letter-spacing: 0; }
.plate--official .plate__band::before { content: 'F'; }
[data-theme="dark"] .plate--official { background: #F5D000; color: #1a1a1a; }

/* ─── Statut générique (pill avec dot sémantique) ───────────────── */
.status { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--c-chip); color: var(--c-text-soft); border-radius: var(--radius-full); font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; line-height: 1.3; }
.status::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--c-muted); flex-shrink: 0; }
.status--active  { background: var(--c-accent-soft);  color: var(--c-accent-hover); }
.status--active::before  { background: var(--c-accent); }
.status--info    { background: var(--c-blue-soft);    color: var(--c-blue-hover); }
.status--info::before    { background: var(--c-blue); }
.status--success { background: var(--c-success-soft); color: var(--c-success); }
.status--success::before { background: var(--c-success); }
.status--warn    { background: var(--c-warning-soft); color: var(--c-warning); }
.status--warn::before    { background: var(--c-warning); }
.status--danger  { background: var(--c-danger-soft);  color: var(--c-danger); }
.status--danger::before  { background: var(--c-danger); }
.status--neutral { background: var(--c-chip);         color: var(--c-muted); }
.status--neutral::before { background: var(--c-muted); }
.status--pulse::before { animation: ds-pulse-dot 1.6s var(--ease) infinite; }
@keyframes ds-pulse-dot { 0% { box-shadow: 0 0 0 0 currentColor; opacity: 1; } 100% { box-shadow: 0 0 0 5px transparent; opacity: 0.6; } }
@media (prefers-reduced-motion: reduce) { .status--pulse::before { animation: none; } }

/* ─── Brand-chip (marques / catégories, neutre + dot couleur via --dot) */
.brand-chip { display: inline-flex; align-items: center; gap: 7px; padding: 3px 11px 3px 9px; background: var(--c-chip); color: var(--c-text-soft); border-radius: var(--radius-full); font-size: var(--fs-xs); font-weight: 600; line-height: 1.3; }
.brand-chip::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--dot, var(--c-muted)); flex-shrink: 0; }

/* ─── Téléphone formaté ─────────────────────────────────────────── */
.phone { font-variant-numeric: tabular-nums; letter-spacing: 0.04em; font-feature-settings: "tnum"; white-space: nowrap; }

/* ─── Champs masqués (SIREN/SIRET/Plaque/IBAN…) ─────────────────── */
.input--monospace { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-variant-numeric: tabular-nums; letter-spacing: 0.04em; }

/* Print styles — épure pour impression A4 */
@media print {
  body { background: #fff !important; background-image: none !important; color: #000; }
  .app-sidebar, .app-topbar, .drawer, .modal-scrim, .picker-scrim,
  .nav-collapse-btn, .nav-mobile-toggle, .toast-stack, .popover,
  .actions, .btn { display: none !important; }
  .app-main { margin-left: 0 !important; }
  .app-body { padding: 0 !important; }
  .card, .table-wrap { box-shadow: none !important; border-color: #000 !important; }
  a { color: #000; text-decoration: underline; }
  .page-break { page-break-before: always; }
}
