/**
 * UMDB Factures — Design System tokens (Tailwind v4 CSS-first).
 *
 * Migration depuis le CDN Tailwind Play (cf. docs/design/DESIGN_SYSTEM.md).
 * Setup :
 *   1. npm install tailwindcss @tailwindcss/vite
 *   2. import "./assets/styles/app.css" dans app.ts (AssetMapper) ou entry Vite
 *   3. Supprimer <script src="https://cdn.tailwindcss.com"> de base.html.twig
 *   4. Supprimer le bloc <style> inline (305 lignes) de base.html.twig
 */

/* Tailwind v4 : preflight (reset) + thème par défaut.
   AssetMapper ne résout pas les bare specifiers CSS ("tailwindcss"),
   on pointe donc sur le fichier exposé par le package (cf. ticket de suivi
   pour brancher un vrai build Tailwind v4 : @tailwindcss/postcss ou bundle). */
@import "../../node_modules/tailwindcss/index.css";

/* ── Phosphor Duotone (remplace Lucide) — icônes premium two-tone.
   Serties via <link> dans base.html.twig (AssetMapper depuis node_modules),
   ce qui permet la résolution correcte des url() des fonts woff2/ttf.
   Palette duotone configurée plus bas dans @layer base. ── */

/* Fallback no-js : si JS ne charge pas (ou reveal_controller absent),
   tous les [data-reveal] restent visibles. Évite contenu invisible. */
.no-js [data-reveal], .no-js [data-reveal-stagger] > * {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}


/* ============================================================================
   DESIGN TOKENS — UMDB Factures (cf. DESIGN_SYSTEM.md)
   ========================================================================== */

