/* ─────────────────────────────────────────────────────────────────────────
   Polices auto-hébergées (fontsource).
   Aucun appel réseau externe. Les variantes `latin-ext` ne sont téléchargées
   par le navigateur que si une lettre du range correspondant apparaît dans
   la page (mécanisme `unicode-range`).
   ───────────────────────────────────────────────────────────────────────── */

@font-face {
  font-family: 'DM Serif Display';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/dm-serif-display-latin-400-normal.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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'DM Serif Display';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/dm-serif-display-latin-ext-400-normal.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: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/cormorant-garamond-latin-300-normal.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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/cormorant-garamond-latin-ext-300-normal.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: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/cormorant-garamond-latin-400-normal.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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/cormorant-garamond-latin-ext-400-normal.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: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/cormorant-garamond-latin-400-italic.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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/cormorant-garamond-latin-ext-400-italic.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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-300-normal.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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-ext-300-normal.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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-400-normal.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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-ext-400-normal.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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-500-normal.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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-ext-500-normal.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;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
:root { color-scheme: dark; }

/* L'attribut [hidden] doit toujours l'emporter sur les display:flex/grid des
   classes — sinon une .drop-zone[hidden] reste visible (vrai bug observé). */
[hidden] { display: none !important; }

body {
  background: #0a0a0a;
  min-height: 100vh;
  padding: 64px 24px;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
button, input { font: inherit; }
button { -webkit-tap-highlight-color: transparent; cursor: pointer; }

.page-shell { width: min(100%, 980px); margin: 0 auto; }

/* ── Cadre éditorial principal ────────────────────────────────────── */
.lab {
  /* Tokens locaux mappés sur le design system parent (style.css).
     Les noms locaux (--paper, --ink, --accent...) sont conservés pour
     ne pas avoir à toucher aux ~1500 lignes de CSS qui les consomment.
     Le mode sombre fonctionne automatiquement : quand le parent
     bascule --color-bg, --color-text, --color-accent, etc., tous les
     tokens locaux suivent par référence. Pour --ko et --warn qui sont
     dérivés via color-mix, la résolution se fait à la lecture, donc
     la variante sombre est automatique aussi. */
  --paper: var(--color-bg);
  --ink: var(--color-text);
  --sepia: var(--color-text-soft);
  --muted: var(--color-text-faint);
  --accent: var(--color-accent);
  --accent-soft: color-mix(in srgb, var(--color-accent) 11%, transparent);
  --rule: var(--color-border);
  --rule-strong: var(--color-border-strong);
  --ok: var(--color-success);
  --warn: #b3791a;
  --ko: color-mix(in srgb, var(--color-accent) 70%, black);

  /* Tokens typographiques Audio Lab.
     Préfixe --al- pour rester autonome : un futur preset du parent
     (qui basculerait --font-display vers Space Grotesk, par exemple)
     ne doit pas affecter l'identité éditoriale chaude d'Audio Lab.
     Les @font-face correspondants sont déclarés en haut de ce fichier.
     Fallbacks lisibles si les woff2 ne se chargent pas. */
  --al-font-display:   'DM Serif Display', Georgia, serif;
  --al-font-editorial: 'Cormorant Garamond', Georgia, serif;
  --al-font-mono:      'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  position: relative;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  padding: 56px 48px 46px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.28);
}

/* Overrides mode sombre : motivés strictement par WCAG 2.1 AA.
   Le violet --color-accent (#726791) du parent et le faint --color-text-faint
   (#8295AC) tombent respectivement à 2.52:1 et 4.25:1 sur la surface en sombre,
   en échec ou en AA-large only — inadaptés pour les eyebrows, la clé musicale,
   les BPM et les support-notes qui sont en texte petit non-bold.
   Ces deux teintes éclaircies passent AA partout (≥5.0:1) et AAA sur le bg
   pour le muted (≥7.2:1). En clair, ces overrides ne s'appliquent pas. */
[data-theme="dark"] .lab {
  --accent: #A899C9; /* violet éclairci : 5.85:1 sur bg, 5.01:1 sur surface */
  --muted:  #A4B4CB; /* faint éclairci  : 7.23:1 sur bg, 6.19:1 sur surface */
}

/* Palette éditoriale viz — utilisée par les canvas (timeline, spectrogram, etc.).
   Indépendante de l'UI : ce sont des choix sémantiques propres aux visualisations
   (teal pour l'énergie, ocre pour la novelty, 4 couleurs pour les segments).
   Variantes sombres calculées pour passer le seuil WCAG 1.4.11 non-text 3:1
   sur fond --color-bg (toutes ≥5:1 en sombre, ≥5:1 en clair également).
   Les canvas lisent ces tokens via le helper theme.js. */
.lab {
  --viz-energy:    #2E5C5F; /* teal sourd  : 6.62:1 sur paper clair */
  --viz-novelty:   #694E3C; /* sépia ocre  : 6.76:1 sur paper clair */
  --viz-segment-a: #A8261C; /* rouille     : 6.29:1 — corrélé à l'accent éditorial */
  --viz-segment-b: #2E5C5F; /* teal        : 6.62:1 — = energy */
  --viz-segment-c: #785F32; /* ocre        : 5.35:1 */
  --viz-segment-d: #3C3C3C; /* gris neutre : 9.78:1 */
}
[data-theme="dark"] .lab {
  --viz-energy:    #7FB6BA; /* teal éclairci  : 6.75:1 sur bg sombre */
  --viz-novelty:   #C8A47A; /* ocre chaud     : 6.56:1 sur bg sombre */
  --viz-segment-a: #E08A7E; /* corail clair   : 5.88:1 sur bg sombre */
  --viz-segment-b: #7FB6BA; /* = energy       : 6.75:1 sur bg sombre */
  --viz-segment-c: #D4B97A; /* ocre clair     : 8.00:1 sur bg sombre */
  --viz-segment-d: #8896A8; /* gris bleuté    : 5.06:1 sur bg sombre */
}

.lab-bg {
  position: absolute; inset: 0;
  background-image:
    radial-gradient(circle at 18% 16%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 44%),
    radial-gradient(circle at 82% 76%, color-mix(in srgb, var(--accent) 5%, transparent), transparent 50%);
  pointer-events: none;
}
.lab > *:not(.lab-bg) { position: relative; }

/* ── En-tête ──────────────────────────────────────────────────────── */
.lab-header { margin-bottom: 40px; }
.lab-eyebrow {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.28em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 22px;
}
.lab-title {
  font-family: var(--al-font-display);
  font-size: clamp(40px, 7vw, 64px);
  line-height: 0.95;
  letter-spacing: -0.025em;
  font-weight: 400;
  margin-bottom: 16px;
}
.lab-subtitle {
  font-family: var(--al-font-editorial);
  font-size: 19px;
  line-height: 1.55;
  color: var(--sepia);
  max-width: 56ch;
}
.lab-subtitle em { color: var(--accent); font-style: italic; }

/* ── Drop zone ────────────────────────────────────────────────────── */
.drop-zone {
  border: 1.5px dashed var(--rule-strong);
  background: color-mix(in srgb, var(--ink) 2.5%, transparent);
  padding: 64px 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  transition: background 0.18s ease, border-color 0.18s ease;
  outline: none;
}
.drop-zone:hover,
.drop-zone:focus-visible,
.drop-zone.is-dragover {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.drop-zone.is-dragover { border-style: solid; }

.drop-inner { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.drop-icon { width: 56px; height: 56px; color: var(--sepia); }
.drop-zone.is-dragover .drop-icon { color: var(--accent); }
.drop-primary {
  font-family: var(--al-font-display);
  font-size: 28px;
  letter-spacing: -0.01em;
}
.drop-secondary {
  font-family: var(--al-font-editorial);
  font-size: 18px;
  color: var(--sepia);
}
.drop-pick {
  background: none;
  border: none;
  color: var(--accent);
  font-family: inherit;
  font-size: inherit;
  font-style: italic;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  padding: 0;
}
.drop-pick:hover { color: var(--ink); }
.drop-formats {
  font-family: var(--al-font-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--muted);
  text-transform: uppercase;
  margin-top: 6px;
}

/* ── Processing (étapes) ─────────────────────────────────────────── */
.processing {
  border-top: 1px solid var(--rule);
  margin-top: 32px;
  padding-top: 28px;
}
.processing-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 20px;
  margin-bottom: 18px;
}
.processing-filename {
  font-family: var(--al-font-mono);
  font-size: 13px;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 60ch;
}
.link-btn {
  background: none;
  border: none;
  color: var(--accent);
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  padding: 0;
  flex-shrink: 0;
}
.link-btn:hover { color: var(--ink); }

/* ── Bandeau de fin d'analyse ──────────────────────────────────────────
   Affiché quand data-phase=collapsed ou errors-only ou expanded.
   Pendant 'running', il est masqué (les chips parlent d'eux-mêmes).
   Mise en page : sur la même ligne que processing-header pour économiser
   de l'espace vertical à la fin de l'analyse. */
.processing-summary {
  display: none;            /* affiché en flex selon data-phase ci-dessous */
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: -8px;         /* compense le gap du header au-dessus */
  margin-bottom: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
  font-family: var(--al-font-mono);
  font-size: 12px;
  color: var(--sepia);
}
.processing-summary-duration {
  color: var(--ink);        /* la durée est l'info la plus saillante */
}
.processing-summary-sep {
  color: var(--muted);
}
.processing-summary-count {
  /* en cas d'erreurs, on accentue subtilement le décompte d'erreurs via
     la sémantique du texte — pas besoin de couleur spéciale ici, le
     bandeau reste éditorialement sobre */
  color: var(--sepia);
}
.processing-toggle {
  margin-left: auto;        /* aligne à droite */
  background: none;
  border: none;
  color: var(--accent);
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  padding: 0;
  cursor: pointer;
}
.processing-toggle:hover { color: var(--ink); }

/* Les deux labels du toggle : visibles selon la phase. Par défaut, on
   montre "tout voir" (état replié), masqué quand expanded. */
.processing-toggle-expand,
.processing-toggle-collapse {
  display: none;
}

/* ── Phases ──────────────────────────────────────────────────────────── */
/* Phase 'running' : par défaut. Pas de bandeau, tous les chips visibles. */
.processing[data-phase="running"] .processing-summary {
  display: none;
}

/* Phase 'collapsed' : tout OK, on masque les chips et on montre le bandeau. */
.processing[data-phase="collapsed"] .processing-summary {
  display: flex;
}
.processing[data-phase="collapsed"] .steps,
.processing[data-phase="collapsed"] .partial-error-notice {
  display: none;
}
.processing[data-phase="collapsed"] .processing-toggle-expand {
  display: inline;
}

/* Phase 'errors-only' : on garde le bandeau ; on masque seulement les
   chips dont data-state est 'done' ou 'pending'. Les chips 'error' et
   'running' (hypothétique reliquat) restent visibles. */
.processing[data-phase="errors-only"] .processing-summary {
  display: flex;
}
.processing[data-phase="errors-only"] .step[data-state="done"],
.processing[data-phase="errors-only"] .step[data-state="pending"],
.processing[data-phase="errors-only"] .step:not([data-state]) {
  display: none;
}
.processing[data-phase="errors-only"] .processing-toggle-expand {
  display: inline;
}

/* Phase 'expanded' : déclenchée par un clic sur 'tout voir' depuis un
   état replié. Tous les chips redeviennent visibles, le bandeau reste,
   et le toggle dit maintenant 'replier'. */
.processing[data-phase="expanded"] .processing-summary {
  display: flex;
}
.processing[data-phase="expanded"] .processing-toggle-collapse {
  display: inline;
}

/* ── Étapes de traitement — chips horizontaux ─────────────────────────
   Flow horizontal avec retour à la ligne automatique. Chaque chip est
   un état visuel autonome (pending / running / done / error), bordure
   subtile au repos, fond plein quand l'étape termine.

   data-state est posé directement sur le <li.step> par setStepState()
   (en plus de l'ancien <span.step-state> conservé pour compatibilité).
   On peut ainsi cibler en CSS pur sans :has() — compatible 100%. */
.steps {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.step {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 110px;          /* compromis : courts confortables, longs respirent */
  padding: 6px 12px;
  border: 1px solid var(--rule);
  border-radius: 999px;       /* pill */
  font-family: var(--al-font-mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--sepia);
  background: transparent;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.step-label {
  color: inherit;
}

/* L'ancien suffixe textuel "EN COURS / OK / ERREUR" est masqué :
   on garde le <span> pour l'accessibilité (lecteurs d'écran) mais
   pas d'affichage visuel — l'icône ::before suffit. */
.step-state {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Bullet/icône à gauche du label, gérée via ::before sur le <li>.
   Le contenu change selon data-state du chip. */
.step::before {
  content: "•";
  font-size: 11px;
  line-height: 1;
  width: 10px;
  text-align: center;
  flex-shrink: 0;
  color: var(--muted);
}

/* État running : bordure accent, fond accent-soft, icône qui pulse */
.step[data-state="running"] {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--ink);
}
.step[data-state="running"]::before {
  content: "◐";
  color: var(--accent);
  animation: pulse 1.4s ease-in-out infinite;
}

/* État done : fond ok plein, texte clair, bordure assortie */
.step[data-state="done"] {
  background: var(--ok);
  border-color: var(--ok);
  color: var(--paper);
}
.step[data-state="done"]::before {
  content: "✓";
  color: var(--paper);
  font-weight: 600;
}

/* État error : fond ko plein, texte clair, bordure assortie */
.step[data-state="error"] {
  background: var(--ko);
  border-color: var(--ko);
  color: var(--paper);
}
.step[data-state="error"]::before {
  content: "✗";
  color: var(--paper);
  font-weight: 600;
}

/* Notice discrète sous les étapes en cas d'analyse partiellement échouée */
.partial-error-notice {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--rule);
  font-family: var(--al-font-editorial);
  font-style: italic;
  font-size: 14px;
  color: var(--ko);
  line-height: 1.5;
}
.partial-error-notice strong {
  font-family: var(--al-font-mono);
  font-style: normal;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ko);
  display: inline-block;
  margin-right: 8px;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* ── Résultats — cards ───────────────────────────────────────────── */
.results {
  display: flex;
  flex-direction: column;
  gap: 28px;
  margin-top: 32px;
  border-top: 1px solid var(--rule);
  padding-top: 32px;
}
.card {
  border: 1px solid var(--rule);
  background: var(--color-surface);
  padding: 28px 30px;
  animation: card-in 0.45s ease-out;
}
@keyframes card-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
.card-header { margin-bottom: 22px; }
.card-eyebrow {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 10px;
}
/* .card-title supprimée — toutes les cards utilisent désormais .qc-title
   pour une hiérarchie cohérente. */
.card-lede {
  margin-top: 8px;
  font-family: var(--al-font-editorial);
  font-size: 17px;
  font-style: italic;
  color: var(--sepia);
  max-width: 60ch;
}

/* Grilles clé/valeur */
.kv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 20px 28px;
}
.kv-grid-large {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 28px 32px;
}
.kv dt {
  font-family: var(--al-font-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 6px;
}
.kv dt small {
  font-size: 0.9em;
  letter-spacing: 0.12em;
  opacity: 0.78;
  text-transform: none;
}
.card-foot {
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1px dashed var(--rule);
  font-family: var(--al-font-editorial);
  font-size: 14.5px;
  line-height: 1.55;
  font-style: italic;
  color: var(--muted);
  max-width: 64ch;
}
.card-foot em { font-style: normal; color: var(--sepia); }
.kv dd {
  font-family: var(--al-font-editorial);
  font-size: 22px;
  color: var(--ink);
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.kv-large dd { margin-bottom: 4px; }
.big-num {
  font-family: var(--al-font-display);
  font-size: 38px;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ink);
}
.unit {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.kv-note {
  font-family: var(--al-font-editorial);
  font-style: italic;
  font-size: 15px;
  color: var(--sepia);
  line-height: 1.4;
  margin-top: 4px;
  max-width: 32ch;
}

/* Waveform */
.waveform-wrap { position: relative; }
#waveform {
  width: 100%;
  height: 220px;
  display: block;
}
canvas.beats-track {
  display: block;
  width: 100%;
  height: 18px;
  margin-top: 4px;
}
.beats-hint {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-top: 12px;
  margin-bottom: 0;
}
.beats-hint strong {
  color: var(--ink);
  font-weight: 500;
}
.waveform-axis {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  text-transform: uppercase;
}

/* ── Erreur ───────────────────────────────────────────────────────── */
.error-panel {
  border-top: 1px solid var(--rule);
  margin-top: 32px;
  padding-top: 28px;
}
.error-title {
  font-family: var(--al-font-display);
  font-size: 28px;
  color: var(--ko);
  margin-bottom: 10px;
}
.error-message {
  font-family: var(--al-font-editorial);
  font-size: 18px;
  font-style: italic;
  color: var(--sepia);
  margin-bottom: 16px;
}

/* ── Footer ───────────────────────────────────────────────────────── */
.lab-footer {
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--rule);
}
.lab-footer p {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  line-height: 1.7;
}
.lab-footer em { color: var(--sepia); font-style: italic; }

/* ── Responsive ───────────────────────────────────────────────────── */
@media (max-width: 640px) {
  body { padding: 24px 12px; }
  .lab { padding: 36px 24px 32px; }
  .lab-title { font-size: 38px; }
  .drop-zone { padding: 44px 20px; }
  .card { padding: 22px 20px; }
  .big-num { font-size: 30px; }
}

/* ─────────────────────────────────────────────────────────────────────
   Loudness · courbe Short-term LUFS (card-loudness)
   ───────────────────────────────────────────────────────────────────── */
.loudness-curve-wrap {
  margin-top: 28px;
}
.loudness-curve-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}
.loudness-curve-hint {
  text-transform: none;
  letter-spacing: 0.04em;
  font-size: 12px;
}
canvas.loudness-curve {
  display: block;
  width: 100%;
  height: 180px;
  background: transparent;
}
.loudness-curve-axis {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
}

/* ─────────────────────────────────────────────────────────────────────
   Spectrogramme Mel (card-spectrogram)
   ───────────────────────────────────────────────────────────────────── */
.spectrogram-wrap {
  position: relative;
  /* padding-left réserve la place pour les labels de l'axe fréquence,
     qui sont positionnés en absolute par-dessus à gauche. */
  padding-left: 44px;
}
#spectrogram {
  display: block;
  width: 100%;
  height: 260px;
  background: var(--paper);
}
.spectrogram-axis-freq {
  /* Container des labels, hauteur du canvas. Les <span> à l'intérieur
     ont un `top: X%` calculé en JS pour coller à l'échelle Mel. */
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 40px;
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--muted);
  text-transform: uppercase;
}
.spectrogram-axis-freq span {
  position: absolute;
  right: 6px;
  transform: translateY(-50%);
  white-space: nowrap;
}
.spectrogram-axis-time {
  /* Aligné sur le canvas, donc on reprend le même padding-left que .wrap */
  padding-left: 44px;
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
}

