/*
 * custom.css — capitalisation-quads
 * Surcharges Pico CSS + système de palettes
 *
 * Trois palettes : Encre (défaut), Parchemin, Graphite
 * Deux thèmes : dark (défaut), light
 * Reprise de l'esprit capitalisation-ia (tokens.css)
 *
 * Usage :
 *   <html data-theme="dark" data-palette="encre">  (défaut)
 *   <html data-theme="light" data-palette="parchemin">
 */

/* ============================================================
   TYPOGRAPHIE — surcharge Pico
   Direction D (PV 16.0 §4) — 3 familles vendorisées par rôle
   ============================================================ */
:root {
  /* Direction D (PV 16.0 §4) — familles par rôle */
  --font-chrome: 'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
  --font-display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-body: 'Public Sans', 'Segoe UI', system-ui, sans-serif;
  --pico-font-family: var(--font-body);
  --pico-font-family-monospace: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace;

  /* Échelle typographique (ratio 1.25, base 14px) */
  --text-h1: 1.75rem;
  --text-h2: 1.4rem;
  --text-h3: 1.125rem;
  --text-h4: 1rem;
  --text-body: 0.875rem;
  --text-small: 0.8125rem;
  --text-xs: 0.75rem;

  --pico-font-size: 0.875rem; /* 14px base */
  --pico-line-height: 1.3;
  --pico-spacing: 0.5rem; /* Densité −30% */

  /* Raccourci mono pour les composants */
  --font-mono: var(--pico-font-family-monospace);

  /* Poids */
  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;

  /* ============================================================
     ESPACEMENTS — reprise capitalisation-ia
     ============================================================ */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;

  /* ============================================================
     RAYONS DE BORDURE — surcharge Pico
     ============================================================ */
  --pico-border-radius: 6px;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-full: 9999px;

  /* ============================================================
     TRANSITIONS
     ============================================================ */
  --transition-fast: 150ms ease;
  --transition-base: 200ms ease;

  /* ============================================================
     LAYOUT
     ============================================================ */
  --sidebar-width: 220px;
  --topbar-height: 40px;
  --statusbar-height: 24px;

  /* Système de colonnes partagé (ADR 072) — tokens de largeur SÉMANTIQUES PAR RÔLE
     (D-035-7 : pas de largeur unique). Valeurs justifiées par cartographie.md. */
  --pane-filters: 240px;            /* colonne facettes/filtres — search */
  --pane-nav: 220px;                /* navigation/contexte latéral — domain, research-note, app-shell */
  --pane-list: minmax(0, 1fr);      /* colonne liste d'un couple liste/détail */
  --browse-col-width: 30rem;        /* colonne liste « Parcourir » — largeur unifiée cross-plugin (POI/Contacts/Liens) */
  --pane-detail: minmax(0, 1.2fr);  /* colonne détail/aperçu (légèrement dominante) */
  --card-min: 240px;                /* largeur mini d'une carte (card-grid auto-fill) — médiane 180/200/240/280 */
  --bp-collapse: 768px;             /* breakpoint canonique d'effondrement 2-pane/colonnes (= search existant) */

  /* ============================================================
     Z-INDEX
     ============================================================ */
  --z-modal: 400;
  --z-toast: 500;

  /* ============================================================
     ALIAS TOKENS — résolution des tokens fantômes (CSS-1, IHM-C)
     Définis ici pour que les composants héritent des valeurs
     thématisées via la cascade (palette vars résolues à l'usage).
     ============================================================ */
  --danger: var(--semantic-error);
  --radius-1: var(--radius-sm);
  --surface-3: var(--surface-hover);
  --text-on-dark: var(--text-on-accent);
  --color-error: var(--semantic-error);
  --accent-warning: var(--semantic-warning);
  /* Accent secondaire de la palette. Seule façon correcte de lire l'accent
     secondaire depuis un shadow root : pico.min.css redéfinit --pico-secondary
     sur le :host de CHAQUE root — un composant qui lit var(--pico-secondary)
     obtient l'ardoise Pico, jamais la valeur de palette (mesuré en 16.B1 B1.4).
     Attention : cet accent n'est PAS une couleur sémantique — sa teinte change
     de famille selon la palette (indigo/ambre/gris) et vaut --semantic-warning
     en parchemin/light. Pour porter du sens, définir un token dédié par palette
     (cf --icon-structural). Aucun consommateur à ce jour ; alias conservé. */
  --accent-secondary: var(--pico-secondary);
  /* Fonds sémantiques : color-mix réactif au thème courant */
  --semantic-error-bg: color-mix(in srgb, var(--semantic-error) 12%, var(--surface-0));
  --semantic-success-bg: color-mix(in srgb, var(--semantic-success) 12%, var(--surface-0));
  --semantic-warning-bg: color-mix(in srgb, var(--semantic-warning) 12%, var(--surface-0));
  --semantic-info-bg: color-mix(in srgb, var(--semantic-info) 12%, var(--surface-0));
  --accent-soft: color-mix(in srgb, var(--accent-primary) 12%, var(--surface-0));
}

