/* PanneauLinux — feuille unique (concaténation de css/*.css). Ne pas modifier : éditer les sources. */

/* ===== tokens.css ===== */
/* ==========================================================================
   PanneauLinux — tokens.css
   Jetons du système de design. Seul fichier à contenir des valeurs brutes.
   Thème : <html data-theme="light|dark">. Sans attribut, prefers-color-scheme décide.
   Contrastes mesurés (WCAG 2.2) : voir GUIDE.md § « Contrastes ».
   ========================================================================== */

:root {
  /* ---- Couleurs (thème clair) ------------------------------------------ */
  --bg: #f5f6f8;
  --surface: #ffffff;
  --surface-2: #f0f2f5;
  --surface-3: #e6e9ee;
  --overlay: #0f121899;
  --border: #dce0e6;
  --border-strong: #c3c9d2;
  --border-control: #7c8594;
  --text: #161b24;
  --text-2: #434c5a;
  --text-3: #596271;
  --text-inverse: #ffffff;
  --brand: #3045b5;
  --brand-hover: #24379a;
  --brand-soft: #eceffc;
  --brand-border: #a9b4ec;
  --primary: #1b212c;
  --primary-hover: #2d3442;
  --on-primary: #ffffff;
  --danger-solid: #b8241b;
  --danger-solid-hover: #9b1c14;
  --on-danger: #ffffff;
  --success: #136a33;
  --success-bg: #e6f4eb;
  --success-border: #9fd2b2;
  --success-dot: #1d9147;
  --danger: #ad2219;
  --danger-bg: #fdedeb;
  --danger-border: #f1b2ab;
  --danger-dot: #d4342a;
  --warning: #844800;
  --warning-bg: #fff3dd;
  --warning-border: #ecc786;
  --warning-dot: #c47c00;
  --progress: #0a5f80;
  --progress-bg: #e3f2f8;
  --progress-border: #9ccde0;
  --progress-dot: #1683ad;
  --maint: #6437bd;
  --maint-bg: #f1ecfc;
  --maint-border: #cbbaf0;
  --maint-dot: #7e52d6;
  --neutral: #434c5a;
  --neutral-bg: #eceef2;
  --neutral-border: #c3c9d2;
  --neutral-dot: #7c8594;
  --unknown: #596271;
  --unknown-border: #8a93a1;
  --detected: #3045b5;
  --detected-bg: #f2f4fd;
  --detected-border: #7f8ede;
  --log-bg: #f7f8fa;
  --log-gutter: #656e7c;
  --log-info: #1d6b3a;
  --log-warn: #844800;
  --log-error: #ad2219;
  --log-debug: #5c6573;
  --log-ts: #596271;
  --diff-add-bg: #e6f4eb;
  --diff-add-fg: #136a33;
  --diff-del-bg: #fdedeb;
  --diff-del-fg: #ad2219;
  --code-key: #24379a;
  --code-str: #136a33;
  --code-num: #844800;
  --focus: #3045b5;
  --selection: #c9d1f6;
  --skeleton: #e6e9ee;
  --skeleton-hi: #f3f5f8;
  color-scheme: light;

  /* ---- Typographie ------------------------------------------------------ */
  --font-sans: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "Cascadia Mono", "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  --text-2xs: 0.6875rem;  /* 11px — compteurs, exposants */
  --text-xs: 0.75rem;     /* 12px — méta, en-têtes de tableau */
  --text-sm: 0.8125rem;   /* 13px — tableaux denses, journaux */
  --text-md: 0.875rem;    /* 14px — corps de l'interface */
  --text-lg: 1rem;        /* 16px — titres de carte */
  --text-xl: 1.25rem;     /* 20px — titre de page */
  --text-2xl: 1.5rem;     /* 24px — chiffres clés */
  --text-3xl: 1.875rem;   /* 30px — grands chiffres de statistique */
  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --leading-mono: 1.6;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --tracking-caps: 0.06em;

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

  /* ---- Dimensions de contrôle ------------------------------------------ */
  --control-h-sm: 1.75rem;  /* 28 */
  --control-h: 2.125rem;    /* 34 */
  --control-h-lg: 2.5rem;   /* 40 */
  --icon-sm: 0.875rem;
  --icon: 1rem;
  --icon-lg: 1.25rem;
  --sidebar-w: 15rem;
  --sidebar-w-collapsed: 3.5rem;
  --topbar-h: 3.25rem;
  --content-max: 90rem;

  /* ---- Rayons ----------------------------------------------------------- */
  --radius-xs: 2px;
  --radius-sm: 4px;
  --radius: 6px;
  --radius-lg: 10px;
  --radius-pill: 999px;

  /* ---- Bordures --------------------------------------------------------- */
  --border-w: 1px;
  --border-w-strong: 2px;
  --focus-w: 2px;
  --focus-offset: 2px;

  /* ---- Ombres ----------------------------------------------------------- */
  --shadow-color: 220 30% 10%;
  --shadow-1: 0 1px 2px hsl(var(--shadow-color) / 0.06);
  --shadow-2: 0 2px 6px hsl(var(--shadow-color) / 0.08), 0 1px 2px hsl(var(--shadow-color) / 0.06);
  --shadow-3: 0 12px 32px hsl(var(--shadow-color) / 0.18), 0 2px 6px hsl(var(--shadow-color) / 0.08);

  /* ---- Mouvement -------------------------------------------------------- */
  --duration-fast: 120ms;
  --duration: 200ms;
  --duration-slow: 320ms;
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --ease-out: cubic-bezier(0, 0, 0.2, 1);

  /* ---- Superposition ---------------------------------------------------- */
  --z-sticky: 10;
  --z-sidebar: 30;
  --z-dropdown: 40;
  --z-overlay: 50;
  --z-dialog: 60;
  --z-toast: 70;

  /* ---- Points de rupture (référence) ------------------------------------
     Les variables CSS ne sont pas utilisables dans @media : les valeurs
     ci-dessous sont recopiées littéralement dans les feuilles de style.  */
  --bp-sm: 40rem;   /* 640  — téléphone large  */
  --bp-md: 56rem;   /* 896  — tablette : barre latérale en tiroir en dessous */
  --bp-lg: 75rem;   /* 1200 — bureau */
  --bp-xl: 90rem;   /* 1440 — grand écran */
}

/* Écrans tactiles : cibles de 44 px minimum (WCAG 2.5.8 recommande 24, Apple/Google 44). */
@media (pointer: coarse) {
  :root {
    --control-h-sm: 2.25rem;
    --control-h: 2.75rem;
    --control-h-lg: 3rem;
  }
}

/* ---- Thème sombre : préférence système, sauf choix explicite « clair » ---- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0e1117;
    --surface: #151922;
    --surface-2: #1b2029;
    --surface-3: #232a35;
    --overlay: #000000b3;
    --border: #2a313d;
    --border-strong: #3a4250;
    --border-control: #6c7586;
    --text: #e5e8ee;
    --text-2: #b2b9c5;
    --text-3: #949dab;
    --text-inverse: #0e1117;
    --brand: #93a2ff;
    --brand-hover: #b0bcff;
    --brand-soft: #1c2240;
    --brand-border: #4a57a3;
    --primary: #e5e8ee;
    --primary-hover: #ffffff;
    --on-primary: #0e1117;
    --danger-solid: #e0463b;
    --danger-solid-hover: #ec5e54;
    --on-danger: #14070a;
    --success: #62d08c;
    --success-bg: #11261a;
    --success-border: #255638;
    --success-dot: #3fbd6e;
    --danger: #ff8b81;
    --danger-bg: #2c1415;
    --danger-border: #6a2a27;
    --danger-dot: #f0574c;
    --warning: #f2b54a;
    --warning-bg: #2a2010;
    --warning-border: #5c4519;
    --warning-dot: #e09f1d;
    --progress: #5ec2e6;
    --progress-bg: #0e2430;
    --progress-border: #1e4e61;
    --progress-dot: #33a8d4;
    --maint: #b9a0ff;
    --maint-bg: #211a37;
    --maint-border: #493a78;
    --maint-dot: #9a7bf0;
    --neutral: #b2b9c5;
    --neutral-bg: #212732;
    --neutral-border: #3a4250;
    --neutral-dot: #8b94a3;
    --unknown: #949dab;
    --unknown-border: #626b7b;
    --detected: #93a2ff;
    --detected-bg: #171c33;
    --detected-border: #5a68b8;
    --log-bg: #0b0e13;
    --log-gutter: #7a8394;
    --log-info: #7fd6a0;
    --log-warn: #f2b54a;
    --log-error: #ff8b81;
    --log-debug: #8d96a5;
    --log-ts: #8d96a5;
    --diff-add-bg: #11261a;
    --diff-add-fg: #7fd6a0;
    --diff-del-bg: #2c1415;
    --diff-del-fg: #ff8b81;
    --code-key: #93a2ff;
    --code-str: #7fd6a0;
    --code-num: #f2b54a;
    --focus: #93a2ff;
    --selection: #2d3770;
    --skeleton: #1f252f;
    --skeleton-hi: #2a313d;
    --shadow-color: 220 40% 2%;
    color-scheme: dark;
  }
}

/* ---- Thème clair forcé sur un sous-arbre (ex. aperçu dans la page de référence) */
[data-theme="light"] {
  --bg: #f5f6f8;
  --surface: #ffffff;
  --surface-2: #f0f2f5;
  --surface-3: #e6e9ee;
  --overlay: #0f121899;
  --border: #dce0e6;
  --border-strong: #c3c9d2;
  --border-control: #7c8594;
  --text: #161b24;
  --text-2: #434c5a;
  --text-3: #596271;
  --text-inverse: #ffffff;
  --brand: #3045b5;
  --brand-hover: #24379a;
  --brand-soft: #eceffc;
  --brand-border: #a9b4ec;
  --primary: #1b212c;
  --primary-hover: #2d3442;
  --on-primary: #ffffff;
  --danger-solid: #b8241b;
  --danger-solid-hover: #9b1c14;
  --on-danger: #ffffff;
  --success: #136a33;
  --success-bg: #e6f4eb;
  --success-border: #9fd2b2;
  --success-dot: #1d9147;
  --danger: #ad2219;
  --danger-bg: #fdedeb;
  --danger-border: #f1b2ab;
  --danger-dot: #d4342a;
  --warning: #844800;
  --warning-bg: #fff3dd;
  --warning-border: #ecc786;
  --warning-dot: #c47c00;
  --progress: #0a5f80;
  --progress-bg: #e3f2f8;
  --progress-border: #9ccde0;
  --progress-dot: #1683ad;
  --maint: #6437bd;
  --maint-bg: #f1ecfc;
  --maint-border: #cbbaf0;
  --maint-dot: #7e52d6;
  --neutral: #434c5a;
  --neutral-bg: #eceef2;
  --neutral-border: #c3c9d2;
  --neutral-dot: #7c8594;
  --unknown: #596271;
  --unknown-border: #8a93a1;
  --detected: #3045b5;
  --detected-bg: #f2f4fd;
  --detected-border: #7f8ede;
  --log-bg: #f7f8fa;
  --log-gutter: #656e7c;
  --log-info: #1d6b3a;
  --log-warn: #844800;
  --log-error: #ad2219;
  --log-debug: #5c6573;
  --log-ts: #596271;
  --diff-add-bg: #e6f4eb;
  --diff-add-fg: #136a33;
  --diff-del-bg: #fdedeb;
  --diff-del-fg: #ad2219;
  --code-key: #24379a;
  --code-str: #136a33;
  --code-num: #844800;
  --focus: #3045b5;
  --selection: #c9d1f6;
  --skeleton: #e6e9ee;
  --skeleton-hi: #f3f5f8;
  --shadow-color: 220 30% 10%;
  color-scheme: light;
}

