/* ====================================================================
   OVNI · Design System UNIFIÉ — source de vérité unique.
   Remplace colors_and_type_v4.css + colors_and_type_v5.css + futurist.css
   + le <style id="ovni-bg-hotfix"> inline de base.html.

   UN seul langage visuel ("futurist"), DEUX modes de surface :
     <html data-theme="dark">   (par défaut, violet sombre — signature OVNI)
     <html data-theme="light">  (même langage, surfaces claires)

   Les composants référencent des tokens ; seules les VALEURS des tokens
   changent entre dark/light. Aucun composant n'a besoin d'être touché.

   Polices chargées par base.html (Google Fonts) : Geist / JetBrains Mono /
   Source Serif 4 — pas de @import ici.
   ==================================================================== */

/* ── Statique (identique dans les deux modes) ───────────────────────── */
:root {
  --font-sans:  "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, "Noto Sans", sans-serif;
  --font-mono:  "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  /* Display éditorial : Newsreader (raffiné) en tête, Source Serif 4 en repli. */
  --font-serif: "Newsreader", "Source Serif 4", "Charter", "Iowan Old Style", Georgia, "Times New Roman", Times, serif;

  /* Échelle de texte */
  --text-10: 10px; --text-11: 11px; --text-xs: 12px; --text-sm: 14px;
  --text-base: 16px; --text-lg: 18px; --text-xl: 20px; --text-2xl: 24px;
  --text-3xl: 30px; --text-4xl: 36px; --text-5xl: 48px; --text-6xl: 60px;

  /* Rayons — noms futurist (--r-*) ET v4 (--radius-*), tous deux référencés */
  --r-xs: 3px;  --r-sm: 5px;  --r-md: 8px;  --r-lg: 12px;
  --radius-sm: 4px; --radius-md: 6px; --radius-lg: 8px; --radius-full: 9999px;

  --container-max: 80rem;
}

/* ====================================================================
   TOKENS · MODE SOMBRE (valeurs futurist actuelles — signature OVNI)
   ==================================================================== */
[data-theme="dark"] {
  /* surfaces — gris neutre près-noir (langage Linear / Vercel) */
  --paper:        #09090b;
  --paper-2:      #131316;   /* cards / nav / footer */
  --paper-3:      #1d1d21;   /* hover / zones surélevées */
  --paper-inset:  #050506;   /* champs de saisie */
  /* ink — gris neutres */
  --ink:    #f4f4f5;
  --ink-2:  #c9c9d1;         /* corps de texte, lecture longue */
  --ink-3:  #8c8c95;
  --ink-4:  #5a5a63;
  --ink-5:  #2a2a30;
  /* rules */
  --rule:   #28282d;         /* hairline */
  --rule-2: #1c1c20;
  /* accent indigo sobre (signature affinée, plus "SaaS" que néon) */
  --ink-red:       #818cf8;
  --ink-red-2:     #a0a8fb;
  --ink-red-glow:  rgba(129,140,248,0.16);
  --ink-red-tint:  rgba(129,140,248,0.10);
  /* secondaire cyan ("emerald") */
  --emerald:       #56c5ec;
  --emerald-2:     #7ad3f2;
  --emerald-glow:  rgba(86,197,236,0.16);
  --emerald-tint:  rgba(86,197,236,0.10);
  /* ambre — urgence "expire bientôt" */
  --amber:         #eab14a;
  --amber-tint:    rgba(234,177,74,0.13);
  /* data viz (sparkline / historique 90j — dégradé indigo→cyan) */
  --line:         #818cf8;
  --line-soft:    #5a5f8f;
  --area-top:     rgba(129,140,248,0.20);
  --area-bottom:  rgba(129,140,248,0);
  --grid:         rgba(255,255,255,0.05);
  --grid-2:       rgba(255,255,255,0.09);
  --spark:        var(--ink-red);
  --spark-soft:   rgba(129,140,248,0.14);
  --spark-grad-a: #818cf8;
  --spark-grad-b: #56c5ec;

  /* sur-accent (texte posé sur un fond accent plein) */
  --on-accent:  #0a0a0f;
  --shadow-card: 0 1px 2px rgba(0,0,0,0.4);
  --shadow-lift: 0 8px 24px rgba(0,0,0,0.45);

  /* ── Alias génériques (v4/v5 + noms Claude Design) ── */
  --bg:            var(--paper);
  --surface:       var(--paper-2);
  --surface-2:     var(--paper-3);
  --surface-inset: var(--paper-inset);
  --fg:            var(--ink);
  --fg-muted:      var(--ink-2);
  --fg-subtle:     var(--ink-3);
  --fg-faint:      var(--ink-4);
  --border:        var(--rule);
  --border-2:      var(--rule-2);
  --border-strong: var(--rule-2);
  --hairline:      1px solid var(--rule);
  --accent:        var(--ink-red);
  --accent-2:      var(--ink-red-2);
  --accent-tint:   var(--ink-red-tint);
  --accent-glow:   var(--ink-red-glow);
  --cyan:          var(--emerald);
  --cyan-tint:     var(--emerald-tint);
}

