/* ============================================================================
   SKYNETS UI — framework.css
   Framework CSS pur (zéro dépendance).
   Fonts : Inter (corps) + Bricolage Grotesque (titres, self-host) + JetBrains Mono (code).
   ----------------------------------------------------------------------------
   SOMMAIRE
   01. FONTS (self-host @font-face — 3 polices locales, latin + latin-ext)
   02. TOKENS — couleurs (rampes)
   03. TOKENS — radius / shadow / typo / spacing / z-index / transitions
   04. THEMES — sémantique light & dark
   05. RESET moderne
   06. BASE — éléments HTML
   07. TYPOGRAPHIE — classes
   08. UTILITIES — layout, spacing, couleurs, borders, effets
   09. ANIMATIONS — keyframes + classes
   ============================================================================ */

/* ============================================================================
   01. FONTS — self-host (100 % local, aucun appel réseau au runtime)
   Les 3 polices sont self-hostées : woff2 variables dans /fonts, sous-ensembles
   latin + latin-ext (couvre l'anglais et les langues européennes ; vietnamien /
   cyrillique / grec volontairement écartés). Le navigateur charge le fichier
   latin-ext seulement si un caractère le requiert (via unicode-range).
   Inter (corps) · Bricolage Grotesque (titres) · JetBrains Mono (code).
   ============================================================================ */
