/* ============================================================================
   SovreAI Chat — thème (source unique des couleurs, polices, rayons, ombres et durées)
   Injecté dans index.html au build (scripts/build-dist.mjs), APRÈS le CSS natif de LibreChat.
   Organisation (docs/DESIGN-SYSTEM.md §12) : ce fichier porte 1 charte · 2 polices · 3 rôles clair · 4 rôles sombre ·
     5 primitives natives remappées · 6 surcharges résiduelles · 7 base (typographie, texte secondaire, liens, désactivé) ;
     theme/parties/*.css (concaténés dans l'ordre des noms au build, un seul fichier servi) portent 8 composants ·
     9 écrans (a principaux, b secondaires, c paramètres et dialogues, d erreurs et états) · 10 mobile et accessibilité ·
     11 chargement et motion.
   Règle : aucune valeur littérale (couleur, ombre, durée) hors de la section 1. Sélecteurs : variables >
   data-testid > ancres sovreai-* injectées au build > classes sémantiques natives > rôles/états ARIA >
   structure (:has) > classes Tailwind (chaque sélecteur fragile est listé dans SOVREAI_CHANGES.md).
   La palette LibreChat codée en dur dans le CSS natif (gris, vert de marque, violets, toasts) est
   substituée au build (scripts/build-data/palette.json) : elle n'est donc pas surchargée ici.
   ========================================================================== */