/* ====================================================================
   TOKENS · MODE CLAIR (même langage, surfaces claires, accent + profond)
   ==================================================================== */
[data-theme="light"] {
  /* surfaces — blanc neutre propre (langage Stripe / Vercel) */
  --paper:        #fafafa;
  --paper-2:      #ffffff;
  --paper-3:      #f4f4f5;   /* zones / hover (zinc-100) */
  --paper-inset:  #fafafa;
  /* ink (texte) — gris zinc neutres */
  --ink:    #18181b;
  --ink-2:  #3f3f46;
  --ink-3:  #71717a;         /* ~4.6:1 sur blanc */
  --ink-4:  #a1a1aa;         /* micro-labels mono */
  --ink-5:  #d4d4d8;
  /* rules */
  --rule:   #e4e4e7;         /* hairline (zinc-200) */
  --rule-2: #f0f0f2;
  /* accent indigo profond — contraste ~6.9:1 sur blanc */
  --ink-red:       #4f46e5;
  --ink-red-2:     #4338ca;
  --ink-red-glow:  rgba(79,70,229,0.14);
  --ink-red-tint:  rgba(79,70,229,0.08);
  /* secondaire cyan profond LISIBLE ~4.4:1 */
  --emerald:       #0b7aa3;
  --emerald-2:     #1aa3d1;
  --emerald-glow:  rgba(11,122,163,0.14);
  --emerald-tint:  rgba(11,122,163,0.11);
  /* ambre or profond ~5.2:1 */
  --amber:         #9c6710;
  --amber-tint:    rgba(156,103,16,0.13);
  /* data viz */
  --line:         #4f46e5;
  --line-soft:    #c7c9f0;
  --area-top:     rgba(79,70,229,0.14);
  --area-bottom:  rgba(79,70,229,0);
  --grid:         rgba(24,24,27,0.05);
  --grid-2:       rgba(24,24,27,0.10);
  --spark:        var(--ink-red);
  --spark-soft:   rgba(79,70,229,0.10);
  --spark-grad-a: #4f46e5;
  --spark-grad-b: #0b7aa3;

  --on-accent:  #ffffff;
  --shadow-card: 0 1px 2px rgba(17,17,17,0.05), 0 1px 3px rgba(17,17,17,0.07);
  --shadow-lift: 0 6px 20px rgba(17,17,17,0.10);

  /* ── Alias génériques (v4/v5 + noms Claude Design) ── */
  --bg:            var(--paper);
  --surface:       var(--paper-2);
  --surface-2:     var(--paper-3);
  --surface-inset: var(--paper-inset);
  --fg:            var(--ink);
  --fg-muted:      var(--ink-2);
  --fg-subtle:     var(--ink-3);
  --fg-faint:      var(--ink-4);
  --border:        var(--rule);
  --border-2:      var(--rule-2);
  --border-strong: var(--rule-2);
  --hairline:      1px solid var(--rule);
  --accent:        var(--ink-red);
  --accent-2:      var(--ink-red-2);
  --accent-tint:   var(--ink-red-tint);
  --accent-glow:   var(--ink-red-glow);
  --cyan:          var(--emerald);
  --cyan-tint:     var(--emerald-tint);
}