/* ============================================================
   PALETTE : ENCRE (sombre professionnel) — DÉFAUT
   ============================================================ */
[data-palette="encre"][data-theme="dark"],
[data-palette="encre"]:not([data-theme]),
:root:not([data-palette]) {
  --pico-background-color: #0f1117;
  --pico-card-background-color: #161922;
  --pico-card-sectioning-background-color: #1c2030;
  --pico-color: #e4e7ed;
  --pico-muted-color: #9ba3b5;
  --pico-muted-border-color: #232838;
  --pico-primary: #00b4ff;
  --pico-primary-hover: #38c8ff;
  --pico-secondary: #6366f1;
  --pico-secondary-hover: #818cf8;
  --pico-contrast: #e4e7ed;
  --pico-contrast-hover: #ffffff;
  --pico-table-border-color: #232838;
  --pico-form-element-background-color: #1c2030;
  --pico-form-element-border-color: #333a4d;
  --pico-form-element-color: #e4e7ed;
  --pico-form-element-focus-color: #00b4ff;

  /* Tokens sémantiques */
  --surface-0: #0f1117;
  --surface-1: #161922;
  --surface-2: #1c2030;
  --surface-hover: #232838;
  --text-0: #e4e7ed;
  --text-1: #9ba3b5;
  --text-2: #8892a8;
  --border-0: #232838;
  --border-1: #333a4d;
  --accent-primary: #00b4ff;
  --accent-primary-hover: #38c8ff;
  --semantic-success: #22c55e;
  /* --semantic-error : #dc2626 garantit ratio ≥ 4.5:1 sur fond clair ET texte blanc sur fond rouge (WCAG AA, T-1081). */
  --semantic-error: #dc2626;
  --semantic-warning: #f59e0b;
  --semantic-info: #06b6d4;
  /* Icônes structurelles (hiérarchie, composition) — D-16B-3, correctif 16.B1.
     Token DÉDIÉ, jamais --pico-secondary : l'accent secondaire de Pico est réglé
     par palette à des teintes hétérogènes et vaut --semantic-warning en
     parchemin/light (collision mesurée : icône hiérarchie == icône voisinage).
     Invariants tenus dans les 6 blocs : famille indigo, distinct de
     --semantic-warning ET --semantic-info du même bloc, contraste ≥ 3:1
     (WCAG 1.4.11, objets graphiques) contre --surface-1 du bloc. */
  --icon-structural: #6366f1; /* vs --surface-1 #161922 : 3.93:1 */
  --text-on-accent: #ffffff;

  color-scheme: dark;
}