/* ---- Thème sombre : choix explicite (sur <html> ou sur un sous-arbre) ---- */
:root[data-theme="dark"], [data-theme="dark"] {
  --bg: #0e1117;
  --surface: #151922;
  --surface-2: #1b2029;
  --surface-3: #232a35;
  --overlay: #000000b3;
  --border: #2a313d;
  --border-strong: #3a4250;
  --border-control: #6c7586;
  --text: #e5e8ee;
  --text-2: #b2b9c5;
  --text-3: #949dab;
  --text-inverse: #0e1117;
  --brand: #93a2ff;
  --brand-hover: #b0bcff;
  --brand-soft: #1c2240;
  --brand-border: #4a57a3;
  --primary: #e5e8ee;
  --primary-hover: #ffffff;
  --on-primary: #0e1117;
  --danger-solid: #e0463b;
  --danger-solid-hover: #ec5e54;
  --on-danger: #14070a;
  --success: #62d08c;
  --success-bg: #11261a;
  --success-border: #255638;
  --success-dot: #3fbd6e;
  --danger: #ff8b81;
  --danger-bg: #2c1415;
  --danger-border: #6a2a27;
  --danger-dot: #f0574c;
  --warning: #f2b54a;
  --warning-bg: #2a2010;
  --warning-border: #5c4519;
  --warning-dot: #e09f1d;
  --progress: #5ec2e6;
  --progress-bg: #0e2430;
  --progress-border: #1e4e61;
  --progress-dot: #33a8d4;
  --maint: #b9a0ff;
  --maint-bg: #211a37;
  --maint-border: #493a78;
  --maint-dot: #9a7bf0;
  --neutral: #b2b9c5;
  --neutral-bg: #212732;
  --neutral-border: #3a4250;
  --neutral-dot: #8b94a3;
  --unknown: #949dab;
  --unknown-border: #626b7b;
  --detected: #93a2ff;
  --detected-bg: #171c33;
  --detected-border: #5a68b8;
  --log-bg: #0b0e13;
  --log-gutter: #7a8394;
  --log-info: #7fd6a0;
  --log-warn: #f2b54a;
  --log-error: #ff8b81;
  --log-debug: #8d96a5;
  --log-ts: #8d96a5;
  --diff-add-bg: #11261a;
  --diff-add-fg: #7fd6a0;
  --diff-del-bg: #2c1415;
  --diff-del-fg: #ff8b81;
  --code-key: #93a2ff;
  --code-str: #7fd6a0;
  --code-num: #f2b54a;
  --focus: #93a2ff;
  --selection: #2d3770;
  --skeleton: #1f252f;
  --skeleton-hi: #2a313d;
  --shadow-color: 220 40% 2%;
  color-scheme: dark;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0ms;
    --duration: 0ms;
    --duration-slow: 0ms;
  }
}

/* ===== base.css ===== */
/* ==========================================================================
   PanneauLinux — base.css
   Remise à zéro, typographie, focus, icônes, utilitaires.
   Convention : préfixe « pl- » + BEM (pl-bloc__element--modificateur).
   Le préfixe évite les collisions avec Bootstrap fourni par le modèle ASP.NET.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  font-feature-settings: "kern", "liga";
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  text-wrap: balance;
}
h1 { font-size: var(--text-xl); }
h2 { font-size: var(--text-lg); }
h3 { font-size: var(--text-md); }
h4, h5, h6 { font-size: var(--text-sm); }

p { margin: 0; }
p + p { margin-top: var(--space-2); }
ul, ol { margin: 0; padding: 0; }
img, svg, video { max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
table { border-collapse: collapse; }
[hidden] { display: none !important; }

a { color: var(--brand); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--brand-hover); }

code, kbd, samp, pre { font-family: var(--font-mono); font-size: 0.92em; }
kbd {
  display: inline-block;
  padding: 0 var(--space-1);
  min-width: 1.5em;
  border: var(--border-w) solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: var(--text-xs);
  text-align: center;
  line-height: 1.5;
}

::selection { background: var(--selection); }

/* Focus : visible uniquement au clavier, jamais supprimé. */
:focus { outline: none; }
:focus-visible {
  outline: var(--focus-w) solid var(--focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-sm);
}

/* ---- Icônes : <svg class="pl-icon"><use href="#i-play"/></svg> ---------- */
.pl-icon {
  width: var(--icon);
  height: var(--icon);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.15em;
}
.pl-icon--sm { width: var(--icon-sm); height: var(--icon-sm); }
.pl-icon--lg { width: var(--icon-lg); height: var(--icon-lg); }
.pl-icon--spin { animation: pl-spin 1s linear infinite; }
@keyframes pl-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .pl-icon--spin { animation-duration: 3s; }
}

/* ---- Lien d'évitement ----------------------------------------------------- */
.pl-skip-link {
  position: absolute;
  left: var(--space-2);
  top: -100px;
  z-index: var(--z-toast);
  padding: var(--space-2) var(--space-3);
  background: var(--primary);
  color: var(--on-primary);
  border-radius: var(--radius);
}
.pl-skip-link:focus { top: var(--space-2); }

/* ---- Utilitaires ---------------------------------------------------------- */
.pl-sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
.pl-mono { font-family: var(--font-mono); font-size: 0.93em; }
.pl-num { font-variant-numeric: tabular-nums; }
.pl-muted { color: var(--text-3); }
.pl-secondary { color: var(--text-2); }
.pl-nowrap { white-space: nowrap; }
.pl-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* Coupe les longues chaînes techniques (domaines, chemins) sans casser la mise en page. */
.pl-break { overflow-wrap: anywhere; }
.pl-caps {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-3);
}

.pl-stack { display: flex; flex-direction: column; gap: var(--space-4); }
.pl-stack--sm { gap: var(--space-2); }
.pl-stack--lg { gap: var(--space-6); }
.pl-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.pl-cluster--end { justify-content: flex-end; }
.pl-cluster--between { justify-content: space-between; }
.pl-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.pl-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); }
.pl-grid--main-aside { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 75rem) {
  .pl-grid--main-aside { grid-template-columns: minmax(0, 2fr) minmax(18rem, 1fr); }
}
.pl-grid > *, .pl-cluster > * { min-width: 0; }

/* ===== layout.css ===== */
/* ==========================================================================
   PanneauLinux — layout.css
   Coque : application, barre latérale, barre supérieure, barre d'onglets
   mobile, fil d'Ariane, en-tête de page, sections.
   ========================================================================== */

/* ---- Application ---------------------------------------------------------- */
.pl-app {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  min-height: 100vh;
}
.pl-app[data-sidebar="collapsed"] { grid-template-columns: var(--sidebar-w-collapsed) minmax(0, 1fr); }
.pl-app__main { display: flex; flex-direction: column; min-width: 0; }

/* ---- Barre latérale ------------------------------------------------------- */
.pl-sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: var(--border-w) solid var(--border);
  z-index: var(--z-sidebar);
  overflow: hidden;
}
.pl-sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--topbar-h);
  padding: 0 var(--space-4);
  border-bottom: var(--border-w) solid var(--border);
  color: var(--text);
  text-decoration: none;
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}
.pl-sidebar__brand:hover { color: var(--text); }
.pl-sidebar__nav { flex: 1; overflow-y: auto; padding: var(--space-3) var(--space-2); }
.pl-sidebar__footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-2);
  border-top: var(--border-w) solid var(--border);
}
.pl-sidebar__host { padding: 0 var(--space-2); font-size: var(--text-xs); color: var(--text-3); line-height: 1.4; }
.pl-sidebar__host strong { display: block; color: var(--text-2); font-family: var(--font-mono); font-weight: var(--weight-medium); }

/* Logo : invite de terminal « ›_ » dans un carré, couleur de marque. */
.pl-logo {
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
  border-radius: var(--radius);
  background: var(--brand);
  color: var(--bg);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.04em;
}
.pl-logo__name { font-size: var(--text-md); letter-spacing: -0.01em; }
.pl-logo__name span { color: var(--text-3); font-weight: var(--weight-regular); }

/* Navigation */
.pl-nav { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.pl-nav__section {
  margin: var(--space-4) var(--space-2) var(--space-1);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-3);
  white-space: nowrap;
}
.pl-nav__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control-h);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius);
  color: var(--text-2);
  text-decoration: none;
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
.pl-nav__link:hover { background: var(--surface-2); color: var(--text); }
.pl-nav__link[aria-current="page"] { background: var(--brand-soft); color: var(--brand); }
.pl-nav__link[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-2));
  top: 6px; bottom: 6px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--brand);
}
.pl-nav__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pl-nav__count {
  min-width: 1.25rem;
  padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-align: center;
  line-height: 1.25rem;
  font-variant-numeric: tabular-nums;
  background: var(--surface-3);
  color: var(--text-2);
}
.pl-nav__count--danger { background: var(--danger-solid); color: var(--on-danger); }

/* Barre repliée : icônes seules, libellés conservés pour les lecteurs d'écran. */
.pl-app[data-sidebar="collapsed"] .pl-logo__name,
.pl-app[data-sidebar="collapsed"] .pl-nav__section,
.pl-app[data-sidebar="collapsed"] .pl-sidebar__host { display: none; }
.pl-app[data-sidebar="collapsed"] .pl-nav__label {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0);
}
.pl-app[data-sidebar="collapsed"] .pl-nav__link { justify-content: center; padding: var(--space-1); }
.pl-app[data-sidebar="collapsed"] .pl-nav__count--danger {
  position: absolute; top: 2px; right: 2px; min-width: 0.5rem; height: 0.5rem; padding: 0; font-size: 0; line-height: 0;
}
.pl-app[data-sidebar="collapsed"] .pl-nav__count:not(.pl-nav__count--danger) { display: none; }
.pl-app[data-sidebar="collapsed"] .pl-sidebar__brand { justify-content: center; padding: 0; }
.pl-app[data-sidebar="collapsed"] .pl-sidebar__collapse .pl-button__label { display: none; }
.pl-app[data-sidebar="collapsed"] .pl-sidebar__collapse { justify-content: center; }
.pl-app[data-sidebar="collapsed"] .pl-sidebar__collapse .pl-icon { transform: scaleX(-1); }

/* ---- Barre supérieure ----------------------------------------------------- */
.pl-topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--topbar-h);
  padding: 0 var(--space-4);
  background: var(--surface);
  border-bottom: var(--border-w) solid var(--border);
}
.pl-topbar .pl-topbar__menu { display: none; }
.pl-topbar__search { position: relative; flex: 1; max-width: 32rem; }
.pl-topbar__search .pl-input { padding-left: 2rem; padding-right: 2rem; background: var(--surface-2); }
.pl-topbar__search > .pl-icon { position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%); color: var(--text-3); pointer-events: none; }
.pl-topbar__search kbd { position: absolute; right: var(--space-2); top: 50%; transform: translateY(-50%); }
.pl-topbar__spacer { flex: 1; }
.pl-topbar__tools { display: flex; align-items: center; gap: var(--space-1); }

/* Bascule de langue : deux boutons radio visuels. */
.pl-lang {
  display: inline-flex;
  padding: 2px;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.pl-lang__option {
  min-width: 2rem;
  height: calc(var(--control-h) - 6px);
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
}
.pl-lang__option[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-1); }

/* Compte */
.pl-account {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-2) 0 var(--space-1);
  border: var(--border-w) solid transparent;
  border-radius: var(--radius);
  background: transparent;
}
.pl-account:hover { background: var(--surface-2); }
.pl-avatar {
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

/* ---- Bandeaux d'alerte globaux (sous la barre supérieure) ---------------- */
.pl-banners { display: flex; flex-direction: column; }

/* ---- Contenu de page ------------------------------------------------------ */
.pl-page {
  flex: 1;
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--space-5) var(--space-6) var(--space-12);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Fil d'Ariane */
.pl-breadcrumb ol { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); font-size: var(--text-sm); }
.pl-breadcrumb li { display: inline-flex; align-items: center; gap: var(--space-1); min-width: 0; color: var(--text-3); }
.pl-breadcrumb li + li::before {
  content: "/";
  color: var(--border-strong);
  margin-right: var(--space-1);
}
.pl-breadcrumb a { color: var(--text-2); text-decoration: none; }
.pl-breadcrumb a:hover { color: var(--text); text-decoration: underline; }
.pl-breadcrumb [aria-current="page"] { color: var(--text); font-weight: var(--weight-medium); overflow-wrap: anywhere; }