/* ─────────────────────────────────────────────────────────────────────
   Stéréo + goniomètre Lissajous (card-stereo)
   ───────────────────────────────────────────────────────────────────── */
.stereo-mono-notice {
  font-family: var(--al-font-editorial);
  font-style: italic;
  font-size: 18px;
  color: var(--sepia);
  margin-top: 12px;
}

.stereo-body {
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
}
/* À partir d'une certaine largeur, chiffres à gauche, gonio à droite. */
@media (min-width: 720px) {
  .stereo-body {
    grid-template-columns: minmax(0, 1.4fr) minmax(220px, 1fr);
    align-items: start;
  }
  .stereo-body .kv-grid {
    margin-top: 0;
  }
}

.goniometer-wrap {
  display: flex;
  flex-direction: column;
}
.goniometer-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}
.goniometer-hint {
  text-transform: none;
  letter-spacing: 0.04em;
  font-size: 12px;
}
canvas.goniometer {
  display: block;
  width: 100%;
  /* Forcer carré : aspect-ratio s'applique au content-box. */
  aspect-ratio: 1 / 1;
  max-height: 280px;
  background: var(--paper);
}
.goniometer-legend {
  display: flex;
  justify-content: space-between;
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-top: 8px;
}
.goniometer-legend strong {
  color: var(--sepia);
  font-weight: normal;
  margin-right: 4px;
}