[data-palette="encre"][data-theme="light"] {
  --pico-background-color: #f8f9fb;
  --pico-card-background-color: #ffffff;
  --pico-card-sectioning-background-color: #f0f1f5;
  --pico-color: #1a1d27;
  --pico-muted-color: #5c6478;
  --pico-muted-border-color: #e8eaf0;
  --pico-primary: #0077cc;
  --pico-primary-hover: #005fa3;
  --pico-secondary: #4f46e5;
  --pico-secondary-hover: #4338ca;
  --pico-contrast: #1a1d27;
  --pico-contrast-hover: #000000;
  --pico-table-border-color: #e8eaf0;
  --pico-form-element-background-color: #ffffff;
  --pico-form-element-border-color: #d0d4de;
  --pico-form-element-color: #1a1d27;
  --pico-form-element-focus-color: #0077cc;

  --surface-0: #f8f9fb;
  --surface-1: #ffffff;
  --surface-2: #f0f1f5;
  --surface-hover: #e8eaf0;
  --text-0: #1a1d27;
  --text-1: #5c6478;
  --text-2: #6b7385;
  --border-0: #e8eaf0;
  --border-1: #d0d4de;
  --accent-primary: #0077cc;
  --accent-primary-hover: #005fa3;
  --semantic-success: #16a34a;
  --semantic-error: #dc2626;
  --semantic-warning: #d97706;
  --semantic-info: #0e7490;
  --icon-structural: #4f46e5; /* vs --surface-1 #ffffff : 6.29:1 */
  --text-on-accent: #ffffff;

  color-scheme: light;
}

/* ============================================================
   PALETTE : PARCHEMIN (clair académique)
   ============================================================ */
[data-palette="parchemin"][data-theme="light"],
[data-palette="parchemin"]:not([data-theme]) {
  --pico-background-color: #faf8f4;
  --pico-card-background-color: #ffffff;
  --pico-card-sectioning-background-color: #f2efe8;
  --pico-color: #2c2a25;
  --pico-muted-color: #6b6560;
  --pico-muted-border-color: #e8e4db;
  --pico-primary: #2563a8;
  --pico-primary-hover: #1d4f8a;
  --pico-secondary: #b45309;
  --pico-secondary-hover: #92400e;
  --pico-contrast: #2c2a25;
  --pico-contrast-hover: #000000;
  --pico-table-border-color: #e8e4db;
  --pico-form-element-background-color: #ffffff;
  --pico-form-element-border-color: #d4cfc5;
  --pico-form-element-color: #2c2a25;
  --pico-form-element-focus-color: #2563a8;

  --surface-0: #faf8f4;
  --surface-1: #ffffff;
  --surface-2: #f2efe8;
  --surface-hover: #eae6dc;
  --text-0: #2c2a25;
  --text-1: #6b6560;
  --text-2: #786e64;
  --border-0: #e8e4db;
  --border-1: #d4cfc5;
  --accent-primary: #2563a8;
  --accent-primary-hover: #1d4f8a;
  --semantic-success: #16753a;
  --semantic-error: #c42b2b;
  --semantic-warning: #b45309;
  --semantic-info: #0e7490;
  /* Palette de la collision corrigée : --pico-secondary y vaut #b45309, soit
     exactement --semantic-warning ci-dessus. L'indigo foncé rétablit le typage. */
  --icon-structural: #4338ca; /* vs --surface-1 #ffffff : 7.90:1 */
  --text-on-accent: #ffffff;

  color-scheme: light;
}

[data-palette="parchemin"][data-theme="dark"] {
  --pico-background-color: #1c1a17;
  --pico-card-background-color: #252320;
  --pico-card-sectioning-background-color: #2e2b27;
  --pico-color: #e8e4db;
  --pico-muted-color: #a09890;
  --pico-muted-border-color: #3a3632;
  --pico-primary: #5ba3e0;
  --pico-primary-hover: #7ab8ea;
  --pico-secondary: #e09040;
  --pico-secondary-hover: #e8a660;
  --pico-contrast: #e8e4db;
  --pico-contrast-hover: #ffffff;
  --pico-table-border-color: #3a3632;
  --pico-form-element-background-color: #2e2b27;
  --pico-form-element-border-color: #504a44;
  --pico-form-element-color: #e8e4db;
  --pico-form-element-focus-color: #5ba3e0;

  --surface-0: #1c1a17;
  --surface-1: #252320;
  --surface-2: #2e2b27;
  --surface-hover: #3a3632;
  --text-0: #e8e4db;
  --text-1: #a09890;
  --text-2: #9a938d;
  --border-0: #3a3632;
  --border-1: #504a44;
  --accent-primary: #5ba3e0;
  --accent-primary-hover: #7ab8ea;
  --semantic-success: #22c55e;
  --semantic-error: #dc2626;
  --semantic-warning: #f59e0b;
  --semantic-info: #06b6d4;
  --icon-structural: #818cf8; /* vs --surface-1 #252320 : 5.25:1 */
  --text-on-accent: #ffffff;

  color-scheme: dark;
}