/* ====================================================================
   BASE
   ==================================================================== */
html { background-color: var(--paper); min-height: 100vh; }
body, body.ovni {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  background-color: var(--paper);
  color: var(--ink-2);
  -webkit-font-smoothing: antialiased;
  margin: 0;
  transition: background-color .25s ease, color .25s ease;
}
main { background-color: transparent; }
.mono { font-family: var(--font-mono); }
.tnum { font-variant-numeric: tabular-nums; }

/* ====================================================================
   TYPE PRIMITIVES (ex-v4)
   ==================================================================== */
.ovni-display {
  font-family: var(--font-serif); font-weight: 600;
  letter-spacing: -0.018em; line-height: 1.05; color: var(--fg); text-wrap: balance;
}
.ovni-display-sm {
  font-family: var(--font-serif); font-weight: 600;
  letter-spacing: -0.012em; line-height: 1.15; color: var(--fg); text-wrap: balance;
}
.ovni-h-internal {
  font-family: var(--font-sans); font-weight: 600;
  letter-spacing: -0.01em; color: var(--fg);
}
.ovni-num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.ovni-micro {
  font-size: var(--text-11); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--fg-subtle); font-weight: 500;
}
.ovni-accent { color: var(--ink-red); }
.ovni-accent-bg { background: var(--ink-red); color: var(--on-accent);
  transition: background-color 150ms ease, transform 150ms ease; }
.ovni-accent-bg:hover { background: var(--ink-red-2); }
.ovni-accent-bg:active { transform: translateY(1px); }
.ovni-focus:focus-visible {
  outline: none; box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--ink-red);
}
.ovni-hairline > * + * { border-top: var(--hairline); }
.ovni-trans { transition: background-color 150ms, opacity 150ms; }
.ovni-nav-active {
  color: var(--ink-red); background-color: var(--ink-red-tint); font-weight: 500;
}
/* (#ovni-countdown retiré 2026-07-08 avec le compte à rebours fabriqué de la fiche.) */

/* ── Tone toggle (presse / mesuré / sobre) — ex-v4, conservé ── */
html:not([data-tone="presse"]) .press-only { display: none !important; }
html:not([data-tone="presse"]) .lede-italic {
  font-family: var(--font-sans) !important; font-style: normal !important;
  font-size: 16px !important; line-height: 1.55 !important; color: var(--fg-muted) !important;
}
.title-mesure { display: none; }
html:not([data-tone="presse"]) .title-presse { display: none; }
html:not([data-tone="presse"]) .title-mesure { display: block; }
html[data-tone="sobre"] .ovni-display:not(.hero-keep),
html[data-tone="sobre"] .ovni-display-sm {
  font-family: var(--font-sans) !important; font-weight: 700 !important; letter-spacing: -0.02em !important;
}
html[data-tone="sobre"] .ovni-display:not(.hero-keep) { font-size: 36px !important; }

/* ====================================================================
   LIVE PRIMITIVES (ex-v5)
   ==================================================================== */
@keyframes ovni-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.92); }
}
.live-pulse, .live-pulse-soft {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink-red); vertical-align: middle; flex-shrink: 0;
}
.live-pulse { animation: ovni-pulse 2s ease-in-out infinite; }
.live-pulse-soft { background: var(--ink-red-glow); animation: ovni-pulse 3.5s ease-in-out infinite; }
.live-pulse-stale { background: var(--fg-faint); animation: none; }
@media (prefers-reduced-motion: reduce) { .live-pulse, .live-pulse-soft { animation: none; } }

.fresh-bar {
  height: 32px; display: flex; align-items: center; gap: 18px; padding: 0 24px;
  background: var(--paper-2); border-bottom: 1px solid var(--rule);
  font-family: var(--font-mono); font-size: var(--text-11);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-2);
}
.fresh-bar .num { text-transform: none; letter-spacing: 0; color: var(--ink); }
.fresh-bar .ovni-accent { letter-spacing: 0.08em; }
.fresh-bar a { color: var(--ink); text-decoration: none; margin-left: auto; }
.fresh-bar a:hover { color: var(--ink-red); }