/* ─────────────────────────────────────────────────────────────────────
   Distribution par bandes (card-bands)
   ───────────────────────────────────────────────────────────────────── */

.bands-profile {
  margin: 8px 0 28px;
  padding: 18px 22px;
  background: var(--accent-soft);
  border-left: 2px solid var(--accent);
}
.bands-profile-label {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 8px;
}
.bands-profile-value {
  font-family: var(--al-font-display);
  font-size: 22px;
  line-height: 1.25;
  color: var(--ink);
  margin-bottom: 6px;
}
.bands-profile-note {
  font-family: var(--al-font-editorial);
  font-style: italic;
  font-size: 16px;
  color: var(--sepia);
  margin: 0;
}
.bands-profile-note strong {
  font-style: normal;
  font-weight: 600;
  color: var(--ink);
}

.bands-chart-wrap {
  margin-bottom: 24px;
}
canvas.bands-chart {
  display: block;
  width: 100%;
  height: 280px;
  background: transparent;
}

/* Table de chiffres précis : grille avec 4 colonnes alignées */
.bands-table {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 16px auto 12px;
  max-width: 640px;
  padding: 0;
  text-align: left;
}
.bands-row {
  display: grid;
  grid-template-columns: 1.4fr 1.4fr 0.8fr 1.1fr;
  align-items: baseline;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px dotted color-mix(in srgb, var(--sepia) 18.0%, transparent);
}
.bands-row:last-child {
  border-bottom: none;
}
.bands-row-label {
  font-family: var(--al-font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink);
  text-transform: uppercase;
}
.bands-row-range {
  font-family: var(--al-font-mono);
  font-size: 11px;
  color: var(--muted);
}
.bands-row-pct {
  font-family: var(--al-font-mono);
  font-size: 13px;
  color: var(--sepia);
  text-align: right;
  font-weight: 500;
}
.bands-row-db {
  font-family: var(--al-font-mono);
  font-size: 13px;
  color: var(--ink);
  text-align: right;
}
.bands-row-db .unit-inline {
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.08em;
}