/* latin-ext */
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;src:url('fonts/Inter.latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:200 800;font-display:swap;src:url('fonts/BricolageGrotesque.latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;src:url('fonts/JetBrainsMono.latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;src:url('fonts/Inter.latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:200 800;font-display:swap;src:url('fonts/BricolageGrotesque.latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;src:url('fonts/JetBrainsMono.latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* ============================================================================
   02. TOKENS — couleurs (rampes brutes, indépendantes du thème)
   ============================================================================ */
:root{
  /* — Gris (échelle neutre) — */
  --gray-25:#fcfcfd; --gray-50:#f9fafb; --gray-100:#f2f4f7; --gray-200:#eaecf0;
  --gray-300:#d0d5dd; --gray-400:#98a2b3; --gray-500:#667085; --gray-600:#475467;
  --gray-700:#344054; --gray-800:#1d2939; --gray-900:#101828; --gray-950:#0c111d;

  /* — Bleu de marque — */
  --brand-25:#f5f8ff; --brand-50:#eff4ff; --brand-100:#d1e0ff; --brand-200:#b2ccff;
  --brand-300:#84adff; --brand-400:#528bff; --brand-500:#2970ff; --brand-600:#155eef;
  --brand-700:#004eeb; --brand-800:#0040c1; --brand-900:#00359e; --brand-950:#002266;

  /* — Sémantiques (rampes) — */
  --success-25:#f6fef9; --success-50:#ecfdf3; --success-100:#dcfae6; --success-300:#75e0a7;
  --success-500:#17b26a; --success-600:#079455; --success-700:#067647;
  --warning-25:#fffcf5; --warning-50:#fffaeb; --warning-100:#fef0c7; --warning-300:#fec84b;
  --warning-500:#f79009; --warning-600:#dc6803; --warning-700:#b54708;
  --error-25:#fffbfa; --error-50:#fef3f2; --error-100:#fee4e2; --error-300:#fda29b;
  --error-500:#f04438; --error-600:#d92d20; --error-700:#b42318;

  /* — Couleurs additionnelles (palette étendue, pour badges/tags/graphs) — */
  --purple-500:#7a5af8; --purple-700:#5925dc; --purple-50:#f4f3ff;
  --pink-500:#ee46bc;   --pink-50:#fdf2fa;
  --teal-500:#15b79e;   --teal-50:#f0fdf9;
  --orange-500:#ef6820; --orange-50:#fff4ed;
  --cyan-500:#06aed4;   --cyan-50:#ecfdff;
}

/* ============================================================================
   03. TOKENS — radius / shadow / typo / spacing / z-index / transitions
   ============================================================================ */
:root{
  /* Radius */
  --radius-xs:4px; --radius-sm:6px; --radius-md:8px; --radius-lg:10px;
  --radius-xl:12px; --radius-2xl:16px; --radius-3xl:20px; --radius-full:9999px;

  /* Shadows (light par défaut, surchargées en dark) */
  --shadow-xs:0 1px 2px rgba(16,24,40,.05);
  --shadow-sm:0 1px 3px rgba(16,24,40,.1),0 1px 2px rgba(16,24,40,.06);
  --shadow-md:0 4px 8px -2px rgba(16,24,40,.1),0 2px 4px -2px rgba(16,24,40,.06);
  --shadow-lg:0 12px 16px -4px rgba(16,24,40,.08),0 4px 6px -2px rgba(16,24,40,.03);
  --shadow-xl:0 20px 24px -4px rgba(16,24,40,.08),0 8px 8px -4px rgba(16,24,40,.03);
  --shadow-2xl:0 24px 48px -12px rgba(16,24,40,.18);

  /* Typo */
  --font-display:'Bricolage Grotesque',var(--font-sans);
  --font-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --text-xs:.75rem;   --lh-xs:1.125rem;
  --text-sm:.875rem;  --lh-sm:1.25rem;
  --text-md:1rem;     --lh-md:1.5rem;
  --text-lg:1.125rem; --lh-lg:1.75rem;
  --text-xl:1.25rem;  --lh-xl:1.875rem;
  --text-2xl:1.5rem;  --lh-2xl:2rem;
  --text-3xl:1.875rem;--lh-3xl:2.375rem;
  --text-4xl:2.25rem; --lh-4xl:2.75rem;
  --text-5xl:3rem;    --lh-5xl:3.75rem;
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;

  /* Spacing (échelle 4px) */
  --sp-0:0; --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px;
  --sp-6:24px; --sp-8:32px; --sp-10:40px; --sp-12:48px; --sp-16:64px;
  --sp-20:80px; --sp-24:96px;

  /* Container */
  --container:1280px; --container-sm:640px; --container-md:768px; --container-lg:1024px;

  /* Z-index */
  --z-dropdown:1000; --z-sticky:1020; --z-overlay:1030; --z-modal:1040;
  --z-popover:1050; --z-toast:1060; --z-tooltip:1070;

  /* Transitions */
  --ease:cubic-bezier(.4,0,.2,1);
  --ease-out:cubic-bezier(0,0,.2,1);
  --ease-in:cubic-bezier(.4,0,1,1);
  --dur-fast:.12s; --dur:.18s; --dur-slow:.3s;
}

/* ============================================================================
   04. THEMES — tokens sémantiques
   ============================================================================ */
[data-theme="light"]{
  --background:var(--gray-25); --surface:#ffffff; --surface-2:var(--gray-50);
  --surface-hover:var(--gray-50); --surface-active:var(--gray-100);
  --foreground:var(--gray-900); --foreground-2:var(--gray-700);
  --muted:var(--gray-100); --muted-foreground:var(--gray-500);
  --border:var(--gray-200); --border-strong:var(--gray-300);
  --input:var(--gray-400); --ring:var(--brand-500);
  --primary:var(--brand-600); --primary-hover:var(--brand-700); --primary-foreground:#fff;
  --primary-subtle:var(--brand-50); --primary-subtle-fg:var(--brand-700);
  color-scheme:light;
}
[data-theme="dark"],
:root:has(.theme-toggle:checked){
  --background:var(--gray-950); --surface:var(--gray-900); --surface-2:var(--gray-800);
  --surface-hover:var(--gray-800); --surface-active:var(--gray-700);
  --foreground:var(--gray-50); --foreground-2:var(--gray-300);
  --muted:var(--gray-800); --muted-foreground:var(--gray-400);
  --border:var(--gray-800); --border-strong:var(--gray-700);
  --input:var(--gray-700); --ring:var(--brand-400);
  --primary:var(--brand-500); --primary-hover:var(--brand-400); --primary-foreground:#fff;
  --primary-subtle:color-mix(in srgb,var(--brand-500) 16%,transparent); --primary-subtle-fg:var(--brand-300);
  --shadow-xs:0 1px 2px rgba(0,0,0,.3);
  --shadow-sm:0 1px 3px rgba(0,0,0,.4);
  --shadow-md:0 4px 8px -2px rgba(0,0,0,.5);
  --shadow-lg:0 12px 16px -4px rgba(0,0,0,.5);
  --shadow-xl:0 20px 24px -4px rgba(0,0,0,.6);
  --shadow-2xl:0 24px 48px -12px rgba(0,0,0,.7);
  color-scheme:dark;
}
/* Auto : suit l'OS si pas de data-theme explicite */
@media (prefers-color-scheme:dark){
  :root:not([data-theme]){
    --background:var(--gray-950); --surface:var(--gray-900); --surface-2:var(--gray-800);
    --surface-hover:var(--gray-800); --surface-active:var(--gray-700);
    --foreground:var(--gray-50); --foreground-2:var(--gray-300);
    --muted:var(--gray-800); --muted-foreground:var(--gray-400);
    --border:var(--gray-800); --border-strong:var(--gray-700);
    --input:var(--gray-700); --ring:var(--brand-400);
    --primary:var(--brand-500); --primary-hover:var(--brand-400); --primary-foreground:#fff;
    --primary-subtle:color-mix(in srgb,var(--brand-500) 16%,transparent); --primary-subtle-fg:var(--brand-300);
    color-scheme:dark;
  }
}
/* En dark, l'élévation se lit mieux par une bordure plus claire que par l'ombre
   noire (qui se voit mal sur fond sombre). */
[data-theme=dark] .card,[data-theme=dark] .modal,[data-theme=dark] .dropdown-menu,
[data-theme=dark] .popover-panel,[data-theme=dark] .command,
:root:has(.theme-toggle:checked) .card,:root:has(.theme-toggle:checked) .modal,
:root:has(.theme-toggle:checked) .dropdown-menu,:root:has(.theme-toggle:checked) .popover-panel,
:root:has(.theme-toggle:checked) .command{border-color:var(--border-strong)}

/* ============================================================================
   05. RESET moderne
   ============================================================================ */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;scroll-behavior:smooth}
body{min-height:100vh;font-family:var(--font-sans);font-size:var(--text-md);
  line-height:var(--lh-md);color:var(--foreground);background:var(--background);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}
img,picture,video,canvas,svg{display:block;max-width:100%}
input,button,textarea,select{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:none}
a{color:inherit;text-decoration:none}
ul,ol{list-style:none}
h1,h2,h3,h4,h5,h6{font-weight:inherit;font-size:inherit}
table{border-collapse:collapse;width:100%}
:focus-visible{outline:2px solid var(--ring);outline-offset:2px}
/* Items dans des conteneurs overflow:hidden (menus, listes, calendrier) :
   anneau INTÉRIEUR pour qu'il ne soit pas rogné par le clipping du parent. */
.nav-item:focus-visible,.dropdown-item:focus-visible,.command-item:focus-visible,
.combobox-option:focus-visible,.page-btn:focus-visible,.cal-day:focus-visible,
.breadcrumb a:focus-visible{outline:none;box-shadow:0 0 0 2px var(--ring) inset}
::selection{background:color-mix(in srgb,var(--ring) 25%,transparent)}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* ============================================================================
   06. BASE — éléments HTML
   ============================================================================ */
hr{border:none;border-top:1px solid var(--border);margin:var(--sp-4) 0}
code,kbd,samp,pre{font-family:var(--font-mono);font-size:.9em}
code{background:var(--muted);padding:.15em .4em;border-radius:var(--radius-xs);font-size:.85em}
pre{background:var(--surface-2);padding:var(--sp-4);border-radius:var(--radius-lg);overflow-x:auto;border:1px solid var(--border)}
pre code{background:none;padding:0}
kbd{background:var(--surface);border:1px solid var(--border-strong);border-bottom-width:2px;border-radius:var(--radius-sm);padding:2px 6px;font-size:var(--text-xs)}
mark{background:var(--warning-100);color:var(--gray-900);padding:0 .2em;border-radius:2px}
small{font-size:.875em}
strong,b{font-weight:var(--fw-semibold);color:var(--foreground)}
em,i,cite,dfn,var{font-style:italic}
del,s{text-decoration:line-through;color:var(--muted-foreground)}
ins{text-decoration:underline;text-decoration-color:var(--success-500);text-underline-offset:2px}
abbr[title]{text-decoration:underline dotted;text-underline-offset:2px;cursor:help}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em} sub{bottom:-.25em}

/* ============================================================================
   07. TYPOGRAPHIE — classes
   ============================================================================ */
.display-2xl{font-family:var(--font-display);font-size:var(--text-5xl);line-height:var(--lh-5xl);font-weight:var(--fw-semibold);letter-spacing:-.02em}
.display-xl,.h1{font-family:var(--font-display);font-size:var(--text-4xl);line-height:var(--lh-4xl);font-weight:var(--fw-semibold);letter-spacing:-.02em}
.h2{font-family:var(--font-display);font-size:var(--text-3xl);line-height:var(--lh-3xl);font-weight:var(--fw-semibold);letter-spacing:-.02em}
.h3{font-family:var(--font-display);font-size:var(--text-2xl);line-height:var(--lh-2xl);font-weight:var(--fw-semibold);letter-spacing:-.01em}
.h4{font-family:var(--font-display);font-size:var(--text-xl);line-height:var(--lh-xl);font-weight:var(--fw-medium)}
.h5{font-family:var(--font-sans);font-size:var(--text-lg);line-height:var(--lh-lg);font-weight:var(--fw-semibold)}
.h6{font-family:var(--font-sans);font-size:var(--text-md);line-height:var(--lh-md);font-weight:var(--fw-semibold)}
.lead{font-size:var(--text-lg);line-height:var(--lh-lg);color:var(--foreground-2)}
.text-lg{font-size:var(--text-lg);line-height:var(--lh-lg)}
.text-md{font-size:var(--text-md);line-height:var(--lh-md)}
.text-sm{font-size:var(--text-sm);line-height:var(--lh-sm)}
.text-xs{font-size:var(--text-xs);line-height:var(--lh-xs)}
.text-mono{font-family:var(--font-mono)}
.text-muted{color:var(--muted-foreground)}
.text-brand{color:var(--primary)}
.eyebrow{font-size:var(--text-sm);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.06em;color:var(--muted-foreground)}
.fw-regular{font-weight:var(--fw-regular)} .fw-medium{font-weight:var(--fw-medium)}
.fw-semibold{font-weight:var(--fw-semibold)} .fw-bold{font-weight:var(--fw-bold)}
.ta-left{text-align:left} .ta-center{text-align:center} .ta-right{text-align:right}

/* ============================================================================
   08. UTILITIES — layout / spacing / couleurs / borders / effets
   (jeu volontairement réduit : le framework est composant-first)
   ============================================================================ */
/* Display */
.flex{display:flex} .inline-flex{display:inline-flex} .grid{display:grid}
.block{display:block} .inline-block{display:inline-block} .hidden{display:none}
/* Accessibilité : visible lecteurs d'écran uniquement */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* Flex */
.flex-col{flex-direction:column} .flex-wrap{flex-wrap:wrap}
.items-center{align-items:center} .items-start{align-items:flex-start} .items-end{align-items:flex-end}
.justify-center{justify-content:center} .justify-between{justify-content:space-between} .justify-end{justify-content:flex-end}
.flex-1{flex:1} .flex-shrink-0{flex-shrink:0}
/* Gap */
.gap-1{gap:var(--sp-1)} .gap-2{gap:var(--sp-2)} .gap-3{gap:var(--sp-3)}
.gap-4{gap:var(--sp-4)} .gap-6{gap:var(--sp-6)} .gap-8{gap:var(--sp-8)}
/* Grid helpers */
.grid-cols-2{grid-template-columns:repeat(2,1fr)} .grid-cols-3{grid-template-columns:repeat(3,1fr)}
.grid-cols-4{grid-template-columns:repeat(4,1fr)}
.grid-auto{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
/* Container */
.container{width:100%;max-width:var(--container);margin-inline:auto;padding-inline:var(--sp-6)}
/* Margin/padding (échelle courte) */
.m-0{margin:0} .mt-2{margin-top:var(--sp-2)} .mt-4{margin-top:var(--sp-4)} .mt-6{margin-top:var(--sp-6)} .mt-8{margin-top:var(--sp-8)}
.mb-2{margin-bottom:var(--sp-2)} .mb-4{margin-bottom:var(--sp-4)} .mb-6{margin-bottom:var(--sp-6)}
.p-4{padding:var(--sp-4)} .p-6{padding:var(--sp-6)} .p-8{padding:var(--sp-8)}
/* Width */
.w-full{width:100%} .max-w-sm{max-width:var(--container-sm)} .max-w-md{max-width:var(--container-md)}
/* Backgrounds */
.bg-surface{background:var(--surface)} .bg-muted{background:var(--muted)} .bg-brand{background:var(--primary);color:var(--primary-foreground)}
/* Borders */
.border{border:1px solid var(--border)} .border-t{border-top:1px solid var(--border)} .border-b{border-bottom:1px solid var(--border)}
.rounded-sm{border-radius:var(--radius-sm)} .rounded-md{border-radius:var(--radius-md)} .rounded-lg{border-radius:var(--radius-lg)}
.rounded-xl{border-radius:var(--radius-xl)} .rounded-full{border-radius:var(--radius-full)}
/* Shadows */
.shadow-xs{box-shadow:var(--shadow-xs)} .shadow-sm{box-shadow:var(--shadow-sm)} .shadow-md{box-shadow:var(--shadow-md)}
.shadow-lg{box-shadow:var(--shadow-lg)} .shadow-xl{box-shadow:var(--shadow-xl)}
/* Effets */
.glass{background:color-mix(in srgb,var(--surface) 75%,transparent);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.gradient-brand{background:linear-gradient(135deg,var(--brand-500),var(--brand-700))}
.gradient-text{width:fit-content;max-width:100%;background:linear-gradient(135deg,var(--brand-500),var(--purple-500));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.ring-brand{box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}

/* ============================================================================
   09. ANIMATIONS — keyframes + classes utilitaires
   ============================================================================ */
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes shimmer{to{background-position:-200% 0}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
@keyframes fade-in-up{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes scale-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}
@keyframes slide-in-right{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:translateX(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.anim-fade-in{animation:fade-in var(--dur) var(--ease)}
.anim-fade-in-up{animation:fade-in-up var(--dur-slow) var(--ease)}
.anim-scale-in{animation:scale-in var(--dur) var(--ease)}
.anim-pulse{animation:pulse 2s var(--ease) infinite}
.transition{transition:transform var(--dur) var(--ease),opacity var(--dur) var(--ease),background var(--dur) var(--ease),color var(--dur) var(--ease),border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.transition-colors{transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)}

/* ============================================================================
   10. FORMS — champs, sélecteurs, coches, switch, groupes
   Tailles sm / md (défaut) / lg. États focus / error / disabled / readonly.
   Coche, point radio et flèche de select dessinés en mask + currentColor
   pour suivre automatiquement le thème.
   ============================================================================ */

/* — Label / hint / messages — */
.label{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--text-sm);
  font-weight:var(--fw-medium);color:var(--foreground-2);margin-bottom:6px}
.label-required::after{content:"*";color:var(--error-500);font-weight:var(--fw-semibold)}
.label-optional{font-weight:var(--fw-regular);color:var(--muted-foreground)}
.hint{font-size:var(--text-sm);color:var(--muted-foreground);margin-top:6px}
.field-msg{display:flex;align-items:flex-start;gap:6px;font-size:var(--text-sm);line-height:1.35;margin-top:6px}
.field-msg[hidden]{display:none}/* l'attribut hidden doit l'emporter sur display:flex */
/* hauteur = une ligne de texte → l'icône reste sur la 1re ligne quand le message passe sur deux lignes */
.field-msg::before{content:"";width:14px;height:1.35em;flex-shrink:0;background:currentColor;
  -webkit-mask:var(--ico) center/contain no-repeat;mask:var(--ico) center/contain no-repeat}
.field-msg-error{color:var(--error-600);
  --ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v4M12 16h.01'/%3E%3C/svg%3E")}
.field-msg-success{color:var(--success-600);
  --ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")}
[data-theme=dark] .field-msg-error,:root:has(.theme-toggle:checked) .field-msg-error{color:var(--error-300)}
[data-theme=dark] .field-msg-success,:root:has(.theme-toggle:checked) .field-msg-success{color:var(--success-300)}

/* — Field : empilement vertical label + contrôle + aide — */
.field{display:flex;flex-direction:column}

/* — Input / Textarea / Select (socle commun) — */
.input,.textarea,.select{
  --field-h:40px; --field-px:12px; --field-fs:var(--text-sm);
  width:100%;min-height:var(--field-h);padding:0 var(--field-px);
  font-size:var(--field-fs);font-family:var(--font-sans);line-height:1.4;
  color:var(--foreground);background:var(--surface);
  border:1px solid var(--input);border-radius:var(--radius-md);
  box-shadow:var(--shadow-xs);
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.input{height:var(--field-h)}
.input::placeholder,.textarea::placeholder{color:var(--muted-foreground);opacity:1}
.input:hover,.textarea:hover,.select:hover{border-color:var(--border-strong)}
.input:focus,.textarea:focus,.select:focus{outline:none;border-color:var(--ring);
  box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}

/* — Tags input / multi-select (champ à jetons) — piloté par JS de page —
   conteneur type input ; jetons = .tag ; saisie inline + suggestions. */
.tags-input{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:var(--field-h,40px);
  padding:5px 8px;background:var(--surface);border:1px solid var(--input);border-radius:var(--radius-md);
  cursor:text;transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.tags-input:has(.tags-input-field:focus){border-color:var(--ring);box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}
.tags-input-field{flex:1;min-width:120px;border:none;outline:none;background:none;padding:4px 2px;
  font-family:inherit;font-size:var(--text-sm);color:var(--foreground)}
.tags-input-field::placeholder{color:var(--muted-foreground)}
.tags-input-wrap{position:relative}
.tags-suggest{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:var(--z-dropdown);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);
  padding:var(--sp-1);max-height:200px;overflow:auto;display:none}
.tags-suggest.is-open{display:block}
.tags-suggest-item{display:block;width:100%;text-align:left;padding:7px 10px;border:none;background:none;cursor:pointer;
  font-size:var(--text-sm);color:var(--foreground);border-radius:var(--radius-sm)}
.tags-suggest-item:hover,.tags-suggest-item.is-active{background:var(--surface-hover)}
.tags-suggest-empty{padding:7px 10px;font-size:var(--text-sm);color:var(--muted-foreground)}

/* Tailles */
.input-sm,.textarea-sm,.select-sm{--field-h:32px;--field-px:10px;--field-fs:var(--text-sm)}
.input-lg,.textarea-lg,.select-lg{--field-h:44px;--field-px:14px;--field-fs:var(--text-md)}
/* Textarea : hauteur libre */
.textarea{height:auto;min-height:88px;padding-top:9px;padding-bottom:9px;resize:vertical}
/* États */
.input:disabled,.textarea:disabled,.select:disabled,
.input[disabled],.textarea[disabled],.select[disabled]{
  background:var(--surface-2);color:var(--muted-foreground);
  cursor:not-allowed;box-shadow:none;border-color:var(--border)}
.input:read-only:not([type=date]):not([type=time]){background:var(--surface-2);box-shadow:none}
.input.is-error,.textarea.is-error,.select.is-error,
.input[aria-invalid=true],.textarea[aria-invalid=true],.select[aria-invalid=true]{border-color:var(--error-500)}
.input.is-error:focus,.textarea.is-error:focus,.select.is-error:focus,
.input[aria-invalid=true]:focus,.textarea[aria-invalid=true]:focus,.select[aria-invalid=true]:focus{
  box-shadow:0 0 0 4px color-mix(in srgb,var(--error-500) 18%,transparent)}
.input.is-success,.textarea.is-success,.select.is-success{border-color:var(--success-500)}

/* — Select natif stylé (flèche en mask currentColor) — */
.select{appearance:none;-webkit-appearance:none;-moz-appearance:none;
  padding-right:36px;cursor:pointer}
.select-wrap{position:relative;width:100%}
.select-wrap::after{content:"";position:absolute;top:50%;right:12px;transform:translateY(-50%);
  width:16px;height:16px;pointer-events:none;background:var(--muted-foreground);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center/contain no-repeat}

/* — Input avec icône / affixe interne — */
.input-affix{position:relative;display:flex;align-items:center;width:100%}
.input-affix .affix{position:absolute;display:flex;align-items:center;justify-content:center;
  width:20px;height:20px;color:var(--muted-foreground);pointer-events:none}
.input-affix .affix svg{width:18px;height:18px}
.input-affix .affix-start{left:12px}
.input-affix .affix-end{right:12px}
.input-affix:has(.affix-start) .input{padding-left:38px}
.input-affix:has(.affix-end) .input{padding-right:38px}
/* affixe cliquable (bouton clear, œil mot de passe…) */
.input-affix .affix-action{pointer-events:auto;cursor:pointer;border-radius:var(--radius-xs)}
.input-affix .affix-action:hover{color:var(--foreground-2)}

/* — Input group : champ + addon texte + bouton accolés — */
.input-group{display:flex;align-items:stretch;width:100%}
.input-group>*{position:relative}
.input-group .input,.input-group .select,.input-group .input-affix .input{box-shadow:none}
.input-group>*:not(:first-child){margin-left:-1px}
.input-group>*:not(:first-child) .input,.input-group>.input:not(:first-child),
.input-group>.select:not(:first-child),.input-group>.input-group-btn:not(:first-child),
.input-group>.input-addon:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}
.input-group>*:not(:last-child) .input,.input-group>.input:not(:last-child),
.input-group>.select:not(:last-child),.input-group>.input-group-btn:not(:last-child),
.input-group>.input-addon:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}
.input-group .input-affix{flex:1}
.input-group .input:focus,.input-group .select:focus{z-index:1}
.input-addon{display:inline-flex;align-items:center;padding:0 12px;white-space:nowrap;
  font-size:var(--text-sm);color:var(--muted-foreground);
  background:var(--surface-2);border:1px solid var(--input);border-radius:var(--radius-md)}
.input-group-btn{display:inline-flex;align-items:center;gap:6px;padding:0 14px;white-space:nowrap;
  font-size:var(--text-sm);font-weight:var(--fw-semibold);
  color:var(--primary-foreground);background:var(--primary);
  border:1px solid var(--primary);border-radius:var(--radius-md);cursor:pointer;
  transition:background var(--dur-fast) var(--ease)}
.input-group-btn:hover{background:var(--primary-hover);border-color:var(--primary-hover)}
.input-group-btn.is-neutral{color:var(--foreground-2);background:var(--surface);border-color:var(--input)}
.input-group-btn.is-neutral:hover{background:var(--surface-hover)}

/* — Checkbox & Radio (appearance:none, coche/point en background) — */
.checkbox,.radio{appearance:none;-webkit-appearance:none;flex-shrink:0;
  width:18px;height:18px;margin:0;display:inline-block;vertical-align:-3px;
  background:var(--surface);border:1px solid var(--input);
  box-shadow:var(--shadow-xs);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)}
.checkbox{border-radius:var(--radius-xs)}
.radio{border-radius:var(--radius-full)}
.checkbox:hover,.radio:hover{border-color:var(--brand-400)}
.checkbox:checked,.radio:checked{background:var(--primary);border-color:var(--primary)}
.checkbox:checked{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-size:13px;background-position:center;background-repeat:no-repeat}
.checkbox:indeterminate{background:var(--primary);border-color:var(--primary);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E");
  background-size:13px;background-position:center;background-repeat:no-repeat}
.radio:checked{background-image:radial-gradient(circle,#fff 0 32%,transparent 36%)}
.checkbox:disabled,.radio:disabled{background:var(--surface-2);border-color:var(--border);
  cursor:not-allowed;box-shadow:none}
.checkbox:disabled:checked,.radio:disabled:checked{background:var(--border-strong);border-color:var(--border-strong)}
.checkbox-lg,.radio-lg{width:20px;height:20px}

/* — Choice : input + label cliquable côte à côte — */
.choice{display:inline-flex;align-items:flex-start;gap:var(--sp-2);cursor:pointer;
  font-size:var(--text-sm);line-height:1.4;color:var(--foreground)}
.choice:has(:disabled){cursor:not-allowed;color:var(--muted-foreground)}
.choice .choice-text{display:flex;flex-direction:column;gap:2px}
.choice .choice-desc{font-size:var(--text-sm);color:var(--muted-foreground)}

/* — Choice card : option encadrée, sélection visible — */
.choice-card{align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.choice-card:hover{border-color:var(--border-strong)}
.choice-card:has(:checked){border-color:var(--primary);background:var(--primary-subtle)}
.choice-card:has(:focus-visible){box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}

/* — Switch — */
.switch{position:relative;display:inline-flex;align-items:center;flex-shrink:0;cursor:pointer}
.switch .switch-input{position:absolute;opacity:0;width:0;height:0}
.switch .switch-track{position:relative;width:36px;height:20px;border-radius:var(--radius-full);
  background:var(--border-strong);
  transition:background var(--dur) var(--ease)}
.switch .switch-track::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;
  background:#fff;border-radius:50%;box-shadow:var(--shadow-sm);
  transition:transform var(--dur) var(--ease)}
.switch .switch-input:checked+.switch-track{background:var(--primary)}
.switch .switch-input:checked+.switch-track::after{transform:translateX(16px)}
.switch .switch-input:focus-visible+.switch-track{box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}
.switch .switch-input:disabled+.switch-track{background:var(--muted);cursor:not-allowed}
.switch:has(:disabled){cursor:not-allowed}
.switch-lg .switch-track{width:44px;height:24px}
.switch-lg .switch-track::after{width:20px;height:20px}
.switch-lg .switch-input:checked+.switch-track::after{transform:translateX(20px)}

/* — Input file (zone simple, label stylé) — */
.file{display:inline-flex;align-items:center;gap:var(--sp-2);padding:0 14px;height:40px;
  font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--foreground-2);
  background:var(--surface);border:1px solid var(--input);border-radius:var(--radius-md);
  box-shadow:var(--shadow-xs);cursor:pointer;transition:background var(--dur-fast) var(--ease)}
.file:hover{background:var(--surface-hover);border-color:var(--border-strong)}
.file input[type=file],.file-drop input[type=file]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);opacity:0}
.file:has(:focus-visible){box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}
/* Dropzone simple (visuel only ; le vrai drag&drop est en phase JS) */
.file-drop{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  padding:var(--sp-8) var(--sp-6);text-align:center;cursor:pointer;
  color:var(--muted-foreground);background:var(--surface);
  border:1.5px dashed var(--border-strong);border-radius:var(--radius-lg);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.file-drop:hover{border-color:var(--brand-400);background:var(--surface-hover)}
.file-drop .file-drop-icon{width:40px;height:40px;display:grid;place-items:center;
  color:var(--primary);background:var(--primary-subtle);border-radius:var(--radius-full)}
.file-drop strong{color:var(--foreground-2);font-weight:var(--fw-medium)}

/* — Drop zone (drag & drop réel + preview, piloté par JS de page) —
   .dropzone (clic + glisser) ; état .is-dragover ; liste .dropzone-files. */
.dropzone{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  padding:var(--sp-8) var(--sp-6);text-align:center;cursor:pointer;color:var(--muted-foreground);
  background:var(--surface-2);border:1.5px dashed var(--border-strong);border-radius:var(--radius-lg);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.dropzone:hover{border-color:var(--primary);background:var(--surface-hover)}
.dropzone.is-dragover{border-color:var(--primary);background:var(--primary-subtle);color:var(--primary-subtle-fg)}
.dropzone svg{width:36px;height:36px;color:var(--muted-foreground)}
.dropzone.is-dragover svg{color:var(--primary)}
.dropzone strong{color:var(--foreground);font-weight:var(--fw-semibold)}
.dropzone input[type=file]{display:none}
.dropzone-files{display:flex;flex-direction:column;gap:var(--sp-2);margin-top:var(--sp-3)}
.dropzone-file{display:flex;align-items:center;gap:var(--sp-3);padding:8px var(--sp-3);
  border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface)}
.dropzone-file-ico{width:32px;height:32px;flex:none;display:grid;place-items:center;border-radius:var(--radius-sm);
  color:var(--primary);background:var(--primary-subtle)}
.dropzone-file-ico svg{width:16px;height:16px;color:inherit}
.dropzone-file-name{font-size:var(--text-sm);color:var(--foreground);font-weight:var(--fw-medium);
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dropzone-file-size{font-size:var(--text-xs);color:var(--muted-foreground);margin-left:auto;white-space:nowrap}
.dropzone-file-x{flex:none;display:grid;place-items:center;width:26px;height:26px;border:none;background:none;
  cursor:pointer;color:var(--muted-foreground);border-radius:var(--radius-sm)}
.dropzone-file-x:hover{background:var(--surface-hover);color:var(--error-500)}
.dropzone-file-x svg{width:15px;height:15px}

/* — Fieldset / groupe de champs — */
.fieldset{border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-4)}
.fieldset>legend{padding:0 var(--sp-2);margin-left:calc(var(--sp-2) * -1);
  font-family:var(--font-sans);font-size:var(--text-md);font-weight:var(--fw-semibold);color:var(--foreground)}

/* — Date range picker (calendrier, JS maison) — */
.daterange{position:relative;display:inline-block}
.daterange-panel{position:absolute;top:calc(100% + 6px);left:0;z-index:var(--z-dropdown);
  display:flex;flex-direction:column;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-xl);box-shadow:var(--shadow-lg);
  overflow:hidden;animation:fade-in-up var(--dur) var(--ease)}
.daterange-panel[hidden]{display:none}
.daterange-body{display:flex}
.daterange-presets{display:flex;flex-direction:column;gap:2px;padding:var(--sp-3);
  border-right:1px solid var(--border);min-width:152px}
.daterange-preset{text-align:left;padding:8px 10px;border-radius:var(--radius-sm);
  font-size:var(--text-sm);color:var(--foreground-2);cursor:pointer;white-space:nowrap;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.daterange-preset:hover{background:var(--surface-hover);color:var(--foreground)}
.daterange-preset.is-active{background:var(--primary-subtle);color:var(--primary-subtle-fg);font-weight:var(--fw-medium)}
.daterange-cals{display:flex;gap:var(--sp-5);padding:var(--sp-4)}
.calendar{width:248px}
.cal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sp-2)}
.cal-title{font-family:var(--font-display);font-weight:var(--fw-semibold);font-size:var(--text-sm);color:var(--foreground)}
.cal-nav{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--radius-sm);color:var(--muted-foreground);cursor:pointer;background:none;border:0}
.cal-nav:hover{background:var(--surface-hover);color:var(--foreground)}
.cal-nav svg{width:16px;height:16px}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr)}
.cal-dow{font-size:11px;color:var(--muted-foreground);text-align:center;padding:6px 0;font-weight:var(--fw-medium)}
.cal-day{height:36px;display:inline-flex;align-items:center;justify-content:center;
  font-size:var(--text-sm);color:var(--foreground-2);cursor:pointer;background:none;border:0;
  border-radius:var(--radius-sm);transition:background var(--dur-fast) var(--ease)}
.cal-day:hover{background:var(--surface-hover)}
.cal-day.is-muted{color:var(--muted-foreground);opacity:.4}
.cal-day.is-today{font-weight:var(--fw-bold);color:var(--primary)}
.cal-day.in-range{background:var(--primary-subtle);border-radius:0;color:var(--primary-subtle-fg)}
.cal-day.is-start,.cal-day.is-end{background:var(--primary);color:#fff;border-radius:var(--radius-full);font-weight:var(--fw-semibold)}
.cal-day.is-start.in-range{border-radius:var(--radius-full)}
.cal-day:disabled{opacity:.3;cursor:not-allowed;background:none}
.daterange-trigger{justify-content:flex-start;font-weight:var(--fw-medium);min-width:240px}
.daterange-trigger .daterange-label{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.daterange-trigger .drp-caret{width:16px;height:16px;color:var(--muted-foreground)}
.daterange-compare{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-4);border-top:1px solid var(--border)}
.daterange-compare-info{font-size:var(--text-sm);color:var(--muted-foreground);margin-left:auto}
.daterange-foot{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);border-top:1px solid var(--border)}
.daterange-foot .daterange-current{font-size:var(--text-sm);color:var(--muted-foreground)}
@media (max-width:640px){
  .daterange-body{flex-direction:column}
  .daterange-presets{flex-direction:row;flex-wrap:wrap;border-right:none;border-bottom:1px solid var(--border)}
  .daterange-cals{flex-direction:column}
  .daterange-panel{max-width:calc(100vw - var(--sp-8))}
}

/* Dark mode : addon/file plus discrets */
[data-theme=dark] .input-addon,:root:has(.theme-toggle:checked) .input-addon{background:var(--surface-2)}

/* — Date / heure : icône du sélecteur visible en dark — */
[data-theme=dark] input[type=date]::-webkit-calendar-picker-indicator,
[data-theme=dark] input[type=time]::-webkit-calendar-picker-indicator,
[data-theme=dark] input[type=datetime-local]::-webkit-calendar-picker-indicator,
[data-theme=dark] input[type=month]::-webkit-calendar-picker-indicator,
[data-theme=dark] input[type=week]::-webkit-calendar-picker-indicator,
:root:has(.theme-toggle:checked) input[type=date]::-webkit-calendar-picker-indicator,
:root:has(.theme-toggle:checked) input[type=time]::-webkit-calendar-picker-indicator,
:root:has(.theme-toggle:checked) input[type=datetime-local]::-webkit-calendar-picker-indicator,
:root:has(.theme-toggle:checked) input[type=month]::-webkit-calendar-picker-indicator,
:root:has(.theme-toggle:checked) input[type=week]::-webkit-calendar-picker-indicator{filter:invert(1) opacity(.7)}

/* — Range (slider) — */
.range{appearance:none;-webkit-appearance:none;width:100%;height:6px;padding:0;
  background:var(--muted);border-radius:var(--radius-full);outline:none;cursor:pointer;
  accent-color:var(--primary)}
.range::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;
  background:var(--primary);border:2px solid var(--surface);box-shadow:var(--shadow-sm);cursor:pointer}