/* En-tête de page */
.pl-page-header { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3) var(--space-6); }
.pl-page-header__main { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; flex: 1 1 22rem; }
.pl-page-header__title { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.pl-page-header__title h1 { overflow-wrap: anywhere; }
.pl-page-header__title h1.pl-mono { font-size: var(--text-xl); font-weight: var(--weight-semibold); letter-spacing: -0.01em; }
.pl-page-header__meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); font-size: var(--text-sm); color: var(--text-2); }
.pl-page-header__meta > span { display: inline-flex; align-items: center; gap: var(--space-1); }
.pl-page-header__meta .pl-icon { color: var(--text-3); }
.pl-page-header__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }

/* Section avec titre */
.pl-section { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.pl-section__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.pl-section__title { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-md); }
.pl-section__title .pl-count { font-weight: var(--weight-regular); color: var(--text-3); }

@media (max-width: 40rem) {
  /* Fil d'Ariane : seuls les deux derniers niveaux sur téléphone */
  .pl-breadcrumb li:not(:nth-last-child(-n+2)) { display: none; }
  .pl-breadcrumb li:nth-last-child(2)::before { content: none; }
  .pl-breadcrumb li:nth-last-child(2) a::before { content: "‹ "; }
  .pl-hide-sm { display: none !important; }
}

/* ---- Barre d'onglets mobile (navigation d'urgence) ----------------------- */
.pl-tabbar { display: none; }

/* ---- Tiroir mobile -------------------------------------------------------- */
.pl-scrim {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-sidebar) - 1);
  background: var(--overlay);
}

@media (max-width: 56rem) {
  .pl-app, .pl-app[data-sidebar="collapsed"] { grid-template-columns: minmax(0, 1fr); }
  .pl-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(18rem, 85vw);
    height: 100%;
    padding-top: env(safe-area-inset-top, 0px);
    transform: translateX(-100%);
    transition: transform var(--duration) var(--ease);
    box-shadow: var(--shadow-3);
    visibility: hidden;
  }
  .pl-app[data-nav="open"] .pl-sidebar { transform: none; visibility: visible; }
  /* En tiroir, on montre toujours les libellés. */
  .pl-app .pl-sidebar .pl-logo__name,
  .pl-app .pl-sidebar .pl-nav__section,
  .pl-app .pl-sidebar .pl-sidebar__host { display: revert; }
  .pl-app[data-sidebar="collapsed"] .pl-nav__label { position: static; width: auto; height: auto; clip: auto; }
  .pl-app[data-sidebar="collapsed"] .pl-nav__link { justify-content: flex-start; padding: var(--space-1) var(--space-3); }
  .pl-sidebar__collapse { display: none !important; }

  .pl-topbar { padding: 0 max(var(--space-3), env(safe-area-inset-right, 0px)) 0 max(var(--space-3), env(safe-area-inset-left, 0px)); top: env(safe-area-inset-top, 0px); }
  .pl-topbar .pl-topbar__menu { display: inline-flex; }
  .pl-topbar__search { display: none; }
  .pl-topbar__search-btn { display: inline-flex !important; }
  .pl-account__name { display: none; }

  .pl-page {
    padding: var(--space-4) max(var(--space-4), env(safe-area-inset-right, 0px)) calc(var(--space-12) + 4rem) max(var(--space-4), env(safe-area-inset-left, 0px));
    gap: var(--space-4);
  }
  .pl-page-header__actions { width: 100%; }
  .pl-hide-md { display: none !important; }

  .pl-tabbar {
    position: fixed;
    inset: auto 0 0 0;
    z-index: var(--z-sticky);
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
    background: var(--surface);
    border-top: var(--border-w) solid var(--border);
  }
  .pl-tabbar__item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 3.5rem;
    padding: var(--space-1) 2px;
    border: 0;
    background: transparent;
    color: var(--text-3);
    font-size: var(--text-2xs);
    font-weight: var(--weight-medium);
    text-decoration: none;
    text-align: center;
    line-height: 1.15;
  }
  .pl-tabbar__item .pl-icon { width: var(--icon-lg); height: var(--icon-lg); }
  .pl-tabbar__item[aria-current="page"] { color: var(--brand); }
  .pl-tabbar__item[aria-current="page"]::before {
    content: ""; position: absolute; top: 0; left: 25%; right: 25%; height: 2px; background: var(--brand); border-radius: 0 0 2px 2px;
  }
  .pl-tabbar__badge {
    position: absolute;
    top: 6px;
    left: calc(50% + 4px);
    min-width: 1rem;
    padding: 0 3px;
    border-radius: var(--radius-pill);
    background: var(--danger-solid);
    color: var(--on-danger);
    font-size: 0.625rem;
    font-weight: var(--weight-semibold);
    line-height: 1rem;
  }
}
@media (min-width: 56.0625rem) {
  .pl-scrim { display: none; }
  .pl-topbar__search-btn { display: none !important; }
}

/* ---- Écrans d'authentification ------------------------------------------- */
.pl-auth {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: var(--space-6) max(var(--space-4), env(safe-area-inset-right, 0px)) var(--space-4) max(var(--space-4), env(safe-area-inset-left, 0px));
  background: var(--bg);
}
.pl-auth__main { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-5); }
.pl-auth__brand { display: flex; align-items: center; gap: var(--space-2); font-weight: var(--weight-semibold); }
.pl-auth__card {
  width: min(24rem, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.pl-auth__title { font-size: var(--text-xl); }
.pl-auth__lead { color: var(--text-2); font-size: var(--text-sm); }
.pl-auth__host { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius); background: var(--surface-2); font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-2); }
.pl-auth__footer { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: var(--space-3); font-size: var(--text-xs); color: var(--text-3); }
/* Code à usage unique : un seul champ, chiffres espacés */
.pl-otp {
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  letter-spacing: 0.5em;
  text-align: center;
  padding-left: 0.5em;
  min-height: 3.25rem;
}
@media (max-width: 40rem) {
  .pl-auth__card { padding: var(--space-5) var(--space-4); border: 0; background: transparent; box-shadow: none; }
}

/* ===== components.css ===== */
/* ==========================================================================
   PanneauLinux — components.css
   Sommaire
     1.  Boutons et groupes
     2.  États : badge, pastille, étiquette
     3.  Cartes et cartes de statistiques
     4.  Liste de propriétés
     5.  Jauges
     6.  Chronologie
     7.  Chaîne d'entités
     8.  Tableau dense (et cartes mobiles)
     9.  Barre d'outils, filtres, contrôle segmenté
     10. Onglets
     11. Pagination
     12. États vides, chargement, erreur
     13. Menu d'actions
     14. Fenêtres de confirmation
     15. Notifications temporaires
     16. Alertes et bandeaux
     17. Formulaires
     18. Assistant en étapes
   ========================================================================== */


/* 1. BOUTONS ================================================================ */

.pl-button {
  --_bg: var(--surface);
  --_fg: var(--text);
  --_bd: var(--border-strong);
  --_bg-hover: var(--surface-2);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  padding: 0 var(--space-3);
  border: var(--border-w) solid var(--_bd);
  border-radius: var(--radius);
  background: var(--_bg);
  color: var(--_fg);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.pl-button:hover { background: var(--_bg-hover); color: var(--_fg); }
.pl-button:active { transform: translateY(1px); }

.pl-button--primary { --_bg: var(--primary); --_fg: var(--on-primary); --_bd: var(--primary); --_bg-hover: var(--primary-hover); }
.pl-button--ghost   { --_bg: transparent; --_bd: transparent; --_fg: var(--text-2); --_bg-hover: var(--surface-2); }
.pl-button--ghost:hover { --_fg: var(--text); }
.pl-button--danger  { --_bg: var(--danger-solid); --_fg: var(--on-danger); --_bd: var(--danger-solid); --_bg-hover: var(--danger-solid-hover); }
/* Destructeur secondaire : déclenche une confirmation, ne détruit jamais directement. */
.pl-button--danger-outline { --_fg: var(--danger); --_bd: var(--danger-border); --_bg-hover: var(--danger-bg); }
.pl-button--link { --_bg: transparent; --_bd: transparent; --_fg: var(--brand); --_bg-hover: transparent; padding: 0; min-height: auto; text-decoration: underline; text-underline-offset: 2px; }

.pl-button--sm { min-height: var(--control-h-sm); padding: 0 var(--space-2); font-size: var(--text-sm); gap: var(--space-1); }
.pl-button--lg { min-height: var(--control-h-lg); padding: 0 var(--space-4); }
.pl-button--block { display: flex; width: 100%; }

/* Bouton icône : toujours un aria-label (et title pour la bulle native). */
.pl-button--icon { width: var(--control-h); padding: 0; flex: none; }
.pl-button--icon.pl-button--sm { width: var(--control-h-sm); }

.pl-button:disabled,
.pl-button[aria-disabled="true"] {
  --_bg: var(--surface-2);
  --_fg: var(--text-3);
  --_bd: var(--border);
  --_bg-hover: var(--surface-2);
  cursor: not-allowed;
  transform: none;
}

/* En cours : <button aria-busy="true" disabled> + icône loader-circle tournante.
   Le libellé change (« Redémarrage… ») : l'état n'est jamais signalé par l'icône seule. */
.pl-button[aria-busy="true"] { cursor: progress; }
/* Bouton bascule (suivi en direct, retour à la ligne) : aria-pressed="true" */
.pl-button[aria-pressed="true"] { --_bg: var(--brand-soft); --_fg: var(--brand); --_bd: var(--brand-border); --_bg-hover: var(--brand-soft); }
.pl-button[aria-busy="true"] .pl-icon { animation: pl-spin 1s linear infinite; }
.pl-button[aria-busy="true"].pl-button--primary,
.pl-button[aria-busy="true"].pl-button--danger { --_bg: var(--surface-3); --_fg: var(--text-2); --_bd: var(--border-strong); }

.pl-button__kbd { margin-left: var(--space-1); font-family: var(--font-mono); font-size: var(--text-2xs); opacity: 0.75; }

/* Groupe de boutons accolés */
.pl-button-group { display: inline-flex; isolation: isolate; }
.pl-button-group > .pl-button { border-radius: 0; }
.pl-button-group > .pl-button + .pl-button { margin-left: calc(-1 * var(--border-w)); }
.pl-button-group > .pl-button:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.pl-button-group > .pl-button:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.pl-button-group > .pl-button:hover, .pl-button-group > .pl-button:focus-visible { z-index: 1; }


/* 2. ÉTATS ================================================================== */
/* Une clé d'état (anglais, comme l'enum C#) → couleur + icône + libellé traduit.
   running · stopped · failed · pending · maintenance · unknown · warning · detected */

.pl-status {
  --_fg: var(--neutral);
  --_bg: var(--neutral-bg);
  --_bd: var(--neutral-border);
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  min-height: 1.375rem;
  padding: 0 var(--space-2) 0 0.375rem;
  border: var(--border-w) solid var(--_bd);
  border-radius: var(--radius-sm);
  background: var(--_bg);
  color: var(--_fg);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  white-space: nowrap;
  vertical-align: middle;
}
.pl-status .pl-icon { width: 0.875rem; height: 0.875rem; stroke-width: 2.25; }
.pl-status__since { font-weight: var(--weight-regular); opacity: 0.9; }
.pl-status__since::before { content: "· "; }

.pl-status--running     { --_fg: var(--success);  --_bg: var(--success-bg);  --_bd: var(--success-border); }
.pl-status--stopped     { --_fg: var(--neutral);  --_bg: var(--neutral-bg);  --_bd: var(--neutral-border); }
.pl-status--failed      { --_fg: var(--danger);   --_bg: var(--danger-bg);   --_bd: var(--danger-border); }
.pl-status--pending     { --_fg: var(--progress); --_bg: var(--progress-bg); --_bd: var(--progress-border); }
.pl-status--pending .pl-icon { animation: pl-spin 1.2s linear infinite; }
.pl-status--maintenance { --_fg: var(--maint);    --_bg: var(--maint-bg);    --_bd: var(--maint-border); }
.pl-status--unknown     { --_fg: var(--unknown);  --_bg: transparent;        --_bd: var(--unknown-border); border-style: dashed; }
.pl-status--warning     { --_fg: var(--warning);  --_bg: var(--warning-bg);  --_bd: var(--warning-border); }
.pl-status--detected    { --_fg: var(--detected); --_bg: var(--detected-bg); --_bd: var(--detected-border); border-style: dashed; }

/* Taille pour l'en-tête de fiche */
.pl-status--lg { min-height: 1.75rem; padding: 0 var(--space-3) 0 var(--space-2); font-size: var(--text-sm); }
.pl-status--lg .pl-icon { width: 1rem; height: 1rem; }

/* Pastille : point coloré + libellé visible ou sr-only. Jamais seule. */
.pl-dot {
  --_c: var(--neutral-dot);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-2);
  white-space: nowrap;
}
.pl-dot::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  flex: none;
  border-radius: 50%;
  background: var(--_c);
}
.pl-dot--running::before { --_c: var(--success-dot); }
.pl-dot--failed::before { --_c: var(--danger-dot); box-shadow: 0 0 0 3px var(--danger-bg); }
.pl-dot--pending::before { --_c: var(--progress-dot); animation: pl-pulse 1.4s var(--ease) infinite; }
.pl-dot--maintenance::before { --_c: var(--maint-dot); }
.pl-dot--warning::before { --_c: var(--warning-dot); border-radius: 1px; transform: rotate(45deg) scale(0.9); }
.pl-dot--unknown::before { background: transparent; border: 1.5px dashed var(--unknown-border); }
.pl-dot--detected::before { background: transparent; border: 1.5px dashed var(--detected-border); }
.pl-dot--stopped::before { border-radius: 1px; }
@keyframes pl-pulse { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .pl-dot--pending::before { animation: none; } }