@theme {
  /* === Fonts ===
     Inter (gratuit, premium SaaS standard). Ajouter via @font-face ou Google Fonts.
     NB : aucune police à chasse fixe. Inter couvre tout via ses OpenType features
     (cf. utilities .num / .num-display / .ref plus bas, DESIGN_SYSTEM.md §3.2). */
  --font-sans:    "Inter", system-ui, -apple-system, sans-serif;
  --font-display: "Inter", system-ui, sans-serif;

  /* === Neutres chauds (foundation) — JAMAIS de gray Tailwind froid ===
     Oklch : perceptuellement uniforme, contraste AA plus facile à tenir. */
  --color-canvas:        oklch(1 0 0);              /* #ffffff — fond principal */
  --color-warm:          oklch(0.98 0.005 60);      /* #faf9f7 — sections alternées */
  --color-surface:       oklch(1 0 0);              /* #ffffff — cartes */
  --color-ink:           oklch(0.20 0.005 60);      /* #18181b warm black — texte primaire */
  --color-ink-strong:    oklch(0.25 0.020 250);     /* neutre foncé réutilisable */
  --color-muted:         oklch(0.50 0.008 60);      /* #6b6864 — texte secondaire */
  --color-faint:         oklch(0.72 0.008 60);      /* #a8a6a2 — texte tertiaire */
  --color-line:          oklch(0.93 0.005 60);      /* #ebe8e3 — bordures subtiles */
  --color-line-strong:   oklch(0.86 0.008 60);      /* #d6d2cc — bordures marquées */

  /* === Primitives bleu UMDB ===
     Échelle du bleu signature #0C71C3 (= umdb-500), conversion oklch.
     Sert à construire les tokens sémantiques + les dégradés de charts.
     Le markup n'utilise JAMAIS ces primitives directement (DESIGN_SYSTEM.md §2). */
  --color-umdb-25:   oklch(0.985 0.008 247);
  --color-umdb-50:   oklch(0.97 0.015 247);
  --color-umdb-100:  oklch(0.94 0.030 247);
  --color-umdb-200:  oklch(0.88 0.055 247);
  --color-umdb-300:  oklch(0.78 0.090 247);
  --color-umdb-400:  oklch(0.66 0.120 247);
  --color-umdb-500:  oklch(0.53 0.140 247);   /* #0C71C3 — bleu signature */
  --color-umdb-600:  oklch(0.45 0.135 247);   /* #0A5FA3 — hover / CTA base */
  --color-umdb-700:  oklch(0.38 0.115 247);   /* liens texte (AA sur blanc) */
  --color-umdb-800:  oklch(0.30 0.085 247);
  --color-umdb-900:  oklch(0.24 0.060 247);

  /* === Primary = BLEU UMDB (action principale) === */
  --color-primary:        var(--color-umdb-500);
  --color-primary-hover:  var(--color-umdb-600);
  --color-primary-soft:   var(--color-umdb-50);
  --color-primary-muted:  var(--color-umdb-25);

  /* === Gold accent — premium touches (TRÈS rare) === */
  --color-gold:        oklch(0.55 0.080 75);        /* #a07c4a — or antique */
  --color-gold-hover:  oklch(0.48 0.085 75);        /* #8b6a3f */
  --color-gold-soft:   oklch(0.96 0.020 75);        /* #f8f3ec — bg badge premium */

  /* === Statuts (workflow factures) === */
  --color-success:       oklch(0.55 0.130 155);     /* #059669 emerald-600 */
  --color-success-soft:  oklch(0.97 0.030 155);     /* #ecfdf5 */
  --color-warning:       oklch(0.62 0.140 60);      /* #d97706 amber-600 */
  --color-warning-soft:  oklch(0.97 0.030 60);      /* #fffbeb */
  --color-danger:        oklch(0.55 0.180 25);      /* #dc2626 red-600 */
  --color-danger-soft:   oklch(0.97 0.020 25);      /* #fef2f2 */
  --color-info:          var(--color-umdb-500);      /* info aliasé sur le bleu UMDB */
  --color-info-soft:     var(--color-umdb-50);

  /* === Chart tokens (lus par assets/js/chart-theme.js) === */
  --chart-primary:      var(--color-umdb-500);
  --chart-primary-soft: var(--color-umdb-200);
  --chart-grid:         var(--color-line);
  --chart-axis:         var(--color-faint);
  --chart-text:         var(--color-muted);
  --chart-c1: var(--color-umdb-500);
  --chart-c2: oklch(0.62 0.140 60);
  --chart-c3: oklch(0.55 0.130 155);
  --chart-c4: oklch(0.55 0.080 75);
  --chart-c5: oklch(0.55 0.180 25);
  --chart-c6: oklch(0.58 0.090 300);

  /* === Radius === */
  --radius-sm:    0.375rem;
  --radius-md:    0.5rem;
  --radius-lg:    0.75rem;
  --radius-xl:    1rem;
  --radius-2xl:   1.25rem;
  --radius-full:  9999px;

  /* === Shadows — subtiles, jamais lourdes === */
  --shadow-xs:    0 1px 2px 0 rgba(24, 24, 27, 0.04);
  --shadow-sm:    0 1px 3px 0 rgba(24, 24, 27, 0.06), 0 1px 2px -1px rgba(24, 24, 27, 0.05);
  --shadow-md:    0 4px 6px -1px rgba(24, 24, 27, 0.07), 0 2px 4px -2px rgba(24, 24, 27, 0.04);
  --shadow-lg:    0 10px 15px -3px rgba(24, 24, 27, 0.08), 0 4px 6px -4px rgba(24, 24, 27, 0.05);

  /* === Easings signature (Emil Kowalski / easeOutExpo) === */
  --ease-out-premium:  cubic-bezier(0.16, 1, 0.3, 1);   /* signature reveals */
  --ease-out-snappy:   cubic-bezier(0.2, 0, 0, 1);      /* boutons, micro-interactions */
  --ease-in-out-fluid: cubic-bezier(0.77, 0, 0.175, 1); /* mouvement sur écran */
  --ease-drawer:       cubic-bezier(0.32, 0.72, 0, 1);  /* drawers / sheets */

  /* === Durées === */
  --duration-fast:     150ms;
  --duration-base:     200ms;
  --duration-slow:     400ms;
  --duration-reveal:   700ms;
}

/* ============================================================================
   BASE — reset & fondations
   ========================================================================== */