.range::-moz-range-thumb{width:18px;height:18px;border:2px solid var(--surface);border-radius:50%;
  background:var(--primary);box-shadow:var(--shadow-sm);cursor:pointer}
.range:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 22%,transparent)}
.range:focus-visible::-moz-range-thumb{box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 22%,transparent)}
.range:disabled{opacity:.5;cursor:not-allowed}

/* — Input couleur — */
.input-color{appearance:none;-webkit-appearance:none;width:44px;height:40px;padding:4px;flex-shrink:0;
  background:var(--surface);border:1px solid var(--input);border-radius:var(--radius-md);
  box-shadow:var(--shadow-xs);cursor:pointer}
.input-color::-webkit-color-swatch-wrapper{padding:0}
.input-color::-webkit-color-swatch{border:none;border-radius:var(--radius-sm)}
.input-color::-moz-color-swatch{border:none;border-radius:var(--radius-sm)}

/* — Stepper numérique (− valeur +) — */
.stepper{display:inline-flex;align-items:stretch}
.stepper .input{text-align:center;border-radius:0;width:64px;box-shadow:none;-moz-appearance:textfield;appearance:textfield}
.stepper .input::-webkit-outer-spin-button,.stepper .input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.stepper .stepper-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;
  color:var(--foreground-2);background:var(--surface);border:1px solid var(--input);cursor:pointer;
  transition:background var(--dur-fast) var(--ease)}
.stepper .stepper-btn:hover{background:var(--surface-hover)}
.stepper .stepper-btn svg{width:16px;height:16px}
.stepper .stepper-btn:first-child{border-radius:var(--radius-md) 0 0 var(--radius-md)}
.stepper .stepper-btn:last-child{border-radius:0 var(--radius-md) var(--radius-md) 0}
.stepper .input{border-left:0;border-right:0}

/* — Label flottant — */
.field-float{position:relative}
.field-float>.input{height:56px;padding-top:22px;padding-bottom:6px}
.field-float>.textarea{padding-top:24px}
.field-float>label{position:absolute;left:13px;top:50%;transform:translateY(-50%);
  color:var(--muted-foreground);pointer-events:none;font-size:var(--text-sm);
  transition:top var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease),font-size var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.field-float>.input:focus+label,
.field-float>.input:not(:placeholder-shown)+label,
.field-float>.textarea:focus+label,
.field-float>.textarea:not(:placeholder-shown)+label{top:9px;transform:none;font-size:11px;font-weight:var(--fw-medium);color:var(--primary)}
.field-float>.textarea+label{top:14px;transform:none}

/* — Layouts de formulaire — */
.form-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--sp-4)}
.field-horizontal{display:grid;grid-template-columns:180px 1fr;align-items:center;gap:var(--sp-4)}
.field-horizontal>.label{margin-bottom:0}
/* si le contrôle de droite empile (champ + hint), aligner le label en haut */
.field-horizontal.field-top{align-items:start}
.field-horizontal.field-top>.label{padding-top:9px}
@media (max-width:600px){.field-horizontal{grid-template-columns:1fr;align-items:start;gap:6px}.field-horizontal.field-top>.label{padding-top:0}}

/* ============================================================================
   11. BUTTONS & ACTIONS — variantes, tailles, états, groupes, dropdown
   Socle .btn (marche sur <button> et <a>). Variantes suffixées. Tailles
   sm / md (défaut) / lg. Loading via .is-loading (spinner intégré, texte
   masqué sans saut de largeur). Dropdown en <details> + JS minimal.
   ============================================================================ */

/* — Socle — */
.btn{--btn-h:40px; --btn-px:16px; --btn-fs:var(--text-sm); --btn-gap:8px;
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  gap:var(--btn-gap);height:var(--btn-h);padding:0 var(--btn-px);
  font-family:var(--font-sans);font-size:var(--btn-fs);font-weight:var(--fw-semibold);
  line-height:1;white-space:nowrap;text-decoration:none;cursor:pointer;
  border:1px solid transparent;border-radius:var(--radius-md);
  user-select:none;-webkit-user-select:none;
  transition:background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease)}
.btn:active{transform:translateY(1px)}
.btn svg{width:18px;height:18px;flex-shrink:0}
.btn:disabled,.btn[disabled],.btn[aria-disabled=true]{
  cursor:not-allowed;opacity:.5;pointer-events:none;box-shadow:none;transform:none}

/* — Tailles — */
.btn-sm{--btn-h:32px;--btn-px:12px;--btn-gap:6px}
.btn-sm svg{width:16px;height:16px}
.btn-lg{--btn-h:44px;--btn-px:20px;--btn-fs:var(--text-md)}
.btn-xl{--btn-h:48px;--btn-px:22px;--btn-fs:var(--text-md)}

/* — Icon-only (carré) — */
.btn-icon{--btn-px:0;width:var(--btn-h);gap:0}

/* — Formes — */
.btn-pill{border-radius:var(--radius-full)}
.btn-square{border-radius:0}

/* — Bloc pleine largeur — */
.btn-block{display:flex;width:100%}

/* — Variantes — */
.btn-primary{background:var(--primary);color:var(--primary-foreground);border-color:var(--primary);box-shadow:var(--shadow-xs)}
.btn-primary:hover{background:var(--primary-hover);border-color:var(--primary-hover)}
.btn-primary:focus-visible{box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 35%,transparent)}

.btn-secondary{background:var(--surface);color:var(--foreground-2);border-color:var(--input);box-shadow:var(--shadow-xs)}
.btn-secondary:hover{background:var(--surface-hover);border-color:var(--border-strong)}

.btn-outline{background:transparent;color:var(--foreground-2);border-color:var(--border-strong)}
.btn-outline:hover{background:var(--surface-hover);color:var(--foreground)}

.btn-ghost{background:transparent;color:var(--foreground-2);border-color:transparent}
.btn-ghost:hover{background:var(--surface-hover);color:var(--foreground)}

.btn-destructive{background:var(--error-600);color:#fff;border-color:var(--error-600);box-shadow:var(--shadow-xs)}
.btn-destructive:hover{background:var(--error-700);border-color:var(--error-700)}
.btn-destructive:focus-visible{box-shadow:0 0 0 4px color-mix(in srgb,var(--error-500) 35%,transparent)}

.btn-subtle{background:var(--primary-subtle);color:var(--primary-subtle-fg);border-color:transparent}
.btn-subtle:hover{background:color-mix(in srgb,var(--primary) 16%,transparent)}

.btn-dark{background:var(--foreground);color:var(--background);border-color:var(--foreground);box-shadow:var(--shadow-xs)}
.btn-dark:hover{background:var(--foreground-2);border-color:var(--foreground-2)}

.btn-link{background:transparent;color:var(--primary);border-color:transparent;height:auto;padding:0;--btn-px:0}
.btn-link:hover{color:var(--primary-hover);text-decoration:underline;text-underline-offset:2px}

/* — Loading : texte masqué (largeur conservée) + spinner centré — */
.btn.is-loading{color:transparent!important;pointer-events:none}
.btn.is-loading>*{visibility:hidden}
.btn.is-loading::after{content:"";position:absolute;width:1.05em;height:1.05em;
  border:2px solid currentColor;border-right-color:transparent;border-radius:50%;
  animation:spin .6s linear infinite;
  color:var(--primary-foreground)}
.btn-secondary.is-loading::after,.btn-outline.is-loading::after,
.btn-ghost.is-loading::after,.btn-link.is-loading::after,.btn-subtle.is-loading::after{color:var(--foreground-2)}

/* — Button group (boutons accolés, bordures fusionnées) — */
.btn-group{display:inline-flex}
.btn-group .btn{border-radius:0;margin-left:-1px}
.btn-group .btn:first-child{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md);margin-left:0}
.btn-group .btn:last-child{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}
.btn-group .btn:hover,.btn-group .btn:focus-visible{z-index:1}

/* — Segmented control (CSS pur, radios cachées) — */
.segmented{display:inline-flex;gap:2px;padding:3px;background:var(--surface-2);
  border:1px solid var(--border);border-radius:var(--radius-md)}
.segmented label{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;
  font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--muted-foreground);
  border-radius:var(--radius-sm);cursor:pointer;white-space:nowrap;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.segmented label svg{width:16px;height:16px}
.segmented input{position:absolute;opacity:0;width:0;height:0}
.segmented label:hover{color:var(--foreground-2)}
.segmented label:has(input:checked){
  background:var(--surface);color:var(--foreground);box-shadow:var(--shadow-xs)}
.segmented label:has(input:focus-visible){box-shadow:0 0 0 3px color-mix(in srgb,var(--ring) 30%,transparent)}

/* — Dropdown (<details>) — */
.dropdown{position:relative;display:inline-block}
.dropdown>summary{list-style:none;cursor:pointer}
.dropdown>summary::-webkit-details-marker{display:none}
.dropdown>summary::marker{content:""}
.dropdown-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:var(--z-dropdown);
  min-width:200px;padding:var(--sp-1);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);animation:fade-in-up var(--dur) var(--ease)}
.dropdown-menu.menu-end{left:auto;right:0}
.dropdown-item{display:flex;align-items:center;gap:var(--sp-2);width:100%;
  padding:8px 10px;font-size:var(--text-sm);color:var(--foreground-2);text-align:left;
  border-radius:var(--radius-sm);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.dropdown-item svg{width:16px;height:16px;flex-shrink:0;color:var(--muted-foreground)}
.dropdown-item:hover{background:var(--surface-hover);color:var(--foreground)}
.dropdown-item.is-danger{color:var(--error-600)}
.dropdown-item.is-danger svg{color:var(--error-600)}
.dropdown-item.is-danger:hover{background:var(--error-50)}
[data-theme=dark] .dropdown-item.is-danger,:root:has(.theme-toggle:checked) .dropdown-item.is-danger{color:var(--error-300)}

/* — Centre de notifications (cloche + badge + panneau) — <details class="notif">.
   Même mécanique que .dropdown (ouverture native + JS clic-extérieur/Échap). */
.notif{position:relative;display:inline-block}
.notif>summary{list-style:none;cursor:pointer}
.notif>summary::-webkit-details-marker{display:none}
.notif>summary::marker{content:""}
.notif-trigger{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border:1px solid var(--border);border-radius:var(--radius-md);
  background:var(--surface);color:var(--foreground-2);transition:background var(--dur-fast) var(--ease)}
.notif>summary:hover .notif-trigger,.notif[open]>summary .notif-trigger{background:var(--surface-hover)}
.notif-trigger svg{width:20px;height:20px}
.notif-badge{position:absolute;top:-6px;right:-6px;min-width:18px;height:18px;padding:0 5px;
  display:grid;place-items:center;border-radius:var(--radius-full);background:var(--error-500);
  color:#fff;font-size:10px;line-height:1;font-weight:var(--fw-bold);border:2px solid var(--surface)}
.notif-panel{position:absolute;right:0;top:calc(100% + 8px);width:340px;z-index:var(--z-dropdown);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);overflow:hidden;animation:fade-in-up var(--dur) var(--ease)}
.notif-panel.panel-start{right:auto;left:0}
.notif-head{display:flex;align-items:center;justify-content:space-between;padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border)}
.notif-head-title{font-weight:var(--fw-semibold);color:var(--foreground)}
.notif-readall{border:none;background:none;color:var(--primary);font-size:var(--text-sm);font-weight:var(--fw-medium);cursor:pointer;padding:0}
.notif-readall:hover{text-decoration:underline}
.notif-list{max-height:340px;overflow-y:auto}
.notif-item{display:flex;align-items:flex-start;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--border);cursor:pointer;text-decoration:none;transition:background var(--dur-fast) var(--ease)}
.notif-item:last-child{border-bottom:none}
.notif-item:hover{background:var(--surface-hover)}
.notif-item.is-unread{background:var(--primary-subtle)}
.notif-ico{flex:none;width:32px;height:32px;display:grid;place-items:center;border-radius:var(--radius-full);background:var(--surface-2);color:var(--muted-foreground)}
.notif-ico svg{width:16px;height:16px}
.notif-ico.is-success{background:color-mix(in srgb,var(--success-500) 15%,transparent);color:var(--success-700)}
.notif-ico.is-warning{background:color-mix(in srgb,var(--warning-500) 16%,transparent);color:var(--warning-700)}
.notif-ico.is-error{background:color-mix(in srgb,var(--error-500) 14%,transparent);color:var(--error-700)}
.notif-body{flex:1;min-width:0}
.notif-title{font-size:var(--text-sm);color:var(--foreground-2);line-height:1.4}
.notif-title b{font-weight:var(--fw-semibold);color:var(--foreground)}
.notif-time{font-size:var(--text-xs);color:var(--muted-foreground);margin-top:2px}
.notif-dot{flex:none;width:8px;height:8px;border-radius:var(--radius-full);background:var(--primary);margin-top:6px}
.notif-item:not(.is-unread) .notif-dot{visibility:hidden}
.notif-foot{padding:var(--sp-2);text-align:center;border-top:1px solid var(--border)}
.notif-foot a{font-size:var(--text-sm);color:var(--primary);font-weight:var(--fw-medium)}
.notif-empty{padding:var(--sp-6);text-align:center;font-size:var(--text-sm);color:var(--muted-foreground)}
[data-theme=dark] .dropdown-item.is-danger svg,:root:has(.theme-toggle:checked) .dropdown-item.is-danger svg{color:var(--error-300)}
[data-theme=dark] .dropdown-item.is-danger:hover,:root:has(.theme-toggle:checked) .dropdown-item.is-danger:hover{background:color-mix(in srgb,var(--error-500) 16%,transparent)}
.dropdown-sep{height:1px;background:var(--border);margin:var(--sp-1) 0}
.dropdown-label{padding:6px 10px;font-size:var(--text-xs);font-weight:var(--fw-semibold);
  text-transform:uppercase;letter-spacing:.04em;color:var(--muted-foreground)}

/* ============================================================================
   12. DATA DISPLAY — badge, tag, avatar, table, list, rating, tooltip, stat
   Badges/tags subtils (fond clair + texte coloré), override translucide en
   dark. Tooltip 100% CSS (:hover / :focus-visible). Rating en étoiles SVG.
   ============================================================================ */

/* — Badge — */
.badge{display:inline-flex;align-items:center;gap:5px;
  padding:2px 9px;font-size:var(--text-xs);font-weight:var(--fw-medium);line-height:1.4;
  border-radius:var(--radius-full);white-space:nowrap;
  background:var(--muted);color:var(--foreground-2)}
.badge svg{width:12px;height:12px}
.badge-sm{padding:1px 7px;font-size:11px}
.badge-lg{padding:3px 11px;font-size:var(--text-sm)}
.badge-dot::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex-shrink:0}
/* Variantes de couleur */
.badge-brand{background:var(--primary-subtle);color:var(--primary-subtle-fg)}
.badge-success{background:var(--success-50);color:var(--success-700)}
.badge-warning{background:var(--warning-50);color:var(--warning-700)}
.badge-error{background:var(--error-50);color:var(--error-700)}
.badge-purple{background:var(--purple-50);color:var(--purple-700)}
.badge-outline{background:transparent;color:var(--foreground-2);box-shadow:inset 0 0 0 1px var(--border-strong)}
[data-theme=dark] .badge-success,:root:has(.theme-toggle:checked) .badge-success{background:color-mix(in srgb,var(--success-500) 16%,transparent);color:var(--success-300)}
[data-theme=dark] .badge-warning,:root:has(.theme-toggle:checked) .badge-warning{background:color-mix(in srgb,var(--warning-500) 16%,transparent);color:var(--warning-300)}
[data-theme=dark] .badge-error,:root:has(.theme-toggle:checked) .badge-error{background:color-mix(in srgb,var(--error-500) 16%,transparent);color:var(--error-300)}
[data-theme=dark] .badge-purple,:root:has(.theme-toggle:checked) .badge-purple{background:color-mix(in srgb,var(--purple-500) 20%,transparent);color:#c3b5fd}

/* — Tag (avec bouton fermer) — */
.tag{display:inline-flex;align-items:center;gap:6px;
  padding:3px 4px 3px 10px;font-size:var(--text-sm);font-weight:var(--fw-medium);
  color:var(--foreground-2);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-sm)}