/* Étiquette de métadonnée (technologie, base, environnement) : jamais un état. */
.pl-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 1.375rem;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: var(--border-w) solid var(--border);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.pl-tag .pl-icon { width: 0.8125rem; height: 0.8125rem; color: var(--text-3); }


/* 3. CARTES ================================================================= */

.pl-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
}
.pl-card__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-w) solid var(--border);
}
.pl-card__title { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-md); font-weight: var(--weight-semibold); }
.pl-card__title .pl-icon { color: var(--text-3); }
.pl-card__title .pl-count { font-weight: var(--weight-regular); color: var(--text-3); font-variant-numeric: tabular-nums; }
.pl-card__body { padding: var(--space-4); min-width: 0; }
.pl-card__body--flush { padding: 0; }
.pl-card__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-top: var(--border-w) solid var(--border);
  font-size: var(--text-sm);
  color: var(--text-3);
}

/* Liste dans une carte (sites en échec, certificats…) */
.pl-list { list-style: none; }
.pl-list__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: var(--border-w) solid var(--border);
}
.pl-list__item:first-child { border-top: 0; }
.pl-list__main { flex: 1 1 14rem; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pl-list__title { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: var(--weight-medium); overflow-wrap: anywhere; color: var(--text); text-decoration: none; }
a.pl-list__title:hover { text-decoration: underline; }
.pl-list__meta { font-size: var(--text-xs); color: var(--text-3); }
.pl-list__item--failed { background: var(--danger-bg); }

/* Statistique : le chiffre est la donnée ; l'icône et le libellé portent l'état. */
.pl-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4);
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
  min-width: 0;
  color: var(--text);
  text-decoration: none;
}
a.pl-stat:hover { border-color: var(--border-strong); color: var(--text); }
.pl-stat__label { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--text-2); font-weight: var(--weight-medium); }
.pl-stat__value { display: flex; align-items: baseline; gap: var(--space-2); font-size: var(--text-3xl); font-weight: var(--weight-semibold); line-height: 1.1; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.pl-stat__unit { font-size: var(--text-md); font-weight: var(--weight-regular); color: var(--text-3); letter-spacing: 0; }
.pl-stat__meta { font-size: var(--text-xs); color: var(--text-3); }
.pl-stat__icon {
  display: inline-grid; place-items: center;
  width: 1.5rem; height: 1.5rem;
  border-radius: var(--radius-sm);
  background: var(--neutral-bg); color: var(--neutral);
}
.pl-stat__icon .pl-icon { width: 0.875rem; height: 0.875rem; }
.pl-stat--running .pl-stat__icon { background: var(--success-bg); color: var(--success); }
.pl-stat--failed  .pl-stat__icon { background: var(--danger-bg);  color: var(--danger); }
.pl-stat--warning .pl-stat__icon { background: var(--warning-bg); color: var(--warning); }
/* Un compteur non nul en échec prend toute la carte : on le voit de loin. */
.pl-stat--failed.pl-stat--alert { background: var(--danger-bg); border-color: var(--danger-border); }
.pl-stat--failed.pl-stat--alert .pl-stat__value { color: var(--danger); }
.pl-stat--warning.pl-stat--alert { border-color: var(--warning-border); }
.pl-stat--warning.pl-stat--alert .pl-stat__value { color: var(--warning); }
.pl-stat .pl-meter { margin-top: var(--space-2); }

.pl-stats { display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }
@media (max-width: 40rem) {
  .pl-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pl-stat { padding: var(--space-3); }
  .pl-stat__value { font-size: var(--text-2xl); }
}


/* 4. LISTE DE PROPRIÉTÉS ===================================================== */
/* <dl class="pl-props"><div class="pl-props__row"><dt>…</dt><dd>…</dd></div></dl> */

.pl-props { margin: 0; display: flex; flex-direction: column; }
.pl-props__row {
  display: grid;
  grid-template-columns: minmax(8rem, 11rem) minmax(0, 1fr);
  gap: var(--space-1) var(--space-4);
  align-items: baseline;
  padding: var(--space-2) 0;
  border-top: var(--border-w) solid var(--border);
}
.pl-props__row:first-child { border-top: 0; padding-top: 0; }
.pl-props dt { color: var(--text-3); font-size: var(--text-sm); }
.pl-props dd { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; font-size: var(--text-sm); }
.pl-props__value--mono { font-family: var(--font-mono); font-size: var(--text-sm); overflow-wrap: anywhere; }
@media (max-width: 40rem) {
  .pl-props__row { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

/* Bouton copier minuscule à côté d'une valeur */
.pl-copy {
  display: inline-grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-3);
  flex: none;
}
.pl-copy:hover { background: var(--surface-2); color: var(--text); }
.pl-copy .pl-icon { width: 0.875rem; height: 0.875rem; }
.pl-copy[data-copied="true"] { color: var(--success); }
@media (pointer: coarse) { .pl-copy { width: 2.25rem; height: 2.25rem; } }


/* 5. JAUGES ================================================================== */
/* <div class="pl-meter pl-meter--warn">
     <div class="pl-meter__head"><span>Disque /</span><span>78 % · 62 / 80 Go</span></div>
     <div class="pl-meter__track" role="meter" aria-valuenow="78" aria-valuemin="0" aria-valuemax="100" aria-label="Disque /">
       <div class="pl-meter__fill" style="--value: 78%"></div></div></div>
   Seuils par défaut : < 70 % ok, 70–89 % warn, ≥ 90 % crit (le serveur pose la classe). */

.pl-meter { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.pl-meter__head { display: flex; justify-content: space-between; gap: var(--space-2); font-size: var(--text-sm); }
.pl-meter__head > :first-child { color: var(--text-2); }
.pl-meter__head > :last-child { font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; }
.pl-meter__track {
  position: relative;
  height: 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  overflow: hidden;
}
.pl-meter__fill {
  width: var(--value, 0%);
  height: 100%;
  border-radius: inherit;
  background: var(--text-3);
  transition: width var(--duration-slow) var(--ease);
}
.pl-meter--ok   .pl-meter__fill { background: var(--success-dot); }
.pl-meter--warn .pl-meter__fill { background: var(--warning-dot); }
.pl-meter--crit .pl-meter__fill { background: var(--danger-dot); }
/* Le niveau est aussi écrit : ajoute « Élevé » / « Critique » dans __head via .pl-meter__flag */
.pl-meter__flag { display: inline-flex; align-items: center; gap: 2px; margin-right: var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-semibold); }
.pl-meter--warn .pl-meter__flag { color: var(--warning); }
.pl-meter--crit .pl-meter__flag { color: var(--danger); }
.pl-meter--compact .pl-meter__track { height: 0.375rem; }
/* Jauge en ligne de tableau : barre courte + valeur */
.pl-meter-inline { display: inline-flex; align-items: center; gap: var(--space-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pl-meter-inline .pl-meter__track { width: 3rem; height: 0.375rem; }


/* 6. CHRONOLOGIE ============================================================= */

.pl-timeline { list-style: none; display: flex; flex-direction: column; }
.pl-timeline__item {
  position: relative;
  display: grid;
  grid-template-columns: 1.75rem minmax(0, 1fr);
  gap: var(--space-3);
  padding-bottom: var(--space-4);
}
.pl-timeline__item::before {
  content: "";
  position: absolute;
  left: calc(0.875rem - 0.5px);
  top: 1.75rem;
  bottom: 0;
  width: 1px;
  background: var(--border);
}
.pl-timeline__item:last-child { padding-bottom: 0; }
.pl-timeline__item:last-child::before { display: none; }
.pl-timeline__marker {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--surface-2);
  border: var(--border-w) solid var(--border);
  color: var(--text-2);
}
.pl-timeline__marker .pl-icon { width: 0.875rem; height: 0.875rem; }
.pl-timeline__marker--success { background: var(--success-bg); border-color: var(--success-border); color: var(--success); }
.pl-timeline__marker--danger  { background: var(--danger-bg);  border-color: var(--danger-border);  color: var(--danger); }
.pl-timeline__marker--warning { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning); }
.pl-timeline__marker--progress{ background: var(--progress-bg);border-color: var(--progress-border);color: var(--progress); }
.pl-timeline__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding-top: 0.1875rem; }
.pl-timeline__title { font-size: var(--text-sm); color: var(--text); }
.pl-timeline__title strong { font-weight: var(--weight-semibold); }
.pl-timeline__title code { overflow-wrap: anywhere; }
.pl-timeline__meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); font-size: var(--text-xs); color: var(--text-3); }
.pl-timeline__meta time { font-variant-numeric: tabular-nums; }
.pl-timeline__day {
  position: relative;
  margin: var(--space-2) 0 var(--space-3);
  padding-left: calc(1.75rem + var(--space-3));
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-3);
}
.pl-timeline__day:first-child { margin-top: 0; }


/* 7. CHAÎNE D'ENTITÉS ======================================================== */
/* domaine → Nginx → port → service → dossier → base. Chaque maillon peut porter un état. */