/* ---------- 1. Charte SovreAI (relevée sur sovreai.com) + compléments validés (DESIGN-SYSTEM §14 A14) ---------- */
:root {
  /* marque */
  --sovreai-primary: #2563eb;        /* bleu marque : boutons, indicateurs (clair) */
  --sovreai-primary-hover: #1d4ed8;
  --sovreai-primary-dark: #0a50cc;   /* bleu header / fond du logo */
  --sovreai-cta: #2a82ec;            /* pilule d'appel des pages marketing (pas de texte blanc courant) */
  --sovreai-accent: #6ec1e4;         /* cyan : liens en sombre uniquement */
  --sovreai-kicker: #4f46e5;         /* indigo : surtitres (clair) */
  --sovreai-badge-text: #93c5fd;     /* bleu clair : surtitres, liens et indicateurs en sombre */
  --sovreai-badge-bg: rgba(37, 99, 235, 0.2);
  --sovreai-badge-border: rgba(37, 99, 235, 0.4);
  /* neutres clairs */
  --sovreai-bg: #f8fafc;             /* page */
  --sovreai-surface: #ffffff;
  --sovreai-surface-alt: #f1f5f9;    /* surface alternative, survol */
  --sovreai-border: #e2e8f0;         /* bordure décorative, actif */
  --sovreai-border-strong: #cbd5e1;
  --sovreai-text: #3f3737;           /* titres */
  --sovreai-text-body: #334155;
  --sovreai-text-muted: #64748b;     /* secondaire au repos ; bordure de composant */
  --sovreai-text-muted-strong: #475569; /* secondaire renforcé (survol, actif, surface alternative) */
  --sovreai-text-faint: #94a3b8;     /* décoratif uniquement (jamais un texte sur fond clair) */
  /* neutres sombres */
  --sovreai-dark-1: #0f172a;         /* page */
  --sovreai-dark-2: #1e293b;         /* surface, surface élevée */
  --sovreai-dark-3: #334155;         /* bordure, survol, surface alternative */
  --sovreai-dark-4: #475569;         /* actif */
  --sovreai-dark-text: #cbd5e1;      /* corps */
  --sovreai-dark-text-strong: #e2e8f0; /* titres */
  --sovreai-dark-text-muted: #94a3b8;  /* secondaire */
  --sovreai-hero: linear-gradient(180deg, #0f172a 0%, #1e293b 100%);
  /* états (compléments A14) — texte / fond doux, clair puis sombre */
  --sovreai-info: #0a50cc;        --sovreai-info-soft: #dbeafe;
  --sovreai-success: #166534;     --sovreai-success-soft: #dcfce7;
  --sovreai-warning: #92400e;     --sovreai-warning-soft: #fef3c7;
  --sovreai-danger: #991b1b;      --sovreai-danger-soft: #fee2e2;   --sovreai-danger-hover: #7f1d1d;
  --sovreai-info-on-dark: #93c5fd;    --sovreai-info-soft-dark: rgba(37, 99, 235, 0.2);
  --sovreai-success-on-dark: #4ade80; --sovreai-success-soft-dark: rgba(22, 101, 52, 0.3);
  --sovreai-warning-on-dark: #fbbf24; --sovreai-warning-soft-dark: rgba(146, 64, 14, 0.3);
  --sovreai-danger-on-dark: #f87171;  --sovreai-danger-soft-dark: rgba(153, 27, 27, 0.3);
  --sovreai-danger-on-dark-hover: #fca5a5;   /* danger posé sur #334155 */
  --sovreai-white: #ffffff;
  --sovreai-overlay: rgba(15, 23, 42, 0.55);
  /* coloration syntaxique (clair sur #fff / sombre sur #1e293b, toutes ≥ 4,76:1) */
  --sovreai-code-keyword: #1d4ed8;  --sovreai-code-keyword-dark: #93c5fd;
  --sovreai-code-string: #166534;   --sovreai-code-string-dark: #4ade80;
  --sovreai-code-number: #92400e;   --sovreai-code-number-dark: #fbbf24;
  --sovreai-code-title: #4f46e5;    --sovreai-code-title-dark: #6ec1e4;
  --sovreai-code-comment: #64748b;  --sovreai-code-comment-dark: #94a3b8;
  --sovreai-code-error: #991b1b;    --sovreai-code-error-dark: #f87171;
  /* formes, élévation, mouvement */
  --sovreai-radius-xs: 4px;          /* code en ligne, case à cocher (complément) */
  --sovreai-radius-btn: 8px;
  --sovreai-radius-md: 12px;         /* menus, popovers, toasts, blocs de code (complément) */
  --sovreai-radius-card: 20px;
  --sovreai-radius-pill: 100px;
  --sovreai-shadow-1: 0 1px 2px rgba(15, 23, 42, 0.06);
  --sovreai-shadow-2: 0 4px 12px rgba(15, 23, 42, 0.08);
  --sovreai-shadow-3: 0 10px 30px rgba(15, 23, 42, 0.18);
  --sovreai-shadow-3-dark: 0 20px 40px rgba(0, 0, 0, 0.45); /* carte d'authentification sur le hero sombre (complément) */
  --sovreai-duration-fast: 150ms;
  --sovreai-duration-base: 200ms;
  --sovreai-duration-slow: 250ms;
  --sovreai-ease-in: cubic-bezier(0.2, 0, 0, 1);
  --sovreai-ease-out: cubic-bezier(0.4, 0, 1, 1);
  /* polices */
  --sovreai-font-title: "PT Serif", Georgia, serif;
  --sovreai-font-body: "Roboto", system-ui, sans-serif;
  --sovreai-font-kicker: "Inter", system-ui, sans-serif;
  --sovreai-font-mono: "JetBrains Mono", ui-monospace, monospace;
}

/* ---------- 2. Polices locales (aucun appel réseau) ---------- */
@font-face { font-family: "PT Serif"; font-style: normal; font-weight: 400; font-display: swap; src: url(./fonts/sovreai/pt-serif-latin-400-normal.woff2) format("woff2"); }
@font-face { font-family: "PT Serif"; font-style: italic; font-weight: 400; font-display: swap; src: url(./fonts/sovreai/pt-serif-latin-400-italic.woff2) format("woff2"); }
@font-face { font-family: "PT Serif"; font-style: normal; font-weight: 700; font-display: swap; src: url(./fonts/sovreai/pt-serif-latin-700-normal.woff2) format("woff2"); }
@font-face { font-family: "Roboto"; font-style: normal; font-weight: 400; font-display: swap; src: url(./fonts/sovreai/roboto-latin-400-normal.woff2) format("woff2"); }
@font-face { font-family: "Roboto"; font-style: italic; font-weight: 400; font-display: swap; src: url(./fonts/sovreai/roboto-latin-400-italic.woff2) format("woff2"); }
@font-face { font-family: "Roboto"; font-style: normal; font-weight: 500; font-display: swap; src: url(./fonts/sovreai/roboto-latin-500-normal.woff2) format("woff2"); }
@font-face { font-family: "Roboto"; font-style: normal; font-weight: 700; font-display: swap; src: url(./fonts/sovreai/roboto-latin-700-normal.woff2) format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url(./fonts/sovreai/inter-latin-400-normal.woff2) format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url(./fonts/sovreai/inter-latin-500-normal.woff2) format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url(./fonts/sovreai/inter-latin-600-normal.woff2) format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url(./fonts/sovreai/inter-latin-700-normal.woff2) format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(./fonts/sovreai/jetbrains-mono-latin-400-normal.woff2) format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(./fonts/sovreai/jetbrains-mono-latin-700-normal.woff2) format("woff2"); }

/* ---------- 3. Rôles, mode clair (variables sémantiques natives de LibreChat) ---------- */
:root {
  --presentation: var(--sovreai-bg);                    /* page */
  --text-primary: var(--sovreai-text-body);
  --text-secondary: var(--sovreai-text-muted);
  --text-secondary-alt: var(--sovreai-text-muted);
  --text-tertiary: var(--sovreai-text-muted);           /* le natif l'utilise pour du texte : pas de #94a3b8 */
  --text-destructive: var(--sovreai-danger);
  --text-warning: var(--sovreai-warning);
  --header-primary: var(--sovreai-bg);
  --header-hover: var(--sovreai-surface-alt);
  --header-button-hover: var(--sovreai-surface-alt);
  --surface-primary: var(--sovreai-surface);
  --surface-primary-alt: var(--sovreai-surface);        /* barre latérale = surface (séparée de la page par un filet) */
  --surface-primary-contrast: var(--sovreai-surface-alt);
  --surface-secondary: var(--sovreai-bg);
  --surface-secondary-alt: var(--sovreai-surface-alt);
  --surface-tertiary: var(--sovreai-surface-alt);
  --surface-tertiary-alt: var(--sovreai-border);
  --surface-dialog: var(--sovreai-surface);
  --surface-hover: var(--sovreai-surface-alt);
  --surface-hover-alt: var(--sovreai-surface-alt);
  --surface-active: var(--sovreai-border);
  --surface-active-alt: var(--sovreai-surface-alt);
  --surface-chat: var(--sovreai-surface);
  --surface-submit: var(--sovreai-primary);
  --surface-submit-hover: var(--sovreai-primary-hover);
  --surface-destructive: var(--sovreai-danger);
  --surface-destructive-hover: var(--sovreai-danger-hover);
  --border-light: var(--sovreai-border);
  --border-medium: var(--sovreai-border-strong);
  --border-medium-alt: var(--sovreai-border-strong);
  --border-heavy: var(--sovreai-text-muted);            /* bordure de composant (A9) */
  --border-xheavy: var(--sovreai-text-muted-strong);
  --border-destructive: var(--sovreai-danger);
  --brand-purple: var(--sovreai-primary);               /* accent historique LibreChat -> bleu SovreAI */
  --ring-primary: var(--sovreai-primary);
  /* rôles SovreAI (utilisés par les sections 7 à 11) */
  --sv-text-title: var(--sovreai-text);
  --sv-text-strong-secondary: var(--sovreai-text-muted-strong);
  --sv-link: var(--sovreai-primary);
  --sv-kicker: var(--sovreai-kicker);
  --sv-indicator: var(--sovreai-primary);
  --sv-indicator-soft: rgba(37, 99, 235, 0.10);
  --sv-indicator-text: var(--sovreai-primary-hover);
  --sv-fill-on: var(--sovreai-primary);
  --sv-fill-on-fg: var(--sovreai-white);
  --sv-ring: var(--sovreai-primary);
  --sv-tooltip-bg: var(--sovreai-dark-1);
  --sv-tooltip-fg: var(--sovreai-white);
  --sv-code-bg: var(--sovreai-surface);
  --sv-card: var(--sovreai-surface);
  --sv-info: var(--sovreai-info);       --sv-info-soft: var(--sovreai-info-soft);
  --sv-success: var(--sovreai-success); --sv-success-soft: var(--sovreai-success-soft);
  --sv-warning: var(--sovreai-warning); --sv-warning-soft: var(--sovreai-warning-soft);
  --sv-danger: var(--sovreai-danger);   --sv-danger-soft: var(--sovreai-danger-soft);
  --sv-elevation-border: transparent;
  --sv-shadow-1: var(--sovreai-shadow-1);
  --sv-shadow-2: var(--sovreai-shadow-2);
  --sv-shadow-3: var(--sovreai-shadow-3);
}

/* ---------- 4. Rôles, mode sombre ---------- */
.dark {
  --presentation: var(--sovreai-dark-1);
  --text-primary: var(--sovreai-dark-text);
  --text-secondary: var(--sovreai-dark-text-muted);
  --text-secondary-alt: var(--sovreai-dark-text-muted);
  --text-tertiary: var(--sovreai-dark-text-muted);
  --text-destructive: var(--sovreai-danger-on-dark);
  --text-warning: var(--sovreai-warning-on-dark);
  --header-primary: var(--sovreai-dark-1);
  --header-hover: var(--sovreai-dark-3);
  --header-button-hover: var(--sovreai-dark-3);
  --surface-primary: var(--sovreai-dark-1);
  --surface-primary-alt: var(--sovreai-dark-2);
  --surface-primary-contrast: var(--sovreai-dark-2);
  --surface-secondary: var(--sovreai-dark-2);
  --surface-secondary-alt: var(--sovreai-dark-3);
  --surface-tertiary: var(--sovreai-dark-3);
  --surface-tertiary-alt: var(--sovreai-dark-3);
  --surface-dialog: var(--sovreai-dark-2);
  --surface-hover: var(--sovreai-dark-3);
  --surface-hover-alt: var(--sovreai-dark-3);
  --surface-active: var(--sovreai-dark-4);
  --surface-active-alt: var(--sovreai-dark-3);
  --surface-chat: var(--sovreai-dark-2);
  --surface-submit: var(--sovreai-primary);
  --surface-submit-hover: var(--sovreai-primary-hover);
  --surface-destructive: var(--sovreai-danger);
  --surface-destructive-hover: var(--sovreai-danger-hover);
  --border-light: var(--sovreai-dark-3);
  --border-medium: var(--sovreai-dark-4);
  --border-medium-alt: var(--sovreai-dark-4);
  --border-heavy: var(--sovreai-text-muted);            /* 3,07:1 sur #1e293b */
  --border-xheavy: var(--sovreai-dark-text-muted);
  --border-destructive: var(--sovreai-danger-on-dark);
  --brand-purple: var(--sovreai-badge-text);            /* texte en sombre : jamais #3b82f6 (3,98:1) */
  --ring-primary: var(--sovreai-badge-text);
  --sv-text-title: var(--sovreai-dark-text-strong);
  --sv-text-strong-secondary: var(--sovreai-dark-text);
  --sv-link: var(--sovreai-accent);
  --sv-kicker: var(--sovreai-badge-text);
  --sv-indicator: var(--sovreai-badge-text);            /* #2563eb n'est jamais un indicateur en sombre (2,83:1) */
  --sv-indicator-soft: rgba(147, 197, 253, 0.14);
  --sv-indicator-text: var(--sovreai-badge-text);
  --sv-fill-on: var(--sovreai-badge-text);
  --sv-fill-on-fg: var(--sovreai-dark-1);
  --sv-ring: var(--sovreai-badge-text);
  --sv-tooltip-bg: var(--sovreai-dark-text-strong);
  --sv-tooltip-fg: var(--sovreai-dark-1);
  --sv-code-bg: var(--sovreai-dark-2);
  --sv-card: var(--sovreai-dark-2);
  --sv-info: var(--sovreai-info-on-dark);       --sv-info-soft: var(--sovreai-info-soft-dark);
  --sv-success: var(--sovreai-success-on-dark); --sv-success-soft: var(--sovreai-success-soft-dark);
  --sv-warning: var(--sovreai-warning-on-dark); --sv-warning-soft: var(--sovreai-warning-soft-dark);
  --sv-danger: var(--sovreai-danger-on-dark);   --sv-danger-soft: var(--sovreai-danger-soft-dark);
  --sv-elevation-border: var(--sovreai-dark-3);
  --sv-shadow-1: none;
  --sv-shadow-2: none;
  --sv-shadow-3: none;
}

/* ---------- 5. Primitives natives remappées ---------- */
/* échelle --gray-* de LibreChat -> slate de la charte (identique en clair et en sombre) */
:root, .dark {
  --gray-20: #f8fafc; --gray-50: #f8fafc; --gray-100: #f1f5f9; --gray-200: #e2e8f0; --gray-300: #cbd5e1;
  --gray-400: #94a3b8; --gray-500: #64748b; --gray-600: #475569; --gray-700: #334155; --gray-800: #1e293b;
  --gray-850: #0f172a; --gray-900: #0f172a;
}
/* jetons shadcn/Radix (triplets HSL, consommés en hsl(var(--x))) */
:root, html {
  --background: 0 0% 100%;               /* #ffffff : dialogues */
  --foreground: 215.3 25% 26.7%;         /* #334155 */
  --secondary: 210 40% 96.1%;            /* #f1f5f9 */
  --secondary-foreground: 215.3 25% 26.7%;
  --muted: 210 40% 96.1%;
  --muted-foreground: 215.4 16.3% 46.9%; /* #64748b */
  --accent: 210 40% 96.1%;
  --accent-foreground: 215.3 25% 26.7%;
  --border: 214.3 31.8% 91.4%;           /* #e2e8f0 */
  --input: 215.4 16.3% 46.9%;            /* #64748b : bordure de composant (A9) */
  --primary: 221.2 83.2% 53.3%;          /* #2563eb exact */
  --primary-foreground: 0 0% 100%;
  --ring: 221.2 83.2% 53.3%;
  --destructive: 0 70% 35.3%;            /* #991b1b */
  --destructive-foreground: 0 0% 100%;
  --switch-unchecked: 215.4 16.3% 46.9%;
  --radius: 0.5rem;
}
.dark {
  --background: 217.2 32.6% 17.5%;       /* #1e293b : surface élevée (au lieu de #121212) */
  --foreground: 212.7 26.8% 83.9%;       /* #cbd5e1 */
  --secondary: 215.3 25% 26.7%;          /* #334155 */
  --secondary-foreground: 214.3 31.8% 91.4%;
  --muted: 215.3 25% 26.7%;
  --muted-foreground: 215 20.2% 65.1%;   /* #94a3b8 */
  --accent: 215.3 25% 26.7%;
  --accent-foreground: 214.3 31.8% 91.4%;
  --border: 215.3 25% 26.7%;             /* #334155 */
  --input: 215.4 16.3% 46.9%;            /* #64748b */
  --primary: 221.2 83.2% 53.3%;          /* fonds de bouton (texte blanc 5,17:1) */
  --primary-foreground: 0 0% 100%;
  --ring: 211.7 96.4% 78.4%;             /* #93c5fd */
  --destructive: 0 70% 35.3%;
  --destructive-foreground: 0 0% 100%;
  --switch-unchecked: 215.4 16.3% 46.9%;
}
/* typographie Markdown (Tailwind Typography) : définie sur l'élément .prose, pas sur :root */
.prose {
  --tw-prose-body: var(--sovreai-text-body); --tw-prose-headings: var(--sovreai-text); --tw-prose-lead: var(--sovreai-text-body);
  --tw-prose-links: var(--sovreai-primary); --tw-prose-bold: var(--sovreai-text); --tw-prose-counters: var(--sovreai-text-muted);
  --tw-prose-bullets: var(--sovreai-text-muted); --tw-prose-hr: var(--sovreai-border); --tw-prose-quotes: var(--sovreai-text-body);
  --tw-prose-quote-borders: var(--sovreai-primary); --tw-prose-captions: var(--sovreai-text-muted); --tw-prose-code: var(--sovreai-text);
  --tw-prose-pre-code: var(--sovreai-text-body); --tw-prose-pre-bg: var(--sovreai-surface); --tw-prose-th-borders: var(--sovreai-border-strong);
  --tw-prose-td-borders: var(--sovreai-border);
  --tw-prose-invert-body: var(--sovreai-dark-text); --tw-prose-invert-headings: var(--sovreai-dark-text-strong); --tw-prose-invert-lead: var(--sovreai-dark-text);
  --tw-prose-invert-links: var(--sovreai-accent); --tw-prose-invert-bold: var(--sovreai-dark-text-strong); --tw-prose-invert-counters: var(--sovreai-dark-text-muted);
  --tw-prose-invert-bullets: var(--sovreai-dark-text-muted); --tw-prose-invert-hr: var(--sovreai-dark-3); --tw-prose-invert-quotes: var(--sovreai-dark-text);
  --tw-prose-invert-quote-borders: var(--sovreai-badge-text); --tw-prose-invert-captions: var(--sovreai-dark-text-muted); --tw-prose-invert-code: var(--sovreai-dark-text-strong);
  --tw-prose-invert-pre-code: var(--sovreai-dark-text-strong); --tw-prose-invert-pre-bg: var(--sovreai-dark-2); --tw-prose-invert-th-borders: var(--sovreai-dark-4);
  --tw-prose-invert-td-borders: var(--sovreai-dark-3);
}
/* le conteneur des réponses porte dark:text-gray-100 (prioritaire sur les variables prose) */
.dark .markdown.prose, .markdown.prose { color: var(--text-primary); }

/* ---------- 6. Surcharges résiduelles (couleurs que ni les variables ni la substitution de palette ne couvrent) ---------- */
/* boutons de composant natifs : .btn-primary devient le bouton primaire, .btn-secondary un bouton secondaire (D001) */
.btn-primary { background-color: var(--sovreai-primary); color: var(--sovreai-white); }
.btn-primary:hover { background-color: var(--sovreai-primary-hover); }
.btn-secondary, .dark .btn-secondary { background-color: var(--surface-primary); color: var(--text-primary); border: 1px solid var(--border-heavy); }
.btn-secondary:hover, .dark .btn-secondary:hover { background-color: var(--surface-hover); color: var(--text-primary); }
/* rouge Tailwind hors charte : astérisques d'obligation, « Danger zone », messages d'erreur (D017) */
.text-red-500, .text-red-600, .dark .dark\:text-red-400, .dark .dark\:text-red-500 { color: var(--text-destructive); }
/* infobulles : texte noir codé en dur dans le natif */
.tooltip, .dark .tooltip { color: var(--sv-tooltip-fg); background-color: var(--sv-tooltip-bg); }
/* coloration syntaxique (D015) */
.hljs { color: var(--text-primary); }
.hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-type { color: var(--sovreai-code-keyword); }
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute { color: var(--sovreai-code-string); }
.hljs-number, .hljs-built_in, .hljs-symbol, .hljs-attr, .hljs-variable, .hljs-template-variable { color: var(--sovreai-code-number); }
.hljs-title, .hljs-section, .hljs-name, .hljs-bullet, .hljs-selector-id, .hljs-selector-class, .hljs-params { color: var(--sovreai-code-title); }
.hljs-comment, .hljs-quote, .hljs-meta { color: var(--sovreai-code-comment); font-style: italic; }
.hljs-deletion { color: var(--sovreai-code-error); }
.dark .hljs-keyword, .dark .hljs-selector-tag, .dark .hljs-literal, .dark .hljs-type { color: var(--sovreai-code-keyword-dark); }
.dark .hljs-string, .dark .hljs-regexp, .dark .hljs-addition, .dark .hljs-attribute { color: var(--sovreai-code-string-dark); }
.dark .hljs-number, .dark .hljs-built_in, .dark .hljs-symbol, .dark .hljs-attr, .dark .hljs-variable, .dark .hljs-template-variable { color: var(--sovreai-code-number-dark); }
.dark .hljs-title, .dark .hljs-section, .dark .hljs-name, .dark .hljs-bullet, .dark .hljs-selector-id, .dark .hljs-selector-class, .dark .hljs-params { color: var(--sovreai-code-title-dark); }
.dark .hljs-comment, .dark .hljs-quote, .dark .hljs-meta { color: var(--sovreai-code-comment-dark); }
.dark .hljs-deletion { color: var(--sovreai-code-error-dark); }
/* interrupteurs : allumé = remplissage d'état (#93c5fd + poignée foncée en sombre) */
button[role="switch"][data-state="checked"] { background-color: var(--sv-fill-on); }
button[role="switch"][data-state="checked"] > span { background-color: var(--sv-fill-on-fg); }
.dark button[role="switch"][data-state="unchecked"] > span { background-color: var(--sovreai-dark-text); }

/* ---------- 7. Base : typographie, texte secondaire renforcé, liens, désactivé ---------- */
/* Roboto pour toute l'interface ; PT Serif 400 pour les titres éditoriaux et le nom du produit ; Inter pour les surtitres ;
   JetBrains Mono pour le code (DESIGN-SYSTEM §3). Pas de règle globale h1-h3 : la serif est posée par contexte. */
html, body, #root { font-family: var(--sovreai-font-body); }
/* le CSS natif impose « code, pre { font-family: Consolas… !important } » : même spécificité, déclaré après (A8) */
code, pre, kbd, samp, .font-mono, .hljs { font-family: var(--sovreai-font-mono) !important; }
.font-light { font-weight: 400; } /* Roboto 300 n'est pas livrée */
/* display : titres d'authentification et de page (Marketplace, Projets) */
.sovreai-auth h1[class], main h1[class] {
  font-family: var(--sovreai-font-title); font-weight: 400; font-size: 30px; line-height: 38px; letter-spacing: -0.01em; color: var(--sv-text-title);
}
/* title-1 : titres de section de page, titre du détail d'un assistant ; h1-h2 des réponses */
main h2.text-2xl[class], [role="dialog"] h2.text-2xl[class], .markdown :is(h1, h2)[class], .markdown :is(h1, h2) {
  font-family: var(--sovreai-font-title); font-weight: 400; font-size: 24px; line-height: 32px; letter-spacing: -0.01em; color: var(--sv-text-title);
}
/* title-2 : titres de dialogue et de panneau ; h3 des réponses */
[role="dialog"] h2:not(.text-2xl)[class], .markdown h3[class], .markdown h3 {
  font-family: var(--sovreai-font-title); font-weight: 400; font-size: 20px; line-height: 28px; letter-spacing: -0.01em; color: var(--sv-text-title);
}
.markdown :is(h4, h5, h6) { font-family: var(--sovreai-font-body); font-weight: 500; font-size: 16px; line-height: 24px; color: var(--sv-text-title); }
/* author : nom d'auteur des messages (le nom du produit « SovreAI » est en PT Serif) */
:is(.agent-turn, .user-turn) > h2[class] { font-family: var(--sovreai-font-title); font-weight: 400; font-size: 16px; line-height: 24px; color: var(--sv-text-title); }
/* kicker : surtitres (sections de la barre latérale et des paramètres, groupes des raccourcis) — jamais sur « SovreAI » */
nav button.text-xs.font-bold, [role="dialog"] section > h3[class], [role="dialog"] section > div > h3[class], [role="dialog"] h3.uppercase[class] {
  font-family: var(--sovreai-font-kicker); font-weight: 600; font-size: 12px; line-height: 16px; letter-spacing: 2px; text-transform: uppercase; color: var(--sv-kicker);
}
[role="dialog"] section > h3.text-red-500[class] { color: var(--text-destructive); }
/* caption : groupes de dates de la barre latérale (natif : serif 11,2 px) */
nav h2[class] { font-family: var(--sovreai-font-body); font-weight: 500; font-size: 12px !important; line-height: 16px; letter-spacing: 0; color: var(--text-secondary); }
/* le texte des réponses : lecture longue (body-read 16/26) */
.markdown.prose { font-size: 16px; line-height: 26px; }

/* le texte et les icônes secondaires passent au ton renforcé sur fond de survol ou d'actif (contraste AA garanti) */
:where(button, a, [role="menuitem"], [role="option"], [role="tab"], [role="button"]):hover,
[aria-selected="true"], [aria-current]:not([aria-current="false"]), [data-active-item], [data-state="active"], [data-state="open"] {
  --text-secondary: var(--sv-text-strong-secondary);
}
/* liens dans le contenu : couleur + soulignement permanent (la couleur seule ne suffit pas, WCAG 1.4.1) */
.markdown a, .prose a { color: var(--sv-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.markdown a:hover, .prose a:hover { text-decoration-thickness: 2px; }
/* désactivé : une seule règle (opacité sur le composant), plus de teinte ad hoc */
:is(button, [role="button"], input, select, textarea):disabled, [aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }

/* SovreAI Chat — thème, partie « composants ». Concaténée après theme/sovreai-theme.css au build (scripts/build-dist.mjs §1) :
   n'utilise que les jetons et rôles définis dans les sections 1 à 7 de ce fichier (aucune valeur littérale). */

/* ---------- 8. Composants ---------- */
/* ── En-tête de conversation : opaque (le texte ne défile plus sous les pastilles, D025), filet bas ── */
main div.absolute.top-0.z-10:has([data-testid="model-selector-button"]) {
  background: var(--presentation) !important; background-image: none !important; border-bottom: 1px solid var(--border-light);
}
/* ── Sélecteur métier : pilule, Roboto 500 (Inter réservée aux surtitres) ── */
[data-testid="model-selector-button"] {
  border-radius: var(--sovreai-radius-pill) !important; height: 36px !important; border-color: var(--border-light) !important;
  background: var(--surface-chat) !important; color: var(--sv-text-title) !important;
  font-family: var(--sovreai-font-body); font-weight: 500; font-size: 14px; padding: 0 12px 0 8px !important;
  transition: background-color var(--sovreai-duration-fast), border-color var(--sovreai-duration-fast);
}
[data-testid="model-selector-button"]:hover { background: var(--surface-hover) !important; border-color: var(--border-medium) !important; }
/* chevron : la pastille ouvre un menu (DESIGN-SYSTEM §11.1 « icône 20 + nom + chevron », D122) */
[data-testid="model-selector-button"]::after {
  content: ""; flex: none; width: 12px; height: 12px; margin-left: 6px; background: currentColor; opacity: 0.8;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>") center / contain no-repeat;
}
/* export masqué dans l'en-tête (DESIGN-SYSTEM §11.1, A5) : pictogramme « partager » trompeur pour un menu d'une entrée */
#export-menu-button { display: none !important; }
/* menu métier : surface élevée, pas de recherche sous 9 profils (DESIGN-SYSTEM §11.1) */
[role="dialog"]:has(#model-search) {
  background: var(--surface-dialog) !important; border-color: var(--sv-elevation-border) !important; border-radius: var(--sovreai-radius-md) !important;
  box-shadow: var(--sv-shadow-2) !important; padding: 4px !important;
}
[role="dialog"]:has(#model-search):not(:has([role="option"]:nth-child(9))) div:has(> div > #model-search) { display: none; }
[role="dialog"]:has(#model-search) [role="option"] { border-radius: var(--sovreai-radius-btn) !important; min-height: 44px; }
[role="dialog"]:has(#model-search) [role="option"][data-active-item] { background: var(--surface-hover) !important; color: var(--text-primary) !important; }
[role="dialog"]:has(#model-search) [role="option"][data-active-item]::before { background: var(--sv-indicator) !important; }
[role="dialog"]:has(#model-search) [role="option"] span.text-xs { color: var(--text-secondary); }
/* ── Composer : surface, rayon 20, bordure décorative + ombre e2 (exception A9), anneau au focus ── */
div:has(> div > div > [data-testid="text-input"]) {
  background: var(--surface-chat) !important; border: 1px solid var(--border-medium) !important; border-radius: var(--sovreai-radius-card) !important;
  box-shadow: var(--sv-shadow-2) !important; transition: border-color var(--sovreai-duration-fast), box-shadow var(--sovreai-duration-fast);
}
div:has(> div > div > [data-testid="text-input"]):focus-within { border-color: var(--sv-indicator) !important; outline: 2px solid var(--sv-ring); outline-offset: 1px; }
[data-testid="text-input"] { font-size: 16px; line-height: 24px; color: var(--text-primary); }
[data-testid="text-input"]::placeholder { color: var(--text-secondary) !important; opacity: 1; }
:is(#attach-file-menu-button, #tools-dropdown-button) { color: var(--text-secondary); }
:is(#attach-file-menu-button, #tools-dropdown-button):hover { color: var(--sv-text-strong-secondary); background: var(--surface-hover); }
/* bouton d'envoi : primaire rond, flèche blanche ; désactivé = règle commune (opacité 0,5) */
[data-testid="send-button"] { background-color: var(--sovreai-primary) !important; color: var(--sovreai-white) !important; border-radius: var(--sovreai-radius-pill) !important; }
[data-testid="send-button"] svg { color: var(--sovreai-white) !important; }
[data-testid="send-button"]:hover:not(:disabled) { background-color: var(--sovreai-primary-hover) !important; }

/* ── Messages (DESIGN-SYSTEM §5.1) ── */
/* avatar 28 px ; horodatage en caption Roboto (le titre d'auteur est en PT Serif) */
.message-render > div:first-child > div { width: 28px !important; height: 28px !important; }
:is(.agent-turn, .user-turn) > h2 time { font: 400 12px/16px var(--sovreai-font-body); letter-spacing: 0; color: var(--text-secondary); }
/* message utilisateur : bulle surface alternative alignée à droite, nom masqué visuellement (lu par les lecteurs d'écran), A7 */
.message-render:has(> .user-turn) { flex-direction: row-reverse; }
.message-render:has(> .user-turn) > div:first-child { display: none; }
.user-turn { align-items: flex-end; }
.user-turn > h2 { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.user-turn .text-message { align-items: flex-end !important; }
.user-turn .markdown.message-content {
  width: auto !important; max-width: 85%; background: var(--surface-secondary-alt); color: var(--text-primary);
  border-radius: var(--sovreai-radius-card); padding: 10px 16px;
}
.user-turn > div > div:last-child { justify-content: flex-end !important; }
.user-turn:has(textarea) .markdown.message-content, .user-turn:has(textarea) .text-message { width: 100% !important; max-width: none; }
/* édition d'un message : pleine colonne (la bulle alignée à droite réduisait l'éditeur à 370 px), champ de la charte,
   actions à droite avec le primaire en dernier, « Annuler » en fantôme (DESIGN-SYSTEM §5.1) */
.user-turn:has([data-testid="message-text-editor"]), .user-turn:has([data-testid="message-text-editor"]) .text-message { align-items: stretch !important; }
div:has(> [data-testid="message-text-editor"]) { background: var(--surface-chat) !important; border: 1px solid var(--border-heavy) !important; border-radius: var(--sovreai-radius-md) !important; }
div:has(> [data-testid="message-text-editor"]):focus-within { border-color: var(--sv-indicator) !important; outline: 2px solid var(--sv-ring); outline-offset: 1px; }
.text-message div:has(> .btn-primary + .btn-secondary) { flex-direction: row-reverse; justify-content: flex-start !important; flex-wrap: wrap; gap: 8px; }
.text-message div:has(> .btn-primary + .btn-secondary) > .btn { margin: 0 !important; }
.text-message div:has(> .btn-primary + .btn-secondary) > .btn-neutral { background: transparent !important; border-color: transparent !important; color: var(--text-primary) !important; }
.text-message div:has(> .btn-primary + .btn-secondary) > .btn-neutral:hover { background: var(--surface-hover) !important; }
/* pendant l'édition, la barre d'actions du message (crayon actif, copier, lire) ne concurrence plus les trois boutons (D097) */
.message-render:has([data-testid="message-text-editor"]) div:has(> .hover-button) { display: none !important; }
/* bouton neutre natif (#40414f, texte ivoire en sombre) : secondaire de la charte partout ailleurs (D082) */
.btn-neutral, .dark .btn-neutral { background: transparent; color: var(--text-primary); border-color: var(--border-heavy); }
.btn-neutral:hover:not(:disabled), .dark .btn-neutral:hover:not(:disabled) { background: var(--surface-hover); }
/* mesure de lecture ~70 caractères pour le texte, pleine colonne pour tableaux et code (A6) */
.agent-turn .markdown.prose > :is(p, ul, ol, blockquote, h1, h2, h3, h4, h5, h6) { max-width: 70ch; }
.markdown.prose :is(h1, h2) { margin: 24px 0 8px; }
.markdown.prose h3 { margin: 20px 0 8px; }
/* tableaux : en-tête surface alternative, filets décoratifs, zébrage page/surface, rayon 12 */
.markdown .markdown-table-wrapper { border: 1px solid var(--border-light); border-radius: var(--sovreai-radius-md); overflow-x: auto; margin: 16px 0; }
.markdown table { width: 100%; border-collapse: collapse; margin: 0 !important; font-size: 14px; line-height: 20px; }
.markdown table :is(th, td) { border: 0 !important; border-bottom: 1px solid var(--border-light) !important; padding: 10px 12px !important; text-align: left; vertical-align: top; }
.markdown table th { background: var(--surface-secondary-alt) !important; color: var(--sv-text-title); font-weight: 500; }
.markdown table tbody tr:last-child td { border-bottom: 0 !important; }
.markdown table tbody tr:nth-child(even) td { background: var(--sv-card); } /* zébrage page / surface (#fff sur #f8fafc, #1e293b sur #0f172a) */
/* citation : liseré indicateur 3 px, italique, sans guillemets ajoutés, interligne de lecture 16/26 (D028) */
.markdown blockquote, .markdown blockquote p { line-height: 26px !important; }
.markdown blockquote { border-left: 3px solid var(--sv-indicator) !important; padding: 2px 0 2px 16px !important; margin: 16px 0; font-style: italic; font-weight: 400 !important; color: var(--text-primary) !important; quotes: none; }
.markdown blockquote p::before, .markdown blockquote p::after { content: none !important; }
/* code : bloc surface + filet, rayon 12, en-tête surface alternative ; code en ligne surface alternative rayon 4 (D014) */
.markdown pre { background: var(--sv-code-bg) !important; border: 1px solid var(--border-light) !important; border-radius: var(--sovreai-radius-md) !important; overflow: hidden; margin: 16px 0 !important; padding: 0 !important; }
.markdown pre > div { background: transparent !important; border-radius: 0 !important; }
.markdown pre > div > div:first-child { background: var(--surface-secondary-alt) !important; color: var(--sv-text-strong-secondary) !important; font-family: var(--sovreai-font-body); border-bottom: 1px solid var(--border-light); }
/* texte secondaire sur surface alternative : ton renforcé (6,9:1 ; #94a3b8 sur #334155 ne faisait que 4,04:1) */
.markdown pre > div > div:first-child :is(span, button) { color: var(--sv-text-strong-secondary) !important; }
/* le bandeau natif est un second niveau (bg-surface-primary-alt, blanc en clair) : il prend la couleur du premier */
.markdown pre > div > div:first-child > div { background: transparent !important; }
.markdown pre code.hljs { color: var(--text-primary) !important; }
.markdown pre code { font-size: 14px !important; line-height: 22px !important; }
.markdown code:not(pre code) { background: var(--surface-secondary-alt) !important; color: var(--sv-text-title) !important; border-radius: var(--sovreai-radius-xs); padding: 1px 5px; font-size: 0.875em; font-weight: 400 !important; }
.markdown code:not(pre code)::before, .markdown code:not(pre code)::after { content: none !important; }
.user-turn .markdown code:not(pre code) { background: var(--surface-primary) !important; }
/* actions de message : icônes secondaires, cibles 36 px (44 en tactile), bifurcation masquée pour une PME (A5) */
.hover-button { color: var(--text-secondary) !important; min-width: 36px; min-height: 36px; border-radius: var(--sovreai-radius-btn) !important; display: inline-flex; align-items: center; justify-content: center; }
.hover-button:hover { color: var(--sv-text-strong-secondary) !important; background: var(--surface-hover) !important; }
.hover-button:has(> svg.lucide-git-fork) { display: none !important; }
/* réflexion du modèle : masquée (A5 : raisonnement brut, souvent en anglais) ; le point de génération (§8.1) signale
   l'activité. À couper aussi à la source (routeur) : le texte reste dans le DOM. */
.agent-turn .group\/reasoning { display: none !important; }
/* attente (§8.1) : tant que la réponse n'a pas de texte, le bloc de réflexion devient « point pulsant + SovreAI rédige sa
   réponse… » (sans cela, rien ne bouge à l'écran pendant que le modèle réfléchit) */
body:has([data-testid="stop-generation-button"]) .agent-turn:not(:has(.markdown)) .group\/reasoning { display: flex !important; align-items: center; gap: 8px; min-height: 24px; margin: 4px 0 8px; }
body:has([data-testid="stop-generation-button"]) .agent-turn:not(:has(.markdown)) .group\/reasoning > * { display: none !important; }
body:has([data-testid="stop-generation-button"]) .agent-turn:not(:has(.markdown)) .group\/reasoning::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--sv-indicator); animation: sovreai-pulse 1.2s ease-in-out infinite; }
body:has([data-testid="stop-generation-button"]) .agent-turn:not(:has(.markdown)) .group\/reasoning::after { content: "SovreAI rédige sa réponse…"; font: 400 12px/16px var(--sovreai-font-body); color: var(--text-secondary); }
/* ── Génération (DESIGN-SYSTEM §8.1) : point de 8 px pulsant au lieu du glyphe « ⬤ » en police système ── */
.result-streaming>:not(ol):not(ul):not(pre):last-child:after, .result-streaming>pre:last-child code:after,
.result-streaming>ul:last-child>li:last-child:not(:has(>:is(ul,ol,pre))):after, .result-streaming>ol:last-child>li:last-child:not(:has(>:is(ul,ol,pre))):after,
.result-streaming>ol:last-child>li:last-child:after, .result-streaming>ul:last-child>li:last-child:after {
  content: "" !important; display: inline-block; width: 8px !important; height: 8px !important; margin-left: 6px; border-radius: 50%;
  background: var(--sv-indicator); vertical-align: middle; font-family: inherit; animation: sovreai-pulse 1.2s ease-in-out infinite;
}
.submitting .result-thinking:empty:last-child:after { background-color: var(--sv-indicator) !important; width: 8px !important; height: 8px !important; animation: sovreai-pulse 1.2s ease-in-out infinite !important; order: -1; }
.submitting .result-thinking:empty:last-child { display: flex; align-items: center; gap: 8px; }
.submitting .result-thinking:empty:last-child::before { content: "SovreAI rédige sa réponse…"; font: 400 12px/16px var(--sovreai-font-body); color: var(--text-secondary); }
.shimmer, .dark .shimmer { background: none !important; -webkit-text-fill-color: currentColor !important; color: var(--text-secondary); animation: sovreai-pulse 1.5s ease-in-out infinite !important; }
/* bouton Arrêter : même forme que l'envoi (au lieu d'un disque gris, D034) */
[data-testid="stop-generation-button"] { background-color: var(--sovreai-primary) !important; color: var(--sovreai-white) !important; border-radius: var(--sovreai-radius-pill) !important; }
[data-testid="stop-generation-button"] svg { color: var(--sovreai-white) !important; fill: currentColor; }
/* aller au dernier message : rond 36 px, surface élevée, centré 12 px au-dessus du composer (DESIGN-SYSTEM §5, D029) ;
   masqué pendant l'édition d'un message (il recouvrait l'éditeur) */
div:has(> .premium-scroll-button) { justify-content: center !important; bottom: 12px !important; }
main:has([data-testid="message-text-editor"]) div:has(> .premium-scroll-button) { display: none !important; }
.premium-scroll-button, .dark .premium-scroll-button {
  width: 36px; height: 36px; background: var(--surface-dialog); border: 1px solid var(--border-light); box-shadow: var(--sv-shadow-2); color: var(--text-secondary);
}

/* SovreAI Chat — thème, partie « écrans principaux (authentification, accueil, barre latérale) ». Concaténée après theme/sovreai-theme.css au build (scripts/build-dist.mjs §1) :
   n'utilise que les jetons et rôles définis dans les sections 1 à 7 de ce fichier (aucune valeur littérale). */

/* ---------- 9. Écrans (repris et complétés thème par thème) ---------- */
/* ── Authentification (connexion, inscription, mot de passe oublié, réinitialisation, vérification, 2FA) ──
   Ancre : classe sovreai-auth injectée au build sur la racine de la mise en page d'authentification (plus de
   dépendance aux aria-label « Login form »… désormais traduits). Hero sombre dans les deux thèmes (A3). */
.sovreai-auth {
  --sv-auth-card: var(--sovreai-surface); --sv-auth-card-border: transparent; --sv-auth-field-label: var(--sovreai-text-muted);
  --sv-auth-badge-fg: var(--sovreai-info); --sv-auth-badge-bg: var(--sovreai-info-soft);
  background: var(--sovreai-hero) !important;
}
.dark .sovreai-auth {
  --sv-auth-card: var(--sovreai-dark-2); --sv-auth-card-border: var(--sovreai-dark-3); --sv-auth-field-label: var(--sovreai-dark-text-muted);
  --sv-auth-badge-fg: var(--sovreai-info-on-dark); --sv-auth-badge-bg: var(--sovreai-info-soft-dark);
}
.sovreai-auth main, .sovreai-auth > div:not(.sovreai-auth-card) { background: transparent !important; }
/* logo : version blanche sur le hero */
.sovreai-auth > div:first-child img { content: url("./assets/logo-white.svg"); }
/* carte */
.sovreai-auth main > div {
  background: var(--sv-auth-card) !important; border: 1px solid var(--sv-auth-card-border); border-radius: var(--sovreai-radius-card) !important;
  padding: 32px !important; box-shadow: var(--sovreai-shadow-3);
}
/* en sombre, la carte se détache du bas du dégradé par un filet plus clair et une ombre portée (D167) */
.dark .sovreai-auth main > div { border-color: var(--sovreai-dark-4); box-shadow: var(--sovreai-shadow-3-dark); }
/* carte ancrée en haut : l'apparition d'un message d'erreur pousse le contenu vers le bas au lieu de faire sauter la carte (D115) */
/* (connexion seulement : les cartes plus hautes, comme l'inscription, restent centrées) */
.sovreai-auth main:has([data-testid="login-button"]) { align-items: flex-start !important; padding-top: clamp(24px, 19vh, 160px); }
.sovreai-auth main h1 { text-wrap: balance; }
/* « Vous avez déjà un compte ? » : texte secondaire, graisse livrée (D091) */
.sovreai-auth main > div > p { color: var(--text-secondary) !important; font-weight: 400; }
/* badge « IA locale & souveraine » (badge Info) au-dessus du titre */
.sovreai-auth main h1 { display: flex; flex-direction: column; align-items: center; margin-bottom: 20px; }
.sovreai-auth main h1::before {
  content: "IA locale & souveraine"; content: "IA locale & souveraine" / ""; display: inline-block; margin: 0 auto 16px; padding: 4px 12px; /* hors du nom accessible du titre (D084) */
  font: 600 12px/16px var(--sovreai-font-kicker); letter-spacing: 2px; text-transform: uppercase;
  color: var(--sv-auth-badge-fg); background: var(--sv-auth-badge-bg); border-radius: var(--sovreai-radius-pill);
}
/* champs : étiquette flottante native, fond = carte (plus de pavé visible), bordure de composant, rayon 8 */
.sovreai-auth input.peer, .sovreai-auth .group\/secret-input input {
  height: 48px !important; /* même hauteur pour les champs avec ou sans l'œil */
  background: transparent !important; border: 1px solid var(--border-heavy) !important; border-radius: var(--sovreai-radius-btn) !important;
  color: var(--text-primary); box-shadow: none !important;
}
.sovreai-auth input.peer:focus, .sovreai-auth .group\/secret-input input:focus { border-color: var(--sv-indicator) !important; outline: 2px solid var(--sv-ring); outline-offset: 1px; }
.sovreai-auth label[for] { background: var(--sv-auth-card) !important; color: var(--sv-auth-field-label) !important; }
.sovreai-auth .peer:focus ~ label[for] { color: var(--sv-indicator) !important; }
/* bouton principal */
.sovreai-auth [type="submit"] { background: var(--sovreai-primary) !important; color: var(--sovreai-white) !important; border-radius: var(--sovreai-radius-btn) !important; height: 44px; font-weight: 500; }
.sovreai-auth [type="submit"]:hover { background: var(--sovreai-primary-hover) !important; }
/* liens de la carte (retour à la connexion, mot de passe oublié) et du pied de page */
.sovreai-auth main a { color: var(--sv-link) !important; text-decoration: underline; text-underline-offset: 2px; }
.sovreai-auth [role="contentinfo"] a { color: var(--sovreai-badge-text) !important; text-decoration: underline; text-decoration-color: currentColor; text-underline-offset: 2px; }
.sovreai-auth [role="contentinfo"] > div { border-color: var(--sovreai-dark-4) !important; }
.sovreai-auth :is(a, button, input):focus-visible { outline: 2px solid var(--sovreai-badge-text); outline-offset: 2px; }
/* mot de passe oublié désactivé (pas d'e-mail configuré) : indication plutôt qu'un lien absent */
.sovreai-auth form:has([data-testid="login-button"]):not(:has(a[href*="forgot-password"]))::after {
  content: "Mot de passe oublié ? Contactez votre administrateur."; display: block; margin-top: 16px; text-align: center;
  font: 400 12px/16px var(--sovreai-font-body); color: var(--text-secondary);
}
/* message d'erreur du formulaire : carte danger de la charte */
.sovreai-auth main > div > div:is([class*="border-red"], [class*="bg-red"]) {
  background: var(--sv-danger-soft) !important; border: 1px solid var(--sv-danger) !important; color: var(--sv-danger) !important;
  border-radius: var(--sovreai-radius-btn) !important; font-size: 14px; line-height: 20px;
}
.sovreai-auth main:has(> div > div:is([class*="border-red"], [class*="bg-red"])) :is(input.peer, .group\/secret-input input):not(:focus) { border-color: var(--sv-danger) !important; }
/* icône d'erreur (DESIGN-SYSTEM §6 : bordure + message + icône, jamais la couleur seule) */
.sovreai-auth main > div > div:is([class*="border-red"], [class*="bg-red"]) { display: flex; align-items: flex-start; gap: 8px; }
.sovreai-auth main > div > div:is([class*="border-red"], [class*="bg-red"])::before {
  content: ""; flex: none; width: 20px; height: 20px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'><circle cx='12' cy='12' r='10'/><path d='M12 8v4M12 16h.01'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'><circle cx='12' cy='12' r='10'/><path d='M12 8v4M12 16h.01'/></svg>") center / contain no-repeat;
}
/* bouton de thème masqué sur ces pages (A3 ; il recouvrait les liens en mobile) */
.sovreai-auth div:has(> button > svg:is(.lucide-sun, .lucide-moon)) { display: none !important; }

/* ── Accueil : badge, titre display (PT Serif 30/38), sous-titre, suggestions en cartes (A12, A18) ── */
main div.flex.flex-col.items-center.justify-center.gap-2 > *:not(.sr-only) {
  font-family: var(--sovreai-font-title); font-weight: 400; font-size: 30px; line-height: 38px; letter-spacing: -0.01em; max-width: 40rem; color: var(--sv-text-title);
}
main .animate-fadeIn.mt-4.max-w-md { max-width: 36rem; margin-top: 8px; font-size: 16px; line-height: 24px; color: var(--text-secondary); }
/* badge : bloc de l'accueil générique = icône, puis titre SplitText (texte masqué .sr-only + p.split-parent, composant propre
   à l'accueil). Indépendant du sous-titre .animate-fadeIn (absent sans modelSpecs ni greeting) ; l'accueil d'un assistant
   métier (titre enveloppé dans un div, sans icône voisine) n'est pas visé. */
main div:has(> div > div + .sr-only + p.split-parent)::before {
  content: "Vos données restent sur votre infrastructure"; content: "Vos données restent sur votre infrastructure" / ""; display: inline-block; margin-bottom: 16px; padding: 4px 12px;
  font: 600 12px/16px var(--sovreai-font-kicker); letter-spacing: 2px; text-transform: uppercase;
  color: var(--sv-info); background: var(--sv-info-soft); border-radius: var(--sovreai-radius-pill);
}
@media (max-width: 767px) {
  /* l'en-tête est posé par-dessus le haut de page : le badge doit passer dessous ; titre display mobile 26/34 */
  main div:has(> div > div + .sr-only + p.split-parent) { margin-top: 56px; }
  main div:has(> div > div + .sr-only + p.split-parent)::before { content: "Vos données restent chez vous"; content: "Vos données restent chez vous" / ""; letter-spacing: 1px; }
  main div.flex.flex-col.items-center.justify-center.gap-2 > *:not(.sr-only) { font-size: 26px; line-height: 34px; }
}
main button:has(> span.line-clamp-2) {
  border-radius: var(--sovreai-radius-md) !important; border: 1px solid var(--border-light) !important; background: var(--surface-chat) !important;
  color: var(--text-primary) !important; box-shadow: var(--sv-shadow-1) !important; font-size: 14px; line-height: 20px; padding: 12px 16px !important;
  transition: border-color var(--sovreai-duration-fast), background-color var(--sovreai-duration-fast);
}
main button:has(> span.line-clamp-2):hover { border-color: var(--sv-indicator) !important; background: var(--surface-chat) !important; }
/* 4 suggestions en 2 × 2 en desktop (plutôt que 3 + 1 orpheline) */
@media (min-width: 768px) {
  main div:has(> button > span.line-clamp-2) { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 640px; margin-inline: auto; }
  main button:has(> span.line-clamp-2) { max-width: none !important; }
}
/* mobile : cartes sur toute la largeur de la colonne du composer (au lieu de 256 px centrés) */
@media (max-width: 767px) {
  main button:has(> span.line-clamp-2) { max-width: none !important; width: 100%; }
}
/* pied de page d'accueil : caption secondaire, sous le sous-titre dans la hiérarchie (D123) */
[role="contentinfo"]:not(.sovreai-auth *) { color: var(--text-secondary) !important; }
/* symbole de marque : une seule forme partout, le carré arrondi du pictogramme (la pastille ronde le rognait, D118) */
.rounded-full:has(> img[src*="logo-mark"]), img.rounded-full[src*="logo-mark"], main .shadow-stroke.rounded-full { border-radius: 25% !important; }
main .shadow-stroke.rounded-full { background: var(--sovreai-primary) !important; color: var(--sovreai-white) !important; box-shadow: none !important; overflow: hidden; }
main .shadow-stroke.rounded-full img { background: var(--sovreai-primary-dark); }
/* ── Barre latérale : rail étiqueté C2 (DESIGN-SYSTEM §14 A1, maquettes docs/screenshots/v2/maquettes/) ──
   Ancre : classe sovreai-rail injectée au build sur le rail natif. Le rail et le panneau forment une seule surface,
   séparée de la page par un filet. La réduction du rail se fait par configuration et par rôle (pas en CSS). */
div:has(> .sovreai-rail) { --surface-primary-alt: var(--surface-primary); }
.dark div:has(> .sovreai-rail) { --surface-primary-alt: var(--sovreai-dark-2); }
.sovreai-rail {
  width: 84px !important; padding: 8px 6px !important; align-items: center !important; gap: 6px !important;
  background: var(--surface-primary-alt) !important; border-right: 1px solid var(--border-light) !important;
}
div:has(> .sovreai-rail):has(> nav) > nav { border-right: 1px solid var(--border-light); }
div:has(> .sovreai-rail):has(> nav) > .sovreai-rail { border-right-color: transparent !important; }
.sovreai-rail > div:has(> [data-testid^="nav-panel-"]) { align-items: center; gap: 4px !important; overflow: visible !important; }
.sovreai-rail > div.mt-auto { display: flex; justify-content: center; }
.sovreai-rail > div.mx-2 { width: 40px; margin: 2px auto; }
/* entrées libellées 68 × 56 : libellé visible = début du nom accessible (WCAG 2.5.3) */
.sovreai-rail :is([data-testid="new-chat-button"], [data-testid^="nav-panel-"], [data-testid="nav-user"]) {
  width: 76px !important; height: 56px !important; flex-direction: column !important; gap: 4px !important; padding: 6px 2px !important;
  border-radius: var(--sovreai-radius-btn) !important; color: var(--text-secondary) !important;
  transition: background-color var(--sovreai-duration-fast), color var(--sovreai-duration-fast);
}
.sovreai-rail :is([data-testid="new-chat-button"], [data-testid^="nav-panel-"], [data-testid="nav-user"])::after {
  content: attr(aria-label); max-width: 74px; overflow: hidden; text-overflow: ellipsis;
  font: 500 12px/16px var(--sovreai-font-body); letter-spacing: 0; white-space: nowrap;
}
.sovreai-rail [data-testid="new-chat-button"]::after { content: "Nouvelle"; }
.sovreai-rail [data-testid="nav-panel-conversations"]::after { content: "Historique"; }
.sovreai-rail [data-testid="nav-panel-files"]::after { content: "Mes fichiers"; }
.sovreai-rail [data-testid="nav-panel-agents"]::after { content: "Assistants"; }
.sovreai-rail [data-testid="nav-panel-prompts"]::after { content: "Modèles"; }
.sovreai-rail [data-testid="nav-panel-mcp-builder"]::after { content: "Connecteurs"; }
.sovreai-rail [data-testid="nav-panel-memories"]::after { content: "Mémoire"; }
.sovreai-rail [data-testid="nav-panel-bookmarks"]::after { content: "Signets"; }
.sovreai-rail [data-testid="nav-panel-skills"]::after { content: "Compétences"; }
.sovreai-rail [data-testid="nav-user"]::after { content: "Compte"; }
/* avatar 28 + libellé : contenu resserré pour tenir dans 56 px (le jambage du « p » était rogné) */
.sovreai-rail [data-testid="nav-user"] { padding: 4px 2px !important; gap: 2px !important; }
.sovreai-rail :is([data-testid="new-chat-button"], [data-testid^="nav-panel-"], [data-testid="nav-user"])::after { flex: none; }
/* survol : l'entrée active garde sa marque (le survol l'effaçait juste après le clic) */
.sovreai-rail :is(button, a):not([aria-pressed="true"], [data-testid="new-chat-button"]):hover { background: var(--surface-hover) !important; color: var(--sv-text-strong-secondary) !important; }
/* état actif : pastille + texte renforcé (5,8:1 en clair, 5,9:1 en sombre) ; éteint quand la barre est repliée */
.sovreai-rail [aria-pressed="true"] { background: var(--sv-indicator-soft) !important; color: var(--sv-indicator-text) !important; }
aside:has(> div > .sovreai-rail > [data-testid="open-sidebar-button"]) .sovreai-rail [aria-pressed="true"] { background: transparent !important; color: var(--text-secondary) !important; }
aside:has(> div > .sovreai-rail > [data-testid="open-sidebar-button"]) { width: 84px !important; min-width: 84px !important; }
/* bascule : icône seule 36 px (pas de libellé qui change en plein plan) */
.sovreai-rail > :is([data-testid="close-sidebar-button"], [data-testid="open-sidebar-button"]) { width: 36px !important; height: 36px !important; color: var(--text-secondary) !important; border-radius: var(--sovreai-radius-btn) !important; }
/* action principale : « Nouvelle » en tuile primaire, icône « + » (le crayon natif évoque « modifier ») */
.sovreai-rail > [data-testid="new-chat-button"] { background: var(--sovreai-primary) !important; color: var(--sovreai-white) !important; }
.sovreai-rail > [data-testid="new-chat-button"]:hover { background: var(--sovreai-primary-hover) !important; color: var(--sovreai-white) !important; }
.sovreai-rail > [data-testid="new-chat-button"]:focus-visible { outline: 2px solid var(--sv-ring) !important; outline-offset: 2px !important; }
.sovreai-rail [data-testid="new-chat-button"] > svg, .sovreai-rail [data-testid="nav-panel-files"] > svg { display: none !important; }
.sovreai-rail :is([data-testid="new-chat-button"], [data-testid="nav-panel-files"])::before {
  content: ""; width: 20px; height: 20px; flex: none; background: currentColor;
  -webkit-mask: var(--sv-rail-icon) center / contain no-repeat; mask: var(--sv-rail-icon) center / contain no-repeat;
}
.sovreai-rail [data-testid="new-chat-button"] { --sv-rail-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round'><path d='M12 5v14M5 12h14'/></svg>"); }
.sovreai-rail [data-testid="nav-panel-files"] { --sv-rail-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round'><path d='M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z'/></svg>"); }
/* focus visible, non rogné par le conteneur défilant */
.sovreai-rail :is(button, a):focus-visible { outline: 2px solid var(--sv-ring) !important; outline-offset: -2px !important; --tw-ring-shadow: 0 0 #0000; --tw-ring-offset-shadow: 0 0 #0000; }
/* panneau : bandeau de marque, surtitres, conversations (actif = fond actif + liseré indicateur, D038) */
nav > div:first-child::before {
  content: ""; display: block; flex: none; height: 36px; margin: 10px 12px 4px;
  background: url("./assets/logo.svg") no-repeat left center / contain;
}
.dark nav > div:first-child::before { background-image: url("./assets/logo-white.svg"); }
[data-testid="convo-item"] { border-radius: var(--sovreai-radius-btn) !important; }
[data-testid="convo-item"].bg-surface-active-alt { background: var(--surface-active) !important; --surface-active-alt: var(--surface-active); }
[data-testid="convo-item"].bg-surface-active-alt::before { background: var(--sv-indicator) !important; }
[data-testid="convo-item"]:not(.bg-surface-active-alt):hover { background: var(--surface-hover) !important; }
/* fondu de troncature natif (80 px) : réduit, il n'estompe plus la fin des titres courts */
[data-testid="convo-item"] .bg-gradient-to-l { width: 24px !important; }
/* menu du compte : « Mes fichiers » est déjà au rail en desktop (D101) ; « Raccourcis clavier » sans objet au toucher (A003) */
@media (min-width: 769px) { .account-settings-popover .select-item:has(svg.lucide-file-text) { display: none; } }
@media (max-width: 767px), (pointer: coarse) { .account-settings-popover .select-item:has(svg.lucide-keyboard) { display: none; } }
/* infobulles des entrées du rail : redondantes avec le libellé visible (DESIGN-SYSTEM §5 « Infobulle ») */
body:has(.sovreai-rail :is([data-testid="new-chat-button"], [data-testid^="nav-panel-"], [data-testid="nav-user"]):is(:hover, :focus-visible)) .tooltip[role="tooltip"] { display: none !important; }
/* doublon de « Nouvelle conversation » dans l'en-tête CONVERSATIONS (le rail porte l'action principale) */
nav button[aria-label="Nouvelle conversation"] { display: none !important; }
/* mobile : tiroir en une seule colonne, barre d'actions en tête (ordre de focus = ordre visuel) */
@media (max-width: 768px) {
  div:has(> .sovreai-rail) { flex-direction: column !important; width: min(340px, 88vw) !important; }
  div:has(> .sovreai-rail) > nav { width: 100% !important; flex: 1 1 auto !important; border-right: 0 !important; }
  .sovreai-rail { flex-direction: row !important; width: 100% !important; height: auto !important; padding: 10px 12px !important;
    border-right: 0 !important; border-bottom: 1px solid var(--border-light) !important; gap: 8px !important; }
  .sovreai-rail > :is(div.mx-2, div:has(> [data-testid^="nav-panel-"])) { display: none !important; }
  .sovreai-rail > [data-testid="close-sidebar-button"] { width: 44px !important; height: 44px !important; flex: none; }
  .sovreai-rail > [data-testid="new-chat-button"] { flex: 1 1 auto !important; width: auto !important; height: 44px !important; flex-direction: row !important; gap: 8px !important; padding: 0 12px !important; }
  .sovreai-rail > [data-testid="new-chat-button"]::after { content: "Nouvelle conversation"; max-width: none; font: 500 14px/20px var(--sovreai-font-body); }
  .sovreai-rail > div.mt-auto { margin: 0 !important; }
  .sovreai-rail [data-testid="nav-user"] { width: 44px !important; height: 44px !important; padding: 0 !important; }
  .sovreai-rail [data-testid="nav-user"]::after { content: none; }
  div[role="presentation"].fixed.inset-0 { background: var(--sovreai-overlay) !important; }
}
/* état vide de l'historique (nouvel utilisateur) : une phrase plutôt qu'un panneau muet (DESIGN-SYSTEM §11.2) */
/* sous l'en-tête CONVERSATIONS : l'en-tête garde l'ordre 0, la phrase passe en 1, la liste (vide, flex 1) en 2 */
nav [role="region"]:not(:has([data-testid="convo-item"])) div.relative.flex.h-full.min-h-0 > .flex-1 { order: 2; }
nav [role="region"]:not(:has([data-testid="convo-item"])) div.relative.flex.h-full.min-h-0::after {
  content: "Vos conversations apparaîtront ici."; display: block; order: 1; margin: 8px 12px; padding: 8px 12px;
  font: 400 14px/20px var(--sovreai-font-body); color: var(--text-secondary); text-wrap: balance;
}

/* SovreAI Chat — thème, partie « écrans secondaires (assistants métier, projets, modèles, constructeur) ». Concaténée après theme/sovreai-theme.css au build (scripts/build-dist.mjs §1) :
   n'utilise que les jetons et rôles définis dans les sections 1 à 7 de ce fichier (aucune valeur littérale). */

/* ════════ Écrans secondaires (assistants métier, projets, modèles de message, constructeur) ════════ */
/* ============================================================================
   SovreAI Chat — fragment « pages » : Assistants métier (Marketplace), détail d'un assistant,
   modèles de message, projets, panneaux du rail (constructeur d'assistant, modèles, fichiers, connecteurs).
   À insérer en section 9 (écrans) de theme/sovreai-theme.css, après la barre latérale.
   Aucune valeur littérale de couleur, d'ombre ou de durée : uniquement les jetons de la charte (--sovreai-*),
   les rôles SovreAI (--sv-*) et les rôles natifs (--surface-*, --text-*, --border-*, --presentation).
   Ancres, par ordre de préférence : id et data-testid natifs (#agent-search, #category-tab-all, #prompt-name,
   #prompts-panel, #instructions, #variables-menu-button, #filename-filter, #mcp-filter, #open-sidebar-button),
   attributs natifs (name="prompt"), rôles ARIA (tablist, tab, grid, gridcell, dialog, search, region),
   structure (:has) et, en dernier recours, classes d'icônes lucide (svg.lucide-*) — listées comme fragiles.
   Aucune ancre sur un libellé français.
   ========================================================================== */

/* ---------- Jeton local : surface de carte (DESIGN-SYSTEM §2.2 « Surface : cartes ») ---------- */
/* --sv-card : rôle « surface de carte » déclaré dans les sections 3-4 du thème */

/* ============================================================================
   1. Assistants métier (Marketplace, /agents) — portée : main:has(#agent-search)
   ========================================================================== */

/* ── En-tête : modèle « Projets » (titre display à gauche, phrase secondaire, D135) ──
   Tout le contenu s'aligne sur la même colonne (gouttière 16 px du conteneur). */
main:has(#agent-search) div:has(> div > h1) { padding-inline: 16px; }
main:has(#agent-search) div:has(> h1) { text-align: left; margin-bottom: 24px; }
main:has(#agent-search) div:has(> h1) > p {
  margin: 8px 0 0; max-width: 40rem; font-size: 16px; line-height: 24px; color: var(--text-secondary);
}
/* recherche pleine largeur de colonne (au lieu d'un bloc centré de 672 px) */
main:has(#agent-search) div:has(> [role="search"]) { max-width: none; margin-inline: 0; padding-bottom: 16px; }

/* ── Accès à l'administration : libellé visible à côté du bouclier (D134) ──
   Libellé visible = fin du nom accessible « Paramètres d'administration » (WCAG 2.5.3). */
main:has(#agent-search) button:has(> svg.lucide-shield-ellipsis) {
  width: auto; min-width: 36px; padding: 0 16px; gap: 8px; flex: none;
  color: var(--text-primary); border-radius: var(--sovreai-radius-btn);
}
main:has(#agent-search) button:has(> svg.lucide-shield-ellipsis) > svg { width: 20px; height: 20px; flex: none; }
main:has(#agent-search) button:has(> svg.lucide-shield-ellipsis)::after {
  content: "Administration"; font: 500 14px/20px var(--sovreai-font-body); white-space: nowrap;
}

/* ── Filtres de catégorie : une ligne défilante, « Tous » en premier (DESIGN-SYSTEM §11.1, D126, D128) ── */
main:has(#agent-search) div:has(> [role="tablist"]) { position: relative; }
main:has(#agent-search) [role="tablist"] {
  flex-wrap: wrap !important; justify-content: flex-start !important; overflow-x: auto; gap: 8px !important;
  padding: 0 32px 8px 0 !important; scrollbar-width: thin; scrollbar-color: var(--border-heavy) transparent;
}
/* indice de défilement : fondu vers le fond de page sur le bord droit */
/* ligne défilante réservée au mobile (en desktop, un onglet choisi resterait hors champ sans défilement JS) */
@media (max-width: 767px) { main:has(#agent-search) [role="tablist"] { flex-wrap: nowrap !important; } }
@media (min-width: 768px) { main:has(#agent-search) div:has(> [role="tablist"])::after { display: none; } main:has(#agent-search) [role="tablist"] { padding-right: 0 !important; } }
main:has(#agent-search) div:has(> [role="tablist"])::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 8px; width: 32px; pointer-events: none;
  background: linear-gradient(to right, transparent, var(--presentation));
}
main:has(#agent-search) #category-tab-all { order: -1; }
/* titre de section rapproché des filtres (l'en-tête collant porte déjà 16 px de marge basse) */
main:has(#agent-search) div:has(> div > h2) { margin-top: 8px !important; }
/* onglet au repos : surface bordée (visible en clair comme en sombre), rayon 8, texte secondaire */
main:has(#agent-search) [role="tab"] {
  flex: none; height: 36px; padding: 0 12px !important; display: inline-flex; align-items: center;
  background: var(--sv-card) !important; border: 1px solid var(--border-light); border-radius: var(--sovreai-radius-btn) !important;
  color: var(--text-secondary) !important; font: 400 14px/20px var(--sovreai-font-body); overflow: hidden;
  transition: background-color var(--sovreai-duration-fast), border-color var(--sovreai-duration-fast), color var(--sovreai-duration-fast);
}
main:has(#agent-search) [role="tab"]:hover { background: var(--surface-hover) !important; color: var(--sv-text-strong-secondary) !important; }
/* onglet actif : fond actif + bordure et liseré 2 px d'état + texte corps (jamais la couleur seule) */
main:has(#agent-search) [role="tab"][aria-selected="true"] {
  background: var(--surface-active) !important; border-color: var(--sv-indicator); color: var(--text-primary) !important; font-weight: 500;
}
main:has(#agent-search) [role="tab"][aria-selected="true"] > div { background: var(--sv-indicator) !important; height: 2px; }
main:has(#agent-search) [role="tab"]:focus-visible { outline: 2px solid var(--sv-ring); outline-offset: -2px; }

/* ── Grille : alignée sur les titres de section (plus de retrait de 16 px, D132) ── */
main:has(#agent-search) [role="grid"] { margin-inline: 0 !important; }

/* ── Carte d'assistant métier : surface, filet décoratif, rayon 20, e1 ; catégorie en pilule au-dessus du nom
   (DESIGN-SYSTEM §5 « Carte d'assistant métier », D054, D132) ── */
main:has(#agent-search) [role="gridcell"] > [role="button"] {
  display: grid !important; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto 1fr;
  column-gap: 16px; row-gap: 4px; align-items: start;
  height: 100% !important; min-height: 128px; padding: 24px !important;
  background: var(--sv-card) !important; border: 1px solid var(--border-light); border-radius: var(--sovreai-radius-card) !important;
  box-shadow: var(--sv-shadow-1);
  transition: border-color var(--sovreai-duration-fast), box-shadow var(--sovreai-duration-fast);
}
main:has(#agent-search) [role="gridcell"] > [role="button"]:hover { background: var(--sv-card) !important; border-color: var(--sv-indicator); }
main:has(#agent-search) [role="gridcell"] > [role="button"]:focus-visible { outline: 2px solid var(--sv-ring) !important; outline-offset: -2px !important; }
/* catégorie : badge Info (pilule, caption), posé au-dessus du nom au lieu de flotter en haut à droite */
main:has(#agent-search) [role="gridcell"] > [role="button"] > span {
  position: static !important; grid-column: 2; grid-row: 1; justify-self: start;
  padding: 4px 8px !important; border-radius: var(--sovreai-radius-pill) !important;
  background: var(--sv-info-soft) !important; color: var(--sv-info) !important;
  font: 500 12px/16px var(--sovreai-font-body);
}
/* avatar : colonne de gauche sur toute la hauteur */
main:has(#agent-search) [role="gridcell"] > [role="button"] > div:first-of-type { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
/* nom + description */
main:has(#agent-search) [role="gridcell"] > [role="button"] > div:last-of-type { grid-column: 2; grid-row: 2; justify-content: flex-start !important; }
main:has(#agent-search) [role="gridcell"] > [role="button"] label {
  font: 400 20px/28px var(--sovreai-font-title) !important; letter-spacing: -0.01em; color: var(--sv-text-title) !important;
  word-break: normal !important; overflow-wrap: anywhere;
}
/* description secondaire sur 2 lignes (4,76:1 sur #fff ; 5,71:1 sur #1e293b) */
main:has(#agent-search) [role="gridcell"] > [role="button"] p[id$="-description"] {
  margin-top: 4px; font-size: 14px; line-height: 20px; color: var(--text-secondary) !important; -webkit-line-clamp: 2 !important;
}
/* pictogramme par défaut (plume) : disque Info au lieu d'un rond gris ombré (D131, à défaut d'avatar téléversé) */
main:has(#agent-search) [role="gridcell"] > [role="button"] > div:first-of-type > div {
  background: var(--sv-info-soft); box-shadow: none !important;
}
main:has(#agent-search) [role="gridcell"] svg.lucide-feather { color: var(--sv-info) !important; }

/* ── Mobile : titre de page visible (le bloc titre natif n'est pas rendu sous 768 px, D128) ──
   Sans administrateur : [Menu] Titre ; avec administrateur : [Menu] … [Administration] puis le titre dessous. */
@media (max-width: 767px) {
  main:has(#agent-search):not(:has(h1)) div:has(> #open-sidebar-button) {
    flex-wrap: wrap; justify-content: flex-start !important; row-gap: 12px; color: var(--sv-text-title);
  }
  main:has(#agent-search):not(:has(h1)) div:has(> #open-sidebar-button)::before {
    content: "Assistants métier"; order: 1; flex: 1 1 0; min-width: 0;
    font: 400 26px/34px var(--sovreai-font-title); letter-spacing: -0.01em; color: var(--sv-text-title);
  }
  main:has(#agent-search):not(:has(h1)) div:has(> #open-sidebar-button) > button:has(> svg.lucide-shield-ellipsis) { order: 2; margin-left: auto; }
  main:has(#agent-search):not(:has(h1)) div:has(> #open-sidebar-button):has(> button > svg.lucide-shield-ellipsis)::before { order: 3; flex-basis: 100%; }
  /* l'en-tête collant garde les filtres sous la main ; les cartes passent en une colonne pleine largeur */
  main:has(#agent-search) [role="gridcell"] > [role="button"] { min-height: 0; padding: 16px !important; }
}

/* ============================================================================
   2. Détail d'un assistant métier (dialogue) — portée : [role=dialog] avec actions Épingler + Copier le lien
   ========================================================================== */
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) { border-radius: var(--sovreai-radius-card) !important; }
/* pictogramme par défaut dans une pastille Info (au lieu d'une plume nue suivie de 60 px de vide, D131) */
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) > div:first-child > div:has(> svg.lucide-feather) {
  width: 80px; height: 80px; border-radius: var(--sovreai-radius-pill); background: var(--sv-info-soft);
}
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) svg.lucide-feather { color: var(--sv-info) !important; width: 36px; height: 36px; }
/* actions : icônes jamais écrasées par le bouton principal */
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) div:has(> button > svg.lucide-pin) > button:has(> svg) { flex: none; min-width: 40px; }
/* fermeture : cible 36 px (44 en tactile), icône secondaire 20 px, survol neutre (D133) */
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) > button:has(> svg.lucide-x) {
  top: 12px !important; right: 12px !important; width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--sovreai-radius-btn) !important; opacity: 1 !important; color: var(--text-secondary);
  transition: background-color var(--sovreai-duration-fast), color var(--sovreai-duration-fast);
}
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) > button:has(> svg.lucide-x) > svg { width: 20px; height: 20px; }
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) > button:has(> svg.lucide-x):hover { background: var(--surface-hover); color: var(--sv-text-strong-secondary); }
[role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) > button:has(> svg.lucide-x):focus-visible { outline: 2px solid var(--sv-ring); outline-offset: 2px; }

/* ============================================================================
   3. Modèles de message : page de création (/prompts/new) — portée : form:has(#prompt-name)
   ========================================================================== */
/* titre de page visible : le h1 natif n'était lu que par les lecteurs d'écran (D135, D141) */
form:has(#prompt-name) > h1.sr-only {
  position: static; width: auto; height: auto; margin: 32px 0 24px; padding: 0; overflow: visible; clip: auto; white-space: normal;
  font: 400 30px/38px var(--sovreai-font-title); letter-spacing: -0.01em; color: var(--sv-text-title);
}
/* mobile : [Menu] [Catégorie] puis le titre, puis le formulaire (ordre visuel = ordre de lecture utile) */
form:has(#prompt-name):has(> div > #open-sidebar-button) { display: flex; flex-direction: column; }
form:has(#prompt-name):has(> div > #open-sidebar-button) > * { order: 2; }
form:has(#prompt-name):has(> div > #open-sidebar-button) > div:has(> #open-sidebar-button) { order: 0; }
form:has(#prompt-name):has(> div > #open-sidebar-button) > h1 { order: 1; margin: 8px 0 12px; font-size: 26px; line-height: 34px; }
/* texte du modèle : Roboto comme les autres champs (la chasse fixe native le faisait passer pour du code, D139) */
textarea[name="prompt"] { font-family: var(--sovreai-font-body) !important; }
/* bouton « Variables » (page et constructeur d'assistant) : hauteur de contrôle 36 px (D141) */
#variables-menu-button { min-height: 36px; }

/* ============================================================================
   4. Projets (/projects) — boutons d'en-tête à la même hauteur (D178)
   Portée : le groupe d'actions qui contient le tri (icône lucide arrow-up-down, fragile).
   ========================================================================== */
main div:has(> button > span > svg.lucide-arrow-up-down) > button { height: 36px !important; }

/* ============================================================================
   5. Panneaux du rail : structure commune (D042) et constructeur d'assistant (D040, D172)
   ========================================================================== */
/* titre de panneau (title-2, PT Serif 20/28) ; le panneau Historique garde ses surtitres */
#prompts-panel::before, nav form:has(#instructions)::before,
nav div:has(> [role="region"] #filename-filter)::before, nav div:has(> [role="region"] #mcp-filter)::before {
  display: block; flex: none; margin: 0 0 8px; font: 400 20px/28px var(--sovreai-font-title); letter-spacing: -0.01em; color: var(--sv-text-title);
}
#prompts-panel::before { content: "Modèles de message"; padding: 0 12px; }
nav form:has(#instructions)::before { content: "Assistants métier"; }
nav div:has(> [role="region"] #filename-filter)::before { content: "Mes fichiers"; }
nav div:has(> [role="region"] #mcp-filter)::before { content: "Connecteurs"; }
/* « Paramètres d'administration » toujours en bas du panneau (comme dans le constructeur et les connecteurs) */
#prompts-panel div:has(> button > svg.lucide-shield-ellipsis) { display: contents; }
#prompts-panel div:has(> button > svg.lucide-shield-ellipsis) > * { margin-top: 0 !important; }
#prompts-panel button:has(> svg.lucide-shield-ellipsis) { order: 99; flex: none; margin-bottom: 8px; }
/* « Envoyer les modèles de message dès leur sélection » : case à gauche, libellé qui passe à la ligne
   (le texte centré débordait des deux côtés et poussait la case hors du panneau) */
#prompts-panel button[aria-pressed]:has(> button[role="checkbox"]) {
  height: auto !important; min-height: 36px; padding: 8px 12px !important; gap: 8px;
  justify-content: flex-start !important; text-align: left; white-space: normal !important; line-height: 20px;
}
#prompts-panel button[aria-pressed]:has(> button[role="checkbox"]) > button[role="checkbox"] { flex: none; }

/* ── Constructeur d'assistant : champs de la charte (surface, bordure de composant, rayon 8) au lieu des gris
   Tailwind (#334155 / #475569 en sombre, #f8fafc / #e2e8f0 en clair), D040 ── */
nav form:has(#instructions) :is(#name, #description, #instructions) {
  background: var(--surface-primary-alt) !important; border: 1px solid var(--border-heavy) !important;
  border-radius: var(--sovreai-radius-btn) !important; color: var(--text-primary) !important; box-shadow: none !important;
  transition: border-color var(--sovreai-duration-fast);
}
nav form:has(#instructions) :is(#name, #description, #instructions)::placeholder { color: var(--text-secondary) !important; opacity: 1; }
nav form:has(#instructions) :is(#name, #description, #instructions):focus {
  background: var(--surface-primary-alt) !important; border-color: var(--sv-indicator) !important; box-shadow: none !important;
  outline: 2px solid var(--sv-ring); outline-offset: 1px;
}
/* listes déroulantes (assistant, catégorie) : famille Champ, pleine largeur sans retrait de 4 px (D172) */
nav form:has(#instructions) div:has(> button[role="combobox"]) { padding-inline: 0 !important; }
nav form:has(#instructions) button[role="combobox"] {
  background: var(--surface-primary-alt) !important; border: 1px solid var(--border-heavy) !important; border-radius: var(--sovreai-radius-btn) !important;
}
nav form:has(#instructions) button[role="combobox"]:hover { background: var(--surface-hover) !important; }
nav form:has(#instructions) button[role="combobox"]:focus-visible { outline: 2px solid var(--sv-ring); outline-offset: 1px; }
/* « Sélectionner un modèle », « Importer comme contexte » (.btn-neutral natif) : bouton secondaire de la charte */
nav form:has(#instructions) .btn-neutral {
  background: var(--surface-primary-alt) !important; border: 1px solid var(--border-heavy) !important;
  border-radius: var(--sovreai-radius-btn) !important; color: var(--text-primary) !important;
}
nav form:has(#instructions) .btn-neutral:hover:not(:disabled) { background: var(--surface-hover) !important; }

/* ============================================================================
   6. Cibles tactiles 44 px (DESIGN-SYSTEM §4, §11.3)
   ========================================================================== */
@media (pointer: coarse) {
  :is(main:has(#agent-search), form:has(#prompt-name), main:has(svg.lucide-arrow-up-down)) #open-sidebar-button { width: 44px; height: 44px; }
  main:has(#agent-search) [role="tab"] { height: 44px; }
  main:has(#agent-search) button:has(> svg.lucide-shield-ellipsis) { min-height: 44px; min-width: 44px; }
  [role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) button { min-height: 44px; }
  [role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) div:has(> button > svg.lucide-pin) > button:has(> svg) { min-width: 44px; }
  [role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) > button:has(> svg.lucide-x) { width: 44px; height: 44px; top: 8px !important; right: 8px !important; }
  form:has(#prompt-name) button { min-height: 44px; }
  form:has(#prompt-name) :is(#prompt-name, #prompt-description, #prompt-command) { min-height: 44px; }
  form:has(#prompt-name) div:has(> div > :is(#prompt-description, #prompt-command)) { height: auto !important; }
  main:has(svg.lucide-arrow-up-down) label:has(> svg.lucide-search) > input { min-height: 44px; }
  #variables-menu-button { min-height: 44px; min-width: 44px; }
  main div:has(> button > span > svg.lucide-arrow-up-down) > button { height: 44px !important; }
  nav form:has(#instructions) :is(#name, #description, button[role="combobox"]) { min-height: 44px; }
}

/* ── Projets : même fond de page que les autres écrans (#fff au lieu de --presentation, D037, D136) ; pastille unique
   « Vos projets » non interactive masquée. Ancre : icône de tri de la page (déjà utilisée ci-dessus). ── */
main.bg-surface-primary:has(svg.lucide-arrow-up-down) { background: var(--presentation) !important; }
main:has(svg.lucide-arrow-up-down) div:has(> span.rounded-full:only-child) { display: none; }

/* détail d'un assistant (desktop) : « Épingler » et « Copier le lien » libellés (les infobulles ne s'affichent pas au
   toucher, D133) ; le libellé suit le nom accessible natif (Épingler / Détacher) */
@media (min-width: 768px) {
  [role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) button:is(:has(> svg.lucide-pin), :has(> svg.lucide-pin-off), :has(> svg.lucide-link)) { width: auto !important; gap: 8px; padding: 0 12px !important; }
  [role="dialog"]:has(svg.lucide-pin):has(svg.lucide-link) button:is(:has(> svg.lucide-pin), :has(> svg.lucide-pin-off), :has(> svg.lucide-link))::after { content: attr(aria-label); font: 500 14px/20px var(--sovreai-font-body); white-space: nowrap; }
}

/* SovreAI Chat — thème, partie « paramètres, dialogues, menu du compte ». Concaténée après theme/sovreai-theme.css au build (scripts/build-dist.mjs §1) :
   n'utilise que les jetons et rôles définis dans les sections 1 à 7 de ce fichier (aucune valeur littérale). */

/* ════════ Paramètres, dialogues, menu du compte ════════ */
/* ============================================================================
   SovreAI Chat — fragment « Paramètres, dialogues (export, archives, fichiers, suppression),
   menu du compte et sous-menu Aide » (à fusionner dans theme/sovreai-theme.css, sections 8 à 10).
   Règles : uniquement des jetons (var(--sovreai-*), var(--sv-*), variables natives) ; rayons 4/8/12/20/100 ;
   espacements de l'échelle 4 ; ancres par ordre de préférence (data-testid, ids natifs non traduits, classes
   sémantiques natives, rôles/états ARIA, structure :has, puis Tailwind listé comme fragile).
   Aucun sélecteur ne repose sur un libellé français.
   ========================================================================== */

/* ---------- 8. Composants : champs de base ---------- */
/* D060 — texte indicatif (placeholder) : le preflight natif le rend en gris décoratif (#94a3b8, 2,6:1 sur la page
   claire). Secondaire au repos (4,76:1 sur surface claire, 5,71:1 sur #1e293b). Les utilitaires placeholder:*
   natifs, plus spécifiques, gardent la main. */
input::placeholder, textarea::placeholder { color: var(--text-secondary); opacity: 1; }

/* ---------- 8. Composants : dialogues (Radix OGDialog et Headless UI des Paramètres) ---------- */
/* Surface élevée, rayon 20, ombre e3 en clair, bordure d'élévation en sombre (DESIGN-SYSTEM §5 Dialogue).
   [data-state] sans [data-side] = contenu de dialogue Radix (les popovers Radix portent data-side). */
[role="dialog"][data-state="open"]:not([data-side]),
[role="dialog"] [id^="headlessui-dialog-panel"] {
  border-radius: var(--sovreai-radius-card) !important;
  border: 1px solid var(--sv-elevation-border);
  box-shadow: var(--sv-shadow-3) !important;
}
/* voile : charte (même valeur en clair et en sombre, au lieu du noir à 50 / 80 %) — Headless UI (enfant du dialogue)
   et Radix (frère qui précède le contenu du dialogue) */
[role="dialog"] > div.fixed.inset-0[aria-hidden="true"] { background: var(--sovreai-overlay) !important; opacity: 1 !important; }
div[data-state="open"][aria-hidden="true"]:has(+ [role="dialog"][data-state="open"]:not([data-side])) { background: var(--sovreai-overlay) !important; }
/* bouton de fermeture (croix) : cible 36 px (44 en tactile), icône secondaire pleine (l'opacité 0,7 native donnait 2,6:1) */
[role="dialog"] [id^="headlessui-dialog-title"] > button:has(> svg.lucide-x),
[role="dialog"][data-state="open"] > button:has(> .sr-only) {
  min-width: 36px; min-height: 36px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--sovreai-radius-btn) !important; color: var(--text-secondary); opacity: 1 !important;
}
[role="dialog"][data-state="open"] > button:has(> .sr-only) { top: 12px !important; right: 12px !important; }
/* barre de titre des Paramètres : hauteur native conservée (68 px) malgré la croix agrandie */
[role="dialog"] [id^="headlessui-dialog-title"] { padding-block: 16px !important; padding-right: 16px !important; }
[role="dialog"] [id^="headlessui-dialog-title"] > button:has(> svg.lucide-x):hover,
[role="dialog"][data-state="open"] > button:has(> .sr-only):hover { background: var(--surface-hover); color: var(--sv-text-strong-secondary); }
/* A002 — libellés natifs en word-break: break-all (min-content d'un caractère : la ligne 2FA s'effondrait en une
   colonne de lettres, « conversation / s ») : coupure aux espaces, mot trop long coupé seulement s'il déborde */
[role="dialog"] .break-all { word-break: normal; overflow-wrap: break-word; hyphens: manual; line-height: 20px; }

/* ── Menu contextuel d'une conversation : « Supprimer » présenté comme destructif, séparé des autres actions (D100) ── */
[role="menuitem"][aria-controls="delete-conversation-dialog"] {
  --sv-danger-item: var(--text-destructive);
  position: relative; margin-top: 9px; color: var(--sv-danger-item) !important;
}
[role="menuitem"][aria-controls="delete-conversation-dialog"] svg { color: currentColor !important; }
[role="menuitem"][aria-controls="delete-conversation-dialog"]::before {
  content: ""; position: absolute; left: 4px; right: 4px; top: -5px; height: 1px; background: var(--border-light); pointer-events: none;
}
/* en sombre, #f87171 sur le fond de survol #334155 tombe à 3,9:1 : #fca5a5 (5,46:1) au survol et au focus */
.dark [role="menuitem"][aria-controls="delete-conversation-dialog"]:is(:hover, :focus, :focus-visible, [data-active-item]) { --sv-danger-item: var(--sovreai-danger-on-dark-hover); }
/* D171 — menu (Ariakit) resté ouvert derrière le dialogue qu'il a ouvert : menu d'une conversation sous
   « Supprimer la conversation ? », menu d'export sous « Exporter la conversation ». Masqué tant qu'un dialogue
   Radix est ouvert (la fermeture réelle du menu relève d'un fork). Ancres : aria-labelledby natifs (ids non traduits),
   pour ne jamais masquer un menu ouvert depuis le dialogue lui-même. */
body:has([role="dialog"][data-state="open"]:not([data-side])) :is([role="menu"][aria-labelledby^="conversation-menu-"], [role="menu"][aria-labelledby="export-menu-button"]) { visibility: hidden !important; }

/* ---------- 9. Écrans : Paramètres (dialogue Headless UI, onglets verticaux Radix) ---------- */
/* D060 — « Rechercher un paramètre » : famille Champ (surface, bordure de composant, rayon 8, focus = bordure
   indicateur + anneau), au lieu d'un pavé sans contour (1,05:1 en clair, invisible en sombre) */
[role="dialog"] svg.lucide-search ~ input {
  background: var(--surface-dialog) !important; border: 1px solid var(--border-heavy) !important; border-radius: var(--sovreai-radius-btn) !important;
  min-height: 36px; box-shadow: none !important;
}
[role="dialog"] svg.lucide-search ~ input:focus { border-color: var(--sv-indicator) !important; outline: 2px solid var(--sv-ring); outline-offset: 1px; }
[role="dialog"] svg.lucide-search { color: var(--text-secondary); }

/* onglets verticaux (D148, D179) : actif = texte corps + fond actif + liseré d'état 2 px à gauche
   (clair : #334155 sur #e2e8f0 8,8:1, liseré 4,19:1 ; sombre : #cbd5e1 sur #475569 5,1:1, liseré 4,2:1) */
[role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"] {
  position: relative; border-radius: var(--sovreai-radius-btn) !important; min-height: 36px;
  transition: background-color var(--sovreai-duration-fast), color var(--sovreai-duration-fast);
}
[role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"][data-state="active"] { background: var(--surface-active) !important; color: var(--text-primary) !important; }
[role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"][data-state="active"]::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 2px; border-radius: var(--sovreai-radius-xs); background: var(--sv-indicator);
}
[role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"]:focus-visible { outline: 2px solid var(--sv-ring); outline-offset: -2px; box-shadow: none; }
/* icônes des onglets : 16 px fixes (17, 16 et 18 px en natif décalaient les libellés de 1 à 2 px) */
[role="dialog"] [role="tab"] > span > svg { width: 16px !important; height: 16px !important; flex: none; }
/* listes déroulantes des réglages : 36 px (32 px en natif pour Langue et Voix) */
[role="dialog"] [role="tabpanel"] [role="combobox"] { min-height: 36px; }

/* D152 — contenu coupé net en bas : marge basse + fondu de 32 px sur le bord du conteneur défilant
   (le masque ne lit que l'opacité ; en fin de défilement, seul l'espace vide est estompé) */
[role="dialog"] [id^="headlessui-dialog-panel"] div:has(> [role="tabpanel"]) {
  padding-bottom: 32px;
  -webkit-mask-image: linear-gradient(to bottom, var(--surface-dialog) calc(100% - 32px), transparent);
  mask-image: linear-gradient(to bottom, var(--surface-dialog) calc(100% - 32px), transparent);
}
[role="dialog"] [role="tabpanel"] section:last-child { margin-bottom: 0; }

/* D145 — actions destructives des lignes (révoquer, vider le cache, effacer les conversations, supprimer le compte) :
   bouton danger en contour ; le bouton plein est réservé à la confirmation qui suit (DESIGN-SYSTEM §5).
   Désactivé : règle commune (opacité 0,5 sur un contour, plus de pavé rose). Ancres : ids natifs des libellés. */
[role="tabpanel"] button:is([aria-labelledby="revoke-info-label"], [aria-labelledby="delete-cache-label"], [aria-labelledby="clear-all-chats-label"], [aria-labelledby="delete-account-label"]) {
  --sv-danger-btn: var(--text-destructive);
  background: transparent !important; color: var(--sv-danger-btn) !important; border: 1px solid var(--sv-danger-btn) !important;
  border-radius: var(--sovreai-radius-btn) !important;
}
[role="tabpanel"] button:is([aria-labelledby="revoke-info-label"], [aria-labelledby="delete-cache-label"], [aria-labelledby="clear-all-chats-label"], [aria-labelledby="delete-account-label"]):hover:not(:disabled) {
  background: var(--sv-danger-soft) !important;
}
.dark [role="tabpanel"] button:is([aria-labelledby="revoke-info-label"], [aria-labelledby="delete-cache-label"], [aria-labelledby="clear-all-chats-label"], [aria-labelledby="delete-account-label"]):hover:not(:disabled) {
  --sv-danger-btn: var(--sovreai-danger-on-dark-hover);
}

/* Parole (D061) — note « (par défaut : -45) » : caption secondaire lisible (4,76:1 / 5,71:1) au lieu de 11,2 px à 40 % */
[role="dialog"] [role="tabpanel"] small { opacity: 1 !important; color: var(--text-secondary); font-size: 12px; line-height: 16px; }
/* Parole (D062) — curseur : piste = famille Champ (fond bordure moyenne + contour de composant 4,76:1 / 3,07:1),
   portion active et poignée = indicateur (#93c5fd en sombre, jamais #2563eb) */
[role="dialog"] span[data-orientation="horizontal"]:has([role="slider"]) > span[data-orientation="horizontal"] {
  background: var(--border-medium) !important; border: 1px solid var(--border-heavy);
}
[role="dialog"] span[data-orientation="horizontal"]:has([role="slider"]) > span[data-orientation="horizontal"] > span { background: var(--sv-indicator) !important; }
[role="dialog"] [role="slider"] { border-color: var(--sv-indicator) !important; background: var(--surface-dialog) !important; }
[role="dialog"] [role="slider"]:focus-visible { outline: 2px solid var(--sv-ring); outline-offset: 2px; box-shadow: none !important; }
/* champ numérique associé : famille Champ (surface, bordure de composant, rayon 8), texte corps */
[role="dialog"] .rc-input-number {
  background: var(--surface-dialog) !important; color: var(--text-primary) !important; border: 1px solid var(--border-heavy) !important;
  border-radius: var(--sovreai-radius-btn) !important; max-height: none !important; min-height: 32px; width: 64px; align-items: center; padding: 0 8px;
}
[role="dialog"] .rc-input-number .rc-input-number-input-wrap { flex: 1 1 auto; min-width: 0; }
[role="dialog"] .rc-input-number input { color: var(--text-primary) !important; background: transparent !important; width: 100%; padding: 0; text-align: right; }
[role="dialog"] .rc-input-number:focus-within { border-color: var(--sv-indicator) !important; outline: 2px solid var(--sv-ring); outline-offset: 1px; }
/* l'anneau est porté par le conteneur : pas de second contour sur le champ interne */
[role="dialog"] .rc-input-number input:is(:focus, :focus-visible) { outline: none !important; }
/* desktop : hauteur de contrôle 36 px, zone de saisie sur toute la hauteur ; interrupteurs cliquables sur 36 px (D151, D161) */
[role="dialog"] .rc-input-number { min-height: 36px; }
[role="dialog"] .rc-input-number .rc-input-number-input-wrap { align-self: stretch; display: flex; }
[role="dialog"] .rc-input-number input { align-self: stretch; height: auto; }
[role="dialog"] [role="switch"] { position: relative; }
[role="dialog"] [role="switch"]::before { content: ""; position: absolute; inset: -6px -2px; }

/* ── Réglages sans objet pour une PME ou liés à des fonctions masquées par la config (A5, A19) : ligne masquée ──
   Ancres : data-testid / aria-labelledby natifs des contrôles (non traduits). Direction de la conversation, badges,
   commande « @ », markdown et LaTeX, nom d'utilisateur (A7), réflexion, changement de fournisseur, conversation
   temporaire, variantes, éditeur avancé de modèles, dictée, moteurs de voix, mémoire, cache vide. */
[role="dialog"] [role="tabpanel"] .divide-y > :has(
  [data-testid="chatDirection"],
  [data-testid="showBadges"],
  [data-testid="atCommand"],
  [data-testid="enableUserMsgMarkdown"],
  [data-testid="UsernameDisplay"],
  [data-testid="latexParsing"],
  [data-testid="showThinking"],
  [data-testid="modularChat"],
  [data-testid="defaultTemporaryChat"],
  [data-testid="rememberDefaultFork"],
  [data-testid="advancedPrompts"],
  [data-testid="alwaysMakeProd"],
  [data-testid="EngineSTTDropdown"],
  [data-testid="LanguageSTTDropdown"],
  [data-testid="AutoTranscribeAudio"],
  [data-testid="autoSendTextToggle"],
  [data-testid="EngineTTSDropdown"],
  [data-testid="ConversationMode"],
  [data-testid="CloudBrowserVoices"],
  [data-testid="CacheTTS"],
  [aria-labelledby="reference-saved-memories-label"], button[aria-labelledby="delete-cache-label"]:disabled) { display: none !important; }
/* sections devenues vides (Mémoire ; dictée quand elle forme sa propre section) */
[role="dialog"] [role="tabpanel"] section:has([aria-labelledby="reference-saved-memories-label"]):not(:has(.divide-y > :nth-child(2))),
[role="dialog"] [role="tabpanel"] section:has([data-testid="SpeechToText"]):not(:has([data-testid="TextToSpeech"])) { display: none !important; }
[role="dialog"] [role="tabpanel"] .divide-y > :has([data-testid="SpeechToText"]):not(:has([data-testid="TextToSpeech"])) { display: none !important; }
/* raccourcis vers des fonctions masquées (signets, conversation temporaire, assistants OpenAI, mémoire, paramètres du modèle) */
[role="dialog"] div:has(> div > :is([data-testid="edit-shortcut-bookmarkConversation"], [data-testid="edit-shortcut-focusSearch"], [data-testid="edit-shortcut-toggleTemporaryChat"], [data-testid="edit-shortcut-openAssistants"], [data-testid="edit-shortcut-openMemories"], [data-testid="edit-shortcut-openBookmarks"], [data-testid="edit-shortcut-openParameters"])) { display: none !important; }
/* un seul voile quand un dialogue s'ouvre au-dessus du tiroir mobile (D163) */
body:has([role="dialog"][data-state="open"]:not([data-side])) div[role="presentation"].fixed.inset-0 { background: transparent !important; }

/* ---------- 9. Écrans : Mes fichiers et Conversations archivées (DataTable natif dans un dialogue) ---------- */
/* en-tête : surface alternative + label (DESIGN-SYSTEM §5.1), bande jusqu'au bord droit (C002 : la gouttière
   « scrollbar-gutter: stable » réservait 8 px vides) */
[role="dialog"] div:has(> table) { scrollbar-gutter: auto !important; border-color: var(--border-light) !important; border-radius: var(--sovreai-radius-md) !important; }
[role="dialog"] table thead, [role="dialog"] table th { background: var(--surface-secondary-alt) !important; }
[role="dialog"] table th { color: var(--sv-text-title); --text-secondary: var(--sv-text-strong-secondary); }
/* A009 — Mes fichiers : colonnes techniques « Stockage » et « Contexte » masquées (ce sont les seules colonnes à
   menu de filtre, [aria-sort][aria-haspopup=menu]) ; les cellules suivent l'en-tête de même rang */
[role="dialog"]:has(#files-filter) th:has([aria-sort][aria-haspopup="menu"]) { display: none; }
[role="dialog"]:has(#files-filter) table:has(th:nth-child(4) [aria-sort][aria-haspopup="menu"]) td:nth-child(4),
[role="dialog"]:has(#files-filter) table:has(th:nth-child(5) [aria-sort][aria-haspopup="menu"]) td:nth-child(5) { display: none; }
/* pagination masquée quand il n'y a qu'une page (précédent et suivant désactivés : « Page 1 / 1 », « 1 / 1 », « 1 / 0 ») :
   dialogue Mes fichiers (compteur de sélection conservé) et panneau Mes fichiers de la barre latérale (navigation) */
[role="dialog"]:has(#files-filter) div:has(> button:disabled + button:disabled:last-child) > :not(:first-child) { display: none; }
[role="navigation"]:has(> button:first-child:disabled):has(> button:last-child:disabled) { display: none; }

/* ---------- 10. Mobile ---------- */
@media (max-width: 767px) {
  /* Paramètres : dialogue de contenu plein écran (DESIGN-SYSTEM §11.3) — même hauteur pour la liste et le détail (D150) */
  [role="dialog"] > div:has(> [id^="headlessui-dialog-panel"]) { padding: 0 !important; }
  [role="dialog"] [id^="headlessui-dialog-panel"] {
    width: 100vw !important; height: 100dvh !important; max-height: 100dvh !important; border-radius: 0 !important; border: 0 !important;
  }
  [role="dialog"] [id^="headlessui-dialog-title"] { min-height: 56px; padding: 0 8px 0 16px !important; }
  [role="dialog"] [id^="headlessui-dialog-panel"] > div[data-orientation="vertical"] { padding: 16px !important; }
  /* liste maître : pas de faux état sélectionné, lignes 48 px en texte corps, chevron indicatif */
  [role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"] { min-height: 48px; color: var(--text-primary) !important; }
  [role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"][data-state="active"] { background: transparent !important; }
  [role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"][data-state="active"]::before { content: none; }
  [role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"]:hover { background: var(--surface-hover) !important; }
  /* D149 — titre de la vue détail (bouton Retour + nom de la rubrique) : title-2 PT Serif comme « Paramètres » */
  [role="dialog"] [id^="headlessui-dialog-title"] > button:has(> svg.lucide-chevron-left) { min-height: 44px; padding: 0 8px 0 4px !important; color: var(--sv-text-title); }
  [role="dialog"] [id^="headlessui-dialog-title"] > button:has(> svg.lucide-chevron-left) > span {
    font-family: var(--sovreai-font-title); font-weight: 400; font-size: 20px; line-height: 28px; letter-spacing: -0.01em;
  }
  /* A002 / C001 — lignes libellé + contrôle : le libellé part d'une base nulle (min 7rem) et s'enroule ; le contrôle
     passe sous le libellé quand il ne tient pas (2FA, curseur de sensibilité) au lieu d'écraser le libellé */
  [role="dialog"] [role="tabpanel"] section > div > div > div:has(> :nth-child(2)) { flex-wrap: wrap; row-gap: 8px; column-gap: 12px; }
  [role="dialog"] [role="tabpanel"] section > div > div > div:has(> :nth-child(2)) > :first-child { flex: 1 1 0; min-width: min(7rem, 100%); }
  [role="dialog"] [role="tabpanel"] section > div > div > div:has(> :nth-child(2)) > :is(:last-child, button) { margin-left: auto; max-width: 100%; }
  [role="dialog"] [role="tabpanel"] section > div > div > div:has(> :nth-child(2)) button:not([role="switch"]):not([role="combobox"]) { white-space: normal; text-align: center; height: auto; min-height: 44px; }
  /* curseur : note sous le libellé, piste pleine largeur sur sa propre ligne */
  [role="dialog"] [role="tabpanel"] div:has(> small) { flex-direction: column; align-items: flex-start !important; gap: 4px; }
  [role="dialog"] [role="tabpanel"] div:has(> small) > div:not([id]) { display: none; }
  [role="dialog"] [role="tabpanel"] div:has(> span > span > [role="slider"]) { flex: 1 1 100% !important; }
  [role="dialog"] [role="tabpanel"] span[data-orientation="horizontal"]:has([role="slider"]) { flex: 1 1 auto; width: auto !important; margin-left: 0 !important; }

  /* Mes fichiers / archives : pas de colonne coupée sans indice (A007) — date masquée dans les tableaux à 3 colonnes
     (archives : Nom, Date, Actions) ; état vide centré sur la largeur visible */
  [role="dialog"] table:has(> thead > tr > th:nth-child(3):last-child) :is(th, td):nth-child(2):not([colspan]) { display: none; }
  [role="dialog"] table:has(> thead > tr > th:nth-child(3):last-child) { table-layout: auto !important; }
  [role="dialog"] table td[colspan] { text-align: center; white-space: normal; }

  /* menu du compte (A001, D173) : tenu dans le tiroir (largeur − 24 px), sous la barre d'actions ; sous-menu Aide
     empilé sous l'entrée « Aide » (décalé de 24 px) au lieu de s'ouvrir hors écran à droite */
  div:has(> .account-settings-popover:not(.popover-from-left)) {
    position: fixed !important; top: 72px !important; left: 12px !important; transform: none !important;
    width: calc(min(340px, 88vw) - 24px) !important;
  }
  .account-settings-popover:not(.popover-from-left) { width: 100% !important; translate: none !important; }
  .account-settings-popover [role="note"] { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; height: 36px; }
  .account-settings-popover [role="menuitem"] { min-height: 44px; }
  div:has(> .account-settings-popover.popover-from-left) {
    position: fixed !important; top: calc(72px + 102px) !important; left: 36px !important; transform: none !important;
    width: calc(min(340px, 88vw) - 48px) !important;
  }
  .account-settings-popover.popover-from-left { width: 100% !important; translate: none !important; }
}
/* A006 — dialogues en mobile : titre aligné à gauche, pied à deux boutons (annuler + action) empilé pleine largeur
   avec 8 px d'écart, action principale en haut (même disposition pour l'export et les confirmations ; les pieds à
   boutons-icônes, comme le détail d'un assistant métier, ne sont pas concernés) */
@media (max-width: 639px) {
  [role="dialog"][data-state="open"]:not([data-side]) > div:first-child:has(> h2) { text-align: left; }
  [role="dialog"][data-state="open"]:not([data-side]) > div:has(> button:first-child + button:last-child) {
    display: flex !important; flex-direction: column-reverse !important; align-items: stretch !important; justify-content: flex-start !important; gap: 8px !important; padding-top: 8px;
  }
  [role="dialog"][data-state="open"]:not([data-side]) > div:has(> button:first-child + button:last-child) > button { width: 100%; margin: 0 !important; min-height: 44px; }
}

/* cibles tactiles 44 px (D151) */
@media (pointer: coarse) {
  [role="dialog"] [id^="headlessui-dialog-title"] > button:has(> svg.lucide-x),
  [role="dialog"][data-state="open"] > button:has(> .sr-only) { min-width: 44px; min-height: 44px; }
  [role="dialog"] [role="tablist"][aria-orientation="vertical"] [role="tab"] { min-height: 48px; }
  [role="dialog"] [role="tabpanel"] [role="combobox"], [role="dialog"] svg.lucide-search ~ input { min-height: 44px; }
  [role="dialog"] [role="tabpanel"] button:not([role="switch"]):not([role="combobox"]) { min-height: 44px; }
  /* interrupteurs 44 × 24 et poignées de curseur 20 × 20 : zone de clic étendue à 44 px sans changer le dessin */
  [role="dialog"] :is([role="switch"], [role="slider"]) { position: relative; }
  [role="dialog"] [role="switch"]::before { content: ""; position: absolute; inset: -12px -2px; }
  [role="dialog"] [role="slider"]::before { content: ""; position: absolute; inset: -14px; border-radius: var(--sovreai-radius-pill); }
  /* champ numérique : 44 px de haut, zone de saisie sur toute la hauteur */
  [role="dialog"] .rc-input-number { min-height: 44px; }
  [role="dialog"] .rc-input-number .rc-input-number-input-wrap { align-self: stretch; display: flex; }
  [role="dialog"] .rc-input-number input { align-self: stretch; height: auto; }
}

/* bouton Compte du rail pendant que son menu est ouvert : fond actif, libellé renforcé (4,34:1 et 4,04:1 avant) */
.sovreai-rail [data-testid="nav-user"][aria-expanded="true"] { --text-secondary: var(--sv-text-strong-secondary); }

/* raccourcis vers des panneaux absents du rail (rôle utilisateur sans assistants, modèles ou connecteurs, A1) */
body:not(:has([data-testid="nav-panel-agents"])) [role="dialog"] div:has(> div > [data-testid="edit-shortcut-openAgents"]),
body:not(:has([data-testid="nav-panel-prompts"])) [role="dialog"] div:has(> div > [data-testid="edit-shortcut-openPrompts"]),
body:not(:has([data-testid="nav-panel-mcp-builder"])) [role="dialog"] div:has(> div > [data-testid="edit-shortcut-openMCP"]) { display: none !important; }
/* touches en Roboto (la règle monospace globale écrasait font-sans), libellés sur deux lignes plutôt que tronqués */
[role="dialog"] kbd.font-sans { font-family: var(--sovreai-font-body) !important; }
[role="dialog"] div:has(> div > [data-testid^="edit-shortcut-"]) > span.truncate { white-space: normal; overflow: visible; }
/* section vidée par les masquages (Commandes, chez l'utilisateur standard qui n'a que la commande « @ ») */
[role="dialog"] [role="tabpanel"] section:has([data-testid="atCommand"]):not(:has([data-testid="slashCommand"])) { display: none !important; }
/* liens partagés : partage désactivé dans le produit (export masqué, ALLOW_SHARED_LINKS=false) */
[role="dialog"] [role="tabpanel"] .divide-y > :has(#shared-links-label) { display: none !important; }
/* suppression : le titre de la conversation se lit en entier (il était coupé après quelques caractères) */
#delete-conversation-description, #delete-conversation-description * { white-space: normal !important; overflow: visible !important; text-overflow: clip !important; overflow-wrap: anywhere; }

/* SovreAI Chat — thème, partie « erreurs, toasts, états vides ». Concaténée après theme/sovreai-theme.css au build (scripts/build-dist.mjs §1) :
   n'utilise que les jetons et rôles définis dans les sections 1 à 7 de ce fichier (aucune valeur littérale). */

/* ════════ Erreurs, toasts, états vides ════════ */
/* ============================================================================
   SovreAI Chat — fragment « Erreurs, toasts, états vides, chargements »
   À insérer dans sovreai-theme.css : blocs 8a à 8d en section 8 (composants), 9a en section 9 (écrans),
   10a en section 10 (mobile), 11a en section 11 (motion).
   Aucune valeur littérale : uniquement des jetons --sovreai-*, --sv-* et des rôles natifs.
   Défauts traités : D064, D155 (toasts) · D065, D067, D181, D182 (écran d'erreur de page) ·
   D068 (états vides) · D102 (panneau Fichiers / Modèles : pagination, coin, tableau vide).
   ========================================================================== */

/* ---------- 8a. Toasts (DESIGN-SYSTEM §5 « Toast », D064, D155) ----------
   Constat : le JS natif pose encore ses utilitaires orange / vert / rouge (classes bg-[…C75209], […02855E],
   […E02F1F]) sur .alert-root, alors que la substitution de palette a renommé ces utilitaires dans le CSS :
   le toast n'a donc plus de fond (texte blanc sur blanc en clair, 1:1). On redessine le toast entier : surface élevée, ombre e2 (bordure en sombre),
   liseré gauche 3 px + icône de la couleur du rôle, texte « ui » corps, rayon 12, 420 px max.
   Ancres : classe sémantique native .toast-root / .alert-root ; sévérité lue sur la classe de couleur native
   (nom d'origine et nom substitué au build, sans « # ») ; classes sovreai-toast-* acceptées d'avance si
   build-dist les injecte un jour (correctif recommandé dans l'audit). */
.toast-root .alert-root { --sv-toast-role: var(--sv-info); }
.toast-root .alert-root:is(.sovreai-toast-success, [class*="02855E" i], [class*="166534"]) { --sv-toast-role: var(--sv-success); }
.toast-root .alert-root:is(.sovreai-toast-warning, [class*="C75209" i], [class*="92400e" i]) { --sv-toast-role: var(--sv-warning); }
.toast-root .alert-root:is(.sovreai-toast-error, [class*="E02F1F" i], [class*="991b1b" i]) { --sv-toast-role: var(--sv-danger); }

/* zone des toasts : sous l'en-tête (52/56 px) au lieu de recouvrir le sélecteur métier (D155) ; 16 px de marge
   latérale en mobile ; ancre = liste Radix qui contient un toast (structure) */
ol:has(> li.toast-root) {
  inset: 56px 16px auto 16px; max-width: 420px; margin: 8px auto 0; padding: 0;
}
.toast-root { transition-duration: var(--sovreai-duration-base); }
/* hauteur fixe de 74 px posée en style inline par le natif : un message de plusieurs lignes débordait */
.toast-root[style] { height: auto !important; }
.toast-root > div { width: auto; padding: 4px 0; text-align: left; }
.toast-root .alert-root {
  display: inline-flex; align-items: flex-start; gap: 12px; max-width: 420px;
  padding: 12px 16px 12px 12px; text-align: left;
  font-family: var(--sovreai-font-body); font-weight: 400; font-size: 14px; line-height: 20px;
  color: var(--text-primary); background-color: var(--surface-dialog);
  border: 1px solid var(--sv-elevation-border); border-left: 3px solid var(--sv-toast-role);
  border-radius: var(--sovreai-radius-md); box-shadow: var(--sv-shadow-2);
}
/* icône du rôle, 20 px, alignée sur la première ligne */
.toast-root .alert-root > div:first-child:has(> svg) { margin: 0; color: var(--sv-toast-role); display: flex; }
.toast-root .alert-root > div:first-child > svg { width: 20px; height: 20px; }
.toast-root .alert-root > div:last-child { min-width: 0; }
@media (max-width: 767px) {
  /* mobile : toute la largeur moins les gouttières */
  .toast-root > div { width: 100%; }
  .toast-root .alert-root { display: flex; width: 100%; max-width: none; }
}

/* ---------- 8b. États vides (DESIGN-SYSTEM §6 « Vide », §11.2, D068) ----------
   Un seul modèle : cadre en bordure décorative, rayon 12, pastille ronde 40 px (surface alternative) avec
   icône secondaire 20 px, titre « label » 14/20 500 corps, texte « caption » 12/16 secondaire.
   Ancre des panneaux (Modèles, Connecteurs, Mémoire) : structure « pastille ronde contenant une icône, puis
   deux paragraphes » — la pastille native est reconnue par .rounded-full (Tailwind, fragile). */
div:has(> div.rounded-full:first-child > svg:only-child):has(> p + p) {
  border: 1px solid var(--border-light); border-radius: var(--sovreai-radius-md);
  padding: 24px 16px; background: transparent;
}
div:has(> div.rounded-full:first-child > svg:only-child):has(> p + p) > div:first-child {
  width: 40px; height: 40px; margin-bottom: 12px; background: var(--surface-tertiary); color: var(--text-secondary);
}
div:has(> div.rounded-full:first-child > svg:only-child):has(> p + p) > div:first-child > svg { width: 20px; height: 20px; }
div:has(> div.rounded-full:first-child > svg:only-child):has(> p + p) > p:nth-child(2) {
  font-family: var(--sovreai-font-body); font-weight: 500; font-size: 14px; line-height: 20px; color: var(--text-primary);
}
div:has(> div.rounded-full:first-child > svg:only-child):has(> p + p) > p:nth-child(3) {
  margin-top: 4px; font-family: var(--sovreai-font-body); font-size: 12px; line-height: 16px; color: var(--text-secondary);
}

/* États vides sans pastille native (page Projets, tableaux vides) : même modèle, pastille dessinée sans
   élément ajouté — disque = dégradé radial du fond (surface alternative), icône = ::before masqué (secondaire).
   Géométrie : marge haute 24 + pastille 40 + écart 12 = 76 ; centre du disque à 24 + 20 = 44. */
/* page Projets : la boîte de 150 px à une ligne devient l'état vide commun ; sous le titre, la phrase de la
   charte (§11.2) tant qu'aucune recherche n'est saisie (le même message sert aux recherches sans résultat).
   Ancre : bloc sans élément enfant qui suit la grille de projets vide (structure + .grid, fragile). */
main div.grid:empty + div:not(:has(*)) {
  --sv-empty-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z'/></svg>");
  padding: 76px 24px 24px; border: 1px solid var(--border-light); border-radius: var(--sovreai-radius-md);
  font-family: var(--sovreai-font-body); font-weight: 500; font-size: 14px; line-height: 20px; color: var(--text-primary);
}
main:has(input[placeholder]:placeholder-shown) div.grid:empty + div:not(:has(*))::after {
  content: "Regroupez vos conversations par dossier."; display: block; margin-top: 4px;
  font-weight: 400; font-size: 12px; line-height: 16px; color: var(--text-secondary);
}
/* tableaux vides (panneau Fichiers, « Mes fichiers », archives) : une seule ligne dont la cellule couvre
   toutes les colonnes. Ancre : structure tbody > tr:only-child > td[colspan]:only-child (aucune ligne de
   données n'utilise colspan). L'en-tête de tri, inutile sans données, est masqué. */
:is(nav, [role="dialog"]) table:has(> tbody > tr:only-child > td[colspan]:only-child) > thead { display: none; }
:is(nav, [role="dialog"]) tbody > tr:only-child > td[colspan]:only-child {
  --sv-empty-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M22 12h-6l-2 3h-4l-2-3H2'/><path d='M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/></svg>");
  height: auto; padding: 76px 16px 24px; text-align: center;
  font-family: var(--sovreai-font-body); font-weight: 500; font-size: 14px; line-height: 20px; color: var(--text-primary);
}
:is(nav, [role="dialog"]) tbody > tr:only-child:has(> td[colspan]:only-child) { background: transparent; }
/* disque et icône communs */
:is(main div.grid:empty + div:not(:has(*)), :is(nav, [role="dialog"]) tbody > tr:only-child > td[colspan]:only-child) {
  position: relative;
  background: radial-gradient(circle 20px at 50% 44px, var(--surface-tertiary) 19.5px, transparent 20px) no-repeat;
}
:is(main div.grid:empty + div:not(:has(*)), :is(nav, [role="dialog"]) tbody > tr:only-child > td[colspan]:only-child)::before {
  content: ""; position: absolute; top: 34px; left: 50%; width: 20px; height: 20px; margin-left: -10px;
  background: var(--text-secondary);
  -webkit-mask: var(--sv-empty-icon) center / contain no-repeat; mask: var(--sv-empty-icon) center / contain no-repeat;
}

/* ---------- 8c. Tableau du panneau Fichiers : coin arrondi respecté, icônes de tri égales (D102) ----------
   Le fond de l'en-tête débordait de l'arrondi du cadre (coin supérieur gauche cassé) : le cadre rogne son contenu.
   Ancre : cadre dont le petit-enfant est un tableau (structure). */
nav div:has(> div > div > table) { overflow: hidden; border-radius: var(--sovreai-radius-md); box-shadow: none; }
/* icônes de tri d'en-tête de tableau : une seule taille (16 px) et un seul écart (gap natif), au lieu de 16/12 px.
   Ancre : classe d'icône lucide (stable) dans un bouton d'en-tête. */
thead th button > svg.lucide-arrow-up-down { width: 16px; height: 16px; margin-left: 0; }

/* ---------- 8d. Pagination inutile masquée (DESIGN-SYSTEM §6 « pagination masquée si vide », D102) ----------
   « Précédent 1 / 0 Suivant » ou deux boutons désactivés sous une liste vide ou d'une seule page.
   Ancre : aria-label anglais littéral « Pagination » (identique en français). */
[aria-label="Pagination"]:not(:has(button:enabled)) { display: none; }

/* ---------- 9a. Écran d'erreur de page (route inconnue, erreur de chargement) — D065, D067, D181, D182 ----------
   Écran natif restylé (A11) : fond de page, carte de marque centrée, logo, titre « display », une phrase et une
   action. Détails techniques (message brut anglais, « 404 Not Found », pile d'appels, données) et bouton de
   journal masqués. La redirection des routes inconnues vers l'accueil relève d'un patch de bundle à part.
   Ancre : role=alert dont la carte contient un titre h2 et un bloc de conseils (liste) — combinaison propre à
   cet écran (les autres role=alert du produit sont des messages de formulaire). */
[role="alert"]:has(> div > h2 ~ div > ul) {
  min-height: 100dvh; padding: 32px 16px; background: var(--presentation); background-image: none;
}
[role="alert"]:has(> div > h2 ~ div > ul) > div {
  width: 100%; max-width: 560px; margin: 0; padding: 32px;
  background: var(--surface-dialog); border: 1px solid var(--border-light); border-radius: var(--sovreai-radius-card);
  box-shadow: var(--sv-shadow-1); -webkit-backdrop-filter: none; backdrop-filter: none; text-align: center;
}
/* logo SovreAI au-dessus du titre (couleur en clair, blanc en sombre) */
[role="alert"]:has(> div > h2 ~ div > ul) > div::before {
  content: ""; display: block; height: 40px; margin: 0 auto 24px;
  background: url("./assets/logo.svg") no-repeat center / contain;
}
.dark [role="alert"]:has(> div > h2 ~ div > ul) > div::before { background-image: url("./assets/logo-white.svg"); }
/* titre : display (PT Serif 400, 30/38 ; 26/34 en mobile) */
[role="alert"]:has(> div > h2 ~ div > ul) > div > h2 {
  margin: 0 0 12px; font-family: var(--sovreai-font-title); font-weight: 400; font-size: 30px; line-height: 38px;
  letter-spacing: -0.01em; color: var(--sv-text-title); text-wrap: balance;
}
/* détails techniques masqués : message brut, statut HTTP (cartes rouge et jaune hors charte), pile, données */
[role="alert"]:has(> div > h2 ~ div > ul) > div > :is(div:has(> h3), details) { display: none; }
/* phrase et conseils : texte secondaire 14/20 ; liste centrée en bloc, puces suspendues (D182) */
[role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) { margin-top: 0; gap: 12px; align-items: center; }
[role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) > p {
  font-family: var(--sovreai-font-body); font-weight: 400; font-size: 14px; line-height: 20px; color: var(--text-secondary);
  text-wrap: balance;
}
[role="alert"]:has(> div > h2 ~ div > ul) > div > div > ul {
  align-self: center; max-width: 100%; margin: 0; padding-left: 24px; list-style-position: outside; text-align: left;
  font-family: var(--sovreai-font-body); font-size: 14px; line-height: 20px; color: var(--text-secondary);
}
[role="alert"]:has(> div > h2 ~ div > ul) > div > div > ul > li + li { margin-top: 4px; }
[role="alert"]:has(> div > h2 ~ div > ul) > div > div > ul > li::marker { color: var(--text-secondary); }
/* actions : une seule (primaire) ; bouton « journal des erreurs » masqué */
[role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) > div { margin-top: 12px; }
[role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) > div > button:not(:first-child) { display: none; }
[role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) > div > button:first-child {
  height: 44px; padding: 0 24px; border-radius: var(--sovreai-radius-btn);
  background-color: var(--sovreai-primary); color: var(--sovreai-white);
  font-family: var(--sovreai-font-body); font-weight: 500; font-size: 14px; line-height: 20px;
  transition: background-color var(--sovreai-duration-fast);
}
[role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) > div > button:first-child:hover { background-color: var(--sovreai-primary-hover); }
[role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) > div > button:first-child:focus-visible {
  outline: 2px solid var(--sv-ring); outline-offset: 2px; box-shadow: none;
}
@media (max-width: 767px) {
  [role="alert"]:has(> div > h2 ~ div > ul) > div { padding: 24px; }
  [role="alert"]:has(> div > h2 ~ div > ul) > div > h2 { font-size: 26px; line-height: 34px; }
  /* action principale pleine largeur (pouce) */
  [role="alert"]:has(> div > h2 ~ div > ul) > div > div:has(> ul) > div { align-self: stretch; }
}

/* ---------- 10a. Cibles tactiles (44 px sous pointeur grossier ; le bouton d'action y est déjà) ---------- */
@media (pointer: coarse) {
  [role="alert"]:has(> div > h2 ~ div > ul) button { min-height: 44px; }
}

/* ---------- 11a. Motion des toasts (DESIGN-SYSTEM §8) : entrée « base » sans rebond, sortie « fast » ---------- */
@keyframes sovreai-toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.toast-root[data-state="open"] { animation: sovreai-toast-in var(--sovreai-duration-base) var(--sovreai-ease-in) both; }
@media (prefers-reduced-motion: reduce) {
  .toast-root[data-state] { animation: none; transition: none; }
}

/* archives vides : comment en ajouter, et cadre ajusté au contenu (A008) ; tableau à 3 colonnes = archives */
[role="dialog"] table:has(> thead > tr > th:nth-child(3):last-child) td[colspan]:only-child::after {
  content: "Archivez une conversation depuis son menu « … » pour la retrouver ici."; display: block; margin-top: 4px;
  font: 400 12px/16px var(--sovreai-font-body); color: var(--text-secondary);
}
[role="dialog"] div.flex-1:has(> table > tbody > tr:only-child > td[colspan]:only-child) { flex: 0 0 auto; }
/* fichiers : l'état vide dit comment en ajouter, tant qu'aucune recherche n'est saisie (D068, D102) */
:is(nav div:has(> [role="region"] #filename-filter:placeholder-shown), [role="dialog"]:has(#files-filter:placeholder-shown)) tbody > tr:only-child > td[colspan]:only-child::after {
  content: "Ajoutez-en un avec le trombone de la zone de saisie."; display: block; margin-top: 4px;
  font: 400 12px/16px var(--sovreai-font-body); color: var(--text-secondary);
}

/* SovreAI Chat — thème, partie « mobile et accessibilité ». Concaténée après theme/sovreai-theme.css au build (scripts/build-dist.mjs §1) :
   n'utilise que les jetons et rôles définis dans les sections 1 à 7 de ce fichier (aucune valeur littérale). */

/* ---------- 10. Mobile et accessibilité (focus unique, infobulles, contenus larges, cibles 44 px, gouttières) ---------- */
/* ============================================================================
   SovreAI Chat — fragment « Mobile 390 et accessibilité »
   (défilement des tableaux et du code, cibles tactiles, gouttières, focus, infobulles)
   À placer dans sovreai-theme.css : bloc A en section 7 (base : focus), blocs B à D en section 8
   (composants), blocs E et F en section 10 (mobile). Aucune valeur littérale de couleur, d'ombre ou de
   durée : uniquement des jetons --sovreai-*, --sv-* et les rôles natifs ; rayons et espacements de
   l'échelle (4 · 8 · 12 · 16 · 20 · 24 · 32).
   Défauts traités : D044, D075, D076, D107, D108, D109, D111, D113, D114, D116, D161, D174 (D175 : déjà
   réglé par le tiroir du thème).
   ========================================================================== */

/* ---------- A. Focus clavier unique (D075, DESIGN-SYSTEM §6) ----------
   Un seul style : contour 2 px de l'anneau de la charte (--sv-ring : #2563eb en clair, #93c5fd en
   sombre), décalé de 2 px. Il remplace le contour noir / blanc natif (:focus-visible codé en dur),
   l'anneau intérieur noir de la barre latérale, l'anneau gris et le double anneau Tailwind : les
   variables --tw-ring-* sont ramenées à une ombre nulle (épaisseur 0) pour éviter le double anneau.
   [data-focus-visible] = focus clavier des composants Ariakit. Les pages d'authentification gardent
   leur anneau clair sur le hero (thème, section 9). */
:where(:focus-visible, [data-focus-visible]):not(.sovreai-auth *) {
  outline: 2px solid var(--sv-ring) !important;
  outline-offset: 2px !important;
  --tw-ring-offset-shadow: 0 0 0 0 var(--sv-ring) !important;
  --tw-ring-shadow: 0 0 0 0 var(--sv-ring) !important;
}
/* spécificités volontairement graduées (toutes en !important, pour passer devant les utilitaires
   natifs) : règle générale (0,1,0) < conteneurs défilants (0,1,0, déclarée après) < items de menu
   (0,2,0) < petites commandes (0,2,1) ; les règles du rail (thème, section 9) restent prioritaires.
   Dans les conteneurs défilants (barre latérale, menus, listes, onglets verticaux) l'anneau passe à
   l'intérieur pour ne pas être rogné. */
:where(nav, [role="menu"], [role="listbox"], [role="tablist"][aria-orientation="vertical"]) :is(:focus-visible, [data-focus-visible]),
:is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"], [role="option"]):is(:focus-visible, [data-focus-visible]) {
  outline-offset: -2px !important;
}
/* … sauf sur les petites commandes (case, radio, interrupteur) : un anneau intérieur se confondrait
   avec leur bordure ; leur conteneur a toujours au moins 4 px de marge */
:is([role="checkbox"], [role="radio"], [role="switch"], input[type="checkbox"], input[type="radio"]):is(:focus-visible, [data-focus-visible]) {
  outline-offset: 2px !important;
}
/* pas d'anneau sur les grands conteneurs qui reçoivent un focus programmatique, ni sur la zone de
   saisie : le cadre du composer porte déjà l'anneau (thème, section 8, :focus-within — D076) */
:is([role="dialog"], [role="menu"], [role="listbox"], [role="tooltip"], main, [data-testid="text-input"]):focus-visible {
  outline: none !important;
}

/* ---------- B. Infobulles (D116, DESIGN-SYSTEM §5 « Infobulle ») ----------
   Rôle Infobulle (couleurs déjà posées par le thème, section 6), caption 12/16, rayon 8, élévation e2
   (aucune en sombre, la bulle claire se détache du fond). Sortie immédiate : l'infobulle qui se ferme
   perd data-open pendant son fondu de sortie (framer-motion) ; on la masque aussitôt, une seule
   infobulle reste visible et aucun fantôme ne recouvre la barre latérale. */
.tooltip, .dark .tooltip {
  font: 400 12px/16px var(--sovreai-font-body);
  letter-spacing: 0;
  padding: 4px 8px;
  border-radius: var(--sovreai-radius-btn);
  box-shadow: var(--sv-shadow-2);
}
.tooltip[role="tooltip"]:not([data-open]) { visibility: hidden !important; }

/* ---------- C. Contenu large : tableaux et blocs de code (D044, DESIGN-SYSTEM §5.1) ----------
   Indice de défilement : le bord du conteneur s'estompe tant qu'il reste du contenu de ce côté.
   L'animation est liée au défilement horizontal du conteneur lui-même : si rien ne déborde, la
   timeline est inactive et aucun fondu n'est appliqué (desktop inchangé). Le masque ne lit que
   l'opacité (couleur de charte opaque quelconque). Sans prise en charge (Firefox), rendu inchangé.
   Tableaux : fondu à droite seulement (la première colonne est collante en mobile, bloc E) ;
   code : fondu des deux côtés. */
@property --sv-fade-start { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --sv-fade-end { syntax: "<length>"; inherits: false; initial-value: 0px; }
@keyframes sovreai-scroll-fade {
  0% { --sv-fade-start: 0px; --sv-fade-end: 32px; }
  8% { --sv-fade-start: 32px; }
  92% { --sv-fade-end: 32px; }
  100% { --sv-fade-start: 32px; --sv-fade-end: 0px; }
}
.markdown .markdown-table-wrapper {
  -webkit-mask-image: linear-gradient(to left, transparent 0, var(--sovreai-white) var(--sv-fade-end));
  mask-image: linear-gradient(to left, transparent 0, var(--sovreai-white) var(--sv-fade-end));
  animation: sovreai-scroll-fade linear both;
  animation-timeline: scroll(self inline);
}
.markdown pre div:has(> code.hljs) {
  -webkit-mask-image: linear-gradient(to right, transparent 0, var(--sovreai-white) var(--sv-fade-start), var(--sovreai-white) calc(100% - var(--sv-fade-end)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, var(--sovreai-white) var(--sv-fade-start), var(--sovreai-white) calc(100% - var(--sv-fade-end)), transparent 100%);
  animation: sovreai-scroll-fade linear both;
  animation-timeline: scroll(self inline);
}

/* ---------- D. Petites cibles hors mobile (D161, D108) ----------
   Case à cocher : 20 px, rayon 4, dans une cible de 36 px (DESIGN-SYSTEM §5) qui ne change pas la mise
   en page ; son libellé natif (label for) reste cliquable. Champ numérique des paramètres : hauteur de
   contrôle (36 px ; son enveloppe native est bridée à 20 px par max-h-5). Libellés flottants des filtres de panneau (« Filtrer les modèles de message par nom ») : une
   seule ligne, points de suspension (le texte court est proposé en surcharge de locale). */
/* cases Radix uniquement ([data-state]) : la pastille d'outil actif du composer est aussi un role=checkbox (Ariakit) */
button[role="checkbox"][data-state] { position: relative; width: 20px; height: 20px; border-radius: var(--sovreai-radius-xs); }
button[role="checkbox"][data-state]::after { content: ""; position: absolute; inset: -8px; }
.rc-input-number { max-height: none !important; }
.rc-input-number-input { padding: 4px 8px; }
nav input.peer[placeholder=" "] + label[for] {
  max-width: calc(100% - 24px); overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}

/* ---------- E. Mobile (≤ 767 px) : gouttières de 16 px, colonne de lecture pleine largeur ---------- */
@media (max-width: 767px) {
  /* D113 : l'avatar passe sur la ligne du nom, le texte des réponses occupe toute la colonne
     (retrait de 52 px supprimé) ; le message utilisateur s'aligne sur la même gouttière droite */
  .message-render:has(> .agent-turn) { position: relative; }
  .message-render:has(> .agent-turn) > div:first-child { position: absolute; top: 0; left: 0; }
  .message-render > :is(.agent-turn, .user-turn) { width: 100% !important; flex: 1 1 auto; }
  .agent-turn > h2 { display: flex; align-items: center; min-height: 28px; padding-left: calc(28px + 8px); margin-bottom: 4px; } /* avatar 28 + 8 */

  /* D044 : cellules resserrées ; première colonne collante des réponses (DESIGN-SYSTEM §5.1), séparée
     des colonnes qui défilent dessous par un filet de 1 px (tracé en ombre intérieure : en
     border-collapse, une bordure est peinte par le tableau et ne suit pas la cellule collante) ; fond
     opaque sous la cellule (celui de la ligne, spécificité nulle pour ne pas écraser un zébrage) */
  .markdown table :is(th, td) { padding: 8px 12px !important; }
  .agent-turn .markdown table :is(th, td):first-child { position: sticky; left: 0; z-index: 1; box-shadow: inset -1px 0 0 var(--border-medium); }
  :where(.agent-turn .markdown table tbody tr:nth-child(odd) > td:first-child) { background: var(--presentation); }

  /* D114 : « Aller au dernier message » centré au-dessus du composer : règle commune (partie 08) */

  /* D174 : composer détaché des bords (gouttière 16 px, rayon 20 sur les 4 coins, anneau de focus
     entièrement visible), marge basse qui tient compte de la zone de sécurité (viewport-fit=cover) */
  form:has([data-testid="text-input"]) { padding: 0 16px max(8px, env(safe-area-inset-bottom)) !important; }
  div:has(> div > div > [data-testid="text-input"]) { padding-bottom: 0 !important; }

  /* D109 : gouttières régulières de 16 px (carte d'authentification, accueil, Marketplace) */
  .sovreai-auth main > div { width: min(370px, calc(100vw - 32px)) !important; max-width: 100%; }
  main div:has(> div > div + .sr-only + p.split-parent) { padding-left: 16px; padding-right: 16px; }
  [role="tabpanel"] > [role="grid"] { margin-left: 0 !important; margin-right: 0 !important; }
  /* grille collée aux bords d'un conteneur rogné : anneau de focus à l'intérieur */
  [role="tabpanel"] > [role="grid"] :is(:focus-visible, [data-focus-visible]) { outline-offset: -2px !important; }
  [role="tablist"]:has(> [id^="category-tab-"]) { padding-left: 0 !important; padding-right: 0 !important; }
  /* recherche de la Marketplace : taille de champ (body 16) pour que le texte d'aide tienne sur 358 px */
  #agent-search { font-size: 16px; line-height: 24px; text-overflow: ellipsis; }
}

/* ---------- F. Cibles tactiles de 44 px (D107, D111, D161 ; DESIGN-SYSTEM §4 « Contrôles ») ---------- */
@media (pointer: coarse) {
  /* en-têtes (conversation, Marketplace) et composer */
  #open-sidebar-button, #close-sidebar-button, #export-menu-button, div:has(> #open-sidebar-button) > button,
  #attach-file-menu-button, #tools-dropdown-button,
  [data-testid="send-button"], [data-testid="stop-generation-button"] { min-width: 44px !important; min-height: 44px !important; }
  [data-testid="model-selector-button"] { min-height: 44px !important; }
  /* actions des messages, réflexion, aller au dernier message */
  .hover-button { min-width: 44px !important; min-height: 44px !important; }
  .group\/reasoning button { min-width: 44px; min-height: 44px; }
  .premium-scroll-button, .dark .premium-scroll-button { width: 44px; height: 44px; }
  /* en-tête des blocs de code : « Copier le code » sur toute la hauteur de la barre (44 px) */
  .markdown pre > div > div:first-child { padding-top: 0 !important; padding-bottom: 0 !important; }
  .markdown pre > div > div:first-child button { min-height: 44px; }
  /* barre latérale (tiroir) : entrées, surtitres repliables, « Tous les projets », « Nouveau projet »,
     options de conversation (dont l'enveloppe native est limitée à 28 px) */
  nav :is(button, a[href], [role="button"]):not([role="switch"], [role="checkbox"], [role="radio"]) { min-height: 44px; }
  nav button:not([role="switch"], [role="checkbox"], [role="radio"]):not(:has(> span, > div)) { min-width: 44px; }
  nav :is(input, select):not([type="checkbox"], [type="radio"], [type="range"], [type="hidden"]) { min-height: 44px; }
  [data-testid="convo-item"] div:has(> button[id^="conversation-menu-"]) { max-width: none !important; }
  [data-testid="convo-item"] button[id^="conversation-menu-"] { min-width: 44px; min-height: 44px; }
  /* « … » des conversations inactives : visible au toucher (le survol n'existe pas, D107) */
  [data-testid="convo-item"] div:has(> button[id^="conversation-menu-"]), [data-testid="convo-item"] button[id^="conversation-menu-"] { opacity: 1 !important; pointer-events: auto !important; }
  /* menus et listes : items de 44 px ; bouton-icône interne (punaise « Épingler » du menu Outils) :
     cible de 44 × 44 qui déborde de 10 px dans le remplissage de l'item (marge négative), sans
     agrandir l'item ni élargir le menu (qui resterait sinon collé au bord de l'écran) */
  :is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"], [role="option"]) { min-height: 44px; }
  :is([role="menuitem"], [role="menuitemcheckbox"]) button:not(:has(> span:not(.sr-only))) { min-width: 44px; min-height: 44px; margin: -10px; }
  /* onglets (catégories de la Marketplace, paramètres) ; boutons des dialogues (croix de fermeture,
     listes déroulantes, actions du détail d'un assistant), les boutons-icônes en 44 × 44 */
  [role="tab"] { min-height: 44px; }
  [role="dialog"] button:not([role="switch"], [role="checkbox"], [role="radio"]) { min-height: 44px; }
  [role="dialog"] button:not([role="switch"], [role="checkbox"], [role="radio"]):not(:has(> span:not(.sr-only), > div)) { min-width: 44px; }
  /* bouton « Épingler » masqué des options du menu métier : ne réserve pas 44 px */
  [role="dialog"]:has(#model-search) [role="option"] button { min-width: 0; min-height: 0; }
  /* authentification : bouton « Afficher le mot de passe » ; liens de la carte et du pied de page :
     zone de toucher agrandie de 12 px en haut et en bas par un pseudo-élément (aucun décalage de mise
     en page, le filet du pied de page garde sa hauteur) */
  .sovreai-auth .group\/secret-input button { min-width: 44px; min-height: 44px; }
  .sovreai-auth :is(main, [role="contentinfo"]) a { position: relative; }
  .sovreai-auth :is(main, [role="contentinfo"]) a::after { content: ""; position: absolute; inset: -12px 0; }
  /* case à cocher et champ numérique */
  button[role="checkbox"][data-state]::after { inset: -12px; }
  .rc-input-number-input { min-height: 44px; }
}

/* cibles tactiles complémentaires relevées à la recette finale (390 px) */
@media (pointer: coarse) {
  .sovreai-auth :is([role="contentinfo"] a, main a) { display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; }
  .markdown pre > div > div:first-child button { min-width: 44px; min-height: 44px; justify-content: center; }
  .sovreai-auth main a.block { display: flex; justify-content: center; } /* « Retour à la connexion » centré (D093) */
}
/* titre display mobile 26/34 sur toutes les pages (Projets restait à 30 px, D135) ; h1[class] exclut les titres des réponses */
@media (max-width: 767px) { main h1[class] { font-size: 26px; line-height: 34px; } }

/* ---------- Lien d'évitement (D162) : injecté au build en tête de <body>, visible seulement au focus clavier ---------- */
.sovreai-skip {
  position: fixed; top: 8px; left: 8px; z-index: 1000; transform: translateY(-200%);
  padding: 8px 12px; border-radius: var(--sovreai-radius-btn); background: var(--surface-dialog); color: var(--text-primary);
  font: 500 14px/20px var(--sovreai-font-body); box-shadow: var(--sv-shadow-2); outline: 2px solid var(--sv-ring); outline-offset: 2px;
  transition: transform var(--sovreai-duration-fast) var(--sovreai-ease-in);
}
.sovreai-skip:focus { transform: none; }
body:has(.sovreai-auth) .sovreai-skip { display: none; }

/* Mes fichiers : même compteur de sélection en mobile qu'en desktop (« 0/3 » n'a pas de sens, A009) */
@media (max-width: 639px) {
  [role="dialog"]:has(#files-filter) span.hidden.sm\:inline { display: inline !important; }
  [role="dialog"]:has(#files-filter) span.sm\:hidden { display: none !important; }
}
/* panneau Fichiers (étroit) : colonne Date assez large pour « 29 sept. 2026 » (elle était rognée par la gauche) */
nav table.table-fixed :is(th, td:not([colspan])):last-child { width: 124px; padding-left: 4px !important; padding-right: 8px !important; white-space: nowrap; }
/* infobulle : ne reste pas ouverte quand le focus quitte la page et que rien n'est survolé (D116) */
html:not(:focus-within):not(:hover) .tooltip[role="tooltip"] { visibility: hidden !important; }

/* SovreAI Chat — thème, partie « écran de chargement et motion ». Concaténée après theme/sovreai-theme.css au build (scripts/build-dist.mjs §1) :
   n'utilise que les jetons et rôles définis dans les sections 1 à 7 de ce fichier (aucune valeur littérale). */

/* ── Écran de chargement initial : pictogramme SovreAI pulsant au centre (premier plan du film ; fond posé par index.html) ── */
#loading-container::before {
  content: ""; width: 56px; height: 56px; background: url("./assets/logo-mark.svg") center / contain no-repeat;
  animation: sovreai-pulse 1.5s ease-in-out infinite;
}

/* ---------- 11. Motion (DESIGN-SYSTEM §8) ---------- */
@keyframes sovreai-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
/* durées ramenées à l'échelle 150 / 200 / 250 ms, sans rebond (D117) — on règle les durées, pas les propriétés */
.duration-300, .duration-500, .duration-700, .duration-1000, .animated-tab-panel, .animated-tab-list::after, .nav-mask { transition-duration: var(--sovreai-duration-slow) !important; }
.duration-100, .btn, .btn-neutral, .custom-btn, .premium-scroll-button { transition-duration: var(--sovreai-duration-fast) !important; }
.animate-fadeIn, .fade-in { animation-duration: var(--sovreai-duration-slow) !important; }
[class*="animate-slideUpAndFade"], [class*="animate-slideDownAndFade"], [class*="animate-slideLeftAndFade"], [class*="animate-slideRightAndFade"] {
  animation-duration: var(--sovreai-duration-base) !important; animation-timing-function: var(--sovreai-ease-in) !important;
}
.toast-root[data-state="open"] { animation-duration: var(--sovreai-duration-base) !important; animation-timing-function: var(--sovreai-ease-in) !important; }
.toast-root[data-state="closed"] { animation-duration: var(--sovreai-duration-fast) !important; animation-timing-function: var(--sovreai-ease-out) !important; }
.scroll-animation-enter-active { animation-duration: var(--sovreai-duration-base) !important; animation-timing-function: var(--sovreai-ease-in) !important; }
.scroll-animation-exit-active { animation-duration: var(--sovreai-duration-fast) !important; }
[class*="motion-safe:animate-slide-in"], [class*="motion-safe:animate-slide-out"] { animation-duration: var(--sovreai-duration-slow) !important; }
/* animations décoratives en boucle supprimées (seuls les indicateurs de chargement et de génération bougent) */
.animate-gradient-x, .moon-rise, .move-up, .slide-to-down, .slide-from-left, .rotate-adjust-and-back, .slow-pulse, .ios-wiggle, .shake, .animate-flash, p > small {
  animation: none !important;
}
/* réduction des mouvements : tout à 0 ; l'indicateur de génération devient un point fixe (le titre animé lettre à lettre aussi) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  .result-streaming *::after, .submitting .result-thinking::after, .agent-turn .group\/reasoning::before, .shimmer { animation: none !important; opacity: 1 !important; }
  main div.flex.flex-col.items-center.justify-center.gap-2 span { opacity: 1 !important; transform: none !important; filter: none !important; }
}