@media (max-width: 560px) {
  .bands-row {
    grid-template-columns: 1fr 0.8fr 1fr;
    row-gap: 2px;
  }
  /* Sur mobile, on cache la colonne range (déjà implicite dans le label) */
  .bands-row-range { display: none; }
}

/* ─────────────────────────────────────────────────────────────────────
   Roue chromatique (card-chroma)
   v0.8 : le layout (grid 2 colonnes, dimensionnement) est désormais
   géré dans card-layouts.css (.card-chroma .chroma-wrap, etc.).
   On ne garde ici que les anciennes règles désactivées pour la trace.
   ───────────────────────────────────────────────────────────────────── */
/* Anciennes règles supprimées :
   .chroma-wrap { display:flex; flex-direction:column ... } — remplacée par grid
   canvas.chroma-wheel { max-width: 280px } — remplacée (max-width: 420px)
   .chroma-legend, .chroma-legend-label, .chroma-dominant — légende remplacée
   par le bloc .chroma-analysis (4 blocs verticaux). */

/* ─────────────────────────────────────────────────────────────────────
   Dynamique rythmique — BeatsLoudness (card-beats-loudness, v0.5.1)
   ───────────────────────────────────────────────────────────────────── */
.bl-chart-wrap {
  margin: 18px 0 8px;
  padding: 14px 14px 10px;
  border: 1px dotted color-mix(in srgb, var(--sepia) 18.0%, transparent);
  border-radius: 4px;
  background: rgba(245, 240, 232, 0.35);
}
canvas.bl-chart {
  display: block;
  width: 100%;
  height: 140px;
  background: transparent;
}