/* ============================================================
   PALETTE : GRAPHITE (hybride neutre)
   ============================================================ */
[data-palette="graphite"][data-theme="dark"],
[data-palette="graphite"]:not([data-theme]) {
  --pico-background-color: #111111;
  --pico-card-background-color: #191919;
  --pico-card-sectioning-background-color: #222222;
  --pico-color: #eeeeee;
  --pico-muted-color: #999999;
  --pico-muted-border-color: #252525;
  --pico-primary: #10b981;
  --pico-primary-hover: #34d399;
  --pico-secondary: #6b7280;
  --pico-secondary-hover: #9ca3af;
  --pico-contrast: #eeeeee;
  --pico-contrast-hover: #ffffff;
  --pico-table-border-color: #252525;
  --pico-form-element-background-color: #222222;
  --pico-form-element-border-color: #363636;
  --pico-form-element-color: #eeeeee;
  --pico-form-element-focus-color: #10b981;

  --surface-0: #111111;
  --surface-1: #191919;
  --surface-2: #222222;
  --surface-hover: #2a2a2a;
  --text-0: #eeeeee;
  --text-1: #999999;
  --text-2: #8a8a8a;
  --border-0: #252525;
  --border-1: #363636;
  --accent-primary: #10b981;
  --accent-primary-hover: #34d399;
  --semantic-success: #22c55e;
  --semantic-error: #dc2626;
  --semantic-warning: #eab308;
  --semantic-info: #06b6d4;
  /* Graphite reste neutre pour le chrome, mais l'icône structurelle garde
     l'indigo : --pico-secondary y est gris #6b7280 (aspect « désactivé »). */
  --icon-structural: #818cf8; /* vs --surface-1 #191919 : 5.89:1 */
  --text-on-accent: #ffffff;

  color-scheme: dark;
}

[data-palette="graphite"][data-theme="light"] {
  --pico-background-color: #fafafa;
  --pico-card-background-color: #ffffff;
  --pico-card-sectioning-background-color: #f2f2f2;
  --pico-color: #171717;
  --pico-muted-color: #737373;
  --pico-muted-border-color: #e5e5e5;
  --pico-primary: #059669;
  --pico-primary-hover: #047857;
  --pico-secondary: #6b7280;
  --pico-secondary-hover: #4b5563;
  --pico-contrast: #171717;
  --pico-contrast-hover: #000000;
  --pico-table-border-color: #e5e5e5;
  --pico-form-element-background-color: #ffffff;
  --pico-form-element-border-color: #d4d4d4;
  --pico-form-element-color: #171717;
  --pico-form-element-focus-color: #059669;

  --surface-0: #fafafa;
  --surface-1: #ffffff;
  --surface-2: #f2f2f2;
  --surface-hover: #e8e8e8;
  --text-0: #171717;
  --text-1: #737373;
  --text-2: #757575;
  --border-0: #e5e5e5;
  --border-1: #d4d4d4;
  --accent-primary: #059669;
  --accent-primary-hover: #047857;
  --semantic-success: #16a34a;
  --semantic-error: #dc2626;
  --semantic-warning: #ca8a04;
  --semantic-info: #0e7490;
  --icon-structural: #4f46e5; /* vs --surface-1 #ffffff : 6.29:1 */
  --text-on-accent: #ffffff;

  color-scheme: light;
}