.tag-close{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:16px;height:16px;border-radius:var(--radius-xs);color:var(--muted-foreground);
  cursor:pointer;transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.tag-close::after{content:"";position:absolute;inset:-8px} /* cible tactile ≥32px (WCAG 2.5.8) */
.tag-close:hover{background:var(--surface-active);color:var(--foreground)}
.tag-close svg{width:12px;height:12px}

/* — Avatar — */
.avatar{--av-size:40px;position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:var(--av-size);height:var(--av-size);flex-shrink:0;
  font-size:max(11px,calc(var(--av-size) * .4));font-weight:var(--fw-semibold);
  color:var(--primary-subtle-fg);background:var(--primary-subtle);
  border-radius:var(--radius-full);overflow:hidden;user-select:none}
.avatar img{width:100%;height:100%;object-fit:cover}
.avatar-xs{--av-size:24px} .avatar-sm{--av-size:32px}
.avatar-lg{--av-size:48px} .avatar-xl{--av-size:64px}
.avatar-square{border-radius:var(--radius-md)}
/* Indicateur de statut */
.avatar-status::after{content:"";position:absolute;right:0;bottom:0;
  width:28%;height:28%;border-radius:50%;background:var(--gray-400);
  box-shadow:0 0 0 2px var(--surface)}
.avatar-status.is-online::after{background:var(--success-500)}
.avatar-status.is-busy::after{background:var(--error-500)}
.avatar-status.is-away::after{background:var(--warning-500)}
/* Groupe (chevauchement) */
.avatar-group{display:inline-flex}
.avatar-group .avatar{box-shadow:0 0 0 2px var(--surface);margin-left:-10px}
.avatar-group .avatar:first-child{margin-left:0}
.avatar-group .avatar-more{background:var(--muted);color:var(--muted-foreground)}

/* — Table — */
.table-wrap{width:100%;overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-lg)}
.table{font-size:var(--text-sm)}
.table th,.table td{padding:12px 16px;text-align:left;vertical-align:middle}
.table thead th{font-size:var(--text-xs);font-weight:var(--fw-semibold);
  color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.03em;
  background:var(--surface-2);border-bottom:1px solid var(--border);white-space:nowrap}
.table tbody td{border-bottom:1px solid var(--border);color:var(--foreground-2)}
.table tbody tr:last-child td{border-bottom:none}
.table tbody tr{transition:background var(--dur-fast) var(--ease)}
.table-hover tbody tr:hover{background:var(--surface-hover)}
.table-striped tbody tr:nth-child(even){background:var(--surface-2)}
.table .td-strong{color:var(--foreground);font-weight:var(--fw-medium)}
.table .td-right{text-align:right}
.table .td-num{text-align:right;font-variant-numeric:tabular-nums}
.table tbody tr.is-selected{background:var(--primary-subtle)}
/* colonne case à cocher (serrée) */
.table .col-check{width:1px;white-space:nowrap;padding-right:0}

/* — Table responsive « empilée » (opt-in) —
   Sous 640px, chaque ligne devient une carte « intitulé : valeur » au lieu de colonnes
   serrées. Le CSS ne peut pas lire les <th>, donc chaque <td> DOIT porter
   data-label="Intitulé" ; une cellule d'action sans intitulé prend data-label="" (label
   masqué, contenu pleine largeur). Alternative au scroll horizontal de .table-wrap. */
@media (max-width:640px){
  .table-stack,.table-stack tbody,.table-stack tr,.table-stack td{display:block;width:auto}
  .table-stack thead{display:none}
  .table-stack tr{border:1px solid var(--border);border-radius:var(--radius-md);
    margin-bottom:var(--sp-3);padding:var(--sp-2) var(--sp-3);background:var(--surface)}
  .table-stack tbody td{border:none;padding:var(--sp-2) 0;
    display:flex;gap:var(--sp-3);align-items:flex-start;overflow-wrap:anywhere}
  .table-stack tbody td::before{content:attr(data-label);flex:0 0 40%;max-width:40%;
    color:var(--muted-foreground);font-size:var(--text-xs);font-weight:var(--fw-medium);
    text-transform:uppercase;letter-spacing:.03em}
  .table-stack tbody td[data-label=""]::before{content:none}
  .table-stack tbody td:empty{display:none}
}

/* — Data table avancé : colonnes redimensionnables + ligne dépliable + 1re colonne épinglée —
   (mécanique pilotée par le JS de page ; table-layout:fixed pour des largeurs nettes) */
.dtable-adv-wrap{width:100%;overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-lg)}
.dtable-adv{table-layout:fixed;border-collapse:separate;border-spacing:0;width:100%;min-width:720px;font-size:var(--text-sm)}
.dtable-adv th,.dtable-adv td{padding:11px 14px;text-align:left;vertical-align:middle;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-bottom:1px solid var(--border)}
.dtable-adv thead th{position:relative;background:var(--surface-2);color:var(--foreground-2);
  font-size:var(--text-xs);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.03em;user-select:none}
.dtable-adv tbody td{color:var(--foreground-2)}
.dtable-adv tbody tr.dt-main:hover{background:var(--surface-hover)}
.dtable-adv .td-strong{color:var(--foreground);font-weight:var(--fw-medium)}
/* 1re colonne épinglée (sticky) */
.dtable-adv .col-pin{position:sticky;left:0;z-index:1;background:var(--surface)}
.dtable-adv thead .col-pin{z-index:2;background:var(--surface-2)}
.dtable-adv tbody tr.dt-main:hover .col-pin{background:var(--surface-hover)}
.dtable-adv .col-pin::after{content:"";position:absolute;top:0;right:0;bottom:-1px;width:1px;background:var(--border)}
/* poignée de redimensionnement (bord droit des en-têtes) */
.dt-rsz{position:absolute;top:0;right:-4px;width:9px;height:100%;cursor:col-resize;z-index:3;touch-action:none}
.dt-rsz::before{content:"";position:absolute;left:4px;top:18%;bottom:18%;width:2px;border-radius:2px;
  background:transparent;transition:background var(--dur-fast) var(--ease)}
.dt-rsz:hover::before,.dtable-adv.is-resizing .dt-rsz::before{background:var(--primary)}
/* bouton déplier + ligne de détail */
.dt-exp{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-right:6px;
  border:none;background:none;cursor:pointer;color:var(--muted-foreground);border-radius:var(--radius-sm);vertical-align:middle}
.dt-exp:hover{background:var(--surface-hover);color:var(--foreground)}
.dt-exp svg{width:15px;height:15px;transition:transform var(--dur-fast) var(--ease)}
.dt-exp[aria-expanded=true] svg{transform:rotate(90deg)}
.dt-detail-row[hidden]{display:none}
.dt-detail-row>td{background:var(--surface-2);padding:0;border-bottom:1px solid var(--border)}
.dt-detail{padding:var(--sp-3) var(--sp-5);color:var(--muted-foreground);white-space:normal}
.dt-detail dl{display:grid;grid-template-columns:auto 1fr;gap:4px var(--sp-4);margin:0}
.dt-detail dt{color:var(--foreground);font-weight:var(--fw-medium)}
.dt-detail dd{margin:0}
/* en-tête triable */
.th-sort{display:inline-flex;align-items:center;gap:4px;cursor:pointer;color:inherit;
  font:inherit;text-transform:inherit;letter-spacing:inherit;background:none;border:0;padding:0}
.th-sort::after{content:"";width:14px;height:14px;opacity:.5;background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 9 4-4 4 4M16 15l-4 4-4-4'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 9 4-4 4 4M16 15l-4 4-4-4'/%3E%3C/svg%3E") center/contain no-repeat}
.th-sort:hover{color:var(--foreground)}
.th-sort.is-asc::after,.th-sort.is-desc::after{opacity:1}
.th-sort.is-asc::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 15 6-6 6 6'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 15 6-6 6 6'/%3E%3C/svg%3E")}
.th-sort.is-desc::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")}
/* point de statut (sans pilule) */
.dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--gray-400);flex-shrink:0;vertical-align:middle}
.dot-success{background:var(--success-600)} .dot-warning{background:var(--warning-600)}
.dot-error{background:var(--error-600)} .dot-brand{background:var(--primary)}
[data-theme=dark] .dot-success,:root:has(.theme-toggle:checked) .dot-success{background:var(--success-500)}
[data-theme=dark] .dot-warning,:root:has(.theme-toggle:checked) .dot-warning{background:var(--warning-500)}
[data-theme=dark] .dot-error,:root:has(.theme-toggle:checked) .dot-error{background:var(--error-500)}
.status-cell{display:inline-flex;align-items:center;gap:8px;white-space:nowrap}
/* sparkline inline */
.sparkline{display:inline-block;width:84px;height:26px;color:var(--primary);vertical-align:middle}
.sparkline-success{color:var(--success-500)} .sparkline-error{color:var(--error-500)}
/* toolbar & footer de data table */
.table-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
  flex-wrap:wrap;margin-bottom:var(--sp-4)}
.table-footer{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
  flex-wrap:wrap;margin-top:var(--sp-4)}
.table-footer .table-count{font-size:var(--text-sm);color:var(--muted-foreground)}

/* — List (riche : média + texte + meta + action) — */
.list{display:flex;flex-direction:column;
  border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface)}
.list-item{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--border);transition:background var(--dur-fast) var(--ease)}
.list-item:last-child{border-bottom:none}
.list-item:hover{background:var(--surface-hover)}
.list-item .list-body{flex:1;min-width:0}
.list-item .list-title{font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--foreground)}
.list-item .list-sub{font-size:var(--text-sm);color:var(--muted-foreground);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.list-item .list-meta{font-size:var(--text-sm);color:var(--muted-foreground);white-space:nowrap}

/* — Timeline / fil d'activité (CSS pur) —
   <div class="timeline"><div class="tl-item"><div class="tl-rail">
     <span class="tl-dot is-success"></span><span class="tl-line"></span></div>
   <div class="tl-body">…</div></div>…</div>  (dernier item : omettre .tl-line) */
.timeline{display:flex;flex-direction:column}
.tl-item{display:grid;grid-template-columns:auto 1fr;gap:var(--sp-3)}
.tl-rail{display:flex;flex-direction:column;align-items:center}
.tl-dot{width:11px;height:11px;flex:none;margin-top:4px;border-radius:var(--radius-full);
  background:var(--border-strong);box-shadow:0 0 0 3px var(--surface);z-index:1}
.tl-dot.is-primary{background:var(--primary)} .tl-dot.is-success{background:var(--success-500)}
.tl-dot.is-warning{background:var(--warning-500)} .tl-dot.is-error{background:var(--error-500)}
.tl-line{flex:1;width:2px;min-height:10px;background:var(--border);margin:2px 0}
.tl-body{padding-bottom:var(--sp-5)}
.tl-item:last-child .tl-body{padding-bottom:0}
.tl-time{font-size:var(--text-xs);color:var(--muted-foreground)}
.tl-title{font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--foreground);margin:1px 0 2px}
.tl-text{font-size:var(--text-sm);color:var(--muted-foreground)}

/* — Rating (étoiles, SVG mask currentColor) — */
.rating{display:inline-flex;align-items:center;gap:2px;color:var(--warning-500);line-height:0}
.rating .star{width:18px;height:18px;background:var(--border-strong);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E") center/contain no-repeat}
.rating .star.is-on{background:var(--warning-500)}
.rating-sm .star{width:14px;height:14px}
.rating-lg .star{width:22px;height:22px}
.rating-value{margin-left:6px;font-size:var(--text-sm);color:var(--muted-foreground);line-height:1}

/* — Tooltip (100% CSS) — */
.tooltip{position:relative;display:inline-flex}
.tooltip::after{content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 8px);
  transform:translateX(-50%) translateY(4px);z-index:var(--z-tooltip);
  padding:6px 10px;font-size:var(--text-xs);font-weight:var(--fw-medium);line-height:1.4;
  width:max-content;max-width:240px;color:var(--gray-50);background:var(--gray-900);
  border-radius:var(--radius-sm);box-shadow:var(--shadow-md);
  opacity:0;pointer-events:none;transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease)}
.tooltip::before{content:"";position:absolute;left:50%;bottom:calc(100% + 3px);
  transform:translateX(-50%);z-index:var(--z-tooltip);
  border:5px solid transparent;border-top-color:var(--gray-900);
  opacity:0;pointer-events:none;transition:opacity var(--dur) var(--ease)}
.tooltip:hover::after,.tooltip:focus-visible::after,
.tooltip:hover::before,.tooltip:focus-visible::before{opacity:1;transform:translateX(-50%) translateY(0);transition-delay:.15s} /* léger délai à l'ouverture, pas au survol de passage */
.tooltip.tip-bottom::after{bottom:auto;top:calc(100% + 8px);transform:translateX(-50%) translateY(-4px)}
.tooltip.tip-bottom::before{bottom:auto;top:calc(100% + 3px);border-top-color:transparent;border-bottom-color:var(--gray-900)}
.tooltip.tip-bottom:hover::after,.tooltip.tip-bottom:focus-visible::after{transform:translateX(-50%) translateY(0)}
[data-theme=dark] .tooltip::after,:root:has(.theme-toggle:checked) .tooltip::after{color:var(--gray-900);background:var(--gray-50)}
[data-theme=dark] .tooltip::before,:root:has(.theme-toggle:checked) .tooltip::before{border-top-color:var(--gray-50)}
[data-theme=dark] .tooltip.tip-bottom::before,:root:has(.theme-toggle:checked) .tooltip.tip-bottom::before{border-top-color:transparent;border-bottom-color:var(--gray-50)}

/* — Stat / KPI card — */
.stat{display:flex;flex-direction:column;gap:var(--sp-2);
  padding:var(--sp-5);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-xl);box-shadow:var(--shadow-xs)}
.stat-label{display:flex;align-items:center;gap:8px;font-size:var(--text-sm);color:var(--muted-foreground)}
.stat-label svg{width:18px;height:18px}
.stat-value{font-family:var(--font-display);font-size:var(--text-3xl);line-height:1.1;
  font-weight:var(--fw-semibold);color:var(--foreground);letter-spacing:-.02em}
.stat-foot{display:flex;align-items:center;gap:6px;font-size:var(--text-sm)}
.stat-delta{display:inline-flex;align-items:center;gap:3px;font-weight:var(--fw-medium)}
.stat-delta svg{width:14px;height:14px}
.stat-delta.is-up{color:var(--success-600)}
.stat-delta.is-down{color:var(--error-600)}
[data-theme=dark] .stat-delta.is-up,:root:has(.theme-toggle:checked) .stat-delta.is-up{color:var(--success-300)}
[data-theme=dark] .stat-delta.is-down,:root:has(.theme-toggle:checked) .stat-delta.is-down{color:var(--error-300)}

/* ============================================================================
   13. FEEDBACK — alert, toast, modal, progress, spinner, skeleton, empty
   Modal sur <dialog> natif : centrage robuste (place-items via margin auto +
   inset), backdrop flou, animation, dark mode OK. Toasts empilés en fixe.
   ============================================================================ */

/* — Spinner — */
.spinner{display:inline-block;width:20px;height:20px;border:2px solid var(--border-strong);
  border-right-color:var(--primary);border-radius:50%;animation:spin .6s linear infinite}
.spinner-sm{width:16px;height:16px;border-width:2px}
.spinner-lg{width:32px;height:32px;border-width:3px}

/* — Progress bar — */
.progress{position:relative;width:100%;height:8px;overflow:hidden;
  background:var(--muted);border-radius:var(--radius-full)}
.progress-sm{height:6px} .progress-lg{height:12px}
.progress-bar{height:100%;background:var(--primary);border-radius:inherit;
  transition:width var(--dur-slow) var(--ease)}
.progress-bar.is-success{background:var(--success-500)}
.progress-bar.is-warning{background:var(--warning-500)}
.progress-bar.is-error{background:var(--error-500)}
.progress-indeterminate .progress-bar{width:40%;border-radius:var(--radius-full);
  animation:progress-slide 1.2s var(--ease) infinite}
@keyframes progress-slide{0%{transform:translateX(-100%)}100%{transform:translateX(350%)}}

/* — Skeleton — */
.skeleton{position:relative;overflow:hidden;background:var(--muted);border-radius:var(--radius-sm)}
.skeleton::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--surface) 60%,transparent),transparent);
  background-size:200% 100%;animation:shimmer 1.4s infinite}
.skeleton-text{height:.85em;margin:.25em 0;border-radius:var(--radius-xs)}
.skeleton-title{height:1.2em;width:55%;border-radius:var(--radius-xs)}
.skeleton-circle{border-radius:var(--radius-full)}

/* — Alert / banner — */
.alert{display:flex;gap:var(--sp-3);padding:var(--sp-4);
  border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface)}
.alert-icon{flex-shrink:0;width:20px;height:20px;color:var(--muted-foreground)}
.alert-icon svg{width:20px;height:20px}
.alert-body{flex:1;min-width:0}
.alert-title{font-size:var(--text-sm);font-weight:var(--fw-semibold);color:var(--foreground)}
.alert-text{font-size:var(--text-sm);color:var(--foreground-2);margin-top:2px}
.alert-actions{display:flex;gap:var(--sp-3);margin-top:var(--sp-3)}
.alert-close{flex-shrink:0;align-self:flex-start;color:var(--muted-foreground);
  width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--radius-xs)}