.blur-teaser { filter: blur(4px); user-select: none; pointer-events: none; display: inline-block; }
.blur-teaser-strong { filter: blur(6px); }
.lock-overlay { position: relative; isolation: isolate; }
.lock-overlay > .lock-content { filter: blur(8px); pointer-events: none; user-select: none; }
.lock-overlay::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 0%, var(--paper-2) 80%); z-index: 1;
}
.lock-cta {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 2;
  display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px;
  background: var(--ink-red); color: var(--on-accent); border-radius: var(--r-md);
  font-size: var(--text-sm); font-weight: 600; text-decoration: none;
  transition: background-color 150ms ease, transform 150ms ease;
}
.lock-cta:hover { background: var(--ink-red-2); transform: translateX(-50%) translateY(-1px); }
.lock-cta:active { transform: translateX(-50%) translateY(0); }
.pill-locked {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px;
  background: transparent; border: 1px solid var(--ink-red); color: var(--ink-red);
  border-radius: 3px; font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
  font-weight: 600; cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}
.pill-locked:hover { background: var(--ink-red); color: var(--on-accent); }

/* ── Chip marketplace (remplace les drapeaux PNG / emojis) ──────────────
   Pastille typographique : point couleur du marché + code pays en mono.
   Cohérent dark/light (tokens). Utilisé via le filtre `marketplace_chip`. */