/* ============================================================
   SURCHARGES GLOBALES PICO
   ============================================================ */

/* Headings : forcer la couleur texte thème dans le shadow DOM.
   Pico utilise :host(:not([data-theme=dark])) qui écrase les variables
   héritées. On force --pico-color sur les headings via --text-0. */
h1, h2, h3, h4, h5, h6 { --pico-color: var(--text-0); }

/* Direction D (PV 16.0 §4) — T-mrm2hm2f : sans règle locale, Pico impose
   --pico-font-size: 2rem / font-weight: 700 sur h1 (ex. graphs-admin-page).
   La règle globale ici uniformise taille, graisse et famille dans tous
   les shadow roots qui adoptent custom.css via sharedStyles. */
h1, h2, h3 { font-family: var(--font-display); line-height: 1.2; }
h1 { font-size: var(--text-h1); font-weight: var(--weight-medium); }
h2 { font-size: var(--text-h2); font-weight: var(--weight-medium); }
h3 { font-size: var(--text-h3); font-weight: var(--weight-semibold); }

/* Tableaux : chiffres tabulaires */
table { font-variant-numeric: tabular-nums; }

/* Code mono */
code, pre, kbd {
  font-family: var(--pico-font-family-monospace);
  font-size: var(--text-small);
}

/* Focus visible */
:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}

/* T-132: suppress outline on programmatic focus (router h1) */
[tabindex="-1"]:focus:not(:focus-visible) {
  outline: none;
}

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

/* ============================================================
   UTILITAIRES PARTAGÉS
   ============================================================ */

/* URIs (monospace, tronquées) */
.uri {
  font-family: var(--pico-font-family-monospace);
  font-size: var(--text-small);
  word-break: break-all;
}

/* Skip link (accessibilité) */
.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  z-index: var(--z-modal);
  padding: var(--space-2) var(--space-4);
  background: var(--accent-primary);
  color: var(--text-on-accent);
  border-radius: var(--radius-md);
  font-size: var(--text-small);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
.skip-link:focus { top: var(--space-2); }

/* ============================================================
   SKELETON — animation de chargement shimmer (Phase 3)
   ============================================================ */
@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-hover) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-md);
}
/* T-682 — skeleton pleine-page (router, distinct des mini-skeletons en composant) */
.skeleton-page {
  height: 200px;
  margin: var(--space-4);
}
/* 9.0.a (W6) — texte d'état vide discret, mutualisé (était local object-view-page) */
.empty-text { color: var(--text-2); font-size: var(--text-small); }
/* T-592 — skeleton 200px sans marge (object-view-page, distinct de .skeleton-page) */
.skeleton-200 { height: 200px; }
/* 16.B1 (B1.6a-bis) — skeleton d'une ligne de texte : AsyncPageMixin
   renderAsyncState({ skeleton: 'line' }) pour un chargement qui remplaçait
   une ligne (bandeau, compteur, ligne d'état), pas une zone de page. */
.skeleton-line { height: 1.25rem; max-width: 24rem; }
/* T-682 — contenant de la page 404 générée par le router */
.page-404 {
  padding: 2rem;
}

/* ============================================================
   TOAST — positionnement global (Phase 3)
   ============================================================ */
/* ============================================================
   ACCESSIBILITÉ
   ============================================================ */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ============================================================
   GRAPH FILTER BUTTON — lien cliquable dans la colonne Graphe
   ============================================================ */
/* Override du style Pico par défaut (bouton bleu plein) pour
   donner l'apparence d'un lien, cohérente avec <uri-link>. Le
   bouton reste sémantiquement un <button> parce qu'il déclenche
   une action JS (toggle filtre) plutôt qu'une navigation. */
button.graph-filter-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  color: var(--accent-primary);
  font-family: var(--font-mono);
  font-size: var(--text-small);
  font-weight: inherit;
  line-height: inherit;
  text-decoration: none;
  cursor: pointer;
  display: inline;
  width: auto;
}
button.graph-filter-btn:hover,
button.graph-filter-btn:focus-visible {
  text-decoration: underline;
  background: none;
  color: var(--accent-primary);
  box-shadow: none;
}