.alert-close:hover{color:var(--foreground);background:var(--surface-hover)}
.alert-close svg{width:16px;height:16px}
/* variantes : bordure gauche + icône colorée + fond teinté */
.alert-info{background:var(--brand-25);border-color:var(--brand-200)}
.alert-info .alert-icon{color:var(--primary)}
.alert-success{background:var(--success-25);border-color:var(--success-300)}
.alert-success .alert-icon{color:var(--success-600)}
.alert-warning{background:var(--warning-25);border-color:var(--warning-300)}
.alert-warning .alert-icon{color:var(--warning-600)}
.alert-error{background:var(--error-25);border-color:var(--error-300)}
.alert-error .alert-icon{color:var(--error-600)}
[data-theme=dark] .alert-info,:root:has(.theme-toggle:checked) .alert-info{background:color-mix(in srgb,var(--brand-500) 12%,transparent);border-color:color-mix(in srgb,var(--brand-500) 35%,transparent)}
[data-theme=dark] .alert-info .alert-icon,:root:has(.theme-toggle:checked) .alert-info .alert-icon{color:var(--brand-300)}
[data-theme=dark] .alert-success,:root:has(.theme-toggle:checked) .alert-success{background:color-mix(in srgb,var(--success-500) 12%,transparent);border-color:color-mix(in srgb,var(--success-500) 35%,transparent)}
[data-theme=dark] .alert-success .alert-icon,:root:has(.theme-toggle:checked) .alert-success .alert-icon{color:var(--success-300)}
[data-theme=dark] .alert-warning,:root:has(.theme-toggle:checked) .alert-warning{background:color-mix(in srgb,var(--warning-500) 12%,transparent);border-color:color-mix(in srgb,var(--warning-500) 35%,transparent)}
[data-theme=dark] .alert-warning .alert-icon,:root:has(.theme-toggle:checked) .alert-warning .alert-icon{color:var(--warning-300)}
[data-theme=dark] .alert-error,:root:has(.theme-toggle:checked) .alert-error{background:color-mix(in srgb,var(--error-500) 12%,transparent);border-color:color-mix(in srgb,var(--error-500) 35%,transparent)}
[data-theme=dark] .alert-error .alert-icon,:root:has(.theme-toggle:checked) .alert-error .alert-icon{color:var(--error-300)}

/* — Toast — */
.toast-container{position:fixed;top:var(--sp-5);right:var(--sp-5);z-index:var(--z-toast);
  display:flex;flex-direction:column;gap:var(--sp-3);max-width:380px;width:calc(100vw - var(--sp-8))}
.toast{display:flex;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);animation:slide-in-right var(--dur-slow) var(--ease-out)}
.toast-icon{flex-shrink:0;width:20px;height:20px}
.toast-icon svg{width:20px;height:20px}
.toast-info .toast-icon{color:var(--primary)}
.toast-success .toast-icon{color:var(--success-600)}
.toast-warning .toast-icon{color:var(--warning-600)}
.toast-error .toast-icon{color:var(--error-600)}
[data-theme=dark] .toast-success .toast-icon,:root:has(.theme-toggle:checked) .toast-success .toast-icon{color:var(--success-300)}
[data-theme=dark] .toast-warning .toast-icon,:root:has(.theme-toggle:checked) .toast-warning .toast-icon{color:var(--warning-300)}
[data-theme=dark] .toast-error .toast-icon,:root:has(.theme-toggle:checked) .toast-error .toast-icon{color:var(--error-300)}
.toast-body{flex:1;min-width:0}
.toast-title{font-size:var(--text-sm);font-weight:var(--fw-semibold);color:var(--foreground)}
.toast-text{font-size:var(--text-sm);color:var(--muted-foreground);margin-top:1px}
/* bouton de fermeture optionnel (ajouté par framework.js) */
.toast-close{flex-shrink:0;align-self:flex-start;margin:-2px -4px -2px 0;width:24px;height:24px;
  display:inline-flex;align-items:center;justify-content:center;border:none;background:none;
  color:var(--muted-foreground);font-size:18px;line-height:1;cursor:pointer;border-radius:var(--radius-sm)}
.toast-close:hover{background:var(--surface-hover);color:var(--foreground)}
.toast.is-leaving{animation:fade-in var(--dur) var(--ease) reverse forwards}

/* — Modal (<dialog> natif, centrage robuste) — */
.modal{margin:auto;padding:0;width:calc(100vw - var(--sp-8));max-width:480px;
  max-height:calc(100dvh - var(--sp-8));border:none;
  color:var(--foreground);background:var(--surface);
  border-radius:var(--radius-2xl);box-shadow:var(--shadow-2xl);
  display:flex;flex-direction:column;overflow:hidden}
.modal:not([open]){display:none}
.modal::backdrop{background:color-mix(in srgb,var(--gray-950) 55%,transparent);
  backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}
/* Entrée : opacité seule sur le dialog (les cibles de clic ne bougent pas) + fond qui fond */
.modal[open]{animation:fade-in var(--dur) var(--ease-out)}
.modal[open]::backdrop{animation:fade-in var(--dur) var(--ease)}
/* Bouton fermer (croix) */
.modal-close{position:absolute;top:var(--sp-4);right:var(--sp-4);z-index:1;
  display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;
  color:var(--muted-foreground);background:transparent;border-radius:var(--radius-md);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.modal-close:hover{background:var(--surface-hover);color:var(--foreground)}
.modal-close svg{width:18px;height:18px}
.modal-header{display:flex;align-items:flex-start;gap:var(--sp-3);padding:var(--sp-5) 48px 0 var(--sp-5);flex-shrink:0}
.modal-header .modal-titles{flex:1;min-width:0}
.modal-title{font-family:var(--font-sans);font-size:var(--text-lg);font-weight:var(--fw-semibold);color:var(--foreground)}
.modal-sub{font-size:var(--text-sm);color:var(--muted-foreground);margin-top:2px}
.modal-body{padding:var(--sp-4) var(--sp-5);font-size:var(--text-sm);color:var(--foreground-2);
  flex:1 1 auto;min-height:0;overflow-y:auto}
.modal-footer{display:flex;justify-content:flex-end;gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5) var(--sp-5);flex-shrink:0}
.modal-icon{flex-shrink:0;width:40px;height:40px;display:grid;place-items:center;border-radius:var(--radius-full)}
.modal-icon svg{width:22px;height:22px}
.modal-icon.is-danger{background:var(--error-50);color:var(--error-600)}
[data-theme=dark] .modal-icon.is-danger,:root:has(.theme-toggle:checked) .modal-icon.is-danger{background:color-mix(in srgb,var(--error-500) 16%,transparent);color:var(--error-300)}
.modal-icon.is-brand{background:var(--primary-subtle);color:var(--primary-subtle-fg)}

/* — Empty state — */
.empty{display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:var(--sp-3);padding:var(--sp-12) var(--sp-6)}
.empty-icon{width:48px;height:48px;display:grid;place-items:center;
  color:var(--muted-foreground);background:var(--surface-2);
  border:1px solid var(--border);border-radius:var(--radius-full)}
.empty-icon svg{width:24px;height:24px}
.empty-title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--fw-semibold);color:var(--foreground)}
.empty-text{font-size:var(--text-sm);color:var(--muted-foreground);max-width:380px}
.empty-actions{display:flex;gap:var(--sp-3);margin-top:var(--sp-2)}

/* ============================================================================
   14. NAVIGATION — tabs, breadcrumb, pagination, steps, navbar, sidebar,
   off-canvas, scrollspy
   Tabs 100% CSS (radio-hack, jusqu'à 6 onglets, mapping par nth générique).
   Off-canvas piloté par .is-open (JS minimal). Scrollspy stylé, JS minimal.
   ============================================================================ */

/* — Tabs (radio-hack, CSS pur) — */
.tabs{display:block}
.tabs>.tab-radio{position:absolute;opacity:0;width:0;height:0;pointer-events:none}
.tab-list{display:flex;gap:var(--sp-1);border-bottom:1px solid var(--border);overflow-x:auto}
.tab{display:inline-flex;align-items:center;gap:6px;padding:10px 12px;
  font-family:inherit;font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--muted-foreground);
  white-space:nowrap;cursor:pointer;background:none;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)}
.tab svg{width:16px;height:16px}
.tab:hover{color:var(--foreground-2)}
/* Variante ARIA (boutons + JS) : sélection via aria-selected, panneau via [hidden] */
.tab[aria-selected="true"]{color:var(--primary);border-bottom-color:var(--primary)}
.tab:focus-visible{outline:none;box-shadow:0 0 0 2px var(--ring) inset;border-radius:var(--radius-sm)}
.tab-panel[hidden]{display:none}
.tab .tab-count{font-size:11px;padding:0 6px;border-radius:var(--radius-full);
  background:var(--muted);color:var(--muted-foreground);line-height:1.5}
.tab-panels{padding-top:var(--sp-5)}
.tab-panel{display:none;animation:fade-in var(--dur) var(--ease)}
/* mapping générique onglet k → label k + panneau k (k = 1..6) */
.tabs>.tab-radio:nth-of-type(1):checked~.tab-list .tab:nth-child(1),
.tabs>.tab-radio:nth-of-type(2):checked~.tab-list .tab:nth-child(2),
.tabs>.tab-radio:nth-of-type(3):checked~.tab-list .tab:nth-child(3),
.tabs>.tab-radio:nth-of-type(4):checked~.tab-list .tab:nth-child(4),
.tabs>.tab-radio:nth-of-type(5):checked~.tab-list .tab:nth-child(5),
.tabs>.tab-radio:nth-of-type(6):checked~.tab-list .tab:nth-child(6){
  color:var(--primary);border-bottom-color:var(--primary)}
.tabs>.tab-radio:nth-of-type(1):checked~.tab-panels>.tab-panel:nth-child(1),
.tabs>.tab-radio:nth-of-type(2):checked~.tab-panels>.tab-panel:nth-child(2),
.tabs>.tab-radio:nth-of-type(3):checked~.tab-panels>.tab-panel:nth-child(3),
.tabs>.tab-radio:nth-of-type(4):checked~.tab-panels>.tab-panel:nth-child(4),
.tabs>.tab-radio:nth-of-type(5):checked~.tab-panels>.tab-panel:nth-child(5),
.tabs>.tab-radio:nth-of-type(6):checked~.tab-panels>.tab-panel:nth-child(6){display:block}
/* focus clavier (la radio reçoit le focus, on stylise son label) */
.tabs>.tab-radio:nth-of-type(1):focus-visible~.tab-list .tab:nth-child(1),
.tabs>.tab-radio:nth-of-type(2):focus-visible~.tab-list .tab:nth-child(2),
.tabs>.tab-radio:nth-of-type(3):focus-visible~.tab-list .tab:nth-child(3),
.tabs>.tab-radio:nth-of-type(4):focus-visible~.tab-list .tab:nth-child(4),
.tabs>.tab-radio:nth-of-type(5):focus-visible~.tab-list .tab:nth-child(5),
.tabs>.tab-radio:nth-of-type(6):focus-visible~.tab-list .tab:nth-child(6){
  outline:2px solid var(--ring);outline-offset:-2px;border-radius:var(--radius-sm) var(--radius-sm) 0 0}

/* — Breadcrumb — */
.breadcrumb{display:flex;align-items:center;flex-wrap:wrap;gap:6px;font-size:var(--text-sm)}
.breadcrumb a{display:inline-flex;align-items:center;gap:6px;color:var(--muted-foreground);
  padding:2px 6px;border-radius:var(--radius-sm);transition:color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.breadcrumb a:hover{color:var(--foreground);background:var(--surface-hover)}
.breadcrumb a svg{width:15px;height:15px}
.breadcrumb li{display:inline-flex;align-items:center;gap:6px}
.breadcrumb li:not(:last-child)::after{content:"";width:16px;height:16px;flex-shrink:0;
  background:var(--border-strong);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center/contain no-repeat}
.breadcrumb .is-current{color:var(--foreground);font-weight:var(--fw-medium);padding:2px 6px}

/* — Pagination — */
.pagination{display:inline-flex;align-items:center;gap:4px}
.page-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-width:36px;height:36px;padding:0 10px;font-size:var(--text-sm);font-weight:var(--fw-medium);
  color:var(--foreground-2);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-md);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.page-btn svg{width:16px;height:16px}
.page-btn:hover{background:var(--surface-hover);border-color:var(--border-strong)}
.page-btn.is-active{background:var(--primary);border-color:var(--primary);color:var(--primary-foreground)}
.page-btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}
.page-ellipsis{display:inline-flex;align-items:center;justify-content:center;
  min-width:38px;height:38px;color:var(--muted-foreground)}

/* — Steps / stepper — */
.steps{display:flex;align-items:flex-start}
.step{display:flex;flex-direction:column;align-items:center;text-align:center;flex:1;position:relative;gap:8px}
.step:not(:last-child)::after{content:"";position:absolute;top:15px;left:calc(50% + 20px);right:calc(-50% + 20px);
  height:2px;background:var(--border);border-radius:2px}
.step.is-done::after{background:var(--primary)}
.step-dot{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;
  font-size:var(--text-sm);font-weight:var(--fw-semibold);border-radius:50%;
  color:var(--muted-foreground);background:var(--surface);border:2px solid var(--border);z-index:1}
.step-dot svg{width:16px;height:16px}
.step-label{font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--foreground-2)}
.step-sub{font-size:var(--text-xs);color:var(--muted-foreground)}
.step.is-active .step-dot{color:var(--primary);background:var(--primary-subtle);border-color:var(--primary)}
.step.is-active .step-label{color:var(--foreground)}
.step.is-done .step-dot{color:var(--primary-foreground);background:var(--primary);border-color:var(--primary)}
/* vertical */
.steps-vertical{flex-direction:column;align-items:stretch}
.steps-vertical .step{flex-direction:row;align-items:flex-start;text-align:left;flex:none;gap:var(--sp-3);padding-bottom:var(--sp-5)}
.steps-vertical .step:not(:last-child)::after{top:32px;bottom:8px;left:15px;right:auto;width:2px;height:auto}
.steps-vertical .step-body{display:flex;flex-direction:column;gap:2px;padding-top:5px}

/* — Wizard (assistant multi-étapes) — réutilise .steps pour l'indicateur ;
   panneaux montrés un à un, navigation + validation par le JS de page. */
.wizard-panels{margin-top:var(--sp-6)}
.wizard-panel{display:none}
.wizard-panel.is-active{display:block;animation:fade-in-up var(--dur) var(--ease)}
.wizard-foot{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);
  margin-top:var(--sp-6);padding-top:var(--sp-5);border-top:1px solid var(--border)}

/* — Onboarding (assistant immersif à pastilles) — carte centrée + progression
   segmentée + choix en pastilles à icônes. Étapes pilotées par le JS de page. */