/* ─────────────────────────────────────────────────────────────────────
   Player audio (v0.6.0) — barre de transport pour la timeline
   ───────────────────────────────────────────────────────────────────── */
.al-player {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  margin: 14px 0;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: rgba(245, 240, 232, 0.45);
}
.al-play {
  width: 36px;
  height: 36px;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  transition: background-color 0.15s;
}
.al-play:hover:not(:disabled) { background: var(--accent-soft); }
.al-play:disabled { opacity: 0.4; cursor: not-allowed; }
.al-play svg { display: block; }

.al-player-times {
  font-family: var(--al-font-mono);
  font-size: 12px;
  color: var(--muted);
  display: flex;
  gap: 4px;
  align-items: baseline;
  flex-shrink: 0;
  min-width: 90px;
}
.al-player-sep { opacity: 0.4; }

.al-player-progress {
  flex: 1;
  height: 4px;
  background: var(--rule);
  border-radius: 2px;
  position: relative;
  cursor: pointer;
}
.al-player-fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  background: var(--accent);
  border-radius: 2px;
  width: 0%;
  pointer-events: none;
  transition: width 0.05s linear;
}
.al-player-progress:focus { outline: 2px solid var(--accent); outline-offset: 2px; }

.al-loop {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border: 1px solid var(--rule-strong);
  border-radius: 14px;
  background: transparent;
  color: var(--muted);
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.al-loop:hover:not(:disabled) {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}
.al-loop:disabled { opacity: 0.4; cursor: not-allowed; }
.al-loop[aria-pressed="true"] {
  background: var(--accent);
  color: #fdf6e3;
  border-color: var(--accent);
}
.al-loop svg { display: block; }

/* ─────────────────────────────────────────────────────────────────────
   Profil sonore avancé (card-profile, v0.5.2)
   ───────────────────────────────────────────────────────────────────── */
.profile-contrast-wrap {
  margin: 16px 0 12px;
  padding: 14px 14px 10px;
  border: 1px dotted color-mix(in srgb, var(--sepia) 18.0%, transparent);
  border-radius: 4px;
  background: rgba(245, 240, 232, 0.35);
}
.profile-section-label {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
.profile-section-note {
  font-size: 12px;
  color: var(--muted);
  margin: 8px 2px 0;
  line-height: 1.45;
}
canvas.profile-contrast {
  display: block;
  width: 100%;
  height: 110px;
  background: transparent;
}
.profile-contrast-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--al-font-mono);
  font-size: 10px;
  color: var(--muted);
  margin-top: 4px;
  padding: 0 4px;
}
.profile-gauges {
  margin-top: 14px;
}

/* =====================================================================
   v0.3.1 — Architecture en 3 axes
   En-tête fichier, bandeau résumé, sections empilées, verdict, lignes denses.
   ===================================================================== */

/* ─── En-tête fichier (remplace card-identity) ──────────────────────── */
.results-header {
  margin-top: 32px;
  padding-top: 32px;
  border-top: 1px solid var(--rule);
}
.results-header-main { margin-bottom: 20px; }
.results-header-eyebrow {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.results-header-title {
  font-family: var(--al-font-display);
  font-size: clamp(22px, 4vw, 32px);
  letter-spacing: -0.02em;
  font-weight: 400;
  line-height: 1.1;
  word-break: break-all;
}
.results-header-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px 24px;
  margin-top: 16px;
}
.rhm dt {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 4px;
}
.rhm dt small {
  font-size: 0.85em;
  letter-spacing: 0.1em;
  opacity: 0.7;
  text-transform: none;
}
.rhm dd {
  font-family: var(--al-font-mono);
  font-size: 13px;
  color: var(--ink);
}
.results-header-note {
  margin-top: 16px;
  font-family: var(--al-font-editorial);
  font-style: italic;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted);
  max-width: 64ch;
}
.results-header-note em {
  font-style: normal;
  color: var(--sepia);
}

/* ─── Bandeau résumé : 3 axes, 3 formes ─────────────────────────────── */
.summary-bar {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-top: 28px;
  /* Hauteur similaire entre les 3 cartouches pour donner un triptyque */
}
.summary-card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  background: var(--color-surface);
  border: 1px solid var(--rule);
  padding: 16px 18px 18px;
  min-height: 130px;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
  position: relative;
}
.summary-card:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.summary-card:active {
  transform: translateY(1px);
}
.summary-eyebrow {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 10px;
}

