/* ==========================================================================
   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.
     Trois jetons distincts, car un même ton ne peut pas servir à la fois de
     fond et de texte au-dessus de 4,5:1 (WCAG 2.1 AA) :
       --c-accent       fond d'action (bouton, item de nav actif)
       --c-accent-on    texte POSÉ SUR ce fond orange        → 7,2:1
       --c-accent-ink   texte orange SUR FOND CLAIR          → 5,6:1 sur blanc
     --c-accent-hover reste un fond (survol), jamais une couleur de texte. */
  --c-accent:       #FE8D00;
  --c-accent-hover: #E07D00;
  --c-accent-on:    #2B1A05;   /* encre chaude sur fond orange */
  --c-accent-ink:   #9A5700;   /* orange lisible en texte sur fond clair */
  --c-accent-soft:  #FFF1DE;   /* fond teinté pour états/sélection */
  --c-accent-mark:  #C26A00;   /* orange d'une icône sur fond clair ou teinté : 3,5:1 (seuil graphique 3:1), reste orange là où l'encre texte tire sur le brun */
  /* Anneau de focus. L'orange de marque ne plafonne qu'à ~2,1:1 sur le fond
     chaud #F5F5F3 : sous les 3:1 exigés pour un indicateur de focus (WCAG
     1.4.11 / 2.4.7). On prend l'encre orange (5,1:1 sur ce fond). Sur les
     surfaces navy (barre latérale, en-tête du visualiseur), c'est l'inverse :
     l'encre y tombe à 2,5:1 et l'orange vif revient (cf. règle :focus-visible). */
  /* Anneau de focus : navy sur fond clair (13,8:1). L'encre orange y tenait
     le contraste mais tirait sur le brun, hors charte. En sombre : ambre clair. */
  --c-focus:        var(--c-navy);

  /* 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:        #63697A;
  --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 */
  /* États sémantiques — tons assombris pour rester lisibles en texte sur
     leur propre fond teinté (pastilles) : 4,6 à 5,5:1. */
  --c-success:      #0E7C4A;  --c-success-soft: #E3F3EA;
  --c-warning:      #B54708;  --c-warning-soft: #FBEEDC;
  --c-danger:       #B42318;  --c-danger-soft:  #FBE9E7;

  /* --- 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) sont rétablis en bleu
     saturé plus bas pour conserver le contraste. */
  --c-blue:         #6AA8FF;
  --c-blue-hover:   #8FC0FF;

  /* Orange en texte sur fond sombre : l'ambre clair remplace le brun. */
  --c-accent-ink:   #FFB14D;
  --c-accent-mark:  #FE8D00;
  --c-accent-on:    #2B1A05;
  /* Anneau de focus : ambre clair, lisible sur le fond ET sur les cartes
     sombres (≥ 8:1). Écrit en toutes lettres pour que l'anneau reste défini
     même si l'encre orange du mode sombre est un jour retouchée. */
  --c-focus:        #FFB14D;

  /* 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);
  /* Les fonds pleins (boutons, jauges) reprennent des tons saturés : les
     tons assombris du mode clair seraient ternes sur fond sombre. */
  --c-success:      #16A34A;
  --c-warning:      #D97706;
  --c-danger:       #DC2626;

  /* 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 & bannières en sombre */
[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 : couleurs d'état foncées codées en dur (navy, #14532d…) illisibles
   sur fond translucide en sombre — mêmes teintes claires que les badges. */
[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; }
/* 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 (topbar, theme-toggle, etc.).
   Définie ici (DS) pour être disponible sur toute page, y compris celles qui
   ne chargent pas app-shell.css (login, visionneuse…). */
.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 « 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-ink);
  font-family: var(--font-display);
  font-weight: 600; font-size: var(--fs-sm); white-space: nowrap;
}
.icon-btn--guide:hover {
  border-color: var(--c-accent); color: var(--c-accent-ink);
  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. */
.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; }

html { -webkit-text-size-adjust: 100%; }

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-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
/* Surfaces navy (barre latérale, en-tête du visualiseur, vitrine de la page
   de connexion) : l'anneau se dessine SUR le navy, où l'encre orange tombe à
   2,5:1 alors que l'orange vif y atteint 5,9:1 — et reste lisible sur le
   navy assombri du mode sombre. On ne change que la couleur : épaisseur et
   décalage (y compris le 3 px du contraste élevé) restent ceux du dessus. */
.app-sidebar :focus-visible,
.viewer-header :focus-visible,
.login-hero :focus-visible { outline-color: var(--c-accent); }

::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;
  /* L'orange de marque ne tient pas le contraste d'un texte de 12 px sur fond
     clair (2,3:1), et son encre lisible (#9A5700) tire sur le brun. Le
     surtitre s'écrit donc dans l'encre des titres et porte l'orange de marque
     en trait d'attaque. Sur la vitrine navy de la connexion, un style en
     ligne (#FFC97D) colore le texte. */
  color: var(--c-heading);
  display: inline-flex; align-items: center; gap: 8px;
}
.ds-eyebrow::before {
  content: ''; flex-shrink: 0; width: 16px; height: 3px; border-radius: 2px;
  background: 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; }

/* PRIMAIRE = action = orange (le seul vrai bouton "agir") */
.btn--primary { --btn-bg: var(--c-accent); --btn-fg: var(--c-accent-on); 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;
}
.badge--accent  { background: var(--c-accent-soft);  color: var(--c-accent-ink); }
.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); }
.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); }