.pl-chain { list-style: none; display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--space-2); }
.pl-chain__node {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 9rem;
  max-width: 100%;
  padding: var(--space-2) var(--space-3);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.pl-chain__node + .pl-chain__node { margin-left: var(--space-4); }
.pl-chain__node + .pl-chain__node::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-4) - var(--space-2) - 1px);
  top: 50%;
  width: calc(var(--space-4) + var(--space-2));
  height: 1px;
  background: var(--border-strong);
}
.pl-chain__node + .pl-chain__node::after {
  content: "";
  position: absolute;
  left: -0.625rem;
  top: calc(50% - 3px);
  border: 3.5px solid transparent;
  border-left: 5px solid var(--border-strong);
}
.pl-chain__kind { display: flex; align-items: center; gap: var(--space-1); font-size: var(--text-2xs); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--text-3); }
.pl-chain__kind .pl-icon { width: 0.75rem; height: 0.75rem; }
.pl-chain__value { font-family: var(--font-mono); font-size: var(--text-sm); overflow-wrap: anywhere; color: var(--text); }
a.pl-chain__value { text-decoration: none; }
a.pl-chain__value:hover { text-decoration: underline; }
.pl-chain__state { margin-top: 2px; font-size: var(--text-xs); }
.pl-chain__node--failed { border-color: var(--danger-border); background: var(--danger-bg); }
.pl-chain__node--warning { border-color: var(--warning-border); }
/* Vertical : sur mobile, ou partout avec .pl-chain--vertical */
@media (max-width: 56rem) {
  .pl-chain { flex-direction: column; }
  .pl-chain__node { flex: none; }
  .pl-chain__node + .pl-chain__node { margin-left: 0; margin-top: var(--space-3); }
  .pl-chain__node + .pl-chain__node::before { left: var(--space-5); top: calc(-1 * var(--space-3) - var(--space-2)); width: 1px; height: calc(var(--space-3) + var(--space-2)); }
  .pl-chain__node + .pl-chain__node::after { left: calc(var(--space-5) - 3px); top: -6px; border: 3.5px solid transparent; border-top: 5px solid var(--border-strong); }
}


/* 8. TABLEAU DENSE =========================================================== */

.pl-table-wrap {
  position: relative;
  max-width: 100%;
  overflow: auto;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
/* En-tête fixe : donner une hauteur max au conteneur (ex. style="max-height: 70vh") */
.pl-table-wrap--scroll { max-height: min(70vh, 48rem); }
.pl-card > .pl-table-wrap { border: 0; border-radius: 0 0 var(--radius-lg) var(--radius-lg); }

.pl-table { width: 100%; font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.pl-table caption { text-align: left; padding: var(--space-3) var(--space-4); font-weight: var(--weight-semibold); }
.pl-table th, .pl-table td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
  vertical-align: middle;
  border-bottom: var(--border-w) solid var(--border);
}
.pl-table th:first-child, .pl-table td:first-child { padding-left: var(--space-4); }
.pl-table th:last-child, .pl-table td:last-child { padding-right: var(--space-4); }
.pl-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  box-shadow: inset 0 -1px 0 var(--border);
  border-bottom: 0;
}
.pl-table tbody tr:last-child td { border-bottom: 0; }
.pl-table tbody tr:hover { background: var(--surface-2); }
.pl-table td.pl-table__num, .pl-table th.pl-table__num { text-align: right; }
.pl-table__name { font-family: var(--font-mono); font-weight: var(--weight-medium); color: var(--text); white-space: nowrap; }
.pl-table__sub { display: block; font-family: var(--font-sans); font-size: var(--text-xs); font-weight: var(--weight-regular); color: var(--text-3); }
.pl-table__actions { width: 1%; white-space: nowrap; text-align: right; }
.pl-table__actions > .pl-cluster { flex-wrap: nowrap; justify-content: flex-end; gap: var(--space-1); }

/* Tri : <th aria-sort="ascending"><button class="pl-table__sort">Port <svg…/></button></th> */
.pl-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin: -2px -4px;
  padding: 2px 4px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  white-space: nowrap;
}
.pl-table__sort:hover { color: var(--text); background: var(--surface-3); }
.pl-table__sort .pl-icon { width: 0.75rem; height: 0.75rem; opacity: 0.55; }
th[aria-sort="ascending"] .pl-table__sort, th[aria-sort="descending"] .pl-table__sort { color: var(--text); }
th[aria-sort="ascending"] .pl-table__sort .pl-icon, th[aria-sort="descending"] .pl-table__sort .pl-icon { opacity: 1; }

/* Ligne cliquable : un vrai lien dans la 1re cellule, étendu à toute la ligne.
   Les boutons d'action restent cliquables au-dessus (z-index). */
.pl-table__row--link { position: relative; cursor: pointer; }
.pl-table__row--link .pl-table__rowlink { color: inherit; text-decoration: none; }
.pl-table__row--link .pl-table__rowlink::after { content: ""; position: absolute; inset: 0; }
.pl-table__row--link .pl-table__rowlink:focus-visible { outline: none; }
.pl-table__row--link:has(.pl-table__rowlink:focus-visible) { outline: var(--focus-w) solid var(--focus); outline-offset: -2px; }
.pl-table__row--link .pl-table__actions, .pl-table__row--link .pl-menu { position: relative; z-index: 2; }

/* Lignes d'état */
.pl-table__row--failed { background: var(--danger-bg); }
.pl-table__row--failed:hover { background: var(--danger-bg) !important; }
.pl-table__row--failed td:first-child { box-shadow: inset 3px 0 0 var(--danger-dot); }
.pl-table__row--detected td { background: transparent; }
.pl-table__row--detected .pl-table__name { color: var(--text-2); }
.pl-table__group th {
  position: static;
  padding: var(--space-2) var(--space-4);
  background: var(--surface);
  font-size: var(--text-xs);
  color: var(--text-2);
  text-transform: none;
  border-bottom: var(--border-w) solid var(--border);
  box-shadow: none;
}

.pl-table--compact th, .pl-table--compact td { padding-top: var(--space-1); padding-bottom: var(--space-1); }
/* Grille de résultats (console SQL) : tout en monospace, cellules bordées */
.pl-table--grid { font-family: var(--font-mono); font-size: var(--text-xs); }
.pl-table--grid th, .pl-table--grid td { border-right: var(--border-w) solid var(--border); padding: var(--space-1) var(--space-2); white-space: nowrap; }
.pl-table--grid th:first-child, .pl-table--grid td:first-child { padding-left: var(--space-2); color: var(--text-3); text-align: right; background: var(--surface-2); }
.pl-table--grid .pl-null { color: var(--text-3); font-style: italic; }

/* Mobile : chaque ligne devient une carte. Chaque <td> porte data-label="Port". */
@media (max-width: 40rem) {
  .pl-table--cards, .pl-table--cards tbody, .pl-table--cards tr, .pl-table--cards td { display: block; }
  .pl-table--cards thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .pl-table-wrap:has(.pl-table--cards) { border: 0; background: transparent; overflow: visible; }
  .pl-table--cards tbody { display: flex; flex-direction: column; gap: var(--space-2); }
  .pl-table--cards tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-3);
    border: var(--border-w) solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
  }
  .pl-table--cards tr.pl-table__row--failed { background: var(--danger-bg); border-color: var(--danger-border); box-shadow: inset 3px 0 0 var(--danger-dot); }
  .pl-table--cards tr.pl-table__row--failed td:first-child { box-shadow: none; }
  .pl-table--cards tr.pl-table__row--detected { border-style: dashed; border-color: var(--detected-border); }
  .pl-table--cards td { padding: 0 !important; border: 0; }
  .pl-table--cards td[data-label] { display: flex; justify-content: space-between; gap: var(--space-3); grid-column: 1 / -1; font-size: var(--text-sm); }
  .pl-table--cards td[data-label]::before { content: attr(data-label); color: var(--text-3); }
  .pl-table--cards td.pl-table__primary { grid-column: 1 / -1; }
  .pl-table--cards .pl-table__name { white-space: normal; overflow-wrap: anywhere; }
  .pl-table--cards td.pl-table__state { grid-column: 1 / -1; justify-self: start; margin-bottom: var(--space-1); }
  .pl-table--cards td.pl-table__state::before, .pl-table--cards td.pl-table__primary::before { content: none; }
  .pl-table--cards td.pl-table__actions { grid-column: 1 / -1; width: auto; margin-top: var(--space-2); padding-top: var(--space-2) !important; border-top: var(--border-w) solid var(--border); text-align: left; }
  .pl-table--cards td.pl-table__actions > .pl-cluster { justify-content: flex-start; flex-wrap: wrap; }
  .pl-table--cards td.pl-table__mobile-hide { display: none; }
  /* Sur mobile, les boutons icônes des actions affichent leur libellé (cibles plus sûres) */
  .pl-table--cards .pl-table__actions .pl-button--icon:not(summary) { width: auto; padding: 0 var(--space-3); }
  .pl-table--cards .pl-table__actions .pl-button--icon:not(summary) .pl-sr-only { position: static !important; width: auto; height: auto; margin: 0; clip: auto; overflow: visible; white-space: nowrap; }
  .pl-table--cards .pl-table__actions details.pl-menu { margin-left: auto; }
  .pl-table--cards .pl-table__group { display: block; }
  .pl-table--cards .pl-table__group th { display: block; padding: var(--space-3) 0 0; background: transparent; border: 0; }
}


/* 9. BARRE D'OUTILS, FILTRES, CONTRÔLE SEGMENTÉ ============================= */

.pl-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.pl-toolbar__grow { flex: 1 1 14rem; min-width: 0; }
.pl-toolbar__end { margin-left: auto; display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* Filtres en pastilles avec compteur : <button class="pl-chip" aria-pressed="true"> */
.pl-chips { display: flex; flex-wrap: wrap; gap: var(--space-1); }
@media (max-width: 40rem) {
  /* Filtres sur une ligne défilante : la liste reste visible sous le pouce */
  .pl-chips { flex-wrap: nowrap; overflow-x: auto; max-width: 100%; padding-bottom: 2px; scrollbar-width: none; }
  .pl-toolbar > .pl-chips { flex: 1 1 100%; min-width: 0; }
}
.pl-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--control-h-sm);
  padding: 0 var(--space-3);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  text-decoration: none;
}
.pl-chip:hover { border-color: var(--border-strong); color: var(--text); }
.pl-chip[aria-pressed="true"], .pl-chip[aria-current="true"] { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.pl-chip__count { font-variant-numeric: tabular-nums; color: var(--text-3); font-weight: var(--weight-regular); }
.pl-chip[aria-pressed="true"] .pl-chip__count, .pl-chip[aria-current="true"] .pl-chip__count { color: inherit; opacity: 0.75; }

.pl-segmented {
  display: inline-flex;
  padding: 2px;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.pl-segmented__option {
  display: inline-flex; align-items: center; gap: var(--space-1);
  min-height: calc(var(--control-h) - 6px);
  padding: 0 var(--space-3);
  border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-2);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  white-space: nowrap;
}
.pl-segmented__option[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-1); }


/* 10. ONGLETS ================================================================ */
/* Onglets = liens de navigation (une URL par onglet, rendu serveur). */

.pl-tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: var(--border-w) solid var(--border);
  overflow-x: auto;
  scrollbar-width: thin;
}
.pl-tabs__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-h-lg);
  padding: 0 var(--space-3);
  color: var(--text-2);
  font-weight: var(--weight-medium);
  text-decoration: none;
  white-space: nowrap;
}
.pl-tabs__link:hover { color: var(--text); }
.pl-tabs__link[aria-current="page"] { color: var(--text); }
.pl-tabs__link[aria-current="page"]::after { content: ""; position: absolute; left: var(--space-2); right: var(--space-2); bottom: -1px; height: 2px; background: var(--text); border-radius: 2px 2px 0 0; }
.pl-tabs__link .pl-icon { color: var(--text-3); }
.pl-tabs__count { font-size: var(--text-xs); color: var(--text-3); font-variant-numeric: tabular-nums; }
.pl-tabs__count--danger { color: var(--danger); font-weight: var(--weight-semibold); }


/* 11. PAGINATION ============================================================= */

.pl-pagination { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4); font-size: var(--text-sm); color: var(--text-2); }
.pl-pagination__pages { list-style: none; display: flex; align-items: center; gap: 2px; }
.pl-pagination__link {
  display: inline-grid; place-items: center;
  min-width: var(--control-h-sm); height: var(--control-h-sm);
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--text-2);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.pl-pagination__link:hover { background: var(--surface-2); color: var(--text); }
.pl-pagination__link[aria-current="page"] { background: var(--primary); color: var(--on-primary); font-weight: var(--weight-semibold); }
.pl-pagination__link[aria-disabled="true"] { color: var(--text-3); pointer-events: none; opacity: 0.6; }
.pl-pagination__gap { padding: 0 var(--space-1); color: var(--text-3); }
@media (max-width: 40rem) { .pl-pagination__page--far { display: none; } }