/* — Forme « verdict » (axe 1) ——————————————————————————————— */
.summary-quality-status {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.summary-verdict-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--muted);
  flex-shrink: 0;
}
.summary-quality[data-status="ok"] .summary-verdict-dot {
  background: var(--ok);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 12%, transparent);
}
.summary-quality[data-status="warn"] .summary-verdict-dot {
  background: var(--warn);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 14%, transparent);
}
.summary-quality[data-status="fail"] .summary-verdict-dot {
  background: var(--ko);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ko) 14%, transparent);
}
.summary-verdict-label {
  font-family: var(--al-font-display);
  font-size: 22px;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--ink);
}
.summary-quality-text {
  font-family: var(--al-font-editorial);
  font-size: 15px;
  line-height: 1.4;
  font-style: italic;
  color: var(--sepia);
}

/* — Forme « fiche » (axe 2) —————————————————————————————————— */
.summary-musical-headline {
  margin-bottom: 8px;
  font-family: var(--al-font-display);
  font-size: 22px;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--ink);
}
.summary-musical-sep {
  color: var(--muted);
  margin: 0 6px;
}
.summary-musical-text {
  font-family: var(--al-font-editorial);
  font-size: 15px;
  line-height: 1.4;
  font-style: italic;
  color: var(--sepia);
}

/* — Forme « mini-waveform » (axe 3) —————————————————————————— */
.summary-structure-canvas {
  display: block;
  width: 100%;
  height: 44px;
  margin: 4px 0 12px;
}
.summary-structure-text {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--sepia);
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
}
.summary-structure-arrow {
  color: var(--accent);
}
.summary-structure-cta {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 10px;
  color: var(--muted);
}

/* Note : le bandeau résumé n'est pas sticky. Il défile avec le reste de
   la page, donc il « disparaît en scrollant » naturellement. La classe
   .is-hidden-by-scroll a été retirée. */