/* ------------------------------------------------------------------ */
/* 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); }
/* Croix de fermeture et action (« Annuler », « Ouvrir ») — mêmes règles qu'au
   Back-Office. `.toast > svg` ne vise que l'icône de tête : la croix a son
   propre trait. */
.toast__msg { flex: 1 1 auto; min-width: 0; }
.toast__act { flex-shrink: 0; background: none; border: 1px solid var(--c-border-strong); border-radius: var(--radius-sm); padding: 4px 10px; font: inherit; font-size: var(--fs-xs); font-weight: 600; color: var(--c-heading); cursor: pointer; transition: background var(--t-fast), border-color var(--t-fast); }
.toast__act:hover { background: var(--c-chip); border-color: var(--c-heading); }
.toast__close { margin-left: auto; flex-shrink: 0; background: none; border: none; cursor: pointer; color: var(--c-muted); width: 24px; height: 24px; 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; }

/* ─── Filets [hidden] ────────────────────────────────────────────────
   L'attribut `hidden` ne vaut que `display: none` dans la feuille du
   navigateur, soit la plus faible des priorités : le `display: flex` /
   `inline-flex` de ces composants l'écrasait, et un bouton, un badge, un
   champ ou une alerte « masqués » par script restaient affichés (et
   focusables). Même parade que #appTour[hidden] plus bas. */
.btn[hidden], .badge[hidden], .field[hidden], .alert[hidden] { display: none !important; }

/* ─── 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: var(--c-accent-on);
  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 var(--c-navy); 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).
   .ds-reveal part d'opacity:0 et compte sur son animation pour se révéler :
   on rétablit explicitement l'opacité, comme le fait déjà la requête média,
   pour qu'aucun contexte où l'animation ne se joue pas ne laisse un écran
   vide. */
[data-motion="reduce"] .ds-reveal { opacity: 1; animation: none; }
[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-ink); 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; }
}

/* ─── 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; }
/* Piste éteinte : gris moyen (≈ 5:1 sur la carte, dans les deux thèmes) et
   non plus la bordure forte, qui ne tenait qu'1,5:1 — l'interrupteur « off »
   se lisait comme désactivé, voire absent (WCAG 1.4.11). L'orange reste le
   signal de l'état coché. */
.switch__track { width: 38px; height: 22px; border-radius: 999px; background: var(--c-muted); 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-focus); 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-ink); 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-ink); }

/* 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: var(--c-accent-on); }
.segmented__item + .segmented__item { border-left: 1px solid var(--c-border); }
.segmented__item.is-active + .segmented__item { border-left-color: var(--c-accent); }

/* 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: var(--c-accent-on); }
.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-ink); 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; }
[data-tooltip-pos="bottom"]::after { bottom: auto; top: calc(100% + 8px); transform: translateX(-50%) translateY(-4px); }
[data-tooltip-pos="bottom"]::before { bottom: auto; top: calc(100% + 2px); border-top-color: transparent; border-bottom-color: var(--c-navy); }
[data-tooltip-pos="bottom"]:hover::after { transform: translateX(-50%) translateY(0); }
[data-tooltip-pos="right"]::after { bottom: 50%; left: calc(100% + 8px); transform: translate(4px, 50%); }
[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-pos="right"]:hover::after { transform: translate(0, 50%); }
[data-tooltip-pos="left"]::after { bottom: 50%; right: calc(100% + 8px); left: auto; transform: translate(-4px, 50%); }
[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-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-ink); }
.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: var(--c-accent-on); 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-ink); 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); }

/* 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-ink); 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; }

/* 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); }

/* 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; }
.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); }

/* 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-ink); }
.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; }
}


/* ─── Visite guidée (TCTour) ────────────────────────────────────────── */
/* Bouton de lancement (#appTour) : masqué tant que le moteur ne l'a pas
   activé. Le !important prime sur le display: inline-flex/-grid de
   .icon-btn / .viewer-icon-btn, sinon l'attribut [hidden] resterait sans
   effet (pas de flash si la page n'a pas de visite ou si le JS ne charge pas). */
#appTour[hidden] { display: none !important; }

/* 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);
  /* 420px : la visite du portail atteint 13 étapes (administrateur sur la page
     de garde), soit autant de pastilles à loger à côté des boutons de
     navigation dans le pied. */
  width: min(420px, 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;
  /* Encre des titres : l'orange de marque plafonnait à 2,3:1 sur la carte
     blanche, et son encre lisible tirait sur le brun. */
  color: var(--c-heading);
}
.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); }
/* Croix de fermeture : entièrement autonome (ne dépend pas de .icon-btn de
   app-shell, absent sur certaines pages comme la visionneuse). */
.tc-tour-pop__close {
  width: 28px; height: 28px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: 1px solid var(--c-border); border-radius: var(--radius-full);
  background: var(--c-card); color: var(--c-muted); cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
.tc-tour-pop__close:hover { color: var(--c-text); background: var(--c-chip); border-color: var(--c-border-strong); }
.tc-tour-pop__close svg { width: 16px; height: 16px; display: block; }

.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); }
/* Les pastilles cèdent la place aux boutons et se replient sur plusieurs lignes
   plutôt que de pousser le pied hors de la bulle : le nombre d'étapes varie
   d'une visite à l'autre, et la taille du texte est réglable (module a11y). */
.tc-tour-pop__dots { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.tc-tour-pop__dot { width: 7px; height: 7px; flex: 0 0 auto; 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; flex: 0 0 auto; 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; }
}