.onb{width:100%;max-width:460px;margin:0 auto;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-xl);box-shadow:var(--shadow-lg);padding:var(--sp-8) var(--sp-6)}
.onb-steps{display:flex;gap:6px;margin-bottom:var(--sp-6)}
.onb-steps span{flex:1;height:4px;border-radius:var(--radius-full);background:var(--muted);transition:background var(--dur) var(--ease)}
.onb-steps span.is-done{background:var(--primary)}
.onb-q{font-family:var(--font-display);font-size:var(--text-2xl);font-weight:var(--fw-semibold);color:var(--foreground);letter-spacing:-.01em}
.onb-sub{color:var(--muted-foreground);margin:4px 0 var(--sp-6)}
.onb-panel{display:none}
.onb-panel.is-active{display:block;animation:fade-in-up var(--dur) var(--ease)}
.onb-opts{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.onb-opt{display:inline-flex;align-items:center;gap:8px;padding:10px 14px;border:1px solid var(--border);
  border-radius:var(--radius-md);background:var(--surface);color:var(--foreground-2);
  font-size:var(--text-sm);font-weight:var(--fw-medium);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.onb-opt svg{width:16px;height:16px;color:var(--muted-foreground)}
.onb-opt:hover{background:var(--surface-hover);border-color:var(--border-strong)}
.onb-opt.is-sel{border-color:var(--primary);background:var(--primary-subtle);color:var(--primary-subtle-fg)}
.onb-opt.is-sel svg{color:var(--primary)}
.onb-foot{margin-top:var(--sp-8)}
.onb-back{display:block;width:100%;margin-top:var(--sp-3);border:none;background:none;cursor:pointer;
  font-size:var(--text-sm);color:var(--muted-foreground);text-align:center}
.onb-back:hover{color:var(--foreground)}
.onb-back[hidden]{display:none}

/* — Navbar / topbar — */
.navbar{display:flex;align-items:center;gap:var(--sp-5);height:64px;padding:0 var(--sp-6);
  background:var(--surface);border-bottom:1px solid var(--border)}
.navbar-brand{display:inline-flex;align-items:center;gap:var(--sp-2);font-family:var(--font-display);
  font-weight:var(--fw-bold);font-size:var(--text-lg);color:var(--foreground)}
.navbar-links{display:flex;align-items:center;gap:var(--sp-1)}
.navbar-link{padding:8px 12px;font-size:var(--text-sm);font-weight:var(--fw-medium);
  color:var(--muted-foreground);border-radius:var(--radius-md);
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.navbar-link:hover{color:var(--foreground);background:var(--surface-hover)}
.navbar-link.is-active{color:var(--primary);background:var(--primary-subtle)}
.navbar-spacer{flex:1}

/* — Sidebar (navigation app) — */
.sidebar{display:flex;flex-direction:column;gap:2px;width:260px;padding:var(--sp-4);
  background:var(--surface);border-right:1px solid var(--border)}
.sidebar-section{padding:var(--sp-3) 10px 6px;font-size:var(--text-xs);font-weight:var(--fw-semibold);
  text-transform:uppercase;letter-spacing:.04em;color:var(--muted-foreground)}
.nav-item{display:flex;align-items:center;gap:var(--sp-3);padding:9px 10px;
  font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--foreground-2);
  border-radius:var(--radius-md);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.nav-item svg{width:18px;height:18px;flex-shrink:0;color:var(--muted-foreground)}
.nav-item:hover{background:var(--surface-hover);color:var(--foreground)}
.nav-item.is-active{background:var(--primary-subtle);color:var(--primary-subtle-fg)}
.nav-item.is-active svg{color:var(--primary)}
.nav-item .nav-badge{margin-left:auto}

/* — Off-canvas (panneau latéral, JS minimal) — */
.offcanvas{position:fixed;top:0;bottom:0;left:0;z-index:var(--z-modal);
  width:300px;max-width:85vw;background:var(--surface);border-right:1px solid var(--border);
  box-shadow:var(--shadow-2xl);transform:translateX(-100%);
  visibility:hidden;transition:transform var(--dur-slow) var(--ease),visibility 0s linear var(--dur-slow);
  display:flex;flex-direction:column}
.offcanvas.oc-right{left:auto;right:0;border-right:none;border-left:1px solid var(--border);transform:translateX(100%)}
/* ouvert : visible immédiatement (pas de tab dans un panneau fermé hors écran) */
.offcanvas.is-open{transform:translateX(0);visibility:visible;transition:transform var(--dur-slow) var(--ease)}
.offcanvas-header{display:flex;align-items:center;justify-content:space-between;
  padding:var(--sp-4);border-bottom:1px solid var(--border)}
.offcanvas-body{flex:1;overflow-y:auto;padding:var(--sp-4)}
.offcanvas-backdrop{position:fixed;inset:0;z-index:var(--z-overlay);
  background:color-mix(in srgb,var(--gray-950) 50%,transparent);
  opacity:0;visibility:hidden;transition:opacity var(--dur) var(--ease),visibility var(--dur) var(--ease)}
.offcanvas-backdrop.is-open{opacity:1;visibility:visible}

/* — Scrollspy (liste d'ancrage) — */
.scrollspy{display:flex;flex-direction:column;gap:2px;border-left:2px solid var(--border)}
.scrollspy a{padding:6px 14px;margin-left:-2px;font-size:var(--text-sm);color:var(--muted-foreground);
  border-left:2px solid transparent;transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)}
.scrollspy a:hover{color:var(--foreground-2)}
.scrollspy a.is-active{color:var(--primary);border-left-color:var(--primary);font-weight:var(--fw-medium)}

/* ============================================================================
   15. SURFACES — card, accordion, carousel, lightbox, divider
   Accordion 100% CSS (<details>). Carousel en scroll-snap + JS minimal pour
   flèches/points. Lightbox JS minimal.
   (App-shell, grilles, containers, hero : voir section 19. LAYOUTS.)
   ============================================================================ */

/* — Card — */
.card{display:flex;flex-direction:column;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-xl);box-shadow:var(--shadow-xs);overflow:hidden}
.card-header{padding:var(--sp-5);border-bottom:1px solid var(--border)}
.card-header .card-title{font-family:var(--font-sans);font-size:var(--text-lg);font-weight:var(--fw-semibold);color:var(--foreground)}
.card-header .card-sub{font-size:var(--text-sm);color:var(--muted-foreground);margin-top:2px}
.card-body{padding:var(--sp-5);flex:1}
.card-footer{padding:var(--sp-4) var(--sp-5);border-top:1px solid var(--border);
  background:var(--surface-2);display:flex;align-items:center;gap:var(--sp-3)}
.card-media{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;background:var(--surface-2)}
/* variantes */
.card-hover{transition:box-shadow var(--dur) var(--ease),transform var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.card-hover:hover{box-shadow:var(--shadow-md);transform:translateY(-2px);border-color:var(--border-strong)}
.card-flush>.card-body{padding:0}
.card-pad{padding:var(--sp-5)}

/* — Accordion (<details>, CSS pur) — */
.accordion-group{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface)}
.accordion-group .accordion{border-bottom:1px solid var(--border)}
.accordion-group .accordion:last-child{border-bottom:none}
.accordion>summary{list-style:none;display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-4);cursor:pointer;font-weight:var(--fw-medium);color:var(--foreground);
  transition:background var(--dur-fast) var(--ease)}
.accordion>summary::-webkit-details-marker{display:none}
.accordion>summary::marker{content:""}
.accordion>summary:hover{background:var(--surface-hover)}
.accordion>summary::after{content:"";margin-left:auto;width:18px;height:18px;flex-shrink:0;
  background:var(--muted-foreground);transition:transform var(--dur) var(--ease);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center/contain no-repeat}
.accordion[open]>summary::after{transform:rotate(180deg)}
.accordion[open]>summary{color:var(--foreground)}
.accordion-body{padding:0 var(--sp-4) var(--sp-4);font-size:var(--text-sm);color:var(--foreground-2);
  animation:fade-in var(--dur) var(--ease)}

/* — Carousel (scroll-snap + JS minimal) — */
.carousel{position:relative}
.carousel-track{display:flex;gap:var(--sp-4);overflow-x:auto;scroll-snap-type:x mandatory;
  scroll-behavior:smooth;scrollbar-width:none;padding-bottom:2px}
.carousel-track::-webkit-scrollbar{display:none}
.carousel-slide{flex:0 0 auto;scroll-snap-align:start}
.carousel-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:1;
  display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;
  color:var(--foreground-2);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-full);box-shadow:var(--shadow-md);cursor:pointer;
  transition:background var(--dur-fast) var(--ease)}
.carousel-nav:hover{background:var(--surface-hover)}
.carousel-nav svg{width:18px;height:18px}
.carousel-prev{left:-12px} .carousel-next{right:-12px}
.carousel-dots{display:flex;justify-content:center;gap:6px;margin-top:var(--sp-4)}
.carousel-dot{position:relative;width:8px;height:8px;border-radius:50%;background:var(--border-strong);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),width var(--dur-fast) var(--ease)}
.carousel-dot::after{content:"";position:absolute;inset:-10px} /* cible tactile ≥28px */
.carousel-dot.is-active{background:var(--primary);width:20px;border-radius:var(--radius-full)}