/* Responsive : empiler sur mobile/tablette étroite */
@media (max-width: 720px) {
  .summary-bar {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .summary-card { min-height: 0; }
}

/* ─── Sections par axe ──────────────────────────────────────────────── */
.lab-section {
  margin-top: 40px;
  padding-top: 32px;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 22px;
  scroll-margin-top: 24px;
}
.lab-section-header { margin-bottom: 4px; }
.lab-section-eyebrow {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.lab-section-title {
  font-family: var(--al-font-display);
  font-size: clamp(28px, 5vw, 40px);
  letter-spacing: -0.02em;
  font-weight: 400;
  line-height: 1.05;
}
.lab-section-lede {
  margin-top: 10px;
  font-family: var(--al-font-editorial);
  font-size: 18px;
  font-style: italic;
  line-height: 1.45;
  color: var(--sepia);
  max-width: 60ch;
}
.lab-section-meta {
  margin-top: 12px;
  font-family: var(--al-font-mono);
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 64ch;
  padding: 10px 14px;
  border-left: 2px solid var(--rule-strong);
  background: color-mix(in srgb, var(--ink) 2.5%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   SYSTÈME DE CARDS DU DRAWER QUALITÉ AUDIO — v0.7.5
   Format unifié, centré, éditorial. Toutes les cards du drawer (verdict,
   loudness, stereo, bands) suivent ce même pattern :

     ┌─────────────────────────────────────────────────┐
     │                    EYEBROW                       │
     │                Titre principal                   │
     │            Valeur principale / hero              │
     │         Texte descriptif italique                │
     │                                                  │
     │   ┌────┐  ┌────┐  ┌────┐  ┌────┐                 │
     │   │ KPI│  │ KPI│  │ KPI│  │ KPI│                 │
     │   └────┘  └────┘  └────┘  └────┘                 │
     │                                                  │
     │      [Canvas / chart pleine largeur]             │
     │              [Disclosure]                        │
     └─────────────────────────────────────────────────┘

   Classes : préfixe .qc- (qualité card). Réutilisables card-à-card.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Conteneur de card — centrage de tout le contenu, padding généreux,
   fond subtil pour détacher de l'arrière-plan crème du drawer. */
.qc-card {
  text-align: center;
  padding: 36px 32px;
  background: var(--color-surface);
  border: 1px solid var(--rule);
}

/* Eyebrow (catégorie en haut) — mono petit, espacé, accent éditorial.
   Cohérent avec ce qu'utilise déjà loudness ("LOUDNESS · EBU R128"). */
.qc-eyebrow {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}

/* Titre principal (Verdict, Volume perçu, Champ stéréo...) en Cormorant
   éditorial. Pas en sans-serif Newsreader — le drawer titre lui-même
   est déjà en sans-serif, on cherche un contraste typographique. */
.qc-title {
  font-family: var(--al-font-display);  /* DM Serif Display */
  font-size: clamp(28px, 4vw, 38px);
  font-weight: 400;
  line-height: 1.15;
  color: var(--ink);
  margin: 0 0 24px;
  letter-spacing: -0.005em;
}

/* Variante avec dot de statut à gauche du titre (verdict).
   On centre l'ensemble dot+texte sans toucher au centrage de la card. */
.qc-title-with-status {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  justify-content: center;
}
.qc-status-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--muted);
  display: inline-block;
}
.qc-card[data-status="ok"]   .qc-status-dot { background: var(--ok); }
.qc-card[data-status="warn"] .qc-status-dot { background: var(--warn); }
.qc-card[data-status="fail"] .qc-status-dot { background: var(--ko); }
/* Le titre prend la couleur du statut en plus du dot — emphase visuelle */
.qc-card[data-status="ok"]   .qc-title { color: var(--ok); }
.qc-card[data-status="warn"] .qc-title { color: var(--warn); }
.qc-card[data-status="fail"] .qc-title { color: var(--ko); }

/* Hero number — la valeur principale (par ex. −9.5 LUFS, +0.42 corrélation).
   Très gros, Cormorant éditorial. Centré. */
.qc-hero {
  margin: 16px 0 8px;
}
.qc-hero-num {
  font-family: var(--al-font-editorial);
  font-size: clamp(56px, 8vw, 88px);
  font-weight: 400;
  font-style: normal;
  line-height: 1;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.qc-hero-unit {
  font-family: var(--al-font-mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  color: var(--muted);
  margin-left: 8px;
  vertical-align: middle;
  text-transform: uppercase;
}

/* Hero text — pour des PHRASES courtes mises en avant (et non des nombres).
   .qc-hero-num est réservé aux valeurs numériques (−9.5 LUFS, +0.42…).
   Pour un verdict textuel type "Très basseux — sub et basses dominent",
   utiliser .qc-hero-text qui reste lisible sans exploser. */
.qc-hero-text {
  font-family: var(--al-font-editorial);
  font-size: clamp(20px, 2.2vw, 26px);
  font-style: italic;
  font-weight: 400;
  line-height: 1.25;
  color: var(--ink);
  letter-spacing: -0.005em;
  max-width: 32ch;
  margin: 0 auto;
}

/* Texte descriptif (italique éditorial). Sous le hero ou sous le titre.
   Le format "summary" que tu aimes. Cormorant italique, 19px. */
.qc-note {
  font-family: var(--al-font-editorial);
  font-size: 19px;
  font-style: italic;
  line-height: 1.5;
  color: var(--ink);
  max-width: 60ch;
  margin: 0 auto;
}
/* Quand la note est dans un multi-paragraphe (verdict avec plusieurs raisons) */
.qc-note p {
  margin: 0 0 14px;
}
.qc-note p:last-child {
  margin-bottom: 0;
}
.qc-note p[data-level="warn"] {
  padding-left: 14px;
  border-left: 2px solid var(--warn);
}
.qc-note p[data-level="fail"] {
  padding-left: 14px;
  border-left: 2px solid var(--ko);
}

/* Grille de KPI — pattern réutilisable. 2/3/4 colonnes auto-fit selon
   la largeur disponible. Si moins de 4 KPI, ils prennent leur largeur
   naturelle, centrés. */
.qc-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 28px 32px;
  margin: 32px 0 8px;
  text-align: center;
}
.qc-kpi {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.qc-kpi-label {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}
.qc-kpi-num {
  font-family: var(--al-font-editorial);
  font-size: clamp(32px, 4vw, 44px);
  font-weight: 400;
  line-height: 1;
  color: var(--ink);
}
.qc-kpi-unit {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--muted);
  margin-left: 4px;
  text-transform: uppercase;
}
.qc-kpi-note {
  font-family: var(--al-font-editorial);
  font-size: 14px;
  font-style: italic;
  line-height: 1.4;
  color: var(--sepia);
  max-width: 28ch;
  margin-top: 2px;
}

/* Zone canvas / chart pleine largeur sous les KPI */
.qc-canvas-wrap {
  margin: 28px 0 0;
}
.qc-canvas-label {
  font-family: var(--al-font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}

/* Disclosure (Comprendre ces mesures) — discret, replié par défaut. */
.qc-disclosure {
  margin-top: 28px;
  border-top: 1px solid var(--rule);
  padding-top: 16px;
}
.qc-disclosure summary {
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  cursor: pointer;
  list-style: none;
  text-align: center;
}
.qc-disclosure summary::-webkit-details-marker { display: none; }
.qc-disclosure summary::before {
  content: '+ ';
}
.qc-disclosure[open] summary::before {
  content: '− ';
}
.qc-disclosure-body {
  font-family: var(--al-font-editorial);
  font-size: 16px;
  font-style: italic;
  line-height: 1.55;
  color: var(--sepia);
  max-width: 64ch;
  margin: 14px auto 0;
  text-align: left;
}

/* Désactiver l'ancien `.results { display: flex; gap: 28px }` qui ne sert
   plus puisque maintenant ce sont les `.lab-section` qui structurent. */
.results {
  display: block;
  gap: 0;
  margin-top: 0;
  border-top: none;
  padding-top: 0;
}

/* ─── Card : Verdict (axe Qualité) ─────────────────────────────────────
   Note v0.7.5 : la card-verdict utilise désormais le système unifié .qc-*
   (cf. SYSTÈME DE CARDS DU DRAWER QUALITÉ AUDIO en haut de ce fichier).
   Les styles spécifiques à .card-verdict (bordure latérale colorée, etc.)
   ont été remplacés par le système data-status sur .qc-card qui colore
   directement le titre et le dot. */

/* ─── Lignes denses (mesures détaillées) ──────────────────────────── */
.dense-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin: 16px auto 0;
  max-width: 640px;
  text-align: left;  /* le contenu de la liste reste aligné à gauche
                        même si la card .qc-card centre tout par défaut */
}
.dense-list .dense-row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) auto minmax(0, 2fr);
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px dotted var(--rule);
  align-items: baseline;
}
.dense-list .dense-row:last-child { border-bottom: none; }
.dense-list .dense-label {
  font-family: var(--al-font-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--muted);
  text-transform: uppercase;
}
.dense-list .dense-value {
  font-family: var(--al-font-mono);
  font-size: 14px;
  color: var(--ink);
  font-weight: 500;
  white-space: nowrap;
  text-align: right;
}
.dense-list .dense-note {
  font-family: var(--al-font-editorial);
  font-style: italic;
  font-size: 14.5px;
  line-height: 1.4;
  color: var(--sepia);
}
@media (max-width: 560px) {
  .dense-list .dense-row {
    grid-template-columns: 1fr auto;
  }
  .dense-list .dense-note {
    grid-column: 1 / -1;
    margin-top: 2px;
  }
}


/* =====================================================================
   v0.3.2 — Timeline composite (axe Structure)
   Un canvas unique qui superpose : waveform, énergie, beats, onsets.
   ===================================================================== */

.timeline-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  list-style: none;
  padding: 0;
  margin: 0 0 14px 0;
  font-family: var(--al-font-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  color: var(--muted);
  text-transform: uppercase;
}
.timeline-legend li {
  display: flex;
  align-items: center;
  gap: 8px;
}
.legend-swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.swatch-waveform {
  background: color-mix(in srgb, var(--ink) 35%, transparent);
}
.swatch-energy {
  /* Teal sourd, distinct du rouille des onsets et waveform */
  background: var(--viz-energy);
}
.swatch-beat {
  /* Représentation visuelle d'une barre verticale fine */
  width: 4px;
  background: color-mix(in srgb, var(--ink) 60%, transparent);
}
.swatch-onset {
  /* Représentation d'une cellule de densité (heatmap) */
  background: color-mix(in srgb, var(--viz-segment-a) 70%, transparent);
}
.swatch-novelty {
  /* Représentation de la courbe novelty */
  background: var(--viz-novelty);
}
.swatch-segment {
  /* Représentation d'une zone de section (cercle d'identification) */
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--viz-segment-a) 18%, transparent) 0%,
    color-mix(in srgb, var(--viz-segment-a) 18%, transparent) 50%,
    color-mix(in srgb, var(--viz-segment-b) 18%, transparent) 50%,
    color-mix(in srgb, var(--viz-segment-b) 18%, transparent) 100%);
}