.mp {
  display: inline-flex; align-items: center;
  font-family: var(--font-mono); font-size: 9px; font-weight: 500;
  letter-spacing: 0.10em; text-transform: uppercase; color: var(--ink-3);
  border: 1px solid var(--rule); border-radius: 3px; padding: 1px 5px; line-height: 1.5;
  vertical-align: middle; white-space: nowrap;
}
.mp::before {
  content: ""; display: inline-block; width: 4px; height: 4px; border-radius: 50%;
  margin-right: 5px; background: var(--mp-dot, var(--ink-4));
}
.mp-fr { --mp-dot: #6366f1; } .mp-de { --mp-dot: #eab14a; }
.mp-es { --mp-dot: #e0564f; } .mp-it { --mp-dot: #3fb98a; }
.mp-uk { --mp-dot: #5b9bf8; } .mp-other { --mp-dot: var(--ink-4); }
.deal-live-bar {
  display: flex; align-items: center; gap: 12px; padding: 12px 24px;
  background: var(--paper-2); border-bottom: 1px solid var(--rule);
  font-size: var(--text-sm); color: var(--ink);
}
.deal-live-bar .state { display: inline-flex; align-items: center; gap: 8px; }
.deal-live-bar .state-text { font-weight: 500; }
.deal-live-bar .viewers { margin-left: auto; color: var(--ink-2); font-size: var(--text-xs); }
/* .cta-urgent (halo pulsant en boucle) retiré 2026-07-08 : classe orpheline
   (0 usage markup) + anti-pattern DESIGN.md (motion décorative). */

/* ====================================================================
   ADAPTATEUR Tailwind (ex-futurist) — remappe les utilitaires neutres/red/
   emerald vers les tokens du thème. !important volontaire : c'est une couche
   d'adaptation qui doit battre les utilitaires Tailwind quel que soit l'ordre
   de chargement. S'applique aux DEUX thèmes (les tokens flippent tout seuls).
   ==================================================================== */
.bg-white       { background-color: var(--paper-2) !important; }
.bg-neutral-50  { background-color: var(--paper)   !important; }
.bg-neutral-100 { background-color: var(--paper-3) !important; }
.bg-neutral-900 { background-color: var(--ink-red) !important; color: var(--on-accent) !important; }
.text-neutral-900 { color: var(--ink)   !important; }
.text-neutral-800 { color: var(--ink-2) !important; }
.text-neutral-700 { color: var(--ink-2) !important; }
.text-neutral-600 { color: var(--ink-3) !important; }
.text-neutral-500 { color: var(--ink-3) !important; }
.text-neutral-400 { color: var(--ink-4) !important; }
.text-neutral-300 { color: var(--ink-5) !important; }
.border-neutral-100, .border-neutral-200, .border-neutral-300 { border-color: var(--rule) !important; }
.divide-neutral-100 > :not([hidden]) ~ :not([hidden]),
.divide-neutral-200 > :not([hidden]) ~ :not([hidden]) { border-color: var(--rule-2) !important; }
.hover\:bg-neutral-50:hover, .hover\:bg-neutral-100:hover { background-color: var(--paper-3) !important; }
.hover\:bg-black:hover, .hover\:bg-neutral-800:hover { background-color: var(--ink-red-2) !important; }
/* red ink → violet */
.text-red-600, .text-red-700 { color: var(--ink-red) !important; }
.bg-red-50 { background-color: var(--ink-red-tint) !important; }
.border-red-200, .border-red-300 { border-color: var(--ink-red) !important; }
/* emerald → cyan */
.text-emerald-500, .text-emerald-600, .text-emerald-700 { color: var(--emerald) !important; }
.bg-emerald-50 { background-color: var(--emerald-tint) !important; }
/* amber → token ambre (warnings "expire bientôt" / "prix déjà vu") */
.text-amber-600, .text-amber-700, .text-orange-600, .text-orange-700 { color: var(--amber) !important; }
.bg-amber-50, .bg-orange-50, .bg-yellow-50 { background-color: var(--amber-tint) !important; }
.border-amber-200, .border-amber-300, .border-orange-200, .border-orange-300 { border-color: var(--amber) !important; }
/* green → cyan (coches "À propos") */
.text-green-600, .text-green-700 { color: var(--emerald) !important; }
.bg-green-50 { background-color: var(--emerald-tint) !important; }

/* Titres haut contraste */
h1.text-neutral-900, h2.text-neutral-900, h3.text-neutral-900 { color: var(--fg) !important; text-shadow: none !important; }
p.text-neutral-600 { color: var(--ink-2) !important; }

/* Photos produit : fond clair conservé (images Amazon sur blanc) */
.bg-white img, .bg-neutral-50 img { border-radius: 4px; }
.ovni-deal-card, .border.border-neutral-200 { box-shadow: var(--shadow-card); }

/* Badges pill ("NOUVEAU"/"BON PLAN") */
.bg-neutral-900.mono, .mono.bg-neutral-900 {
  background-color: var(--paper-3) !important; color: var(--ink-red) !important;
  border: 1px solid var(--ink-red-tint);
}
.bg-neutral-900.mono.text-white, .text-white.bg-neutral-900.mono {
  background: var(--paper-3) !important; color: var(--ink-red) !important;
  border: 1px solid var(--ink-red-glow);
}

/* CTA primaires : accent plein, lift discret au hover, press-down au clic
   (DESIGN.md : « a button pressing down » = la motion d'état canonique). */
button.bg-neutral-900, a.bg-neutral-900 {
  background-color: var(--ink-red) !important; color: var(--on-accent) !important;
  box-shadow: none; transition: background-color 180ms ease, transform 180ms ease;
}
button.bg-neutral-900:hover, a.bg-neutral-900:hover {
  background-color: var(--ink-red-2) !important; transform: translateY(-1px);
}
button.bg-neutral-900:active, a.bg-neutral-900:active {
  transform: translateY(0); transition-duration: 60ms;
}

/* Inputs / selects */
input[type="text"], input[type="email"], input[type="password"],
input[type="search"], select, textarea {
  background-color: var(--paper-inset) !important; border-color: var(--rule) !important; color: var(--ink) !important;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--ink-red) !important; outline-offset: 1px !important; box-shadow: none !important;
}

/* Cards hover — règle CANONIQUE .ovni-deal-card (favoris & co).
   Alignée DESIGN.md : translateY(-3px) + lift + bordure indigo, press -1px.
   (La règle dupliquée/contradictoire de base.html a été retirée 2026-07-08.) */
.ovni-deal-card { transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
.ovni-deal-card:hover {
  border-color: var(--ink-red) !important; transform: translateY(-3px); box-shadow: var(--shadow-lift) !important;
}
.ovni-deal-card:active { transform: translateY(-1px); }

/* ====================================================================
   SPARKLINE (ex-futurist)
   ==================================================================== */
.spark-wrap { position: relative; background: var(--paper, transparent); color: var(--ink, currentColor); font-family: var(--font-sans); }
.spark-svg { display: block; width: 100%; }
.spark-cross-line { stroke: var(--ink-2, currentColor); stroke-width: 1; stroke-dasharray: 2 3; }
.spark-cross-dot { fill: var(--paper, #fff); stroke: var(--ink, #000); stroke-width: 1.5; }
.spark-tooltip {
  position: absolute; pointer-events: none; background: var(--paper-2, #14102b);
  border: 1px solid var(--rule, #2a2456); border-radius: var(--r-sm, 5px); padding: 8px 10px;
  font-family: var(--font-mono); font-size: 11px; line-height: 1.45; color: var(--ink);
  box-shadow: var(--shadow-lift); white-space: nowrap;
  transform: translateX(-50%) translateY(-100%); margin-top: -8px; z-index: 10;
}
.spark-tooltip .tt-date { color: var(--ink-3); font-size: 10px; letter-spacing: 0.04em; }
.spark-tooltip .tt-price { color: var(--ink); font-weight: 600; font-size: 14px; font-variant-numeric: tabular-nums; }
.spark-tooltip .tt-delta { font-size: 10px; }
.spark-tooltip .tt-delta-pos { color: var(--ink-red); }
.spark-tooltip .tt-delta-neg { color: var(--emerald); }
.spark-tooltip .tt-delta-flat { color: var(--ink-3); }
.spark-stats { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--rule); margin-top: 12px; }
.spark-stats > div { padding: 10px 14px; border-right: 1px solid var(--rule-2); display: flex; flex-direction: column; gap: 2px; }
.spark-stats > div:last-child { border-right: 0; }
.spark-stats .lbl { font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; }
.spark-stats .val { font-family: var(--font-mono); font-size: 13px; color: var(--ink); font-variant-numeric: tabular-nums; }
.spark-stats .val-em { color: var(--ink-red); font-weight: 600; }
.spark-stats .val-drop { color: var(--emerald); font-weight: 600; }

.ovni-mark { font-family: var(--font-sans); font-weight: 600; letter-spacing: 0.10em; text-transform: uppercase; font-size: 10px; color: var(--ink-red); }
.ovni-mark::before { content: "·"; margin-right: 4px; color: var(--ink-red); }

/* ====================================================================
   PRIMITIVES PARTAGÉES (ex-halo_coherence) — pulse, live-tape, stat-strip,
   pills, sort-bar, eyebrow, etc. Theme-agnostic (les tokens flippent).
   ==================================================================== */
@keyframes ovniPulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.4); opacity: 0.45; }
}
.pulse-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 999px;
  background: var(--ink-red); vertical-align: middle; flex-shrink: 0;
}
.pulse-dot--live  { animation: ovniPulse 2s ease-in-out infinite; box-shadow: 0 0 0 2px var(--ink-red-tint); }
.pulse-dot--soft  { background: var(--ink-red); opacity: 0.4; animation: ovniPulse 3.5s ease-in-out infinite; }
.pulse-dot--stale { background: var(--fg-faint); animation: none; }
.pulse-dot--sm    { width: 5px; height: 5px; }
.pulse-dot--lg    { width: 9px; height: 9px; }
@media (prefers-reduced-motion: reduce) { .pulse-dot--live, .pulse-dot--soft { animation: none; } }

/* Live tape — bande scanner 32px au-dessus de la nav */
.live-tape {
  height: 32px; display: flex; align-items: center; gap: 22px; padding: 0 24px;
  background: var(--paper-2); border-bottom: 1px solid var(--rule);
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: 0.10em; color: var(--fg-muted); white-space: nowrap; overflow: hidden;
}
.live-tape .lt-item { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; }
.live-tape .lt-num  { font-variant-numeric: tabular-nums; color: var(--fg); letter-spacing: 0; text-transform: none; font-weight: 500; }
.live-tape .lt-end  { margin-left: auto; color: var(--fg); text-decoration: none; }
.live-tape .lt-end:hover { color: var(--ink-red); }

/* Eyebrow — petites capitales au-dessus d'un titre */
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-sans);
  font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-muted);
}
.eyebrow--accent { color: var(--ink-red); }
.eyebrow .ey-sep { color: var(--fg-faint); margin: 0 2px; }