/* 12. ÉTATS VIDE / CHARGEMENT / ERREUR ======================================= */

.pl-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-6);
  max-width: 36rem;
}
.pl-empty--center { align-items: center; text-align: center; margin: 0 auto; }
.pl-empty__icon {
  display: grid; place-items: center;
  width: 2.5rem; height: 2.5rem;
  border-radius: var(--radius);
  border: var(--border-w) dashed var(--border-strong);
  color: var(--text-3);
}
.pl-empty__title { font-size: var(--text-md); font-weight: var(--weight-semibold); }
.pl-empty__text { color: var(--text-2); font-size: var(--text-sm); }
.pl-empty__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.pl-empty__cmd { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-2); background: var(--surface-2); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); }

.pl-error {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4);
  border: var(--border-w) solid var(--danger-border);
  border-radius: var(--radius-lg);
  background: var(--danger-bg);
  color: var(--text);
}
.pl-error > .pl-icon { color: var(--danger); margin-top: 2px; }
.pl-error__body { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.pl-error__title { font-weight: var(--weight-semibold); color: var(--danger); }
.pl-error__detail { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-2); overflow-wrap: anywhere; }

/* Squelettes : mêmes dimensions que le contenu final, aria-busy sur le conteneur. */
.pl-skeleton {
  display: block;
  height: 0.75rem;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--skeleton) 0%, var(--skeleton-hi) 50%, var(--skeleton) 100%);
  background-size: 200% 100%;
  animation: pl-shimmer 1.4s linear infinite;
}
.pl-skeleton--text { width: var(--w, 60%); }
.pl-skeleton--title { height: 1.125rem; width: var(--w, 40%); }
.pl-skeleton--badge { height: 1.375rem; width: 4.5rem; }
.pl-skeleton--block { height: var(--h, 4rem); }
@keyframes pl-shimmer { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .pl-skeleton { animation: none; } }

/* Spinner autonome (rare : préférer squelette ou bouton occupé) */
.pl-spinner { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text-2); font-size: var(--text-sm); }


/* 13. MENU D'ACTIONS ========================================================= */
/* <details class="pl-menu"><summary class="pl-button pl-button--ghost pl-button--icon" aria-label="Actions">…</summary>
     <div class="pl-menu__panel">…<button class="pl-menu__item">…</button></div></details>
   Fonctionne sans JS ; panneau.js ferme au clic extérieur et sur Échap. */

.pl-menu { position: relative; display: inline-block; }
.pl-menu > summary { list-style: none; }
.pl-menu > summary::-webkit-details-marker { display: none; }
.pl-menu[open] > summary { background: var(--surface-3); color: var(--text); }
.pl-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: var(--z-dropdown);
  min-width: 13rem;
  max-width: min(20rem, calc(100vw - 2rem));
  padding: var(--space-1);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-3);
  text-align: left;
}
.pl-menu--start .pl-menu__panel { left: 0; right: auto; }
.pl-menu--up .pl-menu__panel { top: auto; bottom: calc(100% + 4px); }
.pl-menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: var(--control-h);
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-size: var(--text-sm);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
}
.pl-menu__item:hover, .pl-menu__item:focus-visible { background: var(--surface-2); color: var(--text); outline-offset: -2px; }
.pl-menu__item .pl-icon { color: var(--text-3); }
.pl-menu__item kbd { margin-left: auto; }
.pl-menu__item--danger, .pl-menu__item--danger .pl-icon { color: var(--danger); }
.pl-menu__item--danger:hover { background: var(--danger-bg); color: var(--danger); }
.pl-menu__item:disabled { color: var(--text-3); cursor: not-allowed; background: transparent; }
.pl-menu__sep { height: 1px; margin: var(--space-1) calc(-1 * var(--space-1)); background: var(--border); border: 0; }
.pl-menu__label { padding: var(--space-1) var(--space-2); font-size: var(--text-xs); color: var(--text-3); }


/* 14. FENÊTRES DE CONFIRMATION =============================================== */
/* <dialog class="pl-dialog"> natif : focus piégé, Échap, inert du reste de la page. */

.pl-dialog {
  width: min(32rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  padding: 0;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-3);
  overflow: auto;
}
.pl-dialog::backdrop { background: var(--overlay); }
.pl-dialog[open] { animation: pl-dialog-in var(--duration) var(--ease-out); }
@keyframes pl-dialog-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } }
.pl-dialog__form { display: flex; flex-direction: column; margin: 0; }
.pl-dialog__header { display: flex; gap: var(--space-3); padding: var(--space-5) var(--space-5) 0; }
.pl-dialog__icon {
  display: grid; place-items: center; flex: none;
  width: 2.25rem; height: 2.25rem;
  border-radius: 50%;
  background: var(--neutral-bg); color: var(--neutral);
}
.pl-dialog--danger .pl-dialog__icon { background: var(--danger-bg); color: var(--danger); }
.pl-dialog--warning .pl-dialog__icon { background: var(--warning-bg); color: var(--warning); }
.pl-dialog__title { font-size: var(--text-lg); padding-top: var(--space-1); overflow-wrap: anywhere; }
.pl-dialog__body { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3) var(--space-5) var(--space-5); padding-left: calc(var(--space-5) + 2.25rem + var(--space-3)); color: var(--text-2); font-size: var(--text-sm); }
.pl-dialog__body strong, .pl-dialog__body code { color: var(--text); }
.pl-dialog__consequences { list-style: none; display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3); border-radius: var(--radius); background: var(--surface-2); }
.pl-dialog__consequences li { display: flex; gap: var(--space-2); align-items: flex-start; }
.pl-dialog__consequences .pl-icon { margin-top: 3px; color: var(--text-3); }
.pl-dialog__footer {
  display: flex;
  flex-wrap: wrap-reverse;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-top: var(--border-w) solid var(--border);
  background: var(--surface-2);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
/* Confirmation renforcée : champ « tapez le nom du site » */
.pl-confirm-phrase {
  display: block;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-3);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
  user-select: all;
}
@media (max-width: 40rem) {
  .pl-dialog { width: 100%; max-width: 100%; margin: auto 0 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0; max-height: 92dvh; }
  .pl-dialog__body { padding-left: var(--space-5); }
  .pl-dialog__footer { flex-direction: column-reverse; border-radius: 0; padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px)); }
  .pl-dialog__footer .pl-button { width: 100%; min-height: var(--control-h-lg); }
}


/* 15. NOTIFICATIONS TEMPORAIRES ============================================== */

.pl-toasts {
  position: fixed;
  right: calc(var(--space-4) + env(safe-area-inset-right, 0px));
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column-reverse;
  gap: var(--space-2);
  width: min(24rem, calc(100vw - 2rem));
  pointer-events: none;
}
.pl-toast {
  --_c: var(--progress);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-3);
  pointer-events: auto;
  animation: pl-toast-in var(--duration) var(--ease-out);
}
.pl-toast > .pl-icon { color: var(--_c); margin-top: 2px; }
.pl-toast--success { --_c: var(--success); }
.pl-toast--error { --_c: var(--danger); border-color: var(--danger-border); }
.pl-toast--info { --_c: var(--progress); }
.pl-toast__title { font-weight: var(--weight-semibold); font-size: var(--text-sm); }
.pl-toast__text { font-size: var(--text-sm); color: var(--text-2); overflow-wrap: anywhere; }
.pl-toast__actions { display: flex; gap: var(--space-3); margin-top: var(--space-1); }
.pl-toast__close { margin: -4px -4px 0 0; }
@keyframes pl-toast-in { from { opacity: 0; transform: translateY(8px); } }
@media (max-width: 56rem) {
  .pl-toasts { left: calc(var(--space-3) + env(safe-area-inset-left, 0px)); right: calc(var(--space-3) + env(safe-area-inset-right, 0px)); width: auto; bottom: calc(4.25rem + env(safe-area-inset-bottom, 0px)); }
}


/* 16. ALERTES ET BANDEAUX ==================================================== */

.pl-alert {
  --_fg: var(--progress); --_bg: var(--progress-bg); --_bd: var(--progress-border);
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border: var(--border-w) solid var(--_bd);
  border-radius: var(--radius);
  background: var(--_bg);
  color: var(--text);
  font-size: var(--text-sm);
}
.pl-alert > .pl-icon { color: var(--_fg); margin-top: 2px; }
.pl-alert { flex-wrap: wrap; }
.pl-alert__body { flex: 1 1 16rem; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pl-alert__title { font-weight: var(--weight-semibold); color: var(--_fg); }
.pl-alert__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin-left: auto; }
@media (max-width: 40rem) { .pl-alert__actions { margin-left: calc(var(--icon) + var(--space-3)); } }
.pl-alert--success { --_fg: var(--success); --_bg: var(--success-bg); --_bd: var(--success-border); }
.pl-alert--warning { --_fg: var(--warning); --_bg: var(--warning-bg); --_bd: var(--warning-border); }
.pl-alert--danger  { --_fg: var(--danger);  --_bg: var(--danger-bg);  --_bd: var(--danger-border); }
.pl-alert--info    { --_fg: var(--progress); --_bg: var(--progress-bg); --_bd: var(--progress-border); }

/* Bandeau : pleine largeur sous la barre supérieure, sans rayon, un par problème. */
.pl-banner { border-radius: 0; border-width: 0 0 var(--border-w); flex-wrap: wrap; align-items: center; padding-left: var(--space-6); padding-right: var(--space-4); }
.pl-banner .pl-alert__body { flex-direction: row; flex-wrap: wrap; column-gap: var(--space-2); }
.pl-alert__body code { overflow-wrap: anywhere; }
@media (max-width: 56rem) { .pl-banner { padding-left: var(--space-4); } }
@media (max-width: 40rem) {
  .pl-banner { padding-top: var(--space-2); padding-bottom: var(--space-2); row-gap: var(--space-2); font-size: var(--text-xs); }
  .pl-banner .pl-alert__body { flex-basis: calc(100% - 2rem); }
  .pl-banner .pl-alert__actions { flex-basis: 100%; padding-left: calc(var(--icon) + var(--space-3)); }
}


/* 17. FORMULAIRES ============================================================ */

.pl-form { display: flex; flex-direction: column; gap: var(--space-4); }
.pl-form__row { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.pl-form__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: flex-end; padding-top: var(--space-2); }

.pl-field { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.pl-field__label { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text); }
.pl-field__optional { font-weight: var(--weight-regular); color: var(--text-3); font-size: var(--text-xs); }
.pl-field__hint { font-size: var(--text-xs); color: var(--text-3); }
.pl-field__hint code { color: var(--text-2); }
.pl-field__error { display: flex; align-items: flex-start; gap: var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--danger); }
.pl-field__error .pl-icon { width: 0.875rem; height: 0.875rem; margin-top: 1px; }

.pl-input, .pl-select, .pl-textarea {
  width: 100%;
  min-height: var(--control-h);
  padding: 0 var(--space-3);
  border: var(--border-w) solid var(--border-control);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: var(--text-md);
  transition: border-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}