/* — Lightbox (JS minimal) — */
.lightbox{position:fixed;inset:0;z-index:var(--z-modal);display:none;
  align-items:center;justify-content:center;padding:var(--sp-8);
  background:color-mix(in srgb,var(--gray-950) 80%,transparent);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.lightbox.is-open{display:flex;animation:fade-in var(--dur) var(--ease)}
.lightbox img{max-width:100%;max-height:100%;border-radius:var(--radius-lg);box-shadow:var(--shadow-2xl)}
.lightbox-close{position:absolute;top:var(--sp-5);right:var(--sp-5);
  display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;
  color:#fff;background:color-mix(in srgb,#fff 12%,transparent);border-radius:var(--radius-full);cursor:pointer}
.lightbox-close:hover{background:color-mix(in srgb,#fff 22%,transparent)}
.lightbox-close svg{width:22px;height:22px}
.lightbox-thumb{cursor:zoom-in;border-radius:var(--radius-md);overflow:hidden}


/* — Divider / séparateurs — */
.divider{display:flex;align-items:center;gap:var(--sp-4);color:var(--muted-foreground);
  font-size:var(--text-sm);margin:var(--sp-4) 0}
.divider::before,.divider::after{content:"";flex:1;height:1px;background:var(--border)}
.divider-plain{margin:var(--sp-4) 0;border-top:1px solid var(--border)}
.divider-vertical{width:1px;align-self:stretch;background:var(--border);margin:0 var(--sp-2)}
/* Variante verticale du divider labellisé (.divider) : trait | label | trait à la verticale.
   Le parent doit donner une hauteur (flex row + height, ou align-self:stretch). */
.divider-y{flex-direction:column;align-self:stretch;margin:0 var(--sp-4)}
.divider-y::before,.divider-y::after{width:1px;height:auto}

/* ============================================================================
   16. PAGES — gabarits : authentification, erreurs, blank
   Surtout des compositions des composants existants (card, input, btn,
   empty). Quelques helpers de mise en page : auth centrée, auth split,
   bloc d'erreur.
   ============================================================================ */

/* — Auth (carte centrée) — */
.auth-page{display:flex;align-items:center;justify-content:center;min-height:100%;
  padding:var(--sp-8) var(--sp-4);background:var(--background)}
.auth-card{width:100%;max-width:400px;display:flex;flex-direction:column;gap:var(--sp-5)}
.auth-head{text-align:center;display:flex;flex-direction:column;align-items:center;gap:var(--sp-3)}
.auth-logo{width:48px;height:48px;display:grid;place-items:center;border-radius:var(--radius-xl);
  color:#fff;font-family:var(--font-display);font-weight:var(--fw-bold);font-size:var(--text-xl);
  box-shadow:var(--shadow-md)}
.auth-title{font-family:var(--font-display);font-size:var(--text-2xl);font-weight:var(--fw-semibold);color:var(--foreground);letter-spacing:-.01em}
.auth-sub{font-size:var(--text-sm);color:var(--muted-foreground)}
.auth-form{display:flex;flex-direction:column;gap:var(--sp-4)}
.auth-foot{text-align:center;font-size:var(--text-sm);color:var(--muted-foreground)}
.auth-foot a{color:var(--primary);font-weight:var(--fw-medium)}
.auth-foot a:hover{text-decoration:underline;text-underline-offset:2px}
/* split (formulaire + panneau visuel) */
.auth-split{display:grid;grid-template-columns:1fr 1fr;min-height:100%}
.auth-split>.auth-aside{display:flex;flex-direction:column;justify-content:space-between;
  padding:var(--sp-8);color:#fff}
.auth-split>.auth-pane{display:flex;align-items:center;justify-content:center;padding:var(--sp-8) var(--sp-4)}
@media (max-width:768px){.auth-split{grid-template-columns:1fr}.auth-split>.auth-aside{display:none}}

/* — Page d'erreur — */
.error-page{display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;min-height:100%;gap:var(--sp-4);padding:var(--sp-12) var(--sp-6)}
.error-code{font-family:var(--font-display);font-size:var(--text-5xl);font-weight:var(--fw-bold);
  line-height:1;letter-spacing:-.03em;
  background:linear-gradient(135deg,var(--brand-500),var(--purple-500));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.error-eyebrow{font-size:var(--text-sm);font-weight:var(--fw-semibold);text-transform:uppercase;
  letter-spacing:.06em;color:var(--primary)}
.error-title{font-family:var(--font-display);font-size:var(--text-2xl);font-weight:var(--fw-semibold);color:var(--foreground)}
.error-text{font-size:var(--text-md);color:var(--muted-foreground);max-width:440px}
.error-actions{display:flex;gap:var(--sp-3);margin-top:var(--sp-2);flex-wrap:wrap;justify-content:center}

/* ============================================================================
   17. MEDIA & MISC — image/vidéo (ratio, overlay, play, embed), galerie,
       swatches, social icons, markdown (.prose), backgrounds
   .prose rétablit les listes (retirées par le reset) et donne un rythme de
   lecture. Backgrounds : grille, points, dégradés mesh et grain léger.
   ============================================================================ */

/* — Swatch (pastille de couleur affichable) — */
.swatch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:var(--sp-3)}
.swatch{border-radius:var(--radius-md);overflow:hidden;border:1px solid var(--border)}
.swatch-color{height:56px}
.swatch-meta{padding:7px 9px;background:var(--surface)}
.swatch-meta b{display:block;font-size:var(--text-xs);font-weight:var(--fw-semibold);color:var(--foreground)}
.swatch-meta span{font-size:11px;color:var(--muted-foreground);font-family:var(--font-mono)}

/* — Social icons — */
.social-icon{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;
  color:var(--muted-foreground);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-full);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease)}
.social-icon svg{width:18px;height:18px}
.social-icon:hover{color:var(--foreground);background:var(--surface-hover);border-color:var(--border-strong);transform:translateY(-2px)}
.social-icon-sm{width:32px;height:32px}
.social-icon-sm svg{width:16px;height:16px}
.social-icon.is-solid{color:#fff;background:var(--foreground);border-color:var(--foreground)}
.social-icon.is-brand{color:#fff;background:var(--primary);border-color:var(--primary)}
.social-icon.is-brand:hover{background:var(--primary-hover)}

/* — Markdown (.prose) — */
.prose{color:var(--foreground-2);font-size:var(--text-md);line-height:1.75;max-width:72ch}
.prose>*+*{margin-top:var(--sp-4)}
.prose h1,.prose h2,.prose h3,.prose h4,.prose h5,.prose h6{font-family:var(--font-display);color:var(--foreground);
  font-weight:var(--fw-semibold);line-height:1.25;letter-spacing:-.01em}
.prose h1{font-size:var(--text-3xl);margin-top:var(--sp-8)}
.prose h2{font-size:var(--text-2xl);margin-top:var(--sp-8);padding-bottom:var(--sp-2);border-bottom:1px solid var(--border)}
.prose h3{font-size:var(--text-xl);margin-top:var(--sp-6)}
.prose h4{font-size:var(--text-lg);margin-top:var(--sp-5)}
.prose h5{font-size:var(--text-md);margin-top:var(--sp-4)}
.prose h6{font-size:var(--text-sm);margin-top:var(--sp-4);text-transform:uppercase;letter-spacing:.04em;color:var(--muted-foreground)}
.prose h1:first-child,.prose h2:first-child,.prose h3:first-child{margin-top:0}
.prose .lead{font-size:var(--text-lg);line-height:1.6;color:var(--foreground-2)}
.prose a{color:var(--primary);font-weight:var(--fw-medium);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}
.prose a:hover{color:var(--primary-hover)}
.prose strong{color:var(--foreground);font-weight:var(--fw-semibold)}
.prose em,.prose i,.prose cite{font-style:italic}
.prose ul,.prose ol{padding-left:var(--sp-6);display:flex;flex-direction:column;gap:6px}
.prose ul{list-style:disc} .prose ol{list-style:decimal}
.prose li{padding-left:4px} .prose li::marker{color:var(--muted-foreground)}
.prose ul ul{list-style:circle} .prose ul ul ul{list-style:square}
.prose ol ol{list-style:lower-alpha} .prose ol ol ol{list-style:lower-roman}
.prose ul ul,.prose ol ol,.prose ul ol,.prose ol ul{margin-top:6px}
.prose dl{display:grid;grid-template-columns:max-content 1fr;gap:6px var(--sp-4)}
.prose dt{font-weight:var(--fw-semibold);color:var(--foreground)}
.prose dd{color:var(--foreground-2)}
.prose blockquote{border-left:3px solid var(--primary);padding:2px 0 2px var(--sp-4);
  color:var(--foreground-2);font-style:italic}
.prose blockquote cite,.prose blockquote footer{display:block;margin-top:var(--sp-2);
  font-style:normal;font-size:var(--text-sm);color:var(--muted-foreground)}
.prose blockquote cite::before,.prose blockquote footer::before{content:"— "}
.prose figure{margin-top:var(--sp-5)}
.prose figure>*+figcaption{margin-top:var(--sp-2)}
.prose figcaption{font-size:var(--text-sm);color:var(--muted-foreground);text-align:center}
.prose hr{margin:var(--sp-6) 0}
.prose img{border-radius:var(--radius-lg);border:1px solid var(--border)}
.prose table{font-size:var(--text-sm);border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden}
.prose th,.prose td{padding:9px 14px;text-align:left;border-bottom:1px solid var(--border)}
.prose thead th{background:var(--surface-2);font-weight:var(--fw-semibold);color:var(--foreground)}
.prose tbody tr:last-child td{border-bottom:none}
.prose :where(code):not(pre code){font-size:.85em}

/* — Backgrounds (motifs, dégradés, grain) — */
.bg-grid{background-image:linear-gradient(var(--border) 1px,transparent 1px),linear-gradient(90deg,var(--border) 1px,transparent 1px);background-size:24px 24px;background-position:-1px -1px}
.bg-dots{background-image:radial-gradient(var(--border-strong) 1.2px,transparent 1.2px);background-size:18px 18px}
.bg-mesh{background:
  radial-gradient(at 20% 20%,color-mix(in srgb,var(--brand-500) 35%,transparent),transparent 50%),
  radial-gradient(at 80% 10%,color-mix(in srgb,var(--purple-500) 35%,transparent),transparent 45%),
  radial-gradient(at 60% 80%,color-mix(in srgb,var(--teal-500) 30%,transparent),transparent 50%),
  var(--surface-2)}
.bg-radial-brand{background:radial-gradient(120% 120% at 50% 0%,var(--brand-50),var(--surface) 60%)}
[data-theme=dark] .bg-radial-brand,:root:has(.theme-toggle:checked) .bg-radial-brand{background:radial-gradient(120% 120% at 50% 0%,color-mix(in srgb,var(--brand-500) 18%,transparent),var(--surface) 60%)}
.bg-fade-b{-webkit-mask-image:linear-gradient(to bottom,#000 60%,transparent);mask-image:linear-gradient(to bottom,#000 60%,transparent)}
.bg-grain{position:relative;isolation:isolate}
.bg-grain::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E")}

/* — Media (image / vidéo) : ratio verrouillé + object-fit.
   Les primitives : aspect-ratio, object-fit, overlay
   dégradé, bouton play, embed responsive. — */
.media{position:relative;display:block;overflow:hidden;border-radius:var(--radius-lg);
  border:1px solid var(--border);background:var(--surface-2)}
.media>img,.media>video{width:100%;height:100%;object-fit:cover;object-position:center}
button.media,a.media{padding:0;margin:0;font:inherit;color:inherit;text-align:inherit;cursor:pointer;width:100%}
.media-1x1{aspect-ratio:1/1}
.media-4x3{aspect-ratio:4/3}
.media-16x9{aspect-ratio:16/9}
.media-21x9{aspect-ratio:21/9}
.media-3x4{aspect-ratio:3/4}
/* zoom doux au survol (variante) */
.media-zoom>img{transition:transform var(--dur-slow) var(--ease)}
.media-zoom:hover>img{transform:scale(1.04)}

/* Overlay : dégradé bas + légende lisible par-dessus l'image */
.media-overlay{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;
  padding:var(--sp-4);color:#fff;
  background:linear-gradient(to top,rgba(16,24,40,.78),rgba(16,24,40,.15) 45%,transparent 70%)}
.media-overlay .media-title{font-family:var(--font-display);font-weight:var(--fw-semibold);font-size:var(--text-md);
  line-height:var(--lh-md);text-shadow:0 1px 2px rgba(0,0,0,.4)}
.media-overlay .media-sub{font-size:var(--text-sm);opacity:.85;margin-top:2px}
/* badge posé sur un média (durée, format…) */
.media-badge{position:absolute;top:var(--sp-3);right:var(--sp-3);z-index:1;
  display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:var(--radius-full);
  background:rgba(16,24,40,.72);color:#fff;font-size:var(--text-xs);font-weight:var(--fw-medium);backdrop-filter:blur(4px)}

/* Bouton play centré (vignette vidéo) */
.media-play{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1;
  width:56px;height:56px;display:grid;place-items:center;border:none;cursor:pointer;
  border-radius:var(--radius-full);background:rgba(255,255,255,.92);color:var(--gray-900);
  box-shadow:var(--shadow-lg);transition:transform var(--dur) var(--ease),background var(--dur) var(--ease)}
.media-play svg{width:22px;height:22px;margin-left:2px}
.media:hover .media-play,.media-play:hover{transform:translate(-50%,-50%) scale(1.08);background:#fff}
.media-play:focus-visible{outline:2px solid #fff;outline-offset:2px}

/* Embed responsive (YouTube / Vimeo) : wrapper en ratio, iframe en remplissage */
.video-embed{position:relative;aspect-ratio:16/9;overflow:hidden;border-radius:var(--radius-lg);
  border:1px solid var(--border);background:#000}
.video-embed>iframe{position:absolute;inset:0;width:100%;height:100%;border:0}

/* Vidéo native stylée : on garde les contrôles natifs, on cadre juste */
.video{width:100%;display:block;border-radius:var(--radius-lg);border:1px solid var(--border);background:#000}

/* Figure / légende (hors .prose) */
.figure{margin:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.figure>figcaption,figure>figcaption{font-size:var(--text-sm);color:var(--muted-foreground)}

/* Galerie : grille d'images */
.gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:var(--sp-3)}
.gallery .media{border-radius:var(--radius-md)}
/* Masonry légère (colonnes CSS) */
.gallery-masonry{columns:4 200px;column-gap:var(--sp-3)}
.gallery-masonry>*{break-inside:avoid;margin-bottom:var(--sp-3)}
.gallery-masonry .media{display:block}
.gallery-masonry .media>img{height:auto;object-fit:initial}

/* ============================================================================
   18. OVERLAYS & ADVANCED — parité shadcn/ui : popover, hover card, combobox,
   command (⌘K), context menu, menubar, navigation menu, toggle/toggle group,
   input OTP, scroll area, resizable. Les listes de menu réutilisent le style
   .dropdown-menu/.dropdown-item.
   ============================================================================ */

/* — Toggle (bouton bascule) & toggle group — */
.toggle{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:36px;min-width:36px;
  padding:0 10px;font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--foreground-2);
  background:transparent;border:1px solid transparent;border-radius:var(--radius-md);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.toggle:hover{background:var(--surface-hover);color:var(--foreground)}
.toggle svg{width:18px;height:18px}
.toggle[aria-pressed=true]{background:var(--primary-subtle);color:var(--primary-subtle-fg)}
.toggle-group{display:inline-flex;gap:2px;padding:3px;background:var(--surface-2);
  border:1px solid var(--border);border-radius:var(--radius-lg)}
.toggle-group .toggle{height:32px}

/* — Popover (panneau ancré générique, <details>) — */
.popover{position:relative;display:inline-block}
.popover>summary{list-style:none;cursor:pointer}
.popover>summary::-webkit-details-marker{display:none}
.popover>summary::marker{content:""}
.popover-panel{position:absolute;top:calc(100% + 8px);left:0;z-index:var(--z-popover);
  min-width:260px;padding:var(--sp-4);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);animation:fade-in-up var(--dur) var(--ease)}
.popover-panel.popover-end{left:auto;right:0}

/* — Hover card (popover riche au survol, CSS pur) — */
.hover-card{position:relative;display:inline-block}
.hover-card-panel{position:absolute;top:calc(100% + 8px);left:0;z-index:var(--z-popover);
  width:300px;padding:var(--sp-4);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
  opacity:0;visibility:hidden;transform:translateY(4px);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease),visibility 0s linear var(--dur)}
.hover-card:hover .hover-card-panel,.hover-card:focus-within .hover-card-panel{
  opacity:1;visibility:visible;transform:translateY(0);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease)}

/* — Context menu (clic droit) : réutilise .dropdown-menu, positionné en fixed via JS — */
.context-target{border:1px dashed var(--border-strong);border-radius:var(--radius-md);
  padding:var(--sp-10) var(--sp-6);text-align:center;color:var(--muted-foreground);
  background:var(--surface-2);cursor:context-menu;user-select:none}
.context-menu{position:fixed;z-index:var(--z-popover);min-width:200px;padding:var(--sp-1);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);animation:fade-in var(--dur-fast) var(--ease)}
.context-menu[hidden]{display:none}

/* — Menubar (barre de menus type appli) — */
.menubar{display:inline-flex;align-items:center;gap:2px;padding:3px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md)}
.menubar .dropdown>summary{padding:5px 10px;font-size:var(--text-sm);font-weight:var(--fw-medium);
  color:var(--foreground-2);border-radius:var(--radius-sm)}
.menubar .dropdown[open]>summary,.menubar .dropdown>summary:hover{background:var(--surface-hover);color:var(--foreground)}

/* — Navigation menu (méga-menu, CSS pur via hover/focus) — */
.nav-menu{display:flex;gap:var(--sp-1);align-items:center}
.nav-menu-item{position:relative}
.nav-menu-trigger{display:inline-flex;align-items:center;gap:4px;padding:8px 12px;font-size:var(--text-sm);
  font-weight:var(--fw-medium);color:var(--foreground-2);border-radius:var(--radius-md);
  cursor:pointer;background:none;border:none}
.nav-menu-trigger:hover{background:var(--surface-hover);color:var(--foreground)}
.nav-menu-trigger svg{width:16px;height:16px;transition:transform var(--dur) var(--ease)}
.nav-menu-panel{position:absolute;top:calc(100% + 8px);left:0;z-index:var(--z-popover);
  min-width:460px;padding:var(--sp-3);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
  display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-1);
  opacity:0;visibility:hidden;transform:translateY(4px);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease),visibility 0s linear var(--dur)}
/* Pont transparent qui comble les 8px entre le trigger et le panneau : sans lui, déplacer
   la souris du trigger vers le panneau traverse un vide et referme le menu. */
.nav-menu-panel::before{content:"";position:absolute;top:-8px;left:0;right:0;height:8px}
.nav-menu-item:hover .nav-menu-panel,.nav-menu-item:focus-within .nav-menu-panel{
  opacity:1;visibility:visible;transform:translateY(0);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease)}
.nav-menu-item:hover .nav-menu-trigger svg{transform:rotate(180deg)}
/* Survoler un item ferme le panneau des autres, même s'ils gardent le focus
   (sinon un panneau cliqué/focus reste ouvert pendant qu'un autre s'ouvre au survol). */
.nav-menu:hover .nav-menu-item:not(:hover) .nav-menu-panel{
  opacity:0;visibility:hidden;transform:translateY(4px);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease),visibility 0s linear var(--dur)}
.nav-menu-link{display:flex;flex-direction:column;gap:2px;padding:10px;border-radius:var(--radius-md);cursor:pointer}
.nav-menu-link:hover{background:var(--surface-hover)}
.nav-menu-link b{font-size:var(--text-sm);font-weight:var(--fw-semibold);color:var(--foreground)}
.nav-menu-link span{font-size:var(--text-xs);color:var(--muted-foreground)}

/* — Combobox (select cherchable) — */
.combobox{position:relative;width:100%;max-width:320px}
.combobox-list{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:var(--z-popover);
  max-height:240px;overflow-y:auto;padding:var(--sp-1);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg)}
.combobox-list[hidden]{display:none}
.combobox-option{display:flex;align-items:center;gap:var(--sp-2);padding:8px 10px;font-size:var(--text-sm);
  color:var(--foreground-2);border-radius:var(--radius-sm);cursor:pointer}
.combobox-option:hover,.combobox-option.is-active{background:var(--surface-hover);color:var(--foreground)}
.combobox-option .check{margin-left:auto;width:16px;height:16px;color:var(--primary);opacity:0}
.combobox-option.is-selected .check{opacity:1}
.combobox-empty{padding:12px 10px;font-size:var(--text-sm);color:var(--muted-foreground);text-align:center}

/* — Command (palette ⌘K) : s'appuie sur <dialog>.modal — */
.command{padding:0;max-width:560px;width:calc(100vw - var(--sp-8));overflow:hidden}
.command-search{display:flex;align-items:center;gap:var(--sp-2);padding:0 var(--sp-4);border-bottom:1px solid var(--border)}
.command-search svg{width:18px;height:18px;color:var(--muted-foreground);flex:none}
.command-search input{flex:1;border:none;outline:none;background:none;height:52px;font-size:var(--text-md);color:var(--foreground)}
.command-list{max-height:340px;overflow-y:auto;padding:var(--sp-2)}
.command-group-label{padding:8px 10px 4px;font-size:var(--text-xs);font-weight:var(--fw-semibold);
  text-transform:uppercase;letter-spacing:.04em;color:var(--muted-foreground)}
.command-item{display:flex;align-items:center;gap:var(--sp-3);padding:9px 10px;font-size:var(--text-sm);
  color:var(--foreground-2);border-radius:var(--radius-md);cursor:pointer}
.command-item svg{width:18px;height:18px;color:var(--muted-foreground)}
.command-item:hover,.command-item.is-active{background:var(--surface-hover);color:var(--foreground)}
.command-item .shortcut{margin-left:auto}
.command-empty{padding:32px;text-align:center;color:var(--muted-foreground);font-size:var(--text-sm)}

/* — Input OTP (code à usage unique) — */
.otp{display:inline-flex;gap:var(--sp-2);align-items:center}
.otp input{width:44px;height:52px;text-align:center;font-size:var(--text-xl);font-weight:var(--fw-semibold);
  font-family:var(--font-mono);color:var(--foreground);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-md);outline:none;
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.otp input:focus{border-color:var(--ring);box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}
.otp .otp-sep{color:var(--muted-foreground)}

/* — Scroll area (scrollbars stylées) — */
.scroll-area{overflow:auto;scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
.scroll-area::-webkit-scrollbar{width:8px;height:8px}
.scroll-area::-webkit-scrollbar-track{background:transparent}
.scroll-area::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:var(--radius-full);
  border:2px solid var(--surface)}
.scroll-area::-webkit-scrollbar-thumb:hover{background:var(--muted-foreground)}

/* — Resizable (panneaux redimensionnables, splitter JS minimal) — */
.resizable{display:flex;border:1px solid var(--border);border-radius:var(--radius-lg);
  overflow:hidden;min-height:220px}
.resizable-pane{padding:var(--sp-4);overflow:auto;min-width:80px}
.resizable-pane:first-child{flex:0 0 50%}
.resizable-pane:last-child{flex:1 1 auto}
.resizable-handle{width:7px;flex:none;cursor:col-resize;background:var(--surface-2);
  border-left:1px solid var(--border);border-right:1px solid var(--border);
  display:flex;align-items:center;justify-content:center;touch-action:none}
.resizable-handle::before{content:"";width:2px;height:28px;border-radius:var(--radius-full);background:var(--border-strong)}
.resizable-handle:hover::before{background:var(--primary)}

/* ============================================================================
   19. LAYOUTS — variantes de container (fluid / condensed / wide), modes
   d'app-shell (vertical, horizontal, combined, rail condensé), framing boxed,
   et hero. S'appuie sur .navbar / .sidebar / .app-* déjà définis (section 14-15).
   ============================================================================ */

/* — Containers (largeurs) — */
.container-fluid{width:100%;margin-inline:auto;padding-inline:var(--sp-6)}
.container-wide{width:100%;max-width:1440px;margin-inline:auto;padding-inline:var(--sp-6)}
.container-condensed{width:100%;max-width:var(--container-md);margin-inline:auto;padding-inline:var(--sp-6)}

/* — App-shell : parties communes à toutes les variantes (header / main / aside) — */
.app-header{display:flex;align-items:center;gap:var(--sp-4);padding:0 var(--sp-5);
  background:var(--surface);border-bottom:1px solid var(--border)}
.app-main{overflow-y:auto;padding:var(--sp-6);min-width:0}
.app-aside{overflow-y:auto}

/* Vertical (défaut) : sidebar pleine hauteur + topbar + contenu */
.app-shell{display:grid;grid-template-columns:260px 1fr;grid-template-rows:64px 1fr;
  grid-template-areas:"aside header" "aside main";height:100%;background:var(--background)}
.app-shell>.app-aside{grid-area:aside}
.app-shell>.app-header{grid-area:header}
.app-shell>.app-main{grid-area:main}
@media (max-width:768px){
  .app-shell{grid-template-columns:1fr;grid-template-areas:"header" "main"}
}

/* Horizontal : barre en haut, contenu dessous (pas de sidebar) */
.app-shell-horizontal{display:grid;grid-template-rows:64px 1fr;height:100%;background:var(--background)}

/* Combined : barre pleine largeur en haut + sidebar + contenu */
.app-shell-combined{display:grid;grid-template-columns:260px 1fr;grid-template-rows:64px 1fr;
  grid-template-areas:"header header" "aside main";height:100%;background:var(--background)}
.app-shell-combined>.app-header{grid-area:header}
.app-shell-combined>.app-aside{grid-area:aside}
.app-shell-combined>.app-main{grid-area:main}
@media (max-width:768px){
  .app-shell-combined{grid-template-columns:1fr;grid-template-areas:"header" "main"}
}

/* — App-shell mobile : sous 768px la sidebar devient un panneau coulissant
   (burger + backdrop) au lieu de disparaître. framework.js bascule .nav-open sur
   l'app-shell (clic burger / backdrop / Échap). Sans JS : ajouter .nav-open en dur. — */
.app-burger{display:none}
.app-shell-backdrop{display:none}
@media (max-width:768px){
  .app-burger{display:inline-flex}
  .app-shell>.app-aside,.app-shell-combined>.app-aside{
    position:fixed;top:0;left:0;bottom:0;width:260px;max-width:85vw;z-index:var(--z-modal);
    background:var(--surface);border-right:1px solid var(--border);box-shadow:var(--shadow-2xl);
    transform:translateX(-100%);visibility:hidden;
    transition:transform var(--dur-slow) var(--ease),visibility 0s linear var(--dur-slow)}
  .app-shell.nav-open>.app-aside,.app-shell-combined.nav-open>.app-aside{
    transform:translateX(0);visibility:visible;transition:transform var(--dur-slow) var(--ease)}
  .app-shell>.app-shell-backdrop,.app-shell-combined>.app-shell-backdrop{
    display:block;position:fixed;inset:0;z-index:var(--z-overlay);
    background:color-mix(in srgb,var(--gray-950) 50%,transparent);
    opacity:0;visibility:hidden;transition:opacity var(--dur) var(--ease),visibility var(--dur) var(--ease)}
  .app-shell.nav-open>.app-shell-backdrop,.app-shell-combined.nav-open>.app-shell-backdrop{
    opacity:1;visibility:visible}
}

/* Rail condensé : sidebar étroite — modificateur de .app-shell / .app-shell-combined */
.app-shell-rail{grid-template-columns:72px 1fr}
.app-shell-rail .sidebar{width:72px;align-items:center;padding:var(--sp-3) 0}
.app-shell-rail .sidebar .nav-item{justify-content:center;padding:9px}
.app-shell-rail .sidebar .nav-item span,.app-shell-rail .sidebar .sidebar-section{display:none}

/* — Page header : titre de page (+ sous-titre) à gauche, actions à droite.
   Se place en tête de .app-main. Les contrôles d'actions utilisent .input-sm /
   .select-sm / .btn-sm pour une hauteur homogène (32px) — ne pas forcer ici. — */
.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-3);
  flex-wrap:wrap;margin-bottom:var(--sp-6)}
.page-head-titles{display:flex;flex-direction:column;gap:4px;min-width:0}
.page-head h1,.page-head-title{font-family:var(--font-display);font-size:var(--text-2xl);
  font-weight:var(--fw-semibold);line-height:1.2;margin:0;color:var(--foreground)}
.page-head-sub{font-size:var(--text-sm);color:var(--muted-foreground)}
.page-head-actions{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;justify-content:flex-end}
@media (max-width:640px){
  .page-head{flex-direction:column;align-items:stretch}
  .page-head-actions{width:100%;flex-direction:column;align-items:stretch;justify-content:flex-start}
  .page-head-actions>*,
  .page-head-actions form,
  .page-head-actions .btn,
  .page-head-actions a.btn,
  .page-head-actions form .btn,
  .page-head-actions form button,
  .page-head-actions .input-group,
  .page-head-actions .input,
  .page-head-actions .select{width:100%}
}

/* — Grilles responsives — */
.grid-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:var(--sp-4)}
.grid-2-1{display:grid;grid-template-columns:2fr 1fr;gap:var(--sp-6)}
.grid-sidebar{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:var(--sp-6)}
@media (max-width:768px){
  .grid-2-1,.grid-sidebar{grid-template-columns:1fr}
}

/* — Framing boxed : appli centrée dans un cadre max-width, fond autour — */
.layout-boxed{min-height:100%;background:var(--surface-2);display:flex;justify-content:center}
.layout-boxed>*{width:100%;max-width:1140px;background:var(--background);border-inline:1px solid var(--border)}

/* — Hero — */
.hero{position:relative;padding:var(--sp-16) 0;overflow:hidden}
.hero-inner{display:flex;flex-direction:column;gap:var(--sp-5);max-width:680px}
.hero-eyebrow{font-size:var(--text-sm);font-weight:var(--fw-semibold);color:var(--primary);
  text-transform:uppercase;letter-spacing:.04em}