/* Meta strip */
.meta-strip {
  display: flex; justify-content: space-between; align-items: center; padding: 12px 24px;
  border-bottom: 1px solid var(--rule-2); font-family: var(--font-mono); font-size: 10px;
  color: var(--fg-muted); letter-spacing: 0.04em;
}
.meta-strip a { color: inherit; text-decoration: none; }
.meta-strip a:hover { color: var(--fg); }

/* Stat strip — bande KPI hairline */
.stat-strip {
  display: grid; border: 1px solid var(--rule); border-radius: var(--radius-md);
  background: var(--paper-2); overflow: hidden;
}
.stat-strip > .stat-cell { padding: 14px 16px; border-right: 1px solid var(--rule); display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.stat-strip > .stat-cell:last-child { border-right: 0; }
.stat-strip .stat-lbl { font-family: var(--font-sans); font-size: 9px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-muted); }
.stat-strip .stat-val { font-family: var(--font-mono); font-size: 22px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--fg); letter-spacing: -0.02em; line-height: 1; }
.stat-strip .stat-val--em   { color: var(--ink-red); }
.stat-strip .stat-val--drop { color: var(--emerald); }
.stat-strip .stat-sub { font-family: var(--font-mono); font-size: 10px; color: var(--fg-faint); letter-spacing: 0.02em; }