/* Caveat sous la card-foot principale, ton plus discret */
.card-foot-caveat {
  margin-top: 8px;
  padding: 8px 12px;
  border-left: 2px solid color-mix(in srgb, var(--ink) 20%, transparent);
  background: color-mix(in srgb, var(--ink) 2.5%, transparent);
  font-size: 13px;
  font-style: italic;
}

.timeline-wrap {
  position: relative;
  width: 100%;
  margin-bottom: 6px;
}
canvas#timeline {
  display: block;
  width: 100%;
  height: 260px;
  background: color-mix(in srgb, var(--ink) 2.0%, transparent);
}
canvas.timeline-cursor {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 260px;
  pointer-events: none;
}
.timeline-wrap canvas#timeline { cursor: pointer; }
.timeline-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--al-font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  color: var(--muted);
  margin-top: 4px;
  padding: 0 2px;
}
.timeline-axis span {
  white-space: nowrap;
}

.timeline-hint {
  margin: 10px 0 8px 0;
  font-family: var(--al-font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--sepia);
  padding: 8px 12px;
  border-left: 2px solid var(--accent);
  background: var(--accent-soft);
}
.timeline-hint strong {
  color: var(--ink);
  font-weight: 600;
}

/* Responsive : sur mobile, la légende passe à la ligne plus tôt */
@media (max-width: 560px) {
  .timeline-legend {
    gap: 10px 14px;
    font-size: 10px;
  }
  canvas#timeline {
    height: 200px;
  }
}


/* ─────────────────────────────────────────────────────────────────────
   Card Comparaison Meyda ↔ Essentia (v0.8 — temporaire, benchmark)
   À retirer une fois la décision de migration prise.
   ───────────────────────────────────────────────────────────────────── */
.card-compare .compare-meta {
  display: flex;
  gap: 32px;
  margin: 8px 0 20px;
  font-family: var(--al-font-mono);
  font-size: 12px;
}
.card-compare .compare-meta-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.card-compare .compare-meta-label {
  color: var(--muted);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 10px;
}
.card-compare .compare-meta-value {
  color: var(--ink);
  font-size: 14px;
  font-weight: 600;
}

.card-compare .compare-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 12px;
  font-family: var(--al-font-body, system-ui);
}
.card-compare .compare-table thead th {
  text-align: left;
  font-family: var(--al-font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 400;
  padding: 8px 12px 10px;
  border-bottom: 1px solid var(--rule);
}
.card-compare .compare-table thead th:nth-child(2),
.card-compare .compare-table thead th:nth-child(3),
.card-compare .compare-table thead th:nth-child(4) {
  text-align: right;
}
.card-compare .compare-table tbody td {
  padding: 14px 12px;
  border-bottom: 1px dotted color-mix(in srgb, var(--rule) 60%, transparent);
  vertical-align: top;
  font-size: 14px;
  color: var(--ink);
}
.card-compare .compare-table tbody tr:last-child td {
  border-bottom: none;
}
.card-compare .compare-feature {
  font-weight: 600;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.card-compare .compare-feature-note {
  font-weight: 400;
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
}
.card-compare .compare-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--al-font-mono);
  font-size: 13px;
  color: var(--ink);
}
.card-compare .compare-diff {
  text-align: right;
  font-family: var(--al-font-mono);
  font-size: 12px;
  font-weight: 600;
}
/* Code couleur sur l'écart relatif */
.card-compare .compare-diff[data-level="ok"]      { color: var(--ok); }
.card-compare .compare-diff[data-level="fair"]    { color: var(--ink); }
.card-compare .compare-diff[data-level="warn"]    { color: var(--warn); }
.card-compare .compare-diff[data-level="fail"]    { color: var(--ko); }
.card-compare .compare-diff[data-level="unknown"] { color: var(--muted); }

/* Sur mobile, le tableau passe en pseudo-cartes verticales */
@media (max-width: 600px) {
  .card-compare .compare-table thead { display: none; }
  .card-compare .compare-table tbody tr {
    display: block;
    padding: 12px 0;
    border-bottom: 1px solid var(--rule);
  }
  .card-compare .compare-table tbody td {
    display: flex;
    justify-content: space-between;
    border: none;
    padding: 4px 0;
    text-align: left;
  }
  .card-compare .compare-num,
  .card-compare .compare-diff {
    text-align: right;
  }
  .card-compare .compare-num::before,
  .card-compare .compare-diff::before {
    content: attr(data-label);
    font-family: var(--al-font-mono);
    font-size: 10px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
  }
}