@layer base {
  html {
    -webkit-text-size-adjust: 100%;
    text-rendering: optimizeLegibility;
  }

  body {
    @apply bg-canvas text-ink font-sans antialiased;
    font-feature-settings: "ss01", "cv11";  /* Inter stylistic sets */
  }

  h1, h2, h3, h4, h5, h6 {
    @apply font-display;
    text-wrap: balance;
    letter-spacing: -0.02em;
  }

  /* Titres display = font-light (règle premium absolue) */
  h1 { @apply text-4xl md:text-5xl font-light tracking-[-0.03em]; }
  h2 { @apply text-3xl md:text-4xl font-light tracking-[-0.025em]; }
  h3 { @apply text-xl md:text-2xl font-medium tracking-[-0.02em]; }

  p { text-wrap: pretty; }

  /* Focus visible — ring gold signature */
  *:focus-visible {
    @apply outline-none ring-2 ring-gold ring-offset-2 ring-offset-canvas;
  }

  /* Selection */
  ::selection {
    background: var(--color-gold-soft);
    color: var(--color-ink);
  }

  /* Mesure de lecture */
  .prose-reader { max-width: 65ch; }

  /* Tabular nums pour montants (alignement parfait des chiffres) */
  .tabular { font-variant-numeric: tabular-nums; }

  /* ── Phosphor Duotone — palette tokens UMDB ──
     Primaire = ink (warm black), secondaire = faint (warm gray).
     Cohérent avec les neutres chauds (DESIGN_SYSTEM.md §2). La transparence
     du layer secondaire est réduite pour un rendu plus dense/premium. */
  .ph-duotone {
    color: currentColor;
    opacity: 1;
  }
  .ph-duotone::before {
    color: var(--color-faint);
    opacity: 0.8;
  }

  /* ── Variante « solide » : layer secondaire réduit pour un rendu plus net.
     À utiliser sur les icônes nues posées sur fond neutre (nav-links,
     empty-states, boutons d'action) où le duotone fade à 0.8 ferait « fond
     sale » (UNI-67). Les badges icon colorés (bg-*-soft) gardent le duotone
     normal, où le two-tone rend bien. */
  .ph-duotone-solid::before {
    opacity: 0.4;
  }

  /* ── Form base reset (équivalent @tailwindcss/forms, tokens UMDB) ──
     @tailwindcss/forms 0.5.x ne shippe AUCUN CSS (plugin JS Tailwind v3),
     inutilisable par AssetMapper (pas de build step). On réplique donc le
     reset de base inline, avec nos tokens (DESIGN_SYSTEM.md §3.5). Les
     utilities posées sur chaque input surchargent ces defaults
     (layer utilities > base). #}
  input:where([type="text"], [type="email"], [type="url"], [type="password"],
               [type="number"], [type="search"], [type="tel"], [type="date"],
               [type="datetime-local"], [type="time"], [type="month"], [type="week"]),
  textarea, select {
    appearance: none;
    background-color: var(--color-surface);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-md);
    color: var(--color-ink);
    font: inherit;
    padding: 0.625rem 0.875rem;
    line-height: 1.5;
  }
  textarea { resize: vertical; }
  input::placeholder, textarea::placeholder { color: var(--color-faint); }
  input:where([type="checkbox"], [type="radio"]) {
    accent-color: var(--color-gold);
  }
  /* Chevron natif masqué : on le restyle via utilities `appearance-none` + bg SVG au cas par cas */
}

/* ============================================================================
   COMPONENTS — composants réutilisables
   ========================================================================== */