/* Sort bar + view toggle */
.sort-bar { display: flex; justify-content: space-between; align-items: center; padding: 12px 24px; border-bottom: 1px solid var(--rule); background: var(--paper); }
.sort-bar .sb-sorts { display: flex; gap: 18px; }
.sort-bar .sb-meta  { display: flex; gap: 10px; align-items: center; font-family: var(--font-mono); font-size: 11px; color: var(--fg-muted); }
.view-toggle { display: inline-flex; border: 1px solid var(--rule); border-radius: 4px; overflow: hidden; background: var(--paper); }
.view-toggle button { border: 0; background: transparent; color: var(--fg-muted); padding: 5px 10px; cursor: pointer; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; }
.view-toggle button:hover { color: var(--fg); }
.view-toggle button.is-on, .view-toggle a.is-on { background: var(--ink-red); color: var(--on-accent); box-shadow: none; }

/* Pill — souche unique */
.pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px;
  font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: 0.04em;
  border-radius: 3px; border: 1px solid var(--rule); background: transparent; color: var(--fg-muted); text-transform: uppercase;
}
.pill--mp     { color: var(--fg-muted); }
.pill--error  { background: var(--ink-red); color: var(--on-accent); border-color: var(--ink-red); font-weight: 600; }
.pill--locked { border-color: var(--ink-red); color: var(--ink-red); background: transparent; cursor: pointer; font-weight: 600; }
.pill--locked:hover { background: var(--ink-red); color: var(--on-accent); }
/* Statuts deal (cards) — couleurs sémantiques, texte via --on-accent (flip dark/light). */
.pill--new     { background: var(--emerald); color: var(--on-accent); border-color: transparent; font-weight: 600; }
.pill--soon    { background: var(--amber);   color: var(--on-accent); border-color: transparent; font-weight: 600; }
.pill--expired { background: var(--paper-3); color: var(--fg-subtle); border-color: var(--rule); }

/* Section header */
.section-head { display: flex; justify-content: space-between; align-items: baseline; padding: 14px 24px; border-bottom: 1px solid var(--rule); background: var(--paper); }
.section-head .sh-title { font-family: var(--font-sans); font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-muted); }
.section-head .sh-meta  { font-family: var(--font-mono); font-size: 11px; font-variant-numeric: tabular-nums; color: var(--fg-muted); }

/* ── Correctifs de fond (ex-halo + ex-hotfix inline) ──────────────────
   Filet de sécurité : html/body en paper, pas de bandes claires, canvas
   fixe derrière tout. Theme-agnostic. ── */