.hero-title{font-family:var(--font-display);font-size:var(--text-5xl);line-height:var(--lh-5xl);
  font-weight:var(--fw-semibold);letter-spacing:-.02em;color:var(--foreground)}
.hero-sub{font-size:var(--text-lg);color:var(--muted-foreground);max-width:560px}
.hero-actions{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin-top:var(--sp-2)}
.hero-centered .hero-inner{margin-inline:auto;align-items:center;text-align:center}
.hero-centered .hero-sub{margin-inline:auto}
.hero-split{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-10);align-items:center}
.hero-split .hero-inner{max-width:none}
@media (max-width:860px){ .hero-split{grid-template-columns:1fr} }

/* ============================================================================
   20. PHASE 2 — charts (SVG/CSS), select stylé, drawer, tabs verticaux.
   Data table interactive : pas de nouveau CSS (réutilise .table + helpers,
   logique en JS dans la démo 04).
   ============================================================================ */

/* — Tabs verticaux — */
.tabs-vertical{display:flex;gap:var(--sp-6)}
.tabs-vertical>.tab-list{flex-direction:column;gap:2px;min-width:170px;
  border-bottom:none;border-left:1px solid var(--border);overflow:visible}
.tabs-vertical .tab{justify-content:flex-start;text-align:left;padding:8px 14px;
  border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-left:-1px}
.tabs-vertical .tab[aria-selected="true"]{border-bottom-color:transparent;border-left-color:var(--primary)}
.tabs-vertical .tab-panels{flex:1;padding-top:0}

/* — Select stylé (custom, non natif) : trigger + listbox en popover —
   réutilise .combobox-list / .combobox-option pour la liste. */
.select-menu{position:relative;width:100%;max-width:320px}
.select-menu-trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);
  width:100%;height:var(--field-h);padding:0 12px;font-family:inherit;font-size:var(--text-sm);
  color:var(--foreground);background:var(--surface);border:1px solid var(--input);
  border-radius:var(--radius-md);cursor:pointer;box-shadow:var(--shadow-xs);
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.select-menu-trigger:hover{border-color:var(--border-strong)}
.select-menu-trigger[aria-expanded="true"]{border-color:var(--ring);box-shadow:0 0 0 4px color-mix(in srgb,var(--ring) 18%,transparent)}
.select-menu-trigger.is-placeholder{color:var(--muted-foreground)}
.select-menu-trigger .select-menu-caret{width:16px;height:16px;flex:none;color:var(--muted-foreground)}
.select-menu-list{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:var(--z-popover);
  max-height:260px;overflow-y:auto;padding:var(--sp-1);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg)}
.select-menu-list[hidden]{display:none}
.select-menu-option{display:flex;align-items:center;gap:var(--sp-2);padding:8px 10px;font-size:var(--text-sm);
  color:var(--foreground-2);border-radius:var(--radius-sm);cursor:pointer}
.select-menu-option:hover,.select-menu-option.is-active{background:var(--surface-hover);color:var(--foreground)}
.select-menu-option .check{margin-left:auto;width:16px;height:16px;color:var(--primary);opacity:0}
.select-menu-option[aria-selected="true"]{font-weight:var(--fw-medium)}
.select-menu-option[aria-selected="true"] .check{opacity:1}

/* — Drawer (bottom sheet, <dialog> natif) — */
.drawer{position:fixed;inset:auto 0 0 0;width:100%;max-width:none;max-height:85dvh;margin:0;padding:0;
  border:none;color:var(--foreground);background:var(--surface);
  border-radius:var(--radius-2xl) var(--radius-2xl) 0 0;box-shadow:var(--shadow-2xl);
  display:flex;flex-direction:column;overflow:hidden}
.drawer:not([open]){display:none}
.drawer[open]{animation:slide-up var(--dur-slow) var(--ease-out)}
.drawer[open]::backdrop{animation:fade-in var(--dur) var(--ease)}
.drawer::backdrop{background:color-mix(in srgb,var(--gray-950) 55%,transparent);backdrop-filter:blur(2px)}
.drawer-handle{flex:none;width:36px;height:4px;border-radius:var(--radius-full);background:var(--border-strong);margin:10px auto 4px}
.drawer-header{flex:none;padding:var(--sp-3) var(--sp-5) var(--sp-2)}
.drawer-title{font-family:var(--font-sans);font-size:var(--text-lg);font-weight:var(--fw-semibold);color:var(--foreground)}
.drawer-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--sp-2) var(--sp-5)}
.drawer-footer{flex:none;display:flex;gap:var(--sp-3);padding:var(--sp-4) var(--sp-5);border-top:1px solid var(--border)}
@keyframes slide-up{from{transform:translateY(100%)}to{transform:translateY(0)}}

/* — Charts (SVG + CSS, données dans le markup ; pas de dépendance JS) — */
.chart{width:100%}
.chart-bars{display:flex;align-items:flex-end;gap:var(--sp-2);height:180px;padding-top:var(--sp-2)}
.chart-bars .bar{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:8px;height:100%;text-align:center}
.chart-bars .bar>span{width:100%;max-width:22px;height:var(--v,0%);min-height:4px;
  background:linear-gradient(var(--primary),color-mix(in srgb,var(--primary) 70%,transparent));
  border-radius:var(--radius-md) var(--radius-md) 0 0;transition:height var(--dur-slow) var(--ease),filter var(--dur) var(--ease)}
.chart-bars .bar:hover>span{filter:brightness(1.08)}
.chart-bars .bar>small{font-size:11px;color:var(--muted-foreground)}
.chart-bars .bar.is-muted>span{background:var(--border-strong)}
.chart-svg{display:block;width:100%;height:auto;overflow:visible}
.chart-svg .area{fill:color-mix(in srgb,var(--primary) 14%,transparent);stroke:none}
.chart-svg .line{fill:none;stroke:var(--primary);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.chart-svg .line-cmp{fill:none;stroke:var(--border-strong);stroke-width:2;stroke-dasharray:2 5;stroke-linecap:round}
.chart-svg .grid{stroke:var(--border);stroke-width:1;stroke-dasharray:3 4}
.chart-svg .dot{fill:var(--surface);stroke:var(--primary);stroke-width:2.5}
.chart-donut{transform:rotate(-90deg)}
.chart-donut circle{fill:none;stroke-width:var(--dw,12)}
.chart-donut .track{stroke:var(--muted)}
.chart-donut .seg{stroke:var(--primary);stroke-linecap:butt;transition:stroke-dashoffset var(--dur-slow) var(--ease)}
.chart-legend{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin-top:var(--sp-3);font-size:var(--text-sm);color:var(--muted-foreground)}
.chart-legend span{display:inline-flex;align-items:center;gap:6px}
.chart-legend i{width:10px;height:10px;border-radius:3px;background:var(--primary);flex:none}
/* interactif (moteur JS) : tooltip flottant + survol */
.chart-tip{position:fixed;z-index:var(--z-tooltip);transform:translate(-50%,-100%);margin-top:-10px;
  padding:5px 9px;font-size:var(--text-xs);font-weight:var(--fw-medium);white-space:nowrap;line-height:1.4;
  color:var(--gray-50);background:var(--gray-900);border-radius:var(--radius-sm);box-shadow:var(--shadow-md);
  pointer-events:none;opacity:0;transition:opacity var(--dur-fast) var(--ease)}
.chart-tip.is-on{opacity:1}
.chart-tip b{font-weight:var(--fw-bold);color:inherit}/* sinon la règle globale strong,b{color:--foreground} rend la valeur noir-sur-noir */
[data-theme=dark] .chart-tip,:root:has(.theme-toggle:checked) .chart-tip{color:var(--gray-900);background:var(--gray-50)}
.chart-svg .guide{stroke:var(--border-strong);stroke-width:1;stroke-dasharray:3 3;opacity:0;transition:opacity var(--dur-fast)}
.chart-svg.is-hover .guide{opacity:1}
.chart-bars .bar{cursor:pointer}
.chart-donut .seg{cursor:pointer;transition:stroke-dashoffset var(--dur-slow) var(--ease),opacity var(--dur-fast)}
.chart-donut:hover .seg:not(.is-hot){opacity:.45}

/* — Barres empilées (stacked) — CSS pur. Colonnes de segments empilés (--h en %).
   Couleurs des séries via --c1/--c2/--c3 (def. primary / warning / border-strong). */
.chart-stacked{--c1:var(--primary);--c2:var(--warning-500);--c3:var(--border-strong);
  display:flex;align-items:flex-end;gap:var(--sp-2);height:180px}
.chart-stacked .col{flex:1;min-width:0;display:flex;flex-direction:column;height:100%;gap:8px}
.chart-stacked .stack{flex:1;display:flex;flex-direction:column;justify-content:flex-end;width:100%;max-width:30px;margin:0 auto;
  border-radius:var(--radius-sm);overflow:hidden}
.chart-stacked .seg{width:100%;height:var(--h,0%)}
.chart-stacked .seg.s1{background:var(--c1)} .chart-stacked .seg.s2{background:var(--c2)} .chart-stacked .seg.s3{background:var(--c3)}
.chart-stacked small{text-align:center;font-size:11px;color:var(--muted-foreground)}

/* — Barres groupées multi-séries — CSS pur. Chaque groupe = N barres côte à côte. */
.chart-grouped{--c1:var(--primary);--c2:var(--warning-500);--c3:var(--success-500);
  display:flex;align-items:stretch;gap:var(--sp-3);height:180px}
.chart-grouped .grp{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:8px;height:100%}
.chart-grouped .bars{flex:1;display:flex;align-items:flex-end;justify-content:center;gap:4px;width:100%}
.chart-grouped .gbar{width:11px;border-radius:3px 3px 0 0;height:var(--h,0%);transition:filter var(--dur-fast) var(--ease)}
.chart-grouped .gbar:hover{filter:brightness(1.08)}
.chart-grouped .gbar.s1{background:var(--c1)} .chart-grouped .gbar.s2{background:var(--c2)} .chart-grouped .gbar.s3{background:var(--c3)}
.chart-grouped small{font-size:11px;color:var(--muted-foreground)}

/* — Heatmap (grille de cellules, intensité d'une même famille de couleur —
   façon calendrier de contributions). Couleur de base : --heat (def. --primary)
   ou variantes -blue/-purple/-green/-orange. Chaque cellule porte un niveau
   .l0…l4 (ou --l:NN% libre). Cellules carrées de taille fixe (--hm-cell) ;
   --hm-cols colonnes, --hm-gap espacement. Niveaux dérivés en color-mix sur
   --surface-2 → dark mode OK sans override. */
.heatmap{--heat:var(--primary);--hm-cols:7;--hm-cell:15px;--hm-gap:4px;
  display:grid;grid-template-columns:repeat(var(--hm-cols),var(--hm-cell));
  gap:var(--hm-gap);width:max-content;max-width:100%}
.heatmap .cell{aspect-ratio:1;border-radius:var(--radius-sm);
  background:color-mix(in srgb,var(--heat) var(--l,0%),var(--surface-2));
  transition:filter var(--dur-fast) var(--ease)}
.heatmap .cell:hover{filter:brightness(1.06)}
.heatmap .l0{--l:8%} .heatmap .l1{--l:28%} .heatmap .l2{--l:50%}
.heatmap .l3{--l:74%} .heatmap .l4{--l:100%}
.heatmap-blue{--heat:var(--primary)}
.heatmap-purple{--heat:var(--purple-500)}
.heatmap-green{--heat:var(--success-500)}
.heatmap-orange{--heat:var(--warning-500)}

/* — Sparkline (mini courbe inline, interactive via JS de page) — */
.sparkline{display:inline-block;vertical-align:middle;width:120px;height:32px}
.sparkline .sl-area{fill:color-mix(in srgb,var(--primary) 14%,transparent)}
.sparkline .sl-line{fill:none;stroke:var(--primary);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.sparkline .sl-dot{fill:var(--primary);opacity:0}
.sparkline.is-hover .sl-dot{opacity:1}

/* — Gauge radiale (anneau + % au centre), CSS pur via conic-gradient.
   Usage : <span class="gauge" style="--val:91"><b>91</b></span>
   Couleur : --gauge (def. --primary) ou classes .gauge-success/-warning/-error.
   Taille : --gauge-sz / --gauge-th, ou .gauge-sm / .gauge-lg. */
.gauge{--gauge-sz:44px;--gauge-th:4px;--gauge:var(--primary);
  position:relative;display:inline-grid;place-items:center;flex:none;
  width:var(--gauge-sz);height:var(--gauge-sz);border-radius:var(--radius-full)}
.gauge::before{content:"";position:absolute;inset:0;border-radius:inherit;
  background:conic-gradient(var(--gauge) calc(var(--val,0)*1%),var(--muted) 0);
  -webkit-mask:radial-gradient(farthest-side,#0000 calc(100% - var(--gauge-th)),#000 0);
          mask:radial-gradient(farthest-side,#0000 calc(100% - var(--gauge-th)),#000 0)}
.gauge>b{position:relative;font-size:var(--text-xs);font-weight:var(--fw-semibold);color:var(--foreground);line-height:1}
.gauge-sm{--gauge-sz:32px;--gauge-th:3px}
.gauge-sm>b{font-size:10px}
.gauge-lg{--gauge-sz:72px;--gauge-th:6px}
.gauge-lg>b{font-size:var(--text-md)}
.gauge-success{--gauge:var(--success-500)}
.gauge-warning{--gauge:var(--warning-500)}
.gauge-error{--gauge:var(--error-500)}

/* — Barre de progression segmentée (traits) — CSS pur.
   Usage : <div class="segbar" style="--val:58%"></div>
   Couleur de remplissage : --seg (def. --primary). Hauteur : --segbar-h. */
.segbar{--seg:var(--primary);--segbar-h:34px;position:relative;height:var(--segbar-h);border-radius:var(--radius-sm);overflow:hidden}
.segbar::before,.segbar::after{content:"";position:absolute;top:0;bottom:0;left:0;
  background-image:repeating-linear-gradient(90deg,currentColor 0 5px,transparent 5px 11px)}
.segbar::before{right:0;color:var(--muted)}
.segbar::after{width:var(--val,0%);color:var(--seg);transition:width var(--dur-slow) var(--ease)}
.segbar-success{--seg:var(--success-500)} .segbar-warning{--seg:var(--warning-500)} .segbar-error{--seg:var(--error-500)}

/* — Barre de disponibilité (uptime) : N segments = N périodes, une couleur par
   statut, une infobulle par segment (date + statut). Façon status-page.
   Chaque segment = <span class="bar"> avec un statut : défaut = OK (vert),
   .is-warn / .is-down / .is-none. Le data-tip de chaque segment fournit le texte
   de l'infobulle (câblée côté page, comme les charts). Hauteur : --uptime-h. */
.uptime{display:flex;align-items:stretch;gap:2px;height:var(--uptime-h,34px)}
.uptime .bar{flex:1 1 0;min-width:0;border-radius:var(--radius-xs);
  background:var(--success-500);cursor:help;
  transition:filter var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease)}
.uptime .bar:hover{filter:brightness(1.12);transform:scaleY(1.08)}
.uptime .bar.is-warn{background:var(--warning-500)}
.uptime .bar.is-down{background:var(--error-500)}
.uptime .bar.is-none{background:var(--border-strong)}
.uptime-sm{--uptime-h:22px}

/* — Calendrier vue mois (full calendar) — grille rendue par le JS de page.
   Préfixe `.fcal-` pour ne pas entrer en collision avec le date picker (.cal-). */
.fcal{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface)}
.fcal-head{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border)}
.fcal-month{font-family:var(--font-display);font-weight:var(--fw-semibold);font-size:var(--text-md);color:var(--foreground)}
.fcal-nav{margin-left:auto;display:flex;align-items:center;gap:var(--sp-2)}
.fcal-grid{display:grid;grid-template-columns:repeat(7,1fr)}
.fcal-dow{padding:8px 6px;text-align:center;font-size:var(--text-xs);font-weight:var(--fw-semibold);
  color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.03em;background:var(--surface-2);border-bottom:1px solid var(--border)}
.fcal-cell{min-height:104px;padding:6px;display:flex;flex-direction:column;gap:3px;
  border-right:1px solid var(--border);border-bottom:1px solid var(--border)}
.fcal-grid > .fcal-cell:nth-child(7n){border-right:none}
.fcal-daynum{align-self:flex-start;width:24px;height:24px;display:grid;place-items:center;border-radius:var(--radius-full);
  font-size:var(--text-xs);font-weight:var(--fw-medium);color:var(--foreground)}
.fcal-cell.is-out{background:var(--surface-2)}
.fcal-cell.is-out .fcal-daynum{color:var(--muted-foreground);opacity:.55}
.fcal-cell.is-today .fcal-daynum{background:var(--primary);color:var(--primary-foreground)}
.fcal-event{font-size:11px;line-height:1.35;padding:2px 6px;border-radius:var(--radius-sm);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;
  background:var(--primary-subtle);color:var(--primary-subtle-fg)}
.fcal-event.ev-success{background:color-mix(in srgb,var(--success-500) 16%,transparent);color:var(--success-700)}
.fcal-event.ev-warning{background:color-mix(in srgb,var(--warning-500) 18%,transparent);color:var(--warning-700)}
.fcal-event.ev-error{background:color-mix(in srgb,var(--error-500) 16%,transparent);color:var(--error-700)}
.fcal-more{font-size:11px;color:var(--muted-foreground);padding:0 6px}
[data-theme=dark] .fcal-event.ev-success,:root:has(.theme-toggle:checked) .fcal-event.ev-success{color:#6ce9a6}
[data-theme=dark] .fcal-event.ev-warning,:root:has(.theme-toggle:checked) .fcal-event.ev-warning{color:#fec84b}
[data-theme=dark] .fcal-event.ev-error,:root:has(.theme-toggle:checked) .fcal-event.ev-error{color:#fda29b}

/* ============================================================================
   FIN — parité composants shadcn/ui. Phase 2 livrée (charts, data table
   interactive, select stylé, drawer, tabs verticaux).
   ============================================================================ */