@layer components {

  /* ── Buttons ──
     Règle Emil : active:scale + transition-[props] + ease-out-snappy.
     PAS de rounded-full (on est SaaS B2B premium, pas marketing). */
  .btn {
    @apply inline-flex items-center justify-center gap-2
           rounded-md px-4 py-2.5
           text-sm font-medium
           transition-[transform,background-color,border-color]
           duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)]
           active:scale-[0.98]
           focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gold focus-visible:ring-offset-2;
    text-decoration: none;
    cursor: pointer;
  }
  .btn-primary {
    @apply inline-flex items-center justify-center gap-2
           rounded-md px-4 py-2.5
           text-sm font-medium
           transition-[transform,background-color,border-color]
           duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)]
           hover:scale-[1.02] active:scale-[0.98]
            focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gold focus-visible:ring-offset-2 bg-primary-hover text-white shadow-sm hover:bg-primary;
  }
  .btn-secondary {
    @apply inline-flex items-center justify-center gap-2
           rounded-md px-4 py-2.5
           text-sm font-medium
           transition-[transform,background-color,border-color]
           duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)]
           active:scale-[0.98]
           focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gold focus-visible:ring-offset-2 bg-surface text-ink border border-line-strong hover:bg-warm;
  }
  .btn-ghost {
    @apply inline-flex items-center gap-1
           text-sm font-medium text-primary
           underline-offset-4 hover:underline hover:text-primary-hover
           transition-colors duration-[var(--duration-fast)];
    text-decoration: none;
  }
  .btn-danger {
    @apply inline-flex items-center justify-center gap-2
           rounded-md px-4 py-2.5
           text-sm font-medium
           transition-[transform,background-color,border-color]
           duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)]
           active:scale-[0.98]
           focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gold focus-visible:ring-offset-2 bg-danger text-white hover:bg-danger/90;
  }
  .btn-success {
    @apply inline-flex items-center justify-center gap-2
           rounded-md px-4 py-2.5
           text-sm font-medium
           transition-[transform,background-color,border-color]
           duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)]
           active:scale-[0.98]
           focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gold focus-visible:ring-offset-2 bg-success text-white hover:bg-success/90;
  }
  .btn-gold {
    @apply inline-flex items-center justify-center gap-2
           rounded-md px-4 py-2.5
           text-sm font-medium
           transition-[transform,background-color,border-color]
           duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)]
           hover:scale-[1.02] active:scale-[0.98]
           focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gold focus-visible:ring-offset-2 bg-gold text-white shadow-sm hover:bg-gold-hover;
  }
  .btn-sm { @apply px-3 py-1.5 text-xs; }
  .btn-lg { @apply px-6 py-3 text-base; }

  /* ── Cards ── */
  .card {
    @apply bg-surface border border-line rounded-lg overflow-hidden shadow-xs
           transition-[box-shadow,border-color]
           duration-[var(--duration-base)]
           [transition-timing-function:var(--ease-out-premium)];
  }
  .card:hover {
    @apply shadow-sm border-line-strong;
  }
  /* Variante sans hover : cards informatives (filtres, panneaux statiques).
     Même aspect que .card au repos, mais aucun effet au survol. */
  .card-static {
    @apply bg-surface border border-line rounded-lg overflow-hidden shadow-xs;
  }
  .card-header {
    @apply px-6 py-4 border-b border-line flex items-center justify-between;
  }
  .card-title {
    @apply text-base font-medium text-ink;
  }
  .card-body { @apply p-6; }

  /* ── Badges & pills ── */
  .badge {
    @apply inline-flex items-center gap-1 rounded-full px-2.5 py-0.5
           text-xs font-medium whitespace-nowrap;
  }
  .badge-success { @apply bg-success-soft text-success; }
  .badge-warning { @apply bg-warning-soft text-warning; }
  .badge-danger  { @apply bg-danger-soft text-danger; }
  .badge-info    { @apply bg-info-soft text-info; }
  .badge-neutral { @apply bg-warm text-muted border border-line; }
  .badge-gold    { @apply bg-gold-soft text-gold; }

  /* ── Nav links ── */
  .nav-link {
    @apply relative inline-flex items-center gap-2 px-3 py-2
           text-sm font-medium text-muted
           rounded-md
           transition-colors duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)]
           hover:text-ink hover:bg-warm;
    text-decoration: none;
  }
  .nav-link-active {
    @apply text-primary bg-primary-soft;
  }

  /* ── Flash messages ── */
  .flash-msg {
    @apply flex items-center gap-2.5 rounded-md px-4 py-3
           text-sm font-medium border shadow-xs;
  }
  .flash-msg-success { @apply bg-success-soft text-success border-success/20; }
  .flash-msg-error   { @apply bg-danger-soft text-danger border-danger/20; }
  .flash-msg-info    { @apply bg-info-soft text-info border-info/20; }
  .flash-msg-warning { @apply bg-warning-soft text-warning border-warning/20; }

  /* ── KPI value (montant grand) ── */
  .kpi-value {
    @apply font-display font-light text-3xl text-ink
           num-display;
  }
  .kpi-label {
    @apply text-xs font-medium text-faint uppercase tracking-wider;
  }

  /* ============================================================================
     COMPOSANTS PARTAGÉS (migration depuis le <style> inline de base.html.twig)
     Conservés le temps que les pages soient migrées vers utilities/.card
     (Phase 4). Token-adaptés au design system UMDB.
     ========================================================================== */

  /* ── KPI cards (dashboard / admin) ── */
  .kpi-card {
    @apply bg-surface border border-line rounded-lg shadow-xs p-5;
  }
  .kpi-icon {
    @apply size-9 rounded-md flex items-center justify-center shrink-0;
  }
  .kpi-icon-blue    { @apply bg-info-soft text-info; }
  .kpi-icon-amber   { @apply bg-warning-soft text-warning; }
  .kpi-icon-indigo  { @apply bg-primary-soft text-primary; }
  .kpi-icon-emerald { @apply bg-success-soft text-success; }
  .kpi-icon-purple  { @apply bg-gold-soft text-gold; }
  .kpi-icon-red     { @apply bg-danger-soft text-danger; }

  /* ── Data table ── */
  .data-table { @apply w-full text-sm border-collapse; }
  .data-table thead th {
    @apply px-6 py-3 text-left text-xs font-semibold text-faint
           uppercase tracking-wider bg-warm/80 border-b border-line;
  }
  .data-table tbody td { @apply px-6 py-3.5 border-b border-line; }
  .data-table tbody tr:last-child td { @apply border-b-0; }
  .data-table tbody tr {
    @apply transition-[background-color] duration-[var(--duration-fast)]
           [transition-timing-function:var(--ease-out-snappy)];
  }
  .data-table tbody tr:hover td { @apply bg-warm/60; }

  /* ── Link primary ── */
  .link-primary {
    @apply text-primary underline-offset-2
           hover:text-primary-hover hover:underline
           transition-colors duration-[var(--duration-fast)];
    text-decoration: none;
  }

  /* ── Empty state ── */
  .empty-state { @apply text-center py-10 px-6 text-faint; }

  /* ── Leaderboard ── */
  .leaderboard-item {
    @apply flex items-center gap-3 p-2.5 rounded-md
           transition-colors duration-[var(--duration-fast)];
  }
  .leaderboard-gold   { @apply bg-gold-soft border border-gold/30; }
  .leaderboard-silver { @apply bg-warm border border-line; }
  .leaderboard-bronze { @apply bg-warning-soft border border-warning/30; }
  .leaderboard-rank {
    @apply w-7 text-center font-bold tabular-nums shrink-0;
  }

  /* ── Stat hero — mega chiffre KPI (TTC hero, total annuel) ── */
  .stat-hero {
    @apply font-display num-display text-ink;
    font-size: clamp(2.5rem, 1.5rem + 4vw, 4rem);
    line-height: 1.05;
  }

  /* ── Progress bar (budgets, objectifs) — bleu UMDB ── */
  .progress-track {
    @apply w-full h-2 rounded-full bg-warm overflow-hidden;
  }
  .progress-fill {
    @apply h-full rounded-full bg-primary transition-[width]
           duration-[var(--duration-slow)]
           [transition-timing-function:var(--ease-out-premium)];
  }
  .progress-fill-success { @apply bg-success; }
  .progress-fill-warning { @apply bg-warning; }
  .progress-fill-danger  { @apply bg-danger; }

  /* ── Sparkline — mini courbe SVG inline pour KPI secondaires ── */
  .sparkline {
    @apply inline-block align-middle;
  }
  .sparkline-path {
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* ── Pagination ── */
  .pagination-btn {
    @apply inline-flex items-center gap-1 px-3 py-1.5
           text-xs font-medium text-muted
           bg-surface border border-line rounded-md hover:bg-warm
           transition-colors duration-[var(--duration-fast)];
    text-decoration: none;
    cursor: pointer;
  }

  /* ── Badge pending (compteur de notif sur les liens de nav) ── */
  .badge-pending {
    @apply absolute -top-0.5 -right-1.5 min-w-[18px] h-[18px] px-1.5
           bg-danger text-white text-[11px] font-semibold rounded-full
           border-2 border-canvas shadow-xs
           flex items-center justify-center;
  }
}