html.h-full, html.bg-neutral-50 { background-color: var(--paper) !important; height: auto !important; min-height: 100vh !important; }
body.h-full { background-color: var(--paper) !important; height: auto !important; min-height: 100vh !important; }
body > main, body > * { background-color: transparent; }
body::before { content: ''; position: fixed; inset: 0; background-color: var(--paper); z-index: -1; pointer-events: none; }
/* nuances grises Tailwind manquantes → tokens */
.bg-gray-50, .bg-gray-100 { background-color: var(--paper-2) !important; }
.bg-gray-200, .bg-neutral-200 { background-color: var(--paper-3) !important; }
/* text-gray-400 porte des DONNÉES (prix barrés, timestamps) → ink-3 lisible
   (~4,6:1). --ink-4 (~2,7:1, échec AA) est réservé aux placeholders (DESIGN.md). */
.text-gray-400 { color: var(--ink-3) !important; }
.text-gray-500, .text-gray-600 { color: var(--ink-3) !important; }
.text-gray-700, .text-gray-800, .text-gray-900 { color: var(--ink) !important; }
.border-gray-100, .border-gray-200, .border-gray-300 { border-color: var(--rule) !important; }
footer.bg-white { background-color: var(--paper-2) !important; border-color: var(--rule) !important; }

/* ====================================================================
   MICRO-INTERACTIONS D'ÉTAT (2026-07-08) — motion = état uniquement
   (DESIGN.md) : ouverture de menus, arrivée d'un flash, bascule de thème.
   ==================================================================== */
/* Ouverture des menus déroulants (volet compte, menu Staff) — même langage
   que le popover de filtres (ovniPopIn, précédent validé 2026-06-24). */
@keyframes ovniMenuIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.nav-dropdown:not([hidden]), .ovni-acct-menu:not([hidden]) {
  animation: ovniMenuIn .12s ease-out; transform-origin: top;
}
/* Feuille « Menu » mobile : glissement depuis le bas (drawer = motion d'état). */
@keyframes ovniSheetIn { from { transform: translateY(28px); opacity: .55; } to { transform: none; opacity: 1; } }
@keyframes ovniFadeIn  { from { opacity: 0; } to { opacity: 1; } }
.ovni-sheet-panel { animation: ovniSheetIn .22s cubic-bezier(.2,.8,.3,1); }
.ovni-sheet-bg    { animation: ovniFadeIn .18s ease-out; }
/* Message flash Django : apparition = réponse à une action (état). */
@keyframes ovniFlashIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.ovni-flash { animation: ovniFlashIn .18s ease-out; }
/* Bascule de thème v4 « dip » (2026-07-10) : gérée en JS pur (base.html) —
   le body s'éteint en opacité, le thème bascule invisible, il revient.
   Une seule propriété COMPOSITED = fluide sur tout matériel. Historique des
   approches retirées (retours user « pas fluide ») : v1 transition CSS sur
   tous les nœuds (repaint total), v2 View Transitions (snapshot pleine page),
   v3 transition élaguée (toujours paint-bound). Animer les couleurs d'une
   page entière repeint chaque frame — ne pas re-tenter. */
/* Pulse SMIL du point « prix actuel » de la sparkline détail : SMIL ne lit pas
   les media queries → on masque le halo animé, le point statique reste. */
@media (prefers-reduced-motion: reduce) {
  .spark-glow-pulse { display: none; }
  .nav-dropdown:not([hidden]), .ovni-acct-menu:not([hidden]),
  .ovni-sheet-panel, .ovni-sheet-bg, .ovni-flash { animation: none; }
}
/* Skip link a11y : invisible jusqu'au focus clavier. */
.ovni-skip {
  position: fixed; left: 12px; top: -48px; z-index: 100;
  padding: 9px 16px; background: var(--ink-red); color: var(--on-accent);
  border-radius: var(--r-sm, 5px); font-family: var(--font-sans); font-size: 13px;
  font-weight: 600; text-decoration: none; transition: top .12s ease;
}
.ovni-skip:focus-visible { top: 12px; }