.pl-input::placeholder, .pl-textarea::placeholder { color: var(--text-3); opacity: 1; }
.pl-input:hover, .pl-select:hover, .pl-textarea:hover { border-color: var(--text-3); }
.pl-input:focus-visible, .pl-select:focus-visible, .pl-textarea:focus-visible { outline: none; border-color: var(--focus); box-shadow: 0 0 0 1px var(--focus); }
.pl-input[aria-invalid="true"], .pl-select[aria-invalid="true"], .pl-textarea[aria-invalid="true"] { border-color: var(--danger); box-shadow: 0 0 0 1px var(--danger); }
.pl-input:disabled, .pl-select:disabled, .pl-textarea:disabled { background: var(--surface-2); color: var(--text-3); border-color: var(--border); cursor: not-allowed; }
.pl-input[readonly] { background: var(--surface-2); }
.pl-input--mono, .pl-textarea--mono { font-family: var(--font-mono); font-size: var(--text-sm); }
.pl-input--sm { min-height: var(--control-h-sm); font-size: var(--text-sm); padding: 0 var(--space-2); }
.pl-textarea { min-height: 6rem; padding: var(--space-2) var(--space-3); line-height: var(--leading-normal); resize: vertical; }
.pl-select {
  appearance: none;
  padding-right: 2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-2) 50%), linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%;
  background-size: 5px 5px;
  background-repeat: no-repeat;
}

/* Champ avec préfixe / suffixe / bouton intégré */
.pl-input-group { position: relative; display: flex; align-items: stretch; }
.pl-input-group > .pl-input { flex: 1; min-width: 0; }
.pl-input-group > .pl-icon { position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%); color: var(--text-3); pointer-events: none; }
.pl-input-group > .pl-icon ~ .pl-input { padding-left: 2.25rem; }
.pl-input-group__addon {
  display: inline-flex; align-items: center;
  padding: 0 var(--space-3);
  border: var(--border-w) solid var(--border-control);
  background: var(--surface-2);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  white-space: nowrap;
}
.pl-input-group__addon:first-child { border-right: 0; border-radius: var(--radius) 0 0 var(--radius); }
.pl-input-group__addon:last-child { border-left: 0; border-radius: 0 var(--radius) var(--radius) 0; }
.pl-input-group__addon:first-child + .pl-input { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.pl-input-group .pl-input:has(+ .pl-input-group__addon) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
/* Bouton dans le champ (afficher le mot de passe, effacer) */
.pl-input-group__button { position: absolute; right: 2px; top: 2px; bottom: 2px; }
.pl-input-group__button .pl-button { height: 100%; min-height: 0; }
.pl-input-group:has(.pl-input-group__button) > .pl-input { padding-right: calc(var(--control-h) + var(--space-1)); }

/* Case à cocher et bouton radio : natifs, recolorés */
.pl-check { display: inline-flex; align-items: flex-start; gap: var(--space-2); font-size: var(--text-sm); cursor: pointer; }
.pl-check input { width: 1rem; height: 1rem; margin: 2px 0 0; flex: none; accent-color: var(--brand); cursor: pointer; }
.pl-check__text { display: flex; flex-direction: column; gap: 2px; }
.pl-check__hint { font-size: var(--text-xs); color: var(--text-3); }
.pl-check:has(input:disabled) { color: var(--text-3); cursor: not-allowed; }

/* Interrupteur : <label class="pl-switch"><input type="checkbox" role="switch"> <span class="pl-switch__track"></span> Libellé</label> */
.pl-switch { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); cursor: pointer; }
.pl-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.pl-switch__track {
  position: relative;
  width: 2.25rem; height: 1.25rem;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  border: var(--border-w) solid var(--border-control);
  transition: background var(--duration-fast) var(--ease);
}
.pl-switch__track::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 0.875rem; height: 0.875rem;
  border-radius: 50%;
  background: var(--text-2);
  transition: transform var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease);
}
.pl-switch input:checked + .pl-switch__track { background: var(--brand); border-color: var(--brand); }
.pl-switch input:checked + .pl-switch__track::after { transform: translateX(1rem); background: var(--surface); }
.pl-switch input:focus-visible + .pl-switch__track { outline: var(--focus-w) solid var(--focus); outline-offset: var(--focus-offset); }
.pl-switch input:disabled + .pl-switch__track { opacity: 0.5; }
/* Libellé d'état écrit à côté de l'interrupteur (jamais la couleur seule) */
.pl-switch__state { font-size: var(--text-xs); color: var(--text-3); min-width: 3.5em; }

/* Dépôt de fichier */
.pl-dropzone {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-4);
  border: var(--border-w-strong) dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  text-align: center;
  color: var(--text-2);
  font-size: var(--text-sm);
}
.pl-dropzone .pl-icon { width: 1.5rem; height: 1.5rem; color: var(--text-3); }
.pl-dropzone__input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.pl-dropzone:has(.pl-dropzone__input:focus-visible) { outline: var(--focus-w) solid var(--focus); outline-offset: var(--focus-offset); }
.pl-dropzone[data-dragover="true"] { border-color: var(--brand); background: var(--brand-soft); color: var(--text); }
.pl-dropzone[data-dragover="true"] .pl-icon { color: var(--brand); }
.pl-dropzone__title { font-weight: var(--weight-semibold); color: var(--text); }
.pl-dropzone__browse { color: var(--brand); text-decoration: underline; }

/* Fichier en cours d'envoi */
.pl-upload {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--space-1) var(--space-3);
  align-items: center;
  padding: var(--space-3);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.pl-upload > .pl-icon { color: var(--text-3); grid-row: span 2; }
.pl-upload__name { font-family: var(--font-mono); font-size: var(--text-sm); overflow-wrap: anywhere; }
.pl-upload__meta { grid-column: 2; display: flex; justify-content: space-between; gap: var(--space-2); font-size: var(--text-xs); color: var(--text-3); font-variant-numeric: tabular-nums; }
.pl-upload .pl-progress { grid-column: 2; }
.pl-upload--error { border-color: var(--danger-border); }
.pl-upload--error .pl-upload__meta { color: var(--danger); }

.pl-progress { height: 0.375rem; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.pl-progress__bar { height: 100%; width: var(--value, 0%); background: var(--brand); border-radius: inherit; transition: width var(--duration) var(--ease); }
.pl-progress--success .pl-progress__bar { background: var(--success-dot); }
.pl-progress--error .pl-progress__bar { background: var(--danger-dot); }
.pl-progress--indeterminate .pl-progress__bar { width: 35%; animation: pl-indeterminate 1.2s var(--ease) infinite; }
@keyframes pl-indeterminate { from { transform: translateX(-100%); } to { transform: translateX(300%); } }

.pl-fieldset { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.pl-fieldset legend { padding: 0; margin-bottom: var(--space-2); font-weight: var(--weight-semibold); font-size: var(--text-sm); }

/* Carte de choix (radio en carte) : assistant, choix de type de projet */
.pl-choice { position: relative; display: flex; gap: var(--space-3); padding: var(--space-3); border: var(--border-w) solid var(--border); border-radius: var(--radius); background: var(--surface); cursor: pointer; }
.pl-choice input { margin-top: 3px; accent-color: var(--brand); }
.pl-choice:has(input:checked) { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); background: var(--brand-soft); }
.pl-choice__title { font-weight: var(--weight-semibold); font-size: var(--text-sm); }
.pl-choice__text { font-size: var(--text-xs); color: var(--text-2); }


/* 18. ASSISTANT EN ÉTAPES ===================================================== */
/* <ol class="pl-wizard"><li class="pl-wizard__step pl-wizard__step--done">…</li> aria-current="step" sur l'étape courante */

.pl-wizard { list-style: none; display: flex; gap: var(--space-2); counter-reset: step; }
.pl-wizard__step {
  counter-increment: step;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-top: var(--space-2);
  border-top: 3px solid var(--border);
  color: var(--text-3);
  font-size: var(--text-xs);
}
.pl-wizard__step::before { content: counter(step) "/" attr(data-total); font-family: var(--font-mono); font-size: var(--text-2xs); }
.pl-wizard__label { font-size: var(--text-sm); font-weight: var(--weight-medium); line-height: 1.3; overflow-wrap: anywhere; }
.pl-wizard__step--done { border-top-color: var(--success-dot); color: var(--text-2); }
.pl-wizard__step--done .pl-wizard__label::after { content: " ✓"; color: var(--success); }
.pl-wizard__step[aria-current="step"] { border-top-color: var(--brand); color: var(--text); }
.pl-wizard__step--error { border-top-color: var(--danger-dot); color: var(--danger); }
@media (max-width: 40rem) {
  .pl-wizard__step:not([aria-current="step"]) .pl-wizard__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .pl-wizard__step[aria-current="step"] { flex: 4 1 0; }
}

/* ===== tools.css ===== */
/* ==========================================================================
   PanneauLinux — tools.css
   Outils techniques
     1. Visionneuse de journaux
     2. Cadre d'éditeur (Monaco)
     3. Comparaison (diff)
     4. Console SQL
     5. Exécution en étapes (déploiement, création de site)
     6. Explorateur de fichiers
   ========================================================================== */

/* Cadre commun : un panneau outil = barre d'outils + surface + barre d'état */
.pl-tool {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
}
.pl-tool__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-w) solid var(--border);
  background: var(--surface);
}
.pl-tool__title { display: flex; align-items: center; gap: var(--space-2); min-width: 0; font-family: var(--font-mono); font-size: var(--text-sm); font-weight: var(--weight-medium); overflow-wrap: anywhere; }
.pl-tool__title .pl-icon { color: var(--text-3); }
.pl-tool__spacer { flex: 1; }
.pl-tool__status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-4);
  padding: var(--space-1) var(--space-3);
  border-top: var(--border-w) solid var(--border);
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.pl-tool__status > span { display: inline-flex; align-items: center; gap: var(--space-1); }
.pl-tool__status .pl-icon { width: 0.75rem; height: 0.75rem; }


/* 1. VISIONNEUSE DE JOURNAUX ================================================= */
/* Chaque ligne : n° + horodatage + niveau ÉCRIT (info/warn/fail/crit/dbug) + message.
   Le niveau est lisible sans couleur. */

.pl-log { height: var(--log-h, 32rem); }
.pl-log--fill { height: calc(100dvh - 15rem); min-height: 22rem; }
.pl-log__search { flex: 1 1 14rem; max-width: 22rem; }
.pl-log__viewport {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: var(--log-bg);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-mono);
  tab-size: 4;
}
.pl-log__lines { list-style: none; padding: var(--space-2) 0; min-width: max-content; }
.pl-log--wrap .pl-log__lines { min-width: 0; }
.pl-log__line {
  display: grid;
  grid-template-columns: 3.75rem 12ch 4ch minmax(0, 1fr);
  column-gap: var(--space-3);
  padding: 0 var(--space-4) 0 0;
  color: var(--text);
  white-space: pre;
}
.pl-log--wrap .pl-log__line { white-space: pre-wrap; overflow-wrap: anywhere; }
.pl-log__line:hover { background: var(--surface-3); }
.pl-log__no {
  position: sticky; left: 0;
  padding-right: var(--space-2);
  text-align: right;
  color: var(--log-gutter);
  background: var(--log-bg);
  border-right: var(--border-w) solid var(--border);
  user-select: none;
  font-variant-numeric: tabular-nums;
}
.pl-log__line:hover .pl-log__no { background: var(--surface-3); }
.pl-log__ts { color: var(--log-ts); font-variant-numeric: tabular-nums; }
.pl-log__lvl { font-weight: var(--weight-semibold); min-width: 4ch; }
.pl-log__line--info  .pl-log__lvl { color: var(--log-info); }
.pl-log__line--debug .pl-log__lvl, .pl-log__line--debug .pl-log__msg { color: var(--log-debug); }
.pl-log__line--warn  { background: color-mix(in srgb, var(--warning-bg) 70%, transparent); }
.pl-log__line--warn  .pl-log__lvl { color: var(--log-warn); }
.pl-log__line--error { background: color-mix(in srgb, var(--danger-bg) 80%, transparent); }
.pl-log__line--error .pl-log__lvl, .pl-log__line--error .pl-log__msg { color: var(--log-error); }
.pl-log__line--error .pl-log__no { box-shadow: inset -3px 0 0 var(--danger-dot); }
.pl-log__line--warn .pl-log__no { box-shadow: inset -3px 0 0 var(--warning-dot); }
/* Pile d'exception / ligne de suite : décalée, sans niveau */
.pl-log__line--trace .pl-log__msg { padding-left: 4ch; color: var(--text-2); }
.pl-log__line--trace { background: color-mix(in srgb, var(--danger-bg) 45%, transparent); }
.pl-log__cat { color: var(--text-2); }
.pl-log mark { background: var(--warning-bg); color: var(--text); outline: 1px solid var(--warning-border); border-radius: 2px; }
.pl-log mark.is-current { background: var(--warning-dot); color: var(--text-inverse); }
/* Marqueur de suivi en direct en bas de la liste */
.pl-log__tail {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-4) var(--space-2) calc(3.75rem + var(--space-3));
  color: var(--text-3); font-size: var(--text-xs);
}
.pl-log__tail::before { content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--success-dot); animation: pl-pulse 1.4s var(--ease) infinite; }
.pl-log:not([data-follow="true"]) .pl-log__tail { display: none; }
/* Bouton « Revenir au direct » flottant quand l'utilisateur a remonté */
.pl-log__jump { position: absolute; right: var(--space-4); bottom: calc(var(--space-8) + var(--space-2)); box-shadow: var(--shadow-2); }
.pl-log { position: relative; }
@media (max-width: 40rem) {
  .pl-log__line { grid-template-columns: 2.75rem 4ch minmax(0, 1fr); column-gap: var(--space-2); font-size: var(--text-xs); }
  .pl-log__tail { padding-left: calc(2.75rem + var(--space-2)); }
  .pl-log__ts { display: none; }
  .pl-log--fill { height: calc(100dvh - 13rem); }
}