/* ============================================================
   T-158 (5e.B) — Badges scopes colorés. (CSS-4, IHM-C : thématisé)
   ============================================================
   Mappés par ihm/js/lib/scopes.mjs::scopeColorClass(scope).
   Composés avec .scope-tag (font-mono + padding défini en local).
   color-mix réactif au thème courant (clôt la dette T-454). */
.scope-data {
  background: color-mix(in srgb, var(--semantic-success) 20%, var(--surface-0));
  border: 1px solid color-mix(in srgb, var(--semantic-success) 40%, var(--surface-0));
  color: var(--semantic-success);
}
.scope-admin {
  background: color-mix(in srgb, var(--semantic-error) 20%, var(--surface-0));
  border: 1px solid color-mix(in srgb, var(--semantic-error) 40%, var(--surface-0));
  color: var(--semantic-error);
}
.scope-plugin {
  background: color-mix(in srgb, var(--semantic-info) 20%, var(--surface-0));
  border: 1px solid color-mix(in srgb, var(--semantic-info) 40%, var(--surface-0));
  color: var(--semantic-info);
}

/* ============================================================
   SYSTÈME DE COLONNES PARTAGÉ (ADR 072)
   ============================================================
   Utilitaires CSS pour les familles purement-grille (cartes, dl).
   Le 2-pane « liste + détail » est porté par <list-detail-layout>
   (composant comportemental), pas par une classe. Adoptés dans le
   Shadow DOM via sharedStyles (custom.css adopté dans 113 shadow
   roots). Consommés par la migration de masse B4 (.card-grid) /
   B5 (.kv-grid) ; définis dès B2 (fondations). */

/* Famille D — grille de cartes : reflux intrinsèque selon le contenu
   (auto-fill), une seule norme responsive, plus de media query figée. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--card-min), 1fr));
  gap: var(--space-4);
  align-items: start;
}

/* Famille E — liste de définition (dl) clé/valeur : étiquette en
   max-content (peut rétrécir, minmax(0,…)) + valeur fluide protégée
   du débordement. Remplace les 3 normes (auto 1fr / max-content 1fr /
   minmax(100px,auto) 1fr) par une seule. À poser sur le <dl>. */
.kv-grid {
  display: grid;
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
  column-gap: var(--space-3);
  row-gap: var(--space-1);
  align-items: baseline;
}

/* Famille H — liste mono-colonne (grid-template-columns: 1fr n'apportait
   rien : une seule colonne = un flex column). T-mqzlld81 (17.F F7). Espacement
   paramétré par --stack-gap (fallback --space-2) : chaque page qui l'adopte
   règle son propre gap dans sa règle locale (ex. .cards-list { --stack-gap:
   var(--space-1); }) sans dupliquer display/flex-direction. */
.stack {
  --stack-gap: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap);
}

/* Colonne « Parcourir » — chrome unifié cross-plugin (Liens / Contacts / Flux /
   Lieux). Standardise le pane en surface, l'en-tête (titre + compteur), le filtre,
   la liste scrollable et les rangées cliquables (hover/sélection). Une seule norme
   font/espacement pour que le passage d'un plugin à l'autre reste cohérent.
   Adopté dans le Shadow DOM via sharedStyles (custom.css). À poser sur la colonne
   liste de chaque onglet Parcourir. Les data-testid restent portés par le composant. */
.browse-col {
  background: var(--surface-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.browse-col-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
}
.browse-col-title {
  margin: 0;
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  color: var(--text-1);
}
.browse-col-count {
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-normal);
  white-space: nowrap;
}
.browse-filter {
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-2);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-1);
  margin-bottom: var(--space-2);
}
.browse-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 60vh;
  overflow: auto;
  display: grid;
  gap: var(--space-1);
}
.browse-item {
  all: unset;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2);
  border-radius: var(--radius-1);
  cursor: pointer;
  font-size: var(--text-small);
}
.browse-item:hover { background: var(--surface-2); }
.browse-item:focus-visible { outline: 2px solid var(--accent-primary); outline-offset: -2px; }
.browse-item[aria-current="true"],
.browse-item.selected {
  background: var(--accent-soft);
  font-weight: var(--weight-semibold);
}
.browse-item-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.browse-item-meta {
  color: var(--text-2);
  font-size: var(--text-xs);
  white-space: nowrap;
}

