/* =====================================================================================================
   Constellation des agents — fondations visuelles et coquille (DA « Holo HUD »)
   -----------------------------------------------------------------------------------------------------
   0. jetons globaux (--ac-*, --wf-*) + pont de compatibilité      5. formulaires
   1. base (fond, typographie, focus, utilitaires)                 6. sections et panneaux génériques
   2. en-tête (marque, fraîcheur, onglets, instruments)            7. notifications
   3. glyphes d'état, puces, badges                                8. mouvement (no-preference uniquement)
   4. boutons                                                      9. adaptatif (en-tête et coquille)
   10. Suivi — styles de transition du balisage actuel (couche ac-legacy, voir en tête de section)
   11. contraste élevé de Windows (forced-colors: active), pour toute l'application
   Ordre de chargement (index.html) : style.css → monitor.css → wf/editor.css → voice/voice.css. Les jetons sont
   déclarés ici sur :root : toutes les feuilles suivantes les lisent (var(--ac-…), var(--wf-…)).
   Références : docs/DESIGN-SYSTEM.md, design/final/tokens.css (repris tel quel), design/final/ui.css (§0–4, §9).
   Règles : lisibilité avant effets — corps ≥ 12 px, méta ≥ 11 px, texte informatif ≥ 4,5:1, aucune lueur ni
   animation sur du texte, mouvement déclaré uniquement sous prefers-reduced-motion: no-preference.
   Sélecteurs d'éléments nus dans :where() (spécificité nulle) : toute règle à classe d'une autre feuille l'emporte.
   ===================================================================================================== */