/* ============================================================================
   MOTION — scroll reveals (signature premium)
   ========================================================================== */

[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity var(--duration-reveal) var(--ease-out-premium),
    transform var(--duration-reveal) var(--ease-out-premium);
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

[data-reveal-stagger] > * {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity var(--duration-reveal) var(--ease-out-premium),
    transform var(--duration-reveal) var(--ease-out-premium);
}
[data-reveal-stagger].is-visible > * { opacity: 1; transform: translateY(0); }
[data-reveal-stagger].is-visible > *:nth-child(1) { transition-delay: 0ms; }
[data-reveal-stagger].is-visible > *:nth-child(2) { transition-delay: 80ms; }
[data-reveal-stagger].is-visible > *:nth-child(3) { transition-delay: 160ms; }
[data-reveal-stagger].is-visible > *:nth-child(4) { transition-delay: 240ms; }
[data-reveal-stagger].is-visible > *:nth-child(5) { transition-delay: 320ms; }
[data-reveal-stagger].is-visible > *:nth-child(6) { transition-delay: 400ms; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal], [data-reveal-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ============================================================================
   NUMERIC UTILITIES — chiffres financiers (Tailwind v4 @utility)
   Remplace l'ancienne police à chasse fixe partout (cf. DESIGN_SYSTEM.md §3.2).
   Déclarés via @utility (et non @layer) pour rester @apply-ables
   (.kpi-value, .stat-hero). Approche Stripe / Mercury / Linear : aucun mono.
   ========================================================================== */

@utility num {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum", "lnum", "ss01";
  letter-spacing: -0.011em;
}
@utility num-zero {
  font-variant-numeric: tabular-nums lining-nums slashed-zero;
  font-feature-settings: "tnum", "lnum", "zero", "ss01";
}
@utility num-display {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum", "lnum", "ss01";
  font-weight: 300;
  letter-spacing: -0.03em;
}
@utility ref {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  letter-spacing: 0.02em;
  font-weight: 500;
}
@utility currency {
  font-weight: 400;
  margin-left: 0.1em;
  font-size: 0.85em;
  vertical-align: 0.05em;
}

/* ============================================================================
   UTILITIES
   ========================================================================== */

@layer utilities {
  /* Cacher scrollbar pour carrousels natifs (scroll-snap) */
  .scrollbar-hidden {
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .scrollbar-hidden::-webkit-scrollbar { display: none; }

  /* Touch target minimum (RGAA 2.5.5 / 2.5.8) */
  .touch-target {
    min-width: 44px;
    min-height: 44px;
  }

  /* ── Animation d'ouverture/fermeture des <details> (tableaux de données)
     Technique grid-template-rows 0fr → 1fr : transition fluide sans JS.
     Le contenu doit être enveloppé dans .details-expandable > .details-inner. ── */
  .details-expandable {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--duration-slow) var(--ease-out-premium);
  }
  details[open] > .details-expandable {
    grid-template-rows: 1fr;
  }
  .details-expandable > .details-inner {
    overflow: hidden;
    min-height: 0;
    opacity: 0;
    transform: translateY(8px);
    transition:
      opacity var(--duration-slow) var(--ease-out-premium),
      transform var(--duration-slow) var(--ease-out-premium);
  }
  details[open] > .details-expandable > .details-inner {
    opacity: 1;
    transform: translateY(0);
    transition-delay: calc(var(--duration-fast) * 0.5);
  }
}