/* 2. CADRE D'ÉDITEUR (MONACO) ================================================ */

.pl-editor { min-height: 24rem; }
.pl-editor__surface {
  position: relative;
  flex: 1;
  min-height: var(--editor-h, 28rem);
  background: var(--log-bg);
}
/* Point de montage Monaco : monaco.editor.create(el, { automaticLayout: true }) */
.pl-editor__mount { position: absolute; inset: 0; }
/* Rendu de repli (avant chargement de Monaco / maquette) */
.pl-code {
  margin: 0;
  padding: var(--space-3) 0;
  overflow: auto;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-mono);
  color: var(--text);
  counter-reset: ln;
}
.pl-code__line { display: block; padding-right: var(--space-4); white-space: pre; }
.pl-code__line::before {
  counter-increment: ln;
  content: counter(ln);
  display: inline-block;
  width: 3rem;
  margin-right: var(--space-3);
  padding-right: var(--space-2);
  text-align: right;
  color: var(--log-gutter);
  border-right: var(--border-w) solid var(--border);
}
.pl-code .k { color: var(--code-key); }
.pl-code .s { color: var(--code-str); }
.pl-code .n { color: var(--code-num); }
.pl-code .c { color: var(--text-3); font-style: italic; }
.pl-editor__dirty { display: inline-flex; align-items: center; gap: var(--space-1); font-family: var(--font-sans); font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--warning); }
.pl-editor__dirty::before { content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--warning-dot); }


/* 3. COMPARAISON (DIFF) ====================================================== */

.pl-diff__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); background: var(--log-bg); overflow: auto; }
.pl-diff__side + .pl-diff__side { border-left: var(--border-w) solid var(--border); }
.pl-diff__head { position: sticky; top: 0; display: flex; justify-content: space-between; gap: var(--space-2); padding: var(--space-1) var(--space-3); background: var(--surface-2); border-bottom: var(--border-w) solid var(--border); font-size: var(--text-xs); color: var(--text-2); }
.pl-diff__head code { overflow-wrap: anywhere; }
.pl-diff__lines { list-style: none; padding: var(--space-1) 0; font-family: var(--font-mono); font-size: var(--text-sm); line-height: var(--leading-mono); }
.pl-diff__line { display: grid; grid-template-columns: 2.75rem 1.25rem minmax(0, 1fr); white-space: pre-wrap; overflow-wrap: anywhere; }
.pl-diff__no { padding-right: var(--space-2); text-align: right; color: var(--log-gutter); user-select: none; font-variant-numeric: tabular-nums; }
.pl-diff__sign { text-align: center; user-select: none; color: var(--text-3); }
.pl-diff__line--add { background: var(--diff-add-bg); }
.pl-diff__line--add .pl-diff__sign, .pl-diff__line--add .pl-diff__code { color: var(--diff-add-fg); }
.pl-diff__line--del { background: var(--diff-del-bg); }
.pl-diff__line--del .pl-diff__sign, .pl-diff__line--del .pl-diff__code { color: var(--diff-del-fg); }
.pl-diff__line--empty { background: repeating-linear-gradient(-45deg, transparent 0 4px, var(--surface-3) 4px 5px); }
.pl-diff__line--hunk { color: var(--text-3); background: var(--surface-2); font-size: var(--text-xs); }
.pl-diff__line--hunk .pl-diff__code { padding: 2px 0; }
.pl-diff__summary { display: inline-flex; gap: var(--space-2); font-family: var(--font-mono); font-size: var(--text-xs); }
.pl-diff__summary .add { color: var(--diff-add-fg); }
.pl-diff__summary .del { color: var(--diff-del-fg); }
@media (max-width: 56rem) {
  /* Sur petit écran : vue unifiée, colonne « après » seulement, suppressions incluses */
  .pl-diff__grid { grid-template-columns: minmax(0, 1fr); }
  .pl-diff__side--before { display: none; }
  .pl-diff__side + .pl-diff__side { border-left: 0; }
  .pl-diff__line--unified-del { display: grid !important; }
}
.pl-diff__line--unified-del { display: none; }


/* 4. CONSOLE SQL ============================================================= */

.pl-sql__query {
  display: block;
  width: 100%;
  min-height: 9rem;
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-bottom: var(--border-w) solid var(--border);
  background: var(--log-bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-mono);
  resize: vertical;
}
.pl-sql__query:focus-visible { outline: var(--focus-w) solid var(--focus); outline-offset: -2px; }
.pl-sql__results { max-height: 22rem; overflow: auto; }
.pl-sql__messages { list-style: none; padding: var(--space-3) var(--space-4); font-family: var(--font-mono); font-size: var(--text-xs); display: flex; flex-direction: column; gap: var(--space-1); }
.pl-sql__messages li { display: flex; gap: var(--space-2); }
.pl-sql__messages .ok { color: var(--success); }
.pl-sql__messages .err { color: var(--danger); }
.pl-sql__tabs { display: flex; gap: var(--space-1); padding: 0 var(--space-3); border-bottom: var(--border-w) solid var(--border); background: var(--surface); }
.pl-sql__tabs .pl-tabs__link { min-height: var(--control-h); font-size: var(--text-sm); }
.pl-sql__danger {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--warning-bg);
  border-bottom: var(--border-w) solid var(--warning-border);
  font-size: var(--text-xs); color: var(--text);
}
.pl-sql__danger .pl-icon { color: var(--warning); }


/* 5. EXÉCUTION EN ÉTAPES ===================================================== */
/* <ol class="pl-run"><li class="pl-run__step pl-run__step--done">…<details class="pl-run__output">…</details></li></ol> */

.pl-run { list-style: none; display: flex; flex-direction: column; }
.pl-run__step { position: relative; display: grid; grid-template-columns: 1.5rem minmax(0, 1fr); gap: 0 var(--space-3); padding: var(--space-2) 0; }
.pl-run__step::before { content: ""; position: absolute; left: calc(0.75rem - 0.5px); top: calc(var(--space-2) + 1.625rem); bottom: calc(-1 * var(--space-2) + 0.25rem); width: 1px; background: var(--border); }
.pl-run__step:last-child::before { display: none; }
.pl-run__icon {
  display: grid; place-items: center;
  width: 1.5rem; height: 1.5rem;
  border-radius: 50%;
  border: var(--border-w-strong) solid var(--border-strong);
  background: var(--surface);
  color: var(--text-3);
}
.pl-run__icon .pl-icon { width: 0.8125rem; height: 0.8125rem; stroke-width: 2.5; }
.pl-run__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-3); min-height: 1.5rem; }
.pl-run__name { font-size: var(--text-sm); font-weight: var(--weight-medium); }
.pl-run__state { font-size: var(--text-xs); color: var(--text-3); }
.pl-run__time { margin-left: auto; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-3); font-variant-numeric: tabular-nums; }
.pl-run__step--pending .pl-run__name { color: var(--text-3); }
.pl-run__step--running .pl-run__icon { border-color: var(--progress-dot); color: var(--progress); }
.pl-run__step--running .pl-run__icon .pl-icon { animation: pl-spin 1s linear infinite; }
.pl-run__step--running .pl-run__state { color: var(--progress); font-weight: var(--weight-semibold); }
.pl-run__step--done .pl-run__icon { border-color: var(--success-dot); background: var(--success-dot); color: var(--surface); }
.pl-run__step--done::before { background: var(--success-border); }
.pl-run__step--failed .pl-run__icon { border-color: var(--danger-dot); background: var(--danger-dot); color: var(--surface); }
.pl-run__step--failed .pl-run__state { color: var(--danger); font-weight: var(--weight-semibold); }
.pl-run__step--skipped .pl-run__icon { border-style: dashed; }
.pl-run__step--skipped .pl-run__name { color: var(--text-3); text-decoration: line-through; }
.pl-run__output { grid-column: 2; margin-top: var(--space-1); }
.pl-run__output > summary {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-xs); color: var(--text-2);
  cursor: pointer; list-style: none;
  border-radius: var(--radius-sm);
}
.pl-run__output > summary::-webkit-details-marker { display: none; }
.pl-run__output > summary .pl-icon { width: 0.75rem; height: 0.75rem; transition: transform var(--duration-fast) var(--ease); }
.pl-run__output[open] > summary .pl-icon { transform: rotate(90deg); }
.pl-run__output pre {
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  max-height: 16rem;
  overflow: auto;
  border-radius: var(--radius);
  background: var(--log-bg);
  border: var(--border-w) solid var(--border);
  font-size: var(--text-xs);
  line-height: var(--leading-mono);
  white-space: pre;
}
.pl-run__step--failed .pl-run__output pre { border-color: var(--danger-border); }
.pl-run__summary { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }


/* 6. EXPLORATEUR DE FICHIERS ================================================= */

.pl-files { display: grid; grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr); min-height: 24rem; }
.pl-files__tree { border-right: var(--border-w) solid var(--border); padding: var(--space-2); overflow: auto; background: var(--surface); }
.pl-files__list { min-width: 0; overflow: auto; }
.pl-tree, .pl-tree ul { list-style: none; }
.pl-tree ul { padding-left: var(--space-4); }
.pl-tree details > summary { list-style: none; }
.pl-tree details > summary::-webkit-details-marker { display: none; }
.pl-tree__item {
  display: flex; align-items: center; gap: var(--space-1);
  min-height: 1.75rem;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--text-2);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.pl-tree__item:hover { background: var(--surface-2); color: var(--text); }
.pl-tree__item[aria-current="true"] { background: var(--brand-soft); color: var(--brand); }
.pl-tree__item .pl-icon { color: var(--text-3); }
.pl-tree__chev { transition: transform var(--duration-fast) var(--ease); }
.pl-tree details[open] > summary .pl-tree__chev { transform: rotate(90deg); }
.pl-files__path { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; font-family: var(--font-mono); font-size: var(--text-sm); min-width: 0; }
.pl-files__path a { color: var(--text-2); text-decoration: none; padding: 0 2px; border-radius: var(--radius-sm); }
.pl-files__path a:hover { color: var(--text); background: var(--surface-2); }
.pl-files__path span { color: var(--text-3); }
.pl-perm { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-2); letter-spacing: 0.02em; }
.pl-file-name { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); color: var(--text); text-decoration: none; }
.pl-file-name .pl-icon { color: var(--text-3); }
.pl-file-name--dir .pl-icon { color: var(--brand); }
@media (max-width: 56rem) {
  .pl-files { grid-template-columns: minmax(0, 1fr); }
  .pl-files__tree { display: none; }
}