/* ============================================================
   Recettes composants (IHM-2A T5)
   ============================================================
   Convention : préfixe « cq- » = recette partagée OPT-IN.
   Un composant adopte une recette en utilisant la classe cq-* dans son template.
   Les noms non préfixés restent locaux à chaque composant (pas de fuite par cascade).
   Adoptés dans le Shadow DOM via sharedStyles (custom.css entier inclus dans 102 shadow roots).
   Les déclarations locales divergentes écrasent la recette (cascade locale gagne).

   Valeurs dérivées du dominant grep sur l'existant (C2/C3) :
   - .cq-toolbar   : gap space-2 (4 fichiers) > space-3 (3 fichiers)
   - .cq-card      : border var(--border-1) dominant (5/6 fichiers avec bordure).
                     Le brief proposait var(--border-0) — corrigé par grep. obsv-health-cards.js
                     conserve sa déclaration border: 1px solid var(--border-0) en local (C2).
   - .cq-empty-state : color var(--text-2) dominant (10/16). font-size absent de la recette
                     (dominant : var(--text-body) dans 10 fichiers, mais 6 sans font-size —
                     inclure ajouterait implicitement une taille non voulue).
   - .empty        : NON aliasé à .cq-empty-state (usages hétérogènes inline vs full-page, C2).
   - .cq-chip      : padding 0 var(--space-2) selon brief ; les usages locaux conservent
                     leur padding divergent en local. */

.cq-toolbar {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
}

/* .cq-chip : base sans couleur (les usages réels divergent sur color et padding). */
.cq-chip {
  display: inline-flex;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  background: var(--surface-2);
  border: 1px solid var(--border-1);
}

.cq-card {
  background: var(--surface-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}

.cq-empty-state {
  color: var(--text-2);
  text-align: center;
  padding: var(--space-6);
}

.cq-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Badge de cellule (16.B2 lot 9).
   Motif : une cellule rendue par `col.render()` de <data-table> vit dans le
   Shadow DOM de <data-table>, PAS dans celui de la page — les classes locales
   de la page (.badge-active, .badge, badge-${state}…) y sont mortes. La
   recette cq-* est adoptée par tous les shadow roots via sharedStyles, donc
   elle survit à la traversée. Couleurs par tokens sémantiques uniquement. */
.cq-badge {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  border: 1px solid var(--border-1);
  background: var(--surface-2);
  color: var(--text-1);
  white-space: nowrap;
}
.cq-badge-ok { background: var(--semantic-success-bg); color: var(--semantic-success); }
.cq-badge-warn { background: var(--semantic-warning-bg); color: var(--semantic-warning); }
.cq-badge-error { background: var(--semantic-error-bg); color: var(--semantic-error); }
.cq-badge-info { background: var(--semantic-info-bg); color: var(--semantic-info); }
.cq-badge-muted { background: var(--surface-2); color: var(--text-2); }

.cq-mono { font-family: var(--font-mono); }

/* Signal de ligne de tableau (erreur / retard), repris de mv-status-panel dont
   les `tr.row-error` / `tr.row-pending` locaux sont morts après passage à
   <data-table>. Le sélecteur porte `tbody tr` (spécificité 0-1-2) parce que la
   recette doit l'emporter sur le zébrage LOCAL de <data-table>
   (`tr:nth-child(even)`, 0-1-1) adopté APRÈS custom.css dans le même shadow
   root : à spécificité égale, la feuille locale gagnerait. */
tbody tr.cq-row-error { background: var(--semantic-error-bg); }
tbody tr.cq-row-pending td { color: var(--text-1); font-style: italic; }