/* =================================================================================== 0. jetons globaux */
:root {
  /* Thème : clair par défaut. js/theme.js pose data-theme="dark" ou "auto" (selon le système) d'après le choix
     mémorisé (localStorage « ac.theme »). Chaque couleur s'écrit une seule fois, light-dark(clair, sombre) : le sombre
     se déduit des mêmes rôles. Contrastes mesurés par design/prune-site/_tools/contrast.mjs (AA dans les deux thèmes). */
  color-scheme: light;

  /* ------------------------------------------------------------------ surfaces (lavis lavande, blanc mat) */
  --ac-bg-0: light-dark(#f5f1f8, #121017);   /* page */
  --ac-bg-1: light-dark(#ffffff, #1b1822);   /* panneau, carte posée sur la page, flottant (menu, modale, notification) */
  --ac-bg-2: light-dark(#faf8fc, #211d29);   /* carte dans un panneau, en-tête de tableau, ligne paire */
  --ac-bg-3: light-dark(#f3eef8, #2a2534);   /* survol, bouton secondaire */
  --ac-bg-4: light-dark(#eee7f5, #2c2340);   /* contrôle actif, élément choisi */
  --ac-inset: light-dark(#ede7f3, #0c0a10);  /* creux : pistes de jauge, puits, rail des onglets */
  --ac-field: light-dark(#ffffff, #15121b);  /* champs de saisie */
  --ac-canvas: light-dark(#f8f5fb, #0f0d14); /* fond du canevas et de la constellation */
  --ac-scrim: light-dark(rgba(35, 25, 50, .42), rgba(5, 4, 8, .72));        /* voile de modale */
  --ac-glass: light-dark(rgba(255, 255, 255, .86), rgba(27, 24, 34, .86));  /* flottants UNIQUEMENT (en-tête collant, commandes du canevas) */
  --ac-glass-blur: 14px;                     /* jamais sur un panneau de contenu */
  --ac-panel-grad: linear-gradient(var(--ac-bg-1), var(--ac-bg-1));  /* surfaces mates : plus de dégradé (noms conservés) */
  --ac-card-grad: linear-gradient(var(--ac-bg-2), var(--ac-bg-2));

  /* ------------------------------------------------------------------ filets */
  --ac-line-1: light-dark(#efeaf4, #262130);   /* séparateurs internes */
  --ac-line-2: light-dark(#e7e1ee, #2b2634);   /* bordure de carte / panneau */
  --ac-line-3: light-dark(#d7cee2, #3a3346);   /* bordure de bouton, de puce, de menu */
  --ac-line-4: light-dark(#b9adcb, #55496a);   /* survol de contrôle */
  --ac-line-ctl: light-dark(#857e92, #857d96); /* contour d'un champ, d'une case, d'une bascule : ≥ 3:1 (WCAG 1.4.11) */
  --ac-tick: var(--ac-line-3);                 /* graduations, règles */
  --ac-bracket: transparent;                   /* équerres d'angle retirées (nom conservé) */
  --ac-grid-dot: light-dark(rgba(118, 84, 155, .20), rgba(182, 155, 218, .16));   /* points de grille du canevas (pas 20) */
  --ac-grid-line: light-dark(rgba(118, 84, 155, .07), rgba(182, 155, 218, .05));  /* grille majeure (pas 100) */

  /* ------------------------------------------------------------------ texte (ratio le plus faible, toutes surfaces) */
  --ac-tx-1: light-dark(#17131d, #f3eff8);     /* 15,1:1 / 13,0:1 titres, chiffres, texte principal */
  --ac-tx-2: light-dark(#3f3949, #d5cedf);     /*  9,1:1 /  9,6:1 texte courant */
  --ac-tx-3: light-dark(#645d70, #a79fb4);     /*  5,2:1 /  5,8:1 méta, sources, heures (minimum pour un texte lu) */
  --ac-tx-4: light-dark(#9a93a6, #6a6276);     /*  2,4:1 DÉSACTIVÉ ET DÉCOR UNIQUEMENT */
  --ac-tx-ink: light-dark(#ffffff, #17131d);   /* encre sur l'accent (6,0:1 / 7,6:1) */
  --ac-tx-ink-amber: var(--ac-tx-ink);

  /* ------------------------------------------------------------------ accent Prune : action, sélection, focus, « à vous » */
  --ac-accent: light-dark(#76549b, #b69bda);         /* 4,9:1 / 6,1:1 au plus faible */
  --ac-accent-hover: light-dark(#654687, #c6afe6);
  --ac-accent-active: light-dark(#563a75, #a488cc);
  --ac-accent-ink: light-dark(#5d3f80, #cdb8ea);     /* texte violet (7,0:1 / 8,2:1) */
  --ac-accent-soft: light-dark(#eee7f5, #2c2340);    /* pastille, fond d'élément choisi */
  --ac-accent-line: light-dark(#bcaad0, #5f4d80);    /* bordure d'élément choisi */
  --ac-accent-glow: light-dark(rgba(150, 110, 200, .30), rgba(150, 110, 210, .22));  /* lueur haut-droite de la scène */
  /* anneau métallique et sphère de plâtre (hero « front V4 ») */
  --ac-ring-edge: light-dark(#4d3380, #6e4fa8);
  --ac-ring-body: light-dark(#8f6bcc, #a585dd);
  --ac-ring-hi: light-dark(#f7f2ff, #efe6ff);
  --ac-sphere-hi: light-dark(#ffffff, #4a4456);
  --ac-sphere-mid: light-dark(#eeeaf2, #2c2834);
  --ac-sphere-lo: light-dark(#cec6d8, #17141c);
  --ac-sphere-rim: light-dark(#bdb3ca, #3b3547);
  --ac-shadow-ink: light-dark(rgba(60, 40, 90, .22), rgba(0, 0, 0, .55));
  /* noms historiques (Holo HUD), conservés pour les feuilles, app.js et les tests : ce sont des RÔLES, plus des teintes.
     cyan = interaction ; amber = « c'est à vous » (attente humaine) ; magenta = relations ; violet = superviseur, projets. */
  --ac-cyan: var(--ac-accent);
  --ac-cyan-soft: var(--ac-accent-soft);
  --ac-amber: var(--ac-accent);
  --ac-amber-soft: var(--ac-accent-soft);
  --ac-magenta: var(--ac-ring-body);           /* fichiers modifiés en commun : trait Prune (3,4:1, jamais un texte) */
  --ac-magenta-soft: var(--ac-accent-soft);
  --ac-violet: var(--ac-accent-ink);
  --ac-holo: linear-gradient(90deg, var(--ac-ring-edge) 0%, var(--ac-ring-body) 52%, var(--ac-ring-hi) 100%);
  --ac-holo-ring: conic-gradient(from 210deg, var(--ac-ring-edge), var(--ac-ring-body), var(--ac-ring-hi), var(--ac-ring-edge));

  /* ------------------------------------------------------------------ sens : la forme porte l'état, la couleur le confirme */
  --ac-info: light-dark(#2a6499, #86b8e8);     /* en cours — 5,1:1 / 7,1:1 */
  --ac-info-soft: light-dark(#e4eef7, #1b2a3a);
  --ac-ok: light-dark(#27704a, #7fcb9c);       /* fiable, réussi, récent — 5,0:1 / 7,7:1 */
  --ac-ok-soft: light-dark(#e6f2eb, #1e2f25);
  --ac-warn: light-dark(#8a5a00, #e0b05a);     /* à vérifier, avertissement — 4,9:1 / 7,4:1 */
  --ac-warn-soft: light-dark(#f7eedc, #33291a);
  --ac-bad: light-dark(#b3263e, #f08a9a);      /* bloqué, erreur, action destructive — 5,3:1 / 6,2:1 */
  --ac-bad-soft: light-dark(#f8e5e8, #3a1e24);
  --ac-red: var(--ac-bad);
  /* états de session (forme + libellé + couleur) */
  --ac-st-running: var(--ac-info);             /* en cours — disque et halo */
  --ac-st-waiting: var(--ac-accent);           /* attend votre action — anneau et point Prune */
  --ac-st-blocked: var(--ac-bad);              /* bloqué — carré */
  --ac-st-unknown: var(--ac-warn);             /* indéterminé — à vérifier — anneau en tirets */
  --ac-st-done: light-dark(#8e879a, #6f687c);  /* terminé — glyphe seulement (3:1) ; son libellé s'écrit en --ac-tx-3 */
  --ac-st-done-dim: light-dark(#b9b2c4, #4a4456);  /* point « terminé » du graphe (décor) */
  --ac-conf-observed: var(--ac-ok);
  --ac-conf-deduced: var(--ac-tx-3);
  --ac-conf-verify: var(--ac-warn);
  --ac-fresh-ok: var(--ac-ok);                 /* récent (< 15 min) */
  --ac-fresh-mid: var(--ac-warn);              /* à vérifier (< 2 h) — tirets */
  --ac-fresh-old: var(--ac-bad);               /* périmé (≥ 2 h) — tirets */
  --ac-fresh-na: var(--ac-tx-3);               /* indisponible */
  --ac-id-verified: var(--ac-ok);
  --ac-id-deduced: var(--ac-warn);
  --ac-id-unverified: var(--ac-tx-3);

  /* ------------------------------------------------------------------ fournisseurs (repère fonctionnel, hors marque) */
  --ac-claude: light-dark(#a04e28, #ff9e75);   /* 4,8:1 / 7,3:1 */
  --ac-codex: light-dark(#176f61, #5ed9bc);    /* 5,0:1 / 8,5:1 */

  /* ------------------------------------------------------------------ quotas : une seule lecture, la CAPACITÉ RESTANTE */
  --ac-q-ok: var(--ac-accent);
  --ac-q-warn: var(--ac-warn);
  --ac-q-crit: var(--ac-bad);
  --ac-q-track: var(--ac-line-2);
  --ac-q-idle: var(--ac-line-3);
  --ac-q-segments: 20;

  /* ------------------------------------------------------------------ éditeur : types, ports, branches, états */
  --wf-t-input: light-dark(#1c6e9c, #5cc8f5);
  --wf-t-supervisor: var(--ac-accent);
  --wf-t-agent: light-dark(#4f56c8, #9aa0ff);
  --wf-t-model: light-dark(#b23a7c, #f58cc4);
  --wf-t-memory: light-dark(#8a5a00, #e9bc55);
  --wf-t-tool: light-dark(#0b7164, #4fd6c2);
  --wf-t-condition: light-dark(#a84a14, #fba35c);
  --wf-t-output: light-dark(#4a4456, #d9d3e3);
  --wf-t-subworkflow: light-dark(#3465a8, #9cc4f7);
  --wf-t-group: light-dark(#6b6478, #a79fb4);
  --wf-p-task: light-dark(#5f5870, #c9c2d6);
  --wf-p-model: var(--wf-t-model);
  --wf-p-memory: var(--wf-t-memory);
  --wf-p-tool: var(--wf-t-tool);
  --wf-b-out: var(--ac-info);
  --wf-b-success: light-dark(#5d4fb0, #b1b5fb);   /* lavande : le vert est réservé à « réussi » */
  --wf-b-error: var(--ac-bad);
  --wf-b-true: var(--wf-t-tool);
  --wf-b-false: var(--wf-t-group);                /* « faux » n'est jamais rouge */
  --wf-s-pending: var(--wf-t-group);
  --wf-s-ready: var(--wf-t-agent);
  --wf-s-prepared: var(--ac-accent);              /* préparé : c'est à vous */
  --wf-s-running: var(--ac-info);
  --wf-s-succeeded: var(--ac-ok);
  --wf-s-failed: var(--ac-bad);
  --wf-s-skipped: var(--wf-t-group);
  --wf-s-manual: var(--wf-t-condition);
  --wf-s-cancelled: var(--wf-t-group);
  --wf-s-verify: var(--ac-warn);
  --wf-x-assisted: var(--wf-t-subworkflow);
  --wf-x-manual: var(--wf-t-condition);
  --wf-x-local: var(--ac-tx-3);
  --wf-x-declarative: var(--wf-p-task);
  --wf-x-missing: var(--ac-bad);
  --wf-g-violet: light-dark(#7a5bb0, #a78bfa);
  --wf-g-blue: light-dark(#3f63c9, #6f8dff);
  --wf-g-turquoise: light-dark(#0f7f77, #4fe3d0);
  --wf-g-amber: light-dark(#9a6b00, #fbbf24);
  --wf-g-pink: var(--wf-t-model);
  --wf-g-slate: var(--wf-t-group);
  --wf-g-fill: 7%;
  --wf-g-head: 15%;
  --wf-g-border: 42%;
  --wf-canvas: var(--ac-canvas);
  --wf-node: light-dark(#ffffff, #1f1b27);
  --wf-node-2: var(--ac-bg-2);
  --wf-node-line: var(--ac-line-ctl);
  /* Les couleurs JavaScript utilisent désormais les jetons contrastés dans les deux thèmes.
     Garder leur teinte entière ; light-dark() ne prend que des couleurs, pas des pourcentages. */
  --wf-c-keep: 100%;

  /* ------------------------------------------------------------------ géométrie */
  --ac-r-1: 6px;               /* badges, étiquettes */
  --ac-r-2: 10px;              /* champs, petits contrôles */
  --ac-r-3: 14px;              /* cartes */
  --ac-r-4: 18px;              /* panneaux, modales */
  --ac-r-pill: 999px;          /* boutons, puces, onglets (le bouton du hero) */
  --ac-cut: 0px;               /* biseau retiré (nom conservé) */
  --wf-r-node: 14px;
  --wf-r-supervisor: 18px;
  --wf-r-io: 28px;
  --wf-r-group: 18px;
  --ac-bw: 1px;
  --ac-bw-strong: 2px;
  --ac-s-1: 4px;
  --ac-s-2: 8px;
  --ac-s-3: 12px;
  --ac-s-4: 16px;
  --ac-s-5: 20px;
  --ac-s-6: 24px;
  --ac-s-8: 32px;
  --ac-s-10: 40px;
  --ac-gutter: 28px;           /* bord de page (20 px sous 1100, 14 px sous 640) */
  --ac-gap: 16px;              /* gouttière entre panneaux */
  --ac-header-h: 60px;
  --ac-detail-w: 392px;
  --ac-tap: 44px;              /* cible tactile minimale (écrans étroits, pointeur grossier) */
  --wf-palette-w: 216px;
  --wf-inspector-w: 336px;
  --wf-toolbar-h: 52px;
  --wf-ruler: 16px;
  --wf-grid: 20px;

  /* ------------------------------------------------------------------ typographie (piles système, zéro téléchargement) */
  --ac-font-ui: "Segoe UI Variable Text", "Segoe UI Variable", "Segoe UI", system-ui, -apple-system, "Inter", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ac-font-display: "Segoe UI Variable Display", "Segoe UI Variable", "Segoe UI", system-ui, -apple-system, "Inter", Roboto, Arial, sans-serif;
  --ac-font-hud: var(--ac-font-display);  /* chiffres d'instrument et surtitres : plus de capitales espacées (nom conservé) */
  --ac-font-mono: "Cascadia Mono", "Cascadia Code", "JetBrains Mono", Consolas, "SFMono-Regular", ui-monospace, monospace;
  --ac-fs-11: 11px;            /* méta minimum : sources, heures (jamais en dessous) */
  --ac-fs-12: 12px;            /* corps secondaire */
  --ac-fs-13: 13px;            /* corps */
  --ac-fs-14: 14px;
  --ac-fs-16: 16px;            /* titres de section */
  --ac-fs-18: 18px;            /* titre de panneau, de modale */
  --ac-fs-20: 20px;            /* chiffres des compteurs */
  --ac-fs-26: 26px;            /* chiffres d'instrument */
  --ac-fs-30: 30px;
  --ac-fs-hero: 40px;          /* le chiffre « à vous » */
  --ac-lh-tight: 1.2;
  --ac-lh: 1.45;
  --ac-fw-regular: 400;
  --ac-fw-medium: 500;
  --ac-fw-semibold: 600;
  --ac-fw-bold: 650;
  --ac-track-hud: 0em;         /* plus d'interlettrage (noms conservés) */
  --ac-track-hud-wide: 0em;

  /* ------------------------------------------------------------------ ombres (une seule lumière, en haut à droite : elles
     tombent vers le bas à gauche), halos de sélection (jamais sur du texte), focus */
  --ac-shadow-1: inset 0 1px 0 light-dark(transparent, rgba(255, 255, 255, .03)), -1px 1px 0 light-dark(rgba(70, 50, 100, .04), transparent), -4px 8px 18px -10px light-dark(rgba(70, 50, 100, .18), rgba(0, 0, 0, .6));
  --ac-shadow-2: inset 0 1px 0 light-dark(transparent, rgba(255, 255, 255, .04)), -2px 2px 0 light-dark(rgba(70, 50, 100, .04), transparent), -10px 18px 40px -18px light-dark(rgba(70, 50, 100, .28), rgba(0, 0, 0, .7));
  --ac-shadow-3: inset 0 1px 0 light-dark(transparent, rgba(255, 255, 255, .05)), 0 0 0 1px light-dark(rgba(70, 50, 100, .06), rgba(0, 0, 0, .5)), -14px 28px 60px -22px light-dark(rgba(60, 40, 90, .42), rgba(0, 0, 0, .9));
  --wf-shadow-node: -3px 6px 14px -8px light-dark(rgba(70, 50, 100, .30), rgba(0, 0, 0, .7));
  --ac-glow-cyan: 0 0 0 1px var(--ac-accent-line), 0 0 0 4px color-mix(in srgb, var(--ac-accent) 16%, transparent);
  --ac-glow-amber: var(--ac-glow-cyan);
  --ac-glow-red: 0 0 0 1px color-mix(in srgb, var(--ac-bad) 45%, transparent), 0 0 0 4px color-mix(in srgb, var(--ac-bad) 14%, transparent);
  --ac-glow-magenta: drop-shadow(0 0 0 transparent);  /* plus de néon (noms conservés, valeur neutre pour filter) */
  --ac-glow-violet: drop-shadow(0 0 0 transparent);
  --wf-edge-glow-w: 6px;
  --wf-edge-glow-a: .10;
  --ac-focus: 0 0 0 2px var(--ac-bg-1), 0 0 0 4px var(--ac-accent);
  --ac-focus-ring: 2px solid var(--ac-accent);
  --ac-focus-offset: 2px;

  /* ------------------------------------------------------------------ mouvement : rare, porteur d'information */
  --ac-dur-1: 120ms;           /* survol, pression */
  --ac-dur-2: 160ms;           /* bascule, focus */
  --ac-dur-3: 260ms;           /* panneau, onglet */
  --ac-dur-4: 420ms;           /* apparition d'une ligne, d'une notification */
  --ac-dur-fill: 900ms;        /* un quota se remplit */
  --ac-dur-pass: 1600ms;       /* passage d'anneau : un état change */
  --ac-ease-out: cubic-bezier(.16, 1, .3, 1);
  --ac-ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --ac-ease-spring: var(--ac-ease-out);   /* plus de rebond (nom conservé) */
  --ac-loop-pulse: 2.4s;       /* un agent travaille (respiration) */
  --ac-loop-breathe: 2.4s;
  --ac-loop-packet: 2.8s;
  --ac-loop-poll: 5s;          /* anneau de sondage /api/state (lecture toutes les 5 s) */
  --ac-loop-sweep: 16s;
  --ac-loop-dash: 1.1s;
  --ac-loop-scan: 9s;

  /* ------------------------------------------------------------------ plans */
  --ac-z-canvas-ui: 5;
  --ac-z-sticky: 20;
  --ac-z-header: 40;
  --ac-z-menu: 55;
  --ac-z-modal: 60;
  --ac-z-toast: 70;

  /* ------------------------------------------------------------------ icônes en masque (mask-image), réutilisables */
  --ac-ic-info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.6'/%3E%3Cpath d='M12 11v5M12 7.9h.01'/%3E%3C/svg%3E");
  --ac-ic-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.6'/%3E%3Cpath d='m8.3 12.3 2.6 2.6 4.9-5'/%3E%3C/svg%3E");
  --ac-ic-error: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.6'/%3E%3Cpath d='m9.2 9.2 5.6 5.6M14.8 9.2l-5.6 5.6'/%3E%3C/svg%3E");
  --ac-ic-warn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.3 4.7 2.9 17.4c-.8 1.3.2 3 1.7 3h14.8c1.5 0 2.5-1.7 1.7-3L13.7 4.7c-.8-1.3-2.6-1.3-3.4 0z'/%3E%3Cpath d='M12 9.6v4.1M12 16.8h.01'/%3E%3C/svg%3E");
  --ac-ic-flow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='7' height='6' rx='1.5'/%3E%3Crect x='14' y='14' width='7' height='6' rx='1.5'/%3E%3Cpath d='M10 7h2a3 3 0 0 1 3 3v4'/%3E%3C/svg%3E");
  --ac-ic-mic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='3' width='6' height='11.5' rx='3'/%3E%3Cpath d='M5.5 11.5a6.5 6.5 0 0 0 13 0M12 18v3M8.8 21h6.4'/%3E%3C/svg%3E");
}
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="auto"] { color-scheme: light dark; }   /* selon le système */

/* Mouvement réduit : transitions instantanées (les boucles ne sont déclarées que sous no-preference, §8). */
@media (prefers-reduced-motion: reduce) {
  :root { --ac-dur-1: 0ms; --ac-dur-2: 0ms; --ac-dur-3: 0ms; --ac-dur-4: 0ms; --ac-dur-fill: 0ms; --ac-dur-pass: 0ms; }
}
@media (max-width: 1100px) {
  :root { --ac-gutter: 20px; }
}
@media (max-width: 640px) {
  :root { --ac-gutter: 14px; --ac-gap: 12px; --ac-header-h: 56px; }
}

/* Pont de compatibilité : anciens noms (app.js, wf/editor.css, voice/voice.css) → jetons.
   À retirer quand plus aucune règle ne les lit. --faint et --done restent au-dessus de 4,5:1. */
:root {
  --bg: var(--ac-bg-0);
  --bg2: var(--ac-bg-1);
  --panel: var(--ac-bg-1);
  --panel-solid: var(--ac-bg-2);
  --line: var(--ac-line-2);
  --text: var(--ac-tx-1);
  --muted: var(--ac-tx-2);
  --faint: var(--ac-tx-3);
  --claude: var(--ac-claude);
  --codex: var(--ac-codex);
  --project: var(--ac-violet);
  --running: var(--ac-st-running);
  --waiting: var(--ac-st-waiting);
  --blocked: var(--ac-st-blocked);
  --unknown: var(--ac-st-unknown);
  --done: var(--ac-tx-3);
  --ok: var(--ac-ok);
  --radius: var(--ac-r-3);
  --font: var(--ac-font-ui);
  --mono: var(--ac-font-mono);
  --ac-mono: var(--ac-font-mono);
}
.wf-app {
  --wf-line: var(--ac-line-2);
  --wf-line2: var(--ac-line-3);
  --wf-text: var(--ac-tx-1);
  --wf-muted: var(--ac-tx-2);
  --wf-faint: var(--ac-tx-3);
}

/* =================================================================================== 1. base */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; }
/* Débordement horizontal : « clip » sur html ET body. overflow-x: hidden sur body ne suffit pas sur téléphone (Chrome
   mobile élargit alors le viewport de mise en page à la largeur du contenu et dézoome la page) ; « clip » ne crée pas
   de conteneur de défilement, donc l'en-tête et les en-têtes de tableau restent collants par rapport à la fenêtre.
   Test de non-régression : tests/shell_mobile_viewport.test.js (innerWidth === 390 en émulation mobile). */
html { -webkit-text-size-adjust: 100%; background: var(--ac-bg-0); scrollbar-color: var(--ac-line-4) var(--ac-bg-0); overflow-x: clip; }
body {
  min-height: 100vh; overflow-x: clip;
  color: var(--ac-tx-1); font: var(--ac-fw-regular) var(--ac-fs-13)/var(--ac-lh) var(--ac-font-ui);
  font-variant-numeric: tabular-nums; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  /* la scène : lavis lavande, une seule lumière, douce, venue du haut à droite */
  background: radial-gradient(1100px 620px at 100% -120px, var(--ac-accent-glow), transparent 72%) no-repeat, var(--ac-bg-0);
}
::selection { background: color-mix(in srgb, var(--ac-accent) 28%, transparent); color: var(--ac-tx-1); }
[hidden] { display: none !important; }
:where(button, input, select, textarea) { font: inherit; color: inherit; }
:where(button) { cursor: pointer; }
:where(button:disabled) { cursor: not-allowed; }
:where(a) { color: var(--ac-accent-ink); text-decoration-color: color-mix(in srgb, currentColor 40%, transparent); text-underline-offset: 2px; }
:where(a:hover) { text-decoration-color: currentColor; }
:focus-visible { outline: var(--ac-focus-ring); outline-offset: var(--ac-focus-offset); }
:where(h1, h2, h3) { text-wrap: balance; }
:where(h2) { margin: 0 0 12px; font-size: 15px; font-weight: var(--ac-fw-semibold); color: var(--ac-tx-1); }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ic { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; vertical-align: -3px; }
.ic-14 { width: 14px; height: 14px; }
.ic-18 { width: 18px; height: 18px; }
.ic-20 { width: 20px; height: 20px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.mono { font-family: var(--ac-font-mono); font-size: 12px; }
.muted { color: var(--ac-tx-2); }
.faint { color: var(--ac-tx-3); }
.small { font-size: var(--ac-fs-12); }
:where(kbd) { font: 500 11px/1 var(--ac-font-mono); color: var(--ac-tx-2); background: var(--ac-bg-2); border: 1px solid var(--ac-line-3); border-bottom-width: 2px; border-radius: 5px; padding: 2px 5px; }
.hud { /* surtitre : petite étiquette en casse normale (plus de capitales espacées) */
  font: var(--ac-fw-semibold) var(--ac-fs-12)/1.2 var(--ac-font-ui); letter-spacing: var(--ac-track-hud); color: var(--ac-tx-3);
}
.view { position: relative; }
.page, #view-monitor { position: relative; padding: 0 var(--ac-gutter) 28px; } /* Suivi : gouttière ; Workflows : pleine largeur */

/* =================================================================================== 2. en-tête global */
.top {
  position: sticky; top: 0; z-index: var(--ac-z-header); height: var(--ac-header-h);
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; column-gap: 16px; /* onglets centrés, immobiles d'une vue à l'autre */
  padding: 0 var(--ac-gutter);
  background: color-mix(in srgb, var(--ac-bg-0) 86%, transparent);
  -webkit-backdrop-filter: blur(var(--ac-glass-blur)) saturate(140%); backdrop-filter: blur(var(--ac-glass-blur)) saturate(140%);
}
.top::after { /* filet sous l'en-tête */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--ac-line-2); pointer-events: none;
}
.top::before { /* ancien reflet du liseré : retiré (aucun balayage dans cette direction). La règle reste, inerte et pleine
     largeur, pour le test de non-régression : l'élément ne sort jamais de l'en-tête et ne déplace aucune géométrie. */
  content: none; position: absolute; bottom: 0; left: 0; right: 0; height: 0; pointer-events: none;
}
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* emblème d'Ecloria : cercle fin et disque plein décalé vers le haut à droite, le disque en Prune. Le symbole #i-logo
   d'index.html (ancienne constellation aux couleurs figées) n'est plus dessiné : l'emblème est peint sur le cadre,
   avec les jetons (boîte de 24 agrandie à 30 : cercle r 8,5 trait 1,3 ; disque r 4,4 en 14,4 ; 9,8). */
.brand .logo {
  width: 30px; height: 30px; flex: none; color: var(--ac-tx-1);
  background:
    radial-gradient(circle at 18px 12.25px, var(--ac-accent) 0 5.1px, transparent 5.7px),
    radial-gradient(circle at 50% 50%, transparent 0 9.7px, currentColor 10.2px 11.2px, transparent 11.7px);
}
.brand .logo use { display: none; }
.brand-txt { min-width: 0; flex: 1; }
.brand h1 { margin: 0; font: var(--ac-fw-bold) 17px/1.2 var(--ac-font-display); letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand h1 span { color: var(--ac-tx-3); font-weight: var(--ac-fw-regular); font-size: 13px; letter-spacing: 0; }
/* ligne de fraîcheur : bloc (et non flex) pour que l'ellipse coupe proprement le texte trop long */
.brand .sub { margin-top: 2px; font-size: var(--ac-fs-12); line-height: 18px; color: var(--ac-tx-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand .sub b { color: var(--ac-tx-1); font-weight: var(--ac-fw-semibold); }
.brand .sub .sep { color: var(--ac-tx-4); margin: 0 6px; }
.pulse { position: relative; display: inline-block; width: 8px; height: 8px; margin: 0 3px 0 1px; border-radius: 50%; background: var(--ac-ok); vertical-align: 0; flex: none; }
.pulse.stale { background: var(--ac-bad); border-radius: 2px; margin-right: 6px; } /* données figées : carré rouge + libellé explicite */
.poll { width: 16px; height: 16px; flex: none; margin-right: 6px; vertical-align: -4px; transform: rotate(-90deg); } /* anneau de sondage 5 s */
/* ligne de fraîcheur rendue par app.js, renderFreshness (« Collecte en direct · lecture 04:17:39 · 68 ms ·
   historique 7 j ») : segments raccourcis selon la largeur, phrase complète en infobulle et pour les lecteurs d'écran */
.brand .sub b.fr-bad { color: var(--ac-bad); }
@media (max-width: 1599px) { /* « Collecte en direct · lecture hh:mm · 7 j » */
  .brand .sub :is(.fr-s, .fr-ms, .fr-hl, .fr-cl) { display: none; }
}
.poll circle { fill: none; stroke-width: 2; }
.poll .trk { stroke: var(--ac-line-3); }
.poll .val { stroke: var(--ac-ok); stroke-dasharray: 44; stroke-dashoffset: 18; stroke-linecap: round; }

/* onglets en pilule : la vue courante est une pastille blanche posée sur le lavis */
.tabs { display: flex; gap: 2px; padding: 0; border-radius: var(--ac-r-pill); background: transparent; position: relative; }
.tab { /* lien de navigation (#monitor, #workflows) ; vue courante : .on + aria-current="page" */
  position: relative; display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 16px 0 14px; border: 0; border-radius: var(--ac-r-pill);
  background: transparent; color: var(--ac-tx-2); font-size: 13.5px; font-weight: var(--ac-fw-semibold); white-space: nowrap; text-decoration: none;
  transition: color var(--ac-dur-1), background var(--ac-dur-2), box-shadow var(--ac-dur-2);
}
.tab:hover { color: var(--ac-tx-1); background: var(--ac-bg-3); }
.tab .ic { color: var(--ac-tx-3); transition: color var(--ac-dur-1); }
.tab kbd { margin-left: 2px; }
.tab.on { color: var(--ac-tx-1); background: var(--ac-bg-1); box-shadow: inset 0 0 0 1px var(--ac-line-2), var(--ac-shadow-1); }
.tab.on .ic { color: var(--ac-accent); }
.tab:focus-visible { outline-offset: 1px; }
/* colonne centrale : onglets + touche « ? » (aide des raccourcis). La touche prolonge la leçon des <kbd> 1 et 2 des
   onglets : même habit de touche, plus grande, dans une zone de clic de 36 px ; présente dans les deux vues, donc les
   onglets ne bougent pas d'une vue à l'autre. */
.top-mid { display: flex; align-items: center; gap: 6px; min-width: 0; }
.keys-btn {
  display: inline-grid; place-items: center; width: 36px; height: 36px; flex: none; padding: 0; border: 0; border-radius: var(--ac-r-pill);
  background: transparent; color: var(--ac-tx-2); transition: background var(--ac-dur-1), color var(--ac-dur-1);
}
.keys-btn kbd {
  display: grid; place-items: center; min-width: 22px; height: 22px; padding: 0 5px; font: 600 12.5px/1 var(--ac-font-mono); color: inherit;
  background: var(--ac-bg-1); border-color: var(--ac-line-3); border-bottom-width: 2px; transition: border-color var(--ac-dur-1), background var(--ac-dur-1);
}
.keys-btn:hover { color: var(--ac-tx-1); background: var(--ac-bg-3); }
.keys-btn:hover kbd { border-color: var(--ac-line-4); }
.keys-btn:active { color: var(--ac-accent); }
.keys-btn:focus-visible { outline: var(--ac-focus-ring); outline-offset: 0; }

/* zone droite, calée à droite : thème, langue, compte, lanceur vocal, puis les instruments (ou le raccourci de la vue
   Workflows). Le lanceur vocal prend l'habit des boutons ronds de l'en-tête : libellé visible dès 1700 px, sinon icône
   + infobulle (title du balisage). */
.top-right { display: flex; align-items: center; justify-content: flex-end; gap: 8px; min-width: 0; }
.top-right > .counters, .top-right > .wf-shortcut { margin-left: 0; min-width: 0; }
.top-right > .vx-launch { margin: 0; flex: none; }
.top .vx-launch {
  align-self: center; height: 36px; min-height: 36px; padding: 0 14px 0 12px; border-radius: var(--ac-r-pill); border: 1px solid var(--ac-line-3);
  background: var(--ac-bg-1); color: var(--ac-tx-2); font: var(--ac-fw-semibold) 13px/1.2 var(--ac-font-ui); box-shadow: none;
}
.top .vx-launch:hover { color: var(--ac-tx-1); border-color: var(--ac-line-4); background: var(--ac-bg-3); }
.top .vx-launch:focus-visible { outline-color: var(--ac-accent); } /* focus clavier : toujours l'accent dans l'en-tête */

/* compteurs : bande d'états, gros chiffres tabulaires. Chaque compteur est un bouton (app.js, renderCounters) : il ne
   garde que cet état dans « 04 Projets et tâches » (aria-pressed) ; pas de overflow: hidden sur la barre, pour que le
   contour de focus (2 px décalé de 2 px) ne soit jamais rogné — les angles sont arrondis case par case. */
.counters { display: flex; border: 1px solid var(--ac-line-2); border-radius: var(--ac-r-3); background: var(--ac-bg-1); box-shadow: var(--ac-shadow-1); }
.counters:empty { display: none; }
.counter {
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 7px; row-gap: 0;
  padding: 5px 14px 5px 13px; border: 0; border-left: 1px solid var(--ac-line-1); background: transparent; color: var(--ac-tx-3); text-align: left;
  font-size: 11.5px; line-height: 1.2; white-space: nowrap; min-width: 0; overflow: hidden;
}
.counter:first-child { border-left: 0; border-radius: 13px 0 0 13px; }
.counter:last-child { border-radius: 0 13px 13px 0; }
.counter:only-child { border-radius: 13px; }
:where(button).counter { cursor: pointer; transition: background var(--ac-dur-1), color var(--ac-dur-1); }
:where(button).counter:hover { background: var(--ac-bg-3); color: var(--ac-tx-1); }
:where(button).counter:focus-visible { z-index: 1; outline: var(--ac-focus-ring); outline-offset: var(--ac-focus-offset); }
/* filtre actif : fond d'élément choisi + barre d'accent de 2 px */
.counter[aria-pressed="true"] { background: var(--ac-bg-4); color: var(--ac-accent-ink); }
.counter[aria-pressed="true"]::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: 0; height: 2px; border-radius: 2px;
  background: var(--ac-cyan);
}
.counter .lbl { grid-column: 1 / -1; display: flex; align-items: center; gap: 6px; font-size: 11.5px; line-height: 1.2; white-space: nowrap; }
.counter .lbl .short { display: none; }
.counter > b { grid-column: 1; grid-row: 2; font: var(--ac-fw-bold) 20px/1.15 var(--ac-font-hud); color: var(--ac-tx-1); font-variant-numeric: tabular-nums; }
.counter > small { grid-column: 2; grid-row: 2; align-self: end; padding-bottom: 3px; font-size: 11px; color: var(--ac-tx-3); }
.counter.zero > b { color: var(--ac-tx-4); }
/* repli : ancien balisage d'app.js (<div class="counter"><i class="dot"></i>libellé long <b>n</b></div>), même
   instrument. Le libellé long reste dans le document ; le libellé court est affiché en contenu généré au texte
   alternatif vide (non lu deux fois). Sans effet sur le balisage actuel (.lbl). */
.counter:has(> .dot) { column-gap: 6px; font-size: 0; }
.counter:has(> .dot) > .dot { grid-column: 1; grid-row: 1; }
.counter:has(> .dot) > b { grid-column: 1 / -1; }
.counter:has(> .dot)::after { grid-column: 2; grid-row: 1; font-size: 11.5px; line-height: 1.2; white-space: nowrap; content: var(--lbl, "") / ""; }
.counter:has(> .dot.running) { --lbl: "En cours"; }
.counter:has(> .dot.waiting) { --lbl: "Attend votre action"; }
.counter:has(> .dot.blocked) { --lbl: "Bloqué"; }
.counter:has(> .dot.unknown) { --lbl: "À vérifier"; }
.counter:has(> .dot.done) { --lbl: "Terminé"; }
.counter:has(> .dot.other) { --lbl: "Autre"; }
.counter { align-content: space-between; } /* chiffres alignés d'une case à l'autre, même si un libellé passe à la ligne */
/* « attend votre action » : la seule surface pleine de l'en-tête (c'est à vous), en Prune ; calme et blanche à zéro */
.counter:is(.is-waiting, :has(.dot.waiting)) { --c-runs-ink: var(--ac-tx-ink); background: var(--ac-amber); color: var(--ac-tx-ink-amber); }
.counter:is(.is-waiting, :has(.dot.waiting)) > :is(b, small) { color: var(--ac-tx-ink-amber); }
.counter:is(.is-waiting, :has(.dot.waiting)) .dot.waiting { box-shadow: inset 0 0 0 2px currentColor; }
.counter:is(.is-waiting, :has(.dot.waiting)) .dot.waiting::after { background: currentColor; }
.counter:is(.is-waiting, :has(.dot.waiting)).zero { --c-runs-ink: var(--ac-amber); background: transparent; color: var(--ac-tx-3); }
.counter:is(.is-waiting, :has(.dot.waiting)).zero > b { color: var(--ac-tx-4); }
.counter:is(.is-waiting, :has(.dot.waiting)).zero > small { color: var(--ac-tx-3); }
:where(button).counter.is-waiting:not(.zero):hover { background: var(--ac-accent-hover); color: var(--ac-tx-ink-amber); }
.counter.is-waiting:not(.zero)[aria-pressed="true"] { background: var(--ac-accent-active); color: var(--ac-tx-ink-amber); }
.counter.is-waiting:not(.zero)[aria-pressed="true"]::after { background: currentColor; }
:where(button).counter.is-waiting.zero:hover { background: var(--ac-bg-3); }
.counter.is-waiting.zero[aria-pressed="true"] { background: var(--ac-bg-4); color: var(--ac-accent-ink); }

/* vue Workflows : raccourci unique vers les sessions en attente (remplace la bande d'états) */
.wf-shortcut {
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 12px 0 14px; border-radius: var(--ac-r-pill); border: 1px solid transparent;
  background: var(--ac-amber); color: var(--ac-tx-ink-amber); font-size: 13px; font-weight: var(--ac-fw-semibold); white-space: nowrap; cursor: pointer;
  transition: background var(--ac-dur-1), border-color var(--ac-dur-1);
}
.wf-shortcut:hover { background: var(--ac-accent-hover); }
.wf-shortcut b { font: var(--ac-fw-bold) 17px/1 var(--ac-font-hud); color: inherit; }
.wf-shortcut .ic { color: inherit; }
.wf-shortcut .dot.waiting { box-shadow: inset 0 0 0 2px currentColor; }
.wf-shortcut .dot.waiting::after { background: currentColor; }
.wf-shortcut.zero { border-color: var(--ac-line-3); background: var(--ac-bg-1); color: var(--ac-tx-2); }
.wf-shortcut.zero:hover { border-color: var(--ac-line-4); background: var(--ac-bg-3); }
.wf-shortcut.zero .ic { color: var(--ac-tx-3); }
/* libellé court (1024–1240 px, §9) : suit la classe .zero posée par index.html et app.js ; décor (aria-hidden), la phrase
   complète est dans aria-label et l'infobulle du bouton */
.wf-shortcut .wl-short { display: none; }
.wf-shortcut .wl-short::before { content: "à vous"; }
.wf-shortcut.zero .wl-short::before { content: "Rien en attente"; }

/* étapes de run qui attendent l'utilisateur, rappelées dans le compteur « Attend votre action » : attente humaine =
   couleur du rôle « à vous » (jeton --ac-amber), opaque, précédée du glyphe de workflow (forme distinctive) ; sur le
   compteur plein, elle prend l'encre du compteur (--c-runs-ink, posée plus haut).
   Spécificité relevée (.top) : la règle d'origine de ce balisage d'app.js vit dans monitor.css, chargée après. */
.top #counters .counter > .c-runs {
  display: inline-flex; align-items: center; gap: 3px; color: var(--c-runs-ink, var(--ac-amber)); font-style: normal;
}
.top #counters .counter > .c-runs::before {
  content: ""; width: 11px; height: 11px; flex: none; background: currentColor;
  -webkit-mask: var(--ac-ic-flow) center / 11px 11px no-repeat; mask: var(--ac-ic-flow) center / 11px 11px no-repeat;
}
/* même rôle dans la file « À vous » (03 Détail) : le surtitre « Runs à faire avancer » prend la couleur « à vous », le
   glyphe de workflow remplace le chevron (spécificité relevée par :root : règle d'origine dans monitor.css) */
:root #view-monitor .q-sub { color: var(--ac-amber); }
:root #view-monitor .q-sub > .ic { display: none; }
:root #view-monitor .q-sub::before {
  content: ""; width: 13px; height: 13px; flex: none; background: currentColor;
  -webkit-mask: var(--ac-ic-flow) center / 13px 13px no-repeat; mask: var(--ac-ic-flow) center / 13px 13px no-repeat;
}

/* liens d'évitement : premiers arrêts de tabulation, hors écran jusqu'au focus clavier ; le groupe apparaît alors en
   plateau opaque « Accès rapide » au-dessus de l'en-tête (seuls les liens de la vue affichée existent : index.html) */
.skip-links {
  position: fixed; top: 8px; left: var(--ac-gutter); z-index: calc(var(--ac-z-toast) + 5);
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; max-width: calc(100vw - 2 * var(--ac-gutter));
  padding: 6px; border-radius: var(--ac-r-4); border: 1px solid var(--ac-line-3); background: var(--ac-bg-1); box-shadow: var(--ac-shadow-3);
  opacity: 0; transform: translateY(calc(-100% - 20px)); pointer-events: none;
  transition: transform var(--ac-dur-2) var(--ac-ease-out), opacity var(--ac-dur-2);
}
.skip-links::before { /* surtitre, décor (texte alternatif vide : non lu) */
  content: "Accès rapide" / ""; padding: 0 6px 0 10px; font: var(--ac-fw-semibold) 12px/1 var(--ac-font-ui); color: var(--ac-accent-ink);
}
.skip-links:focus-within { opacity: 1; transform: none; pointer-events: auto; }
.skip-link {
  display: inline-flex; align-items: center; gap: 10px; height: 36px; padding: 0 14px; border-radius: var(--ac-r-pill);
  border: 1px solid var(--ac-line-3); background: var(--ac-bg-1); color: var(--ac-tx-1);
  font: var(--ac-fw-semibold) 13px/1 var(--ac-font-ui); text-decoration: none; white-space: nowrap;
  transition: background var(--ac-dur-1), border-color var(--ac-dur-1);
}
.skip-link::after { content: "Entrée" / ""; font: 500 11px/1 var(--ac-font-mono); color: var(--ac-tx-2); padding: 3px 5px; border: 1px solid var(--ac-line-3); border-bottom-width: 2px; border-radius: 5px; }
.skip-link:not(:focus)::after { display: none; }
.skip-link:hover { background: var(--ac-bg-3); border-color: var(--ac-line-4); }
.skip-link:focus-visible { border-color: var(--ac-accent-line); background: var(--ac-bg-4); outline: var(--ac-focus-ring); outline-offset: var(--ac-focus-offset); }
/* cibles des liens d'évitement et des compteurs : jamais cachées sous l'en-tête collant */
:where(.work, .detail, .stage, .s-quotas) { scroll-margin-top: calc(var(--ac-header-h) + 12px); }
#detail[tabindex="-1"]:focus { outline: none; }
#detail[tabindex="-1"]:focus-visible { outline: var(--ac-focus-ring); outline-offset: 3px; }

/* aide des raccourcis clavier : feuille modale (<dialog> natif, index.html). Même famille que les fenêtres de
   l'éditeur (.wf-modal) : surface blanche mate, rayon de panneau, ombre de flottant, voile. Deux colonnes dès 720 px :
   « Partout » et « Suivi » à gauche, l'éditeur à droite ; la vue affichée est signalée (surtitre en accent +
   « vue affichée ») et passe en tête sur une colonne. */
.ac-keys {
  width: min(900px, calc(100vw - 2 * var(--ac-gutter))); max-width: none; max-height: none; margin: auto; padding: 0; border: 0;
  background: transparent; color: var(--ac-tx-1); overflow: visible;
}
.ac-keys::backdrop { background: var(--ac-scrim); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.ak-sheet {
  position: relative; display: flex; flex-direction: column; max-height: min(86vh, 780px); overflow: hidden; border-radius: var(--ac-r-4);
  border: 1px solid var(--ac-line-2); background: var(--ac-bg-1); box-shadow: var(--ac-shadow-3);
}
.ak-sheet:focus { outline: none; }
.ak-head { flex: none; display: flex; align-items: center; gap: 12px; padding: 16px 14px 14px 20px; border-bottom: 1px solid var(--ac-line-1); }
.ak-head > .ic { width: 22px; height: 22px; color: var(--ac-accent); }
.ak-titles { min-width: 0; }
.ak-titles .hud { color: var(--ac-tx-3); }
.ak-titles h2 { margin: 2px 0 0; font: var(--ac-fw-bold) var(--ac-fs-18)/1.25 var(--ac-font-display); }
.ak-close { margin-left: auto; }
.ak-body {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto 1fr; gap: 20px 32px; align-items: start;
  padding: 16px 20px 20px; overflow: auto; overscroll-behavior: contain; scrollbar-width: thin;
}
.ak-sec[data-keys-view="all"] { grid-column: 1; grid-row: 1; }
.ak-sec[data-keys-view="monitor"] { grid-column: 1; grid-row: 2; }
.ak-sec[data-keys-view="workflows"] { grid-column: 2; grid-row: 1 / span 2; }
.ak-sec h3 { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; padding-bottom: 6px; border-bottom: 1px solid var(--ac-line-2); font-size: 13px; color: var(--ac-tx-1); }
.ak-here { display: none; }
.ak-sec.is-current h3 { color: var(--ac-accent-ink); border-bottom-color: var(--ac-accent-line); }
.ak-sec.is-current .ak-here {
  display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: var(--ac-r-pill);
  background: var(--ac-accent-soft); font-size: 11px; font-weight: var(--ac-fw-semibold); color: var(--ac-accent-ink);
}
.ak-list { margin: 0; display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: 16px; }
/* colonne des touches à la largeur de la plus longue combinaison de la liste (sous-grille) : descriptions alignées */
.ak-list > div { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: baseline; padding: 6px 0; border-top: 1px solid var(--ac-line-1); }
.ak-list > div:first-child { border-top: 0; }
.ak-list dt { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.ak-list dd { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ac-tx-2); }
.ak-list kbd, .ak-note kbd { min-width: 22px; text-align: center; color: var(--ac-tx-1); font-size: 11.5px; }
.ak-list dd kbd { min-width: 0; font-size: 11px; padding: 1px 4px; }
.ak-gesture { font-size: 12px; color: var(--ac-tx-2); font-style: italic; }
.ak-note { margin: 10px 0 0; font-size: 12px; line-height: 1.45; color: var(--ac-tx-3); }
@media (max-width: 719px) {
  .ak-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; display: flex; flex-direction: column; }
  .ak-sec[data-keys-view="all"] { order: -2; }
  .ak-sec.is-current { order: -1; }
}

/* bandeau de session : seulement si le jeton du serveur redémarré n'a pas pu être relu (index.html). Flottant (aucun
   décalage de la mise en page, l'éditeur garde sa hauteur), opaque ; mise en garde : ocre, avec son icône. */
.ac-session-banner {
  position: fixed; z-index: calc(var(--ac-z-header) + 2); top: calc(var(--ac-header-h) + 10px); left: 50%; transform: translateX(-50%);
  width: min(840px, calc(100vw - 2 * var(--ac-gutter)));
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px 12px;
  padding: 12px 14px 12px 16px; border-radius: var(--ac-r-3); border: 1px solid color-mix(in srgb, var(--ac-warn) 40%, transparent); overflow: hidden;
  background: linear-gradient(var(--ac-warn-soft), var(--ac-warn-soft)), var(--ac-bg-1); box-shadow: var(--ac-shadow-3); color: var(--ac-tx-1);
}
.ac-session-banner > .ic { color: var(--ac-warn); align-self: start; margin-top: 1px; }
.ac-session-banner .sb-txt b { display: block; font-size: 13.5px; font-weight: var(--ac-fw-semibold); }
.ac-session-banner .sb-txt span { display: block; margin-top: 2px; font-size: 12.5px; line-height: 1.45; color: var(--ac-tx-2); }
.ac-session-banner .sb-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }

/* =================================================================================== 3. glyphes d'état, puces, badges */
/* la forme porte l'état, la couleur le confirme : disque et halo (en cours), anneau et point (à vous), carré (bloqué),
   anneau en tirets (à vérifier), coche (terminé) */
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: none; }
.dot.running { background: var(--ac-st-running); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ac-st-running) 20%, transparent); }
.dot.waiting { position: relative; background: transparent; box-shadow: inset 0 0 0 2px var(--ac-st-waiting); }
.dot.waiting::after { content: ""; position: absolute; inset: 2.5px; border-radius: 50%; background: var(--ac-st-waiting); }
.dot.blocked { width: 8px; height: 8px; border-radius: 2px; background: var(--ac-st-blocked); }
.dot.unknown { background: transparent; border: 1.5px dashed var(--ac-st-unknown); }
.dot.done { position: relative; width: 10px; height: 10px; border-radius: 0; background: transparent; }
.dot.done::after { content: ""; position: absolute; left: 1px; top: 1px; width: 6px; height: 3.5px; border-left: 1.8px solid var(--ac-st-done); border-bottom: 1.8px solid var(--ac-st-done); transform: rotate(-45deg); }
.dot.other { background: var(--ac-tx-3); }

/* puce d'état : glyphe + libellé + couleur, en pilule douce */
.status {
  display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 10px 0 8px; border-radius: var(--ac-r-pill); vertical-align: middle;
  font-size: 12px; font-weight: var(--ac-fw-semibold); white-space: nowrap; border: 1px solid transparent; cursor: help;
}
.status.running { color: var(--ac-info); background: var(--ac-info-soft); }
.status.waiting { color: var(--ac-accent-ink); background: var(--ac-accent-soft); }
.status.blocked { color: var(--ac-bad); background: var(--ac-bad-soft); }
.status.unknown { color: var(--ac-warn); background: var(--ac-warn-soft); border: 1px dashed color-mix(in srgb, var(--ac-warn) 55%, transparent); }
.status.done { color: var(--ac-tx-3); background: var(--ac-bg-2); border-color: var(--ac-line-2); }
.status.other { color: var(--ac-tx-2); background: var(--ac-bg-2); border: 1px dashed var(--ac-line-4); }
.status.hud { font-size: 11px; }
.conf { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: var(--ac-fw-medium); color: var(--ac-tx-2); white-space: nowrap; cursor: help; }
.conf .ic { width: 14px; height: 14px; }
.conf.c-obs { color: var(--ac-conf-observed); }
.conf.c-deduit { color: var(--ac-conf-deduced); }
.conf.c-verif { color: var(--ac-conf-verify); }
.badge {
  display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 8px; border-radius: var(--ac-r-pill);
  font-size: 11.5px; font-weight: var(--ac-fw-semibold); white-space: nowrap; border: 1px solid transparent;
}
.badge.f-ok { color: var(--ac-fresh-ok); background: var(--ac-ok-soft); }
.badge.f-mid { color: var(--ac-fresh-mid); background: var(--ac-warn-soft); border: 1px dashed color-mix(in srgb, var(--ac-warn) 55%, transparent); }
.badge.f-old { color: var(--ac-fresh-old); background: var(--ac-bad-soft); border: 1px dashed color-mix(in srgb, var(--ac-bad) 55%, transparent); }
.badge.na { color: var(--ac-tx-3); background: var(--ac-bg-2); border-color: var(--ac-line-2); }
.chip-hud { /* étiquette technique : offre, RÉV., DÉCLARATIF */
  display: inline-flex; align-items: center; height: 18px; padding: 0 7px; border-radius: var(--ac-r-pill); border: 1px solid var(--ac-line-3);
  font: var(--ac-fw-semibold) 11px/1 var(--ac-font-ui); color: var(--ac-accent-ink); white-space: nowrap;
}
.tag {
  display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: var(--ac-r-1); border: 1px solid var(--ac-line-2);
  background: var(--ac-bg-2); font: 11px/1 var(--ac-font-mono); color: var(--ac-tx-2); white-space: nowrap;
}
.note { font-size: 12px; color: var(--ac-tx-3); line-height: 1.45; margin-top: 8px; }
.pdot { display: inline-block; width: 8px; height: 8px; border-radius: 2px; transform: rotate(45deg); flex: none; }
.agent { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.agent .ic { width: 14px; height: 14px; }
.ok { color: var(--ac-ok); }
.ko { color: var(--ac-tx-3); }

/* =================================================================================== 4. boutons */
/* pilules, comme le bouton du hero : principal plein Prune, secondaire blanc cerné, fantôme, danger */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 36px; padding: 0 16px; border-radius: var(--ac-r-pill);
  border: 1px solid transparent; font-size: 13px; font-weight: var(--ac-fw-semibold); line-height: 1; white-space: nowrap; text-decoration: none;
  background: var(--ac-accent); color: var(--ac-tx-ink);
  transition: background var(--ac-dur-1), border-color var(--ac-dur-1), color var(--ac-dur-1), box-shadow var(--ac-dur-2);
}
.btn:hover { background: var(--ac-accent-hover); }
.btn:active { background: var(--ac-accent-active); }
.btn:focus-visible { outline: none; box-shadow: var(--ac-focus); }
.btn .ic { margin-left: -2px; }
.btn.sec { background: var(--ac-bg-1); color: var(--ac-accent-ink); border-color: var(--ac-line-3); }
.btn.sec:hover { border-color: var(--ac-line-4); background: var(--ac-bg-3); }
.btn.sec:active { background: var(--ac-bg-4); }
.btn.ghost { background: transparent; color: var(--ac-accent-ink); border-color: transparent; }
.btn.ghost:hover { background: var(--ac-bg-3); }
.btn.act { background: var(--ac-amber); color: var(--ac-tx-ink-amber); } /* action humaine (carte Prochaine action) */
.btn.act:hover { background: var(--ac-accent-hover); }
.btn.danger { background: var(--ac-bad-soft); color: var(--ac-bad); border-color: color-mix(in srgb, var(--ac-bad) 40%, transparent); }
.btn.danger:hover { background: color-mix(in srgb, var(--ac-bad) 16%, var(--ac-bg-1)); }
.btn.sm { height: 30px; padding: 0 12px; font-size: 12.5px; }
.btn.lg { height: 44px; padding: 0 22px; font-size: 14px; }
.btn.icon { width: 36px; padding: 0; }
.btn:disabled, .btn.is-disabled { background: var(--ac-bg-3); color: var(--ac-tx-4); border-color: var(--ac-line-1); cursor: not-allowed; }
.btn .kbd-in { font: 500 11px var(--ac-font-mono); opacity: .8; margin-left: 2px; }
.btn.is-loading .spin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; }
.ghost { /* bouton fantôme (outils de panneau) */
  display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border-radius: var(--ac-r-pill); border: 1px solid var(--ac-line-3);
  background: var(--ac-bg-1); color: var(--ac-tx-1); font-size: 12.5px; font-weight: var(--ac-fw-medium); white-space: nowrap; transition: border-color var(--ac-dur-1), background var(--ac-dur-1);
}
.ghost:hover { border-color: var(--ac-line-4); background: var(--ac-bg-3); }
.ghost:disabled { color: var(--ac-tx-4); border-color: var(--ac-line-1); background: transparent; }
.iconbtn { display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: var(--ac-r-pill); border: 1px solid transparent; background: transparent; color: var(--ac-tx-2); transition: background var(--ac-dur-1), color var(--ac-dur-1); }
.iconbtn:hover { color: var(--ac-tx-1); background: var(--ac-bg-3); border-color: var(--ac-line-2); }
.iconbtn.on { color: var(--ac-accent-ink); background: var(--ac-accent-soft); border-color: var(--ac-accent-line); }
.iconbtn:disabled { color: var(--ac-tx-4); cursor: not-allowed; background: transparent; border-color: transparent; }

/* =================================================================================== 5. formulaires */
:where(input[type=search], input[type=text], input[type=number], textarea, select), .field {
  background: var(--ac-field); border: 1px solid var(--ac-line-ctl); color: var(--ac-tx-1); border-radius: var(--ac-r-2); padding: 7px 10px; font-size: 13px;
  transition: border-color var(--ac-dur-1), box-shadow var(--ac-dur-2);
}
:where(textarea) { width: 100%; min-height: 90px; resize: vertical; line-height: 1.45; }
:where(input, textarea)::placeholder { color: var(--ac-tx-3); opacity: 1; }
:where(input[type=search], input[type=text], input[type=number], textarea, select):hover { border-color: var(--ac-tx-3); }
:where(input[type=search], input[type=text], input[type=number], textarea, select):focus, .field.is-focus { outline: none; border-color: var(--ac-accent); box-shadow: var(--ac-glow-cyan); }
:where(input[type=search], input[type=text], input[type=number], textarea, select):disabled, .field:disabled, .field.is-disabled {
  color: var(--ac-tx-4); border-color: var(--ac-line-3); cursor: not-allowed; background: var(--ac-bg-3);
}
.field.is-error { border-color: var(--ac-bad); box-shadow: var(--ac-glow-red); }
.field-err { display: flex; align-items: center; gap: 6px; margin-top: 5px; font-size: 12px; color: var(--ac-bad); }
.searchbox { position: relative; display: flex; align-items: center; }
.searchbox .ic { position: absolute; left: 12px; color: var(--ac-tx-3); pointer-events: none; }
.searchbox input { padding-left: 34px; width: 100%; border-radius: var(--ac-r-pill); }
.searchbox kbd { position: absolute; right: 10px; }
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; border-radius: var(--ac-r-pill); border: 1px solid var(--ac-line-3);
  background: var(--ac-bg-1); color: var(--ac-tx-2); font-size: 12.5px; white-space: nowrap; transition: color var(--ac-dur-1), border-color var(--ac-dur-1), background var(--ac-dur-1);
}
.chip:hover { color: var(--ac-tx-1); border-color: var(--ac-line-4); background: var(--ac-bg-3); }
.chip b { font-weight: var(--ac-fw-semibold); color: var(--ac-tx-1); }
.chip.on { color: var(--ac-accent-ink); background: var(--ac-accent-soft); border-color: var(--ac-accent-line); }
.chip.on b { color: var(--ac-accent-ink); }
.chip.off { color: var(--ac-tx-3); background: transparent; border-style: dashed; }
.chip:disabled { color: var(--ac-tx-4); border-color: var(--ac-line-1); cursor: not-allowed; }
/* bascule : .toggle (i dessiné) ou case native dans .chk (même rendu) */
.toggle, .chk { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ac-tx-2); cursor: pointer; white-space: nowrap; user-select: none; }
.toggle:hover, .chk:hover { color: var(--ac-tx-1); }
.toggle i { position: relative; width: 32px; height: 18px; border-radius: 999px; background: var(--ac-field); border: 1px solid var(--ac-line-ctl); flex: none; transition: background var(--ac-dur-2), border-color var(--ac-dur-2); }
.toggle i::after { content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: var(--ac-line-ctl); transition: transform var(--ac-dur-2) var(--ac-ease-out), background var(--ac-dur-2); }
.toggle.on i { background: var(--ac-accent); border-color: var(--ac-accent); }
.toggle.on i::after { transform: translateX(14px); background: var(--ac-tx-ink); }
.toggle.on, .chk:has(> input:checked) { color: var(--ac-tx-1); }
.toggle b { font-weight: var(--ac-fw-semibold); color: var(--ac-tx-3); }
/* .toggle avec case native (<label class="toggle"><input type="checkbox"><i></i>Libellé</label>) : la case reste
   focalisable et annoncée, le rendu est porté par <i> */
.toggle { position: relative; }
.toggle > input[type=checkbox] { position: absolute; left: 0; top: 50%; width: 32px; height: 18px; margin: -9px 0 0; opacity: 0; cursor: pointer; }
.toggle:has(> input:checked) i { background: var(--ac-accent); border-color: var(--ac-accent); }
.toggle:has(> input:checked) i::after { transform: translateX(14px); background: var(--ac-tx-ink); }
.toggle:has(> input:checked) { color: var(--ac-tx-1); }
.toggle:has(> input:focus-visible) i { outline: var(--ac-focus-ring); outline-offset: var(--ac-focus-offset); }
.toggle:has(> input:disabled) { opacity: .55; cursor: not-allowed; }
.toggle:hover i { border-color: var(--ac-tx-3); }
.chk > input[type=checkbox] {
  --knob: var(--ac-line-ctl);
  -webkit-appearance: none; appearance: none; margin: 0; flex: none; width: 32px; height: 18px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--ac-line-ctl);
  background: radial-gradient(circle, var(--knob) 0 5.6px, transparent 6.4px) 0 50% / 16px 16px no-repeat, var(--ac-field);
  transition: background-position var(--ac-dur-2) var(--ac-ease-out), background-color var(--ac-dur-2), border-color var(--ac-dur-2);
}
.chk > input[type=checkbox]:hover { border-color: var(--ac-tx-3); }
.chk > input[type=checkbox]:checked { --knob: var(--ac-tx-ink); background-position: 14px 50%; background-color: var(--ac-accent); border-color: var(--ac-accent); }
.chk > input[type=checkbox]:disabled { cursor: not-allowed; opacity: .5; }

/* =================================================================================== 6. sections et panneaux génériques */
.sec-head { display: flex; align-items: center; gap: 10px; min-height: 28px; min-width: 0; }
.sec-idx { /* index de section (01, 02…) : pastille douce */
  display: inline-grid; place-items: center; height: 20px; min-width: 26px; padding: 0 6px; font: 600 11px/1 var(--ac-font-mono); color: var(--ac-accent-ink);
  background: var(--ac-accent-soft); border-radius: var(--ac-r-pill);
}
.sec-head h2 { margin: 0; font: var(--ac-fw-bold) var(--ac-fs-16)/1.25 var(--ac-font-display); color: var(--ac-tx-1); white-space: nowrap; }
.sec-head > h2 { flex: 0 .1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* faute de place : la méta cède d'abord, le titre finit en ellipse (jamais chevauché) */
.sec-meta { font-size: var(--ac-fs-12); color: var(--ac-tx-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.sec-meta b { color: var(--ac-tx-2); font-weight: var(--ac-fw-semibold); }
.sec-tools { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.panel, .work { position: relative; background: var(--ac-bg-1); border: 1px solid var(--ac-line-2); border-radius: var(--ac-r-4); box-shadow: var(--ac-shadow-1); }
.panel-head { display: flex; align-items: center; gap: 10px; height: 48px; padding: 0 14px 0 16px; border-bottom: 1px solid var(--ac-line-1); }
.p-body { padding: 14px 16px 16px; }
/* équerres d'angle de l'ancienne direction : retirées (le balisage .brackets et .br reste, sans dessin) */
.brackets::before, .brackets::after, .brackets > .br::before, .brackets > .br::after { content: none; }

/* =================================================================================== 7. notifications */
.toasts { position: fixed; right: var(--ac-gutter); bottom: 20px; z-index: var(--ac-z-toast); display: flex; flex-direction: column; gap: 8px; width: min(420px, calc(100vw - 32px)); pointer-events: none; }
.toast {
  --tc: var(--ac-accent); --tic: var(--ac-ic-info);
  pointer-events: auto; position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 2px 10px; align-items: start;
  padding: 12px 14px; border-radius: var(--ac-r-3); border: 1px solid var(--ac-line-2); background: var(--ac-bg-1);
  box-shadow: var(--ac-shadow-3); font-size: 13px; line-height: 1.45; color: var(--ac-tx-1); overflow: hidden;
}
.toast .ic { color: var(--tc); margin-top: 1px; }
.toast b { font-weight: var(--ac-fw-semibold); }
.toast p { margin: 2px 0 0; grid-column: 2; font-size: 12.5px; color: var(--ac-tx-2); }
.toast .acts { grid-column: 2; display: flex; gap: 8px; margin-top: 8px; }
.toast .x { color: var(--ac-tx-3); }
.toast.ok { --tc: var(--ac-ok); --tic: var(--ac-ic-check); }
.toast.err { --tc: var(--ac-bad); --tic: var(--ac-ic-error); border-color: color-mix(in srgb, var(--ac-bad) 40%, transparent); }
.toast.warn { --tc: var(--ac-warn); --tic: var(--ac-ic-warn); }
.toast .bar5 { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--ac-line-1); }
.toast .bar5 i { display: block; height: 100%; width: 100%; background: var(--tc); opacity: .7; }
/* notification unique d'app.js (#toast : texte seul, classes « show » et « err ») : icône dessinée en masque */
#toast.toast {
  position: fixed; right: var(--ac-gutter); bottom: 20px; z-index: var(--ac-z-toast); display: block; width: max-content; max-width: min(440px, calc(100vw - 32px));
  padding: 12px 16px 12px 42px; opacity: 0; transform: translateY(8px); pointer-events: none;
  transition: opacity var(--ac-dur-3) var(--ac-ease-out), transform var(--ac-dur-3) var(--ac-ease-out);
}
#toast.toast:empty { display: none; }
#toast.toast::after {
  content: ""; position: absolute; left: 16px; top: 14px; width: 16px; height: 16px; background: var(--tc);
  -webkit-mask: var(--tic) center / 16px 16px no-repeat; mask: var(--tic) center / 16px 16px no-repeat;
}
#toast.toast.show { opacity: 1; transform: none; pointer-events: auto; }

/* =================================================================================== 8. mouvement (uniquement si accepté) */
/* rare et porteur d'information : le point de collecte respire, l'anneau de sondage se vide, une notification s'épuise */
@media (prefers-reduced-motion: no-preference) {
  .pulse:not(.stale)::after { content: ""; position: absolute; inset: 0; border-radius: 50%; animation: ac-ping var(--ac-loop-pulse) var(--ac-ease-out) infinite; }
  .poll .val { animation: ac-poll var(--ac-loop-poll) linear infinite; }
  .toasts .toast .bar5 i { animation: ac-drain 5.2s linear both; }
  .ac-keys[open] .ak-sheet { animation: ac-sheet-in var(--ac-dur-3) var(--ac-ease-out) both; }
  .ac-keys[open]::backdrop { animation: ac-fade-in var(--ac-dur-3) var(--ac-ease-out) both; }
}
@keyframes ac-sheet-in { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes ac-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ac-scan { 0% { background-position: -200px 0; opacity: 0; } 10% { opacity: 1; } 55% { opacity: 1; } 70%, 100% { background-position: calc(100% + 200px) 0; opacity: 0; } }
@keyframes ac-ping { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ac-ok) 55%, transparent); } 80%, 100% { box-shadow: 0 0 0 7px transparent; } }
@keyframes ac-poll { from { stroke-dashoffset: 0; } to { stroke-dashoffset: 40; } } /* plein à chaque lecture, se vide jusqu’à la suivante */
@keyframes ac-spin { to { transform: rotate(360deg); } }
@keyframes ac-ring { 0% { r: 7; opacity: .9; } 100% { r: 19; opacity: 0; } }
@keyframes ac-breathe { 0%, 100% { opacity: .08; } 50% { opacity: .3; } }
@keyframes ac-lock { from { transform: scale(1.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes ac-dash { to { stroke-dashoffset: -24; } }
@keyframes ac-drain { from { width: 100%; } to { width: 0; } }

/* =================================================================================== 9. adaptatif (coquille) */
@media (max-width: 1699px) {
  .counter .lbl .long { display: none; }
  .counter .lbl .short { display: inline; }
  .counter:has(> .dot.waiting) { --lbl: "À vous"; }
  .counter { padding: 5px 12px 5px 11px; }
}
/* lanceur vocal compact (icône micro + point d'état) sous 1700 px : la colonne droite garde de l'air entre les onglets
   et les instruments ; le libellé reste lu par les lecteurs d'écran et affiché en infobulle */
@media (max-width: 1699px) {
  .top .vx-launch { position: relative; min-width: 36px; width: 36px; padding: 0; justify-content: center; gap: 6px; }
  .top .vx-launch .vx-launch-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .top .vx-launch:not(:has(svg))::before {
    content: ""; width: 18px; height: 18px; flex: none; background: currentColor;
    -webkit-mask: var(--ac-ic-mic) center / 18px 18px no-repeat; mask: var(--ac-ic-mic) center / 18px 18px no-repeat;
  }
  .top .vx-launch .vx-launch-dot { position: absolute; top: 5px; right: 5px; width: 7px; height: 7px; box-shadow: 0 0 0 2px var(--ac-bg-1); }
}
/* 1241–1699 px : cinq compteurs + onglets + lanceurs ne tiennent pas en une rangée avec libellés ; glyphe et chiffre
   restent, le libellé complet est en infobulle et dans aria-label (app.js). */
@media (max-width: 1699px) and (min-width: 1241px) {
  .counter { grid-template-columns: auto auto auto; grid-template-rows: 38px; align-items: center; align-content: center; column-gap: 5px; padding: 0 10px; }
  .counter .lbl { grid-column: 1; grid-row: 1; font-size: 0; gap: 0; }
  .counter > b { grid-column: 2; grid-row: 1; font-size: 19px; line-height: 1; }
  .counter > small { display: none; }
  .wf-shortcut #waitLabel, .wf-shortcut .wl-short { display: none; }
}
/* 1024–1240 px (dont 1366 × 768 à 125 % = 1093 × 614) : l'en-tête reste sur UNE rangée de 60 px. Instruments compacts
   (glyphe d'état + chiffre ; libellé complet en infobulle et dans aria-label, posés par app.js), onglets sans leur
   touche affichée (aria-keyshortcuts conservé), raccourci de la vue Workflows réduit à « 10 à vous ». Les formes des
   glyphes (disque, anneau + point, carré, anneau en tirets, coche) portent l'état, jamais la couleur seule. */
@media (max-width: 1240px) and (min-width: 1024px) {
  .top { column-gap: 12px; }
  .tab { padding: 0 12px 0 10px; }
  .tab kbd { display: none; }
  .counter { grid-template-columns: auto auto auto; grid-template-rows: 38px; align-items: center; align-content: center; column-gap: 5px; padding: 0 9px; }
  .counter .lbl { grid-column: 1; grid-row: 1; font-size: 0; gap: 0; }   /* libellé nu ou .long/.short : masqués, le glyphe reste */
  .counter .lbl .dot { width: 10px; height: 10px; }
  .counter .lbl .dot.blocked { width: 9px; height: 9px; }
  .counter > b { grid-column: 2; grid-row: 1; font-size: 19px; line-height: 1; }
  .counter > small { display: none; }
  .top #counters .counter > .c-runs { grid-column: 3; grid-row: 1; align-self: center; padding: 0; }
  .wf-shortcut { gap: 7px; padding: 0 10px 0 12px; }
  .wf-shortcut #waitLabel { display: none; }
  .wf-shortcut .wl-short { display: inline; }
}
@media (max-width: 1100px) and (min-width: 1024px) { /* dernier cran avant les deux rangées : quelques pixels de plus */
  .top { column-gap: 10px; }
  .tab { gap: 6px; padding: 0 10px 0 9px; }
  .counter { padding: 0 8px; }
  .counter > b { font-size: 18px; }
}
/* En-tête sur trois rangées dès 641 px : marque et compte, onglets, puis instruments.
   Les compteurs gardent leur largeur même lorsque tous les onglets sont visibles.
   Hauteur fixe et identique dans les deux vues : --ac-header-h reste exact pour les éléments collants */
@media (min-width: 641px) {
  :root { --ac-header-h: 160px; }
  .top { grid-template-columns: minmax(0, 1fr) auto auto auto auto; grid-template-rows: 42px 34px 50px; height: var(--ac-header-h); padding-top: 8px; padding-bottom: 10px; row-gap: 8px; column-gap: 12px; }
  .top-right { display: contents; }
  .top > .top-mid { grid-column: 1 / -1; grid-row: 2; min-width: 0; }
  .top-right > .lang-slot { grid-column: 2; grid-row: 1; }
  .top-right > .acct { grid-column: 3; grid-row: 1; }
  .top-right > .ask-launch { grid-column: 5; grid-row: 1; }
  .top-right > .vx-launch { grid-column: 4; grid-row: 1; }
  .top-right > .counters, .top-right > .wf-shortcut { grid-column: 1 / -1; grid-row: 3; justify-self: start; margin-left: 0; max-width: 100%; }
}
/* Écran bas avec l'en-tête sur trois rangées : il défile avec la page au lieu
   de confisquer 160 px en permanence (app.js mesure alors 0 px d'en-tête collant pour le défilement et le tableau) */
@media (min-width: 641px) and (max-height: 700px) {
  .top { position: relative; }
  :where(.work, .detail, .stage, .s-quotas) { scroll-margin-top: 12px; }
}
@media (max-width: 640px) {
  :root { --ac-header-h: 56px; } /* en-tête non collant sur mobile */
  .hide-sm { display: none !important; }
  .top { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 8px; padding: 10px var(--ac-gutter); height: auto; }
  .brand { flex: 1; min-width: 0; order: 1; gap: 10px; }
  .brand h1 { font-size: 16px; }
  .brand .sub .fr-hist, .brand .sub:has(.pulse.stale) .fr-read { display: none; } /* une ligne : « Collecte en direct · lecture hh:mm » */
  .top-right { display: contents; }
  .top-right > :is(.lang-slot, .acct, .vx-launch, .ask-launch) { order: 2; align-self: center; }
  .top .vx-launch { width: var(--ac-tap); min-width: var(--ac-tap); height: var(--ac-tap); }
  .top-mid { order: 3; width: 100%; }
  .top-mid > .tabs { flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
  .keys-btn { display: none; }   /* raccourcis clavier : sans objet au doigt (« ? » reste actif avec un clavier) */
  .tab { flex: 0 0 auto; justify-content: center; height: var(--ac-tap); padding: 0 12px; }
  .tab kbd { display: none; }
  .top-right > .counters, .top-right > .wf-shortcut { order: 4; width: 100%; margin-left: 0; }
  .top-right > .wf-shortcut { justify-content: center; height: var(--ac-tap); }
  .counters { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .counter { padding: 6px 4px 6px 8px; grid-template-columns: auto; min-height: var(--ac-tap); }
  .counter .lbl { font-size: 11px; gap: 4px; overflow: hidden; }
  .counter .lbl .long { display: none; }
  .counter .lbl .short { display: inline; }
  .counter .lbl .dot { width: 7px; height: 7px; }
  .counter > small { display: none; }
  .counter > b { font-size: 19px; }
  .counter:has(> .dot) { grid-template-columns: auto minmax(0, 1fr); }
  .counter:has(> .dot)::after { font-size: 11px; }
  .counter:has(> .dot.waiting) { --lbl: "À vous"; }
  .counter[aria-pressed="true"]::after { left: 8px; right: 8px; }
  .top #counters .counter > .c-runs { display: none; }   /* cinquième de largeur : « À vous » entier ; les étapes sont dans la file */
  #toast.toast, .toasts { right: var(--ac-gutter); left: var(--ac-gutter); width: auto; max-width: none; }
  :where(.work, .detail, .stage, .s-quotas) { scroll-margin-top: 12px; } /* en-tête non collant */
  .skip-link { height: var(--ac-tap); }
  .ac-session-banner { top: 8px; grid-template-columns: auto minmax(0, 1fr); }
  .ac-session-banner .sb-acts { grid-column: 1 / -1; justify-content: flex-start; }
}
/* cibles tactiles : 44 px au doigt (écran étroit ou pointeur grossier), pour les composants génériques */
@media (max-width: 640px), (pointer: coarse) {
  .btn, .btn.sm, .ghost, .chip, .lang-btn { min-height: var(--ac-tap); }
  .btn.icon, .iconbtn, .theme-btn { min-width: var(--ac-tap); min-height: var(--ac-tap); }
  :where(input[type=search], input[type=text], input[type=number], input[type=email], input[type=password], select), .field { min-height: var(--ac-tap); }
  .toggle, .chk { min-height: var(--ac-tap); }
  .lang-menu li { min-height: var(--ac-tap); }
}

/* =====================================================================================================
   11. Contraste élevé de Windows (forced-colors: active) — toute l'application, en un seul endroit
   -----------------------------------------------------------------------------------------------------
   Windows impose alors sa palette : couleurs de texte, de fond et de bordure remplacées par les couleurs système,
   dégradés et ombres supprimés. Tout ce qui porte une information par un FOND ou une OMBRE disparaîtrait (pastille des
   bascules, glyphes d'état, segments de jauge, icônes en masque, barre de l'onglet actif…). Ces éléments sortent de
   l'ajustement (forced-color-adjust: none) et sont redessinés en couleurs système (Canvas, CanvasText, ButtonText,
   Highlight, HighlightText, GrayText) : ils suivent le thème choisi, clair ou sombre. Les formes portent l'état
   (DESIGN-SYSTEM §1.4). Éléments de monitor.css et voice.css : sélecteurs relevés par :root / .top (feuilles chargées
   après celle-ci). Vérification : émulation CDP forced-colors (tests/shell_mobile_viewport.test.js).
   ===================================================================================================== */
@media (forced-colors: active) {
  /* bascules (.toggle, .chk, .wf-switch de l'éditeur) : piste cernée, pastille pleine ; activée = piste Highlight,
     pastille à droite en HighlightText (la position porte aussi l'état) */
  .toggle i, :root .wf-switch-ui { forced-color-adjust: none; background: Canvas; border: 1px solid ButtonText; }
  .toggle i::after, :root .wf-switch-ui::after { background: ButtonText; }
  .toggle.on i, .toggle:has(> input:checked) i, :root .wf-switch input:checked + .wf-switch-ui { background: Highlight; border-color: Highlight; }
  .toggle.on i::after, .toggle:has(> input:checked) i::after, :root .wf-switch input:checked + .wf-switch-ui::after { background: HighlightText; }
  .chk > input[type=checkbox] { forced-color-adjust: none; --knob: ButtonText; background-color: Canvas; border-color: ButtonText; }
  .chk > input[type=checkbox]:checked { --knob: HighlightText; background-color: Highlight; border-color: Highlight; }
  .chk > input[type=checkbox]:disabled, .toggle:has(> input:disabled) i { --knob: GrayText; border-color: GrayText; }

  /* glyphes d'état (compteurs, puces, file « À vous », raccourci Workflows) : encre système explicite — Chrome résout
     currentColor sur la couleur d'auteur, illisible sur un thème clair —, HighlightText sur une sélection */
  .dot { forced-color-adjust: none; --fc-ink: CanvasText; }
  .chip.on .dot, .tab.on .dot { --fc-ink: HighlightText; }
  .dot.running, .dot.blocked, .dot.other { background: var(--fc-ink); box-shadow: none; }
  .dot.waiting { background: transparent; box-shadow: inset 0 0 0 2px var(--fc-ink); }
  .dot.waiting::after { background: var(--fc-ink); }
  .dot.unknown { border-color: var(--fc-ink); }
  .dot.done::after { border-color: var(--fc-ink); }
  .pulse { forced-color-adjust: none; background: CanvasText; }

  /* icônes dessinées en masque (fond = forme) : micro du lanceur vocal, notification, glyphes de workflow */
  .top .vx-launch:not(:has(svg))::before, #toast.toast::after, .top #counters .counter > .c-runs::before, :root #view-monitor .q-sub::before {
    forced-color-adjust: none; background: CanvasText;
  }
  .top .vx-launch:not(:has(svg))::before, .top #counters .counter > .c-runs::before { background: ButtonText; }
  /* point d'état du lanceur vocal (voice.css) : disque, anneau « sans clé », carré « plafond atteint », Highlight en direct */
  .top .vx-launch .vx-launch-dot { forced-color-adjust: none; background: ButtonText; box-shadow: none; }
  .top .vx-launch[data-ready="nokey"] .vx-launch-dot { background: transparent; box-shadow: inset 0 0 0 1.6px ButtonText; }
  .top .vx-launch.vx-is-live .vx-launch-dot { background: Highlight; }
  .top .vx-launch[aria-expanded="true"] { border-color: Highlight; }

  /* onglet courant et filtres actifs : sélection système (Highlight / HighlightText) */
  .tab.on { forced-color-adjust: none; background: Highlight; color: HighlightText; box-shadow: none; }
  .tab.on .ic, .tab.on kbd { color: HighlightText; border-color: HighlightText; background: transparent; }
  .tab.on::after { display: none; }
  .chip.on { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
  .chip.on b { color: HighlightText; }
  .counter[aria-pressed="true"]::after { forced-color-adjust: none; background: Highlight; box-shadow: none; height: 3px; }
  /* « Attend votre action » : seul instrument cerné (c'est à vous) ; le contour de focus garde sa place */
  .counter.is-waiting:not(.zero):not(:focus-visible) { outline: 2px solid Highlight; outline-offset: -2px; }
  .wf-shortcut:not(.zero) { border: 2px solid Highlight; }

  /* jauges de quota (monitor.css) : segments allumés = Highlight, éteints = cernés ; valeur inconnue = cernés en gris */
  :root #view-monitor .gauge i, :root #view-monitor .qlg i { forced-color-adjust: none; background: Canvas; box-shadow: inset 0 0 0 1px CanvasText; }
  :root #view-monitor .gauge i.on, :root #view-monitor .qlg i:not(.off) { background: Highlight; box-shadow: none; }
  :root #view-monitor .gauge.idle i { background: Canvas; box-shadow: inset 0 0 0 1px GrayText; }
  :root #view-monitor .gauge .tick { forced-color-adjust: none; background: CanvasText; }
  :root #view-monitor .minibar { forced-color-adjust: none; background: Canvas; box-shadow: inset 0 0 0 1px CanvasText; }
  :root #view-monitor .minibar i { background: Highlight; opacity: 1; }
  :root #view-monitor .minibar.idle { background: Canvas; box-shadow: inset 0 0 0 1px GrayText; }
  /* sélections du Suivi : compte lié ou choisi, ligne de tableau, cible de distribution */
  :root #view-monitor .qcard:is(.is-link, .is-sel) { outline: 2px solid Highlight; outline-offset: -1px; }
  :root #view-monitor tr.row.sel td:first-child { forced-color-adjust: none; box-shadow: inset 4px 0 0 Highlight; }
  :root #view-monitor .target.on { outline: 2px solid Highlight; outline-offset: -1px; }
  :root #view-monitor .target .radio { forced-color-adjust: none; border-color: ButtonText; background: Canvas; box-shadow: none; }
  :root #view-monitor .target.on .radio { border-color: Highlight; background: Highlight; box-shadow: inset 0 0 0 3.5px Canvas; }
}

/* =====================================================================================================
   10. Garde-fous fonctionnels du graphe (SVG posé par app.js). Couche « ac-legacy » : toute règle hors couche
   (monitor.css, qui habille la constellation d'après design/final/ui.css §6) l'emporte quelle que soit sa
   spécificité. Seul rôle : que la constellation reste lisible et utilisable même si monitor.css manque
   (tracés sans remplissage, libellés masqués qui restent masqués, curseurs de déplacement).
   ===================================================================================================== */
@layer ac-legacy {
  .edge { fill: none; stroke: var(--ac-line-4); stroke-width: 1.1; stroke-linecap: round; }
  .edge.e-files { stroke: var(--ac-magenta); stroke-width: 1.7; }
  .labels, .lbl { pointer-events: none; }
  .lbl.hidden { display: none; }
  .lbl.hidden.hover, .lbl.hidden.sel { display: inline; }
  .node { cursor: pointer; }
  #graph { cursor: grab; touch-action: none; }
  #graph.dragging { cursor: grabbing; }
}


/* =================================================================================== sélecteurs de thème et de langue
   (js/theme.js, js/i18n.js) : même bouton en pilule, même liste ; le thème se place devant la langue */
[data-lang-picker] { display: flex; align-items: center; gap: 6px; }
.lang-pick { position: relative; }
.lang-btn {
  display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 12px; border: 1px solid var(--ac-line-3); border-radius: var(--ac-r-pill);
  background: var(--ac-bg-1); color: var(--ac-tx-2); font: 600 12px/1 var(--ac-font-ui); cursor: pointer;
  transition: border-color var(--ac-dur-1), color var(--ac-dur-1), background var(--ac-dur-1);
}
.lang-btn:hover, .lang-btn[aria-expanded="true"] { border-color: var(--ac-line-4); color: var(--ac-tx-1); background: var(--ac-bg-3); }
.lang-btn:focus-visible { outline: none; box-shadow: var(--ac-focus); }
.theme-btn { width: 36px; padding: 0; justify-content: center; }
.flag { width: 20px; height: 14px; flex: none; border-radius: 2px; clip-path: inset(0 round 2px); box-shadow: 0 0 0 1px var(--ac-line-3); }
.lang-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60; min-width: 190px; margin: 0; padding: 5px; list-style: none;
  background: var(--ac-bg-1); border: 1px solid var(--ac-line-2); border-radius: var(--ac-r-3);
  box-shadow: var(--ac-shadow-3);
}
.lang-menu li {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--ac-r-2); cursor: pointer; font-size: 13px; color: var(--ac-tx-1);
}
.lang-menu li span { flex: 1; }
.lang-menu li small { font: 600 11px/1 var(--ac-font-mono); color: var(--ac-tx-3); }
.lang-menu li .ic { color: var(--ac-tx-3); }
.lang-menu li:hover, .lang-menu li:focus { outline: none; background: var(--ac-bg-3); }
.lang-menu li:focus-visible { outline: var(--ac-focus-ring); outline-offset: -2px; }
.lang-menu li[aria-selected="true"] { background: var(--ac-accent-soft); color: var(--ac-accent-ink); font-weight: var(--ac-fw-semibold); }
.lang-menu li[aria-selected="true"] .ic { color: var(--ac-accent); }
.lang-corner { position: fixed; top: 16px; right: 18px; z-index: 30; }

@media (max-width: 640px) { .lang-menu { left: 0; right: auto; max-width: calc(100vw - 32px); } }
