/* Accueil — extracted from index.Rmd inline <style> block for browser caching */
/* Auto-extracted, do not edit directly — modify the Rmd source then re-extract */

/* ═════════════════════════════════════════════════════════════
   CAPITAL ANTIFRAGILE — Design v6 (validé)
   Triple stack typo · palette warm-dark · texture grain
   ═════════════════════════════════════════════════════════════ */

/* Hide Rmd auto-title — multi-selectors + nuclear */
body #header,
body > div > #header,
body div#header,
h1.title,
h1.toc-ignore,
.title.toc-ignore,
#header h1,
#header > h1,
div#header{ display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; }


/* Bootstrap containers — full-width override */
.container-fluid,
.container-fluid.main-container,
.main-container,
.main-container > .container,
.main-container .container{ max-width: 100% !important; width: 100% !important; padding: 0 !important; margin: 0 !important; }

/* Bootstrap navbar — refonte 2026-05-21 v9 : DA dashboard navy/cyan calee sur maquette
   Clean Inter sans-serif, brand uppercase tracking, accent cyan electrique sur active */
body{ background-color: #050b1a !important; color: #eaf2fb !important; }
/* ── Fond grille technique derrière les widgets (2026-07-15) ──────────────────
   Grille bleue (DA vidéo hero) en calque FIXE plein écran, DERRIÈRE tout le
   contenu (z-index:-1). On utilise position:fixed (PAS background-attachment:fixed
   qui fait laguer l'iGPU Intel) → calque composité, zéro repaint au scroll. Le
   hero (canvas opaque) la masque en haut ; les sections .ca-section sont
   transparentes → la grille transparaît uniformément dans les gouttières entre
   les widgets. Voile #050b1a 0.30 pour poser la grille en retrait (lisibilité). */
body::before{
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(rgba(5,11,26,0.30), rgba(5,11,26,0.30)),
    url("assets/grid_bg.webp") center center / cover no-repeat,
    #050b1a;
  pointer-events: none;
}
.navbar,
.navbar-default,
.navbar-inverse,
.navbar.navbar-default,
.navbar.navbar-inverse{
  /* Perf 2026-05-21 : backdrop-filter blur(18px) retire (toujours en viewport,
     genere un shader pass GPU a chaque frame de scroll meme avec opt).
     2026-05-29 : navbar scrollee allegee. Avant = bloc navy opaque 0.95 + grosse
     ombre portee 32px + bordure marquee 0.18 => trop "grossier" sur le dashboard.
     La page est entierement dark, donc on descend a 0.82 (lisibilite intacte,
     les liens clairs restent nets sur le dashboard dark), on retire l'ombre
     portee et on adoucit la bordure => barre proche du flottant du hero. */
  background: rgba(6, 12, 26, 0.82) !important;
  border: 0 !important;
  border-bottom: 1px solid rgba(120, 190, 235, 0.08) !important;
  box-shadow: none !important;
  margin: 0 !important;
  min-height: 60px !important;
  font-family: 'Inter', -apple-system, sans-serif !important;
  transition: background 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease !important;
}
/* 2026-05-21 v9.1 : navbar 100% INVISIBLE sur le hero (DA image arbre cyan).
   Fond/bordure/ombre/backdrop-filter/glow logo ABSOLUMENT zero — seul le texte
   des liens reste visible flottant. Quand on scrolle au-dela du hero,
   body.ca-hero-out (IntersectionObserver) redonne le navy opaque. */
body:has(.hero-landing):not(.ca-hero-out) .navbar,
body:has(.hero-landing):not(.ca-hero-out) .navbar-default,
body:has(.hero-landing):not(.ca-hero-out) .navbar-inverse{
  background: transparent !important;
  background-color: transparent !important;
  background-image: none !important;
  border: 0 !important;
  border-bottom: 0 !important;
  border-bottom-color: transparent !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  filter: none !important;
  transition: none !important;
}
/* Masquer entierement le .navbar-brand (texte CAPITAL ANTIFRAGILE + pentagone
   cyan) sur TOUTE la page d'accueil — hero visible OU scrolle (2026-05-29 :
   user le trouve moche en etat scrolle ; sur l'accueil il fait doublon avec le
   H1 du hero, et l'ancre retour-accueil est inutile puisqu'on y est deja — le
   lien "Accueil" de la nav est d'ailleurs masque ici aussi). Liens flottant a
   droite, gauche vide = barre epuree proche du flottant du hero.
   NB : sur les AUTRES pages (pas de .hero-landing) le brand reste (ancre retour-accueil). */
body:has(.hero-landing) .navbar .navbar-brand{
  display: none !important;
}
/* Masquer le lien "Accueil" dans la navbar quand on EST deja sur l'Accueil.
   Detection : la page d'accueil est la seule a contenir .hero-landing. */
body:has(.hero-landing) .navbar-nav > li:has(> a[href="index.html"]){
  display: none !important;
}
/* Tuer les eventuels backgrounds sur les conteneurs internes de la navbar.
   IMPORTANT : wrap @media min-width: 768px → sur mobile, on veut l'overlay
   menu fullscreen OPAQUE pour la lisibilité (sinon hero visible derrière). */
@media (min-width: 768px) {
  body:has(.hero-landing):not(.ca-hero-out) .navbar .navbar-header,
  body:has(.hero-landing):not(.ca-hero-out) .navbar .navbar-collapse,
  body:has(.hero-landing):not(.ca-hero-out) .navbar .container,
  body:has(.hero-landing):not(.ca-hero-out) .navbar .container-fluid{
    background: transparent !important;
    background-color: transparent !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}
.navbar .container{ max-width: 1400px !important; padding: 0 32px !important; margin: 0 auto !important; }
.navbar-nav{ float: right !important; margin: 0 !important; }
.navbar-nav > li > a,
.navbar-default .navbar-nav > li > a,
.navbar-inverse .navbar-nav > li > a{
  color: #8a9bbf !important;
  font-family: 'Inter', -apple-system, sans-serif !important;
  font-size: 11.5px !important;
  font-weight: 500 !important;
  letter-spacing: 0.04em !important;
  text-transform: none !important;
  padding: 20px 14px !important;
  background: transparent !important;
  border: 0 !important;
  position: relative !important;
  transition: color 0.25s ease !important;
}
.navbar-nav > li > a:hover,
.navbar-nav > li > a:focus,
.navbar-default .navbar-nav > li > a:hover,
.navbar-default .navbar-nav > li > a:focus,
.navbar-inverse .navbar-nav > li > a:hover,
.navbar-inverse .navbar-nav > li > a:focus{
  color: #eaf2fb !important;
  background: transparent !important;
}
.navbar-default .navbar-nav > li.active > a,
.navbar-default .navbar-nav > li.active > a:hover,
.navbar-default .navbar-nav > li.active > a:focus,
.navbar-inverse .navbar-nav > li.active > a,
.navbar-inverse .navbar-nav > li.active > a:hover,
.navbar-inverse .navbar-nav > li.active > a:focus{
  color: #3d8bff !important;
  background: transparent !important;
}
/* Underline cyan sous le lien actif (signature image) */
.navbar-default .navbar-nav > li.active > a::after,
.navbar-inverse .navbar-nav > li.active > a::after{
  content: '';
  position: absolute;
  left: 14px; right: 14px; bottom: 14px;
  height: 2px;
  background: linear-gradient(90deg, transparent 0%, #3d8bff 25%, #74aeff 75%, transparent 100%);
  border-radius: 2px;
  box-shadow: 0 0 8px rgba(61, 139, 255, 0.55);
}
/* Hover underline subtil pour les liens non-actifs */
.navbar-nav > li:not(.active) > a::before{
  content: '';
  position: absolute;
  left: 14px; right: 14px; bottom: 14px;
  height: 2px;
  background: rgba(61, 139, 255, 0.30);
  border-radius: 2px;
  opacity: 0;
  transform: scaleX(0.4);
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.navbar-nav > li:not(.active) > a:hover::before{
  opacity: 1;
  transform: scaleX(1);
}
.navbar-default .navbar-brand,
.navbar-inverse .navbar-brand,
.navbar-brand{
  color: #eaf2fb !important;
  font-family: 'Inter', -apple-system, sans-serif !important;
  font-style: normal !important;
  font-weight: 800 !important;
  font-size: 13.5px !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  padding: 18px 0 !important;
  height: auto !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 11px !important;
}
.navbar-default .navbar-brand:hover,
.navbar-inverse .navbar-brand:hover{ color: #3d8bff !important; }
/* Logo mark cyan a gauche du brand (mark geometrique echo maquette) */
.navbar-default .navbar-brand::before,
.navbar-inverse .navbar-brand::before{
  content: '';
  display: inline-block;
  width: 22px; height: 22px;
  background: linear-gradient(135deg, #74aeff 0%, #3d8bff 50%, #1a5fd0 100%);
  clip-path: polygon(50% 4%, 100% 38%, 82% 96%, 18% 96%, 0% 38%);
  box-shadow: 0 0 14px rgba(61, 139, 255, 0.55), inset 0 0 8px rgba(255, 255, 255, 0.22);
  transition: filter 0.25s ease, transform 0.25s ease;
}
.navbar-default .navbar-brand:hover::before,
.navbar-inverse .navbar-brand:hover::before{
  filter: brightness(1.18);
  transform: scale(1.06);
}
.navbar-toggle{ border-color: rgba(61, 139, 255, 0.30) !important; }
.navbar-default .navbar-toggle .icon-bar,
.navbar-inverse .navbar-toggle .icon-bar{ background: #3d8bff !important; }
.navbar-collapse{ border: 0 !important; box-shadow: none !important; }
/* Texte droit (badge date "Mai 2026") — version muted mono */
.navbar-default .navbar-text,
.navbar-right > li > p,
.navbar-default .navbar-right > li > p{
  color: #6b7a99 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 10.5px !important;
  letter-spacing: 0.10em !important;
  text-transform: uppercase !important;
}

/* Canvas defensive sizing pour Three.js */



:root{
  /* ═══ Palette CAPITAL ANTIFRAGILE — Dashboard Navy/Cyan (refonte 2026-05-21) ═══
     Calee sur la maquette de reference : navy profond uniforme + cyan electrique
     comme unique accent primaire. Or/violet/rouge utilises uniquement sur les
     jauges et les indicateurs charts ou la semantique l'exige. */
  --bg-deep:    #050b1a;        /* fond le plus profond (sous navbar, fond global) */
  --bg-base:    #07101f;        /* fond base de page */
  --bg-elev:    #0a1530;        /* elevation 1 (sections) */
  --bg-card:    #0d1a35;        /* fond des tiles/widgets */
  --bg-card-2:  #11214a;        /* hover card */
  --hair:       rgba(70, 140, 240, 0.08);    /* hairline tres discret */
  --hair-2:     rgba(40, 78, 130, 0.45);
  --hair-3:     rgba(70, 140, 240, 0.28);    /* hairline accent visible */
  --hair-strong: rgba(70, 140, 240, 0.40);   /* border focus */
  --fg:         #eaf2fb;        /* texte principal blanc tres legerement bleute */
  --fg-2:       #b8c5d9;        /* texte secondaire */
  --muted:      #6b7a99;        /* texte muet (labels, meta) */
  --muted-2:    #45577a;        /* tres muet (chrome) */
  /* --gold == accent CYAN principal (nomme "gold" historiquement, ne pas casser la cascade) */
  --gold:       #3d8bff;        /* bleu electrique signature (DA video hero 2026-07-14, ex-cyan #1ec5ff) */
  --gold-l:     #74aeff;        /* bleu clair (hover, halo) */
  --gold-d:     #1a5fd0;        /* bleu profond (gradient end) */
  --gold-deep:  #0b2f66;        /* cyan tres profond */
  --cyan:       #3d8bff;        /* alias explicite */
  --cyan-l:     #74aeff;
  --cyan-d:     #1a5fd0;
  --blue:       #3b82f6;        /* bleu secondaire */
  --orange:     #f5a623;        /* RESERVE indicateurs "surchauffe" uniquement */
  --purple:     #8b5cf6;        /* RESERVE etat "extreme" gauges uniquement */
  --pos:        #28e07e;        /* vert vif tableau */
  --neg:        #ff5570;        /* rouge vif tableau */
  --crimson:    #ff5570;
  --crimson-d:  #c5364c;
  --moss:       #1fb86a;
  --moss-l:     #28e07e;
  --cream:      #eaf2fb;
  --ink:        #0d1a35;
  /* === Palette jauges (refonte 2026-05-21 v2, DA dashboard) ===
     Calee sur la maquette : gradient classique rouge -> orange -> jaune -> vert
     pour les jauges sentiment (Fear&Greed, Sentiment Marche, Radar V1, etc).
     Aiguille blanche par defaut. Or = surchauffe haute, Violet = extreme rare. */
  --gauge-low:     #ff5570;   /* rouge          (score 0, fear extreme)   */
  --gauge-mid:     #f5a623;   /* orange         (~25, fear)               */
  --gauge-mid-hi:  #ffd93d;   /* jaune          (~55, neutre)             */
  --gauge-high:    #28e07e;   /* vert vif       (~80, greed/sain)         */
  --gauge-extreme: #8b5cf6;   /* violet         (100, extreme rare)       */
  --gauge-needle:  #ffffff;   /* aiguille blanche neutre (match image)    */
  --gauge-track:   rgba(70,140,240,0.10);    /* arc inactif navy-cyan tres discret */
  --gauge-label:   rgba(184, 197, 217, 0.55); /* labels gauche/droite     */
  /* Aiguille selon zone (utilise par les jauges qui distinguent etat) */
  --needle-calm:   #28e07e;
  --needle-warm:   #f5a623;
  --needle-hot:    #ff5570;
  --needle-cold:   #3d8bff;
  /* Hauteur du mini-historique 90j sous les jauges (cf renderHistChart) */
  --hist90-h: 56px;
  --hist90-h-tall: 92px;  /* 68 -> 92 : Sentiment wide a besoin de plus d'espace vertical pour rendre la volatilite visible quand le chart est etire sur 3 cols */
  --serif-display: 'Playfair Display', Georgia, serif;
  --serif-body:    'Source Serif 4', Georgia, serif;
  --mono:          'JetBrains Mono', 'SF Mono', Menlo, monospace;
  --max-w: 1400px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

*{ box-sizing: border-box; }
html{ scroll-behavior: smooth; }
body{ font-family: var(--serif-body) !important; font-weight: 400; -webkit-font-smoothing: antialiased; line-height: 1.65; font-size: 17px; overflow-x: hidden; position: relative; }
body a, body button, body [onclick]{ cursor: pointer; }
a{ text-decoration: none !important; }
.ca-tile, .ca-tile *, .ca-tile-name, .ca-tile-big, .ca-tile-news-title{ text-decoration: none !important; }
::selection{ background: rgba(108, 221, 255, 0.35); color: var(--fg); }

/* Custom cursor : retire (RAF infini = lag perceptible). Curseur natif restaure. */
.ca-cursor{ display: none !important; }

/* ── Atmosphere v9 : Dashboard navy/cyan (refonte 2026-05-21) ──
   Calee sur maquette : fond navy profond uniforme + tres legere teinte cyan
   au sommet (echo du hero), tout le reste eteint. Aurora/magenta/or supprimes. */
body{
  background-image:
    linear-gradient(180deg,
      rgba(61, 139, 255, 0.045) 0%,
      rgba(61, 139, 255, 0.020) 12%,
      transparent 28%,
      transparent 100%);
  background-color: #050b1a !important;
  background-attachment: scroll;
}

/* Calque atmospherique global */
.ca-atmo{ position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }

/* 2 halos discrets au top, echo subtil de l'aurora image. Opacity-only (pas de scale = pas de kitsch lava-lamp).
   PERF 2026-05-21 : blur 110px -> 60px. Sur iGPU Intel le blur kernel coute en
   O(r) memoire+temps, et 110px etait l'un des 2-3 plus gros couts GPU restants.
   60px reste visuellement diffus, le halo conserve sa souplesse. */
/* Halos atmospheriques RETIRES 2026-05-21 (perf user) : filter: blur(60px) sur
   48vw x 38vw + 40vw x 34vw etait le bottleneck #1 du scroll lag sur iGPU Intel.
   Le buffer GPU pour un blur 60px de cette taille = ~50-100 MB recalcules a chaque
   compositing. Selecteurs gardes en display:none pour rollback rapide si necessaire. */
.ca-atmo-halo{ display: none !important; }

/* Embers RETIRES 2026-05-21 (perf user) : transform+opacity infinite sur 6 layers
   = compositing constant. Selecteur garde en display:none pour rollback. */
.ca-atmo-embers,
.ca-atmo-ember{ display: none !important; }
@keyframes ca-ember-rise{
  0%   { transform: translate3d(0, 0, 0)              scale(0.5); opacity: 0;    }
  10%  { opacity: 0.9; }
  50%  { transform: translate3d(var(--dx,1vw), -50vh, 0) scale(1);   opacity: 0.7;  }
  100% { transform: translate3d(var(--dx2,-1vw), -100vh, 0) scale(0.4); opacity: 0; }
}

/* Bolt RETIRE 2026-05-21 (perf user) : drop-shadow + animation infinite + SVG data-URI.
   Coupe la creation du layer GPU pour cet element. */
.ca-atmo-bolt{ display: none !important; }
@keyframes ca-bolt-rare{
  0%, 85%, 100% { opacity: 0; }
  86% { opacity: 0.85; }
  87% { opacity: 0; }
  88% { opacity: 0.4; }
  89% { opacity: 0; }
}

/* Grain SVG turbulence : statique (peint 1x) */
.ca-atmo-grain{ position: absolute; inset: 0; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.7'/></svg>"); background-size: 240px 240px; opacity: 0.05; }

/* Stars existantes — wrapper sans will-change (le wrapper n'anime pas, économise un layer) */
.ca-stars{ position: fixed; inset: 0; pointer-events: none; z-index: 1; contain: layout style paint; }
/* will-change: transform retiré (37 étoiles × layer dédié = ~37 buffers GPU sur iGPU
   Intel — coûteux pour rien, le compositor auto-promote les transforms animés). */
.ca-star{ position: absolute; background: var(--fg); border-radius: 50%; opacity: 0.5; box-shadow: 0 0 4px rgba(244, 232, 208, 0.3); }
/* Perf 2026-05-21 round 5 : animation caTwinkle retiree (15 layers d'animation
   transform infinite = ~15 buffers GPU compositor permanents). Stars statiques. */

/* ════ Voile d'aurore boréale (fixed, z:0, derrière les étoiles) ════════════
   3 rubans colorés (violet, magenta, teal-vert) qui ondulent lentement.
   Cantonné à la moitié supérieure (l'aurore est dans le ciel).
   isolation:isolate critique pour mix-blend-mode (limite compositing au container). */
.ca-sky-aurora{
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
  isolation: isolate;
  contain: layout style paint;
  transform: translateZ(0);
  backface-visibility: hidden;
  mask-image: linear-gradient(180deg,
    black 0%, black 45%, rgba(0,0,0,0.6) 65%, transparent 88%);
  -webkit-mask-image: linear-gradient(180deg,
    black 0%, black 45%, rgba(0,0,0,0.6) 65%, transparent 88%);
}




@keyframes ca-aurora-drift-1{
  0%   { transform: translate3d(-3%, -1%, 0) rotate(-8deg) scaleY(1);    opacity: 0.50; }
  50%  { transform: translate3d( 2%,  1%, 0) rotate(-5deg) scaleY(1.08); opacity: 0.65; }
  100% { transform: translate3d( 3%, -2%, 0) rotate(-10deg) scaleY(0.95); opacity: 0.55; }
}
@keyframes ca-aurora-drift-2{
  0%   { transform: translate3d( 3%,  1%, 0) rotate(6deg)  scaleY(0.95); opacity: 0.45; }
  50%  { transform: translate3d(-2%, -1%, 0) rotate(9deg)  scaleY(1.08); opacity: 0.60; }
  100% { transform: translate3d(-3%,  2%, 0) rotate(4deg)  scaleY(1);    opacity: 0.50; }
}
@keyframes ca-aurora-drift-3{
  0%   { transform: translate3d( 2%,  0%, 0) rotate(-3deg) scaleX(1);    opacity: 0.35; }
  50%  { transform: translate3d(-3%, -1%, 0) rotate(2deg)  scaleX(1.1);  opacity: 0.50; }
  100% { transform: translate3d( 1%,  1%, 0) rotate(-1deg) scaleX(0.95); opacity: 0.40; }
}

/* ════ Étoiles filantes (fixed, z:2, devant les étoiles fixes) ════════════
   Rotations calculées rigoureusement via atan2(dy,dx)+180° pour que la
   traînée pointe TOUJOURS dans la direction strictement opposée au mouvement.
   M1 : motion 146° → trail 326° → rotation 146° (trail nat. = 180°/gauche)
   M2 : motion  27° → trail 207° → rotation 207° (trail nat. =   0°/droite)
   M3 : motion 121° → trail 301° → rotation 121° (trail nat. = 180°/gauche) */
.ca-meteors{
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 2;
  overflow: hidden;
  contain: layout style paint;
  transform: translateZ(0);
  backface-visibility: hidden;
}
.ca-meteor{
  position: absolute;
  width: 2px; height: 2px;
  background: #fff;
  border-radius: 50%;
  box-shadow:
    0 0 6px 1px rgba(255, 255, 255, 0.95),
    0 0 14px 2px rgba(180, 220, 255, 0.5);
  opacity: 0;
  will-change: transform, opacity;
}
.ca-meteor::before{
  content: '';
  position: absolute;
  top: 50%; right: 0;
  width: 120px; height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(180, 220, 255, 0.4) 30%,
    rgba(255, 255, 255, 0.85) 100%);
  transform: translateY(-50%);
  filter: blur(0.4px);
}
.ca-meteor--1{
  top: 8vh; left: 95vw;
  animation: ca-meteor-fall-1 18s linear infinite;
  animation-delay: 4s;
}
@keyframes ca-meteor-fall-1{
  0%   { transform: translate3d(0, 0, 0) rotate(146deg);            opacity: 0; }
  1%   { opacity: 0; }
  3%   { opacity: 1; }
  10%  { transform: translate3d(-60vw, 40vh, 0) rotate(146deg);     opacity: 0; }
  100% { transform: translate3d(-60vw, 40vh, 0) rotate(146deg);     opacity: 0; }
}


@keyframes ca-meteor-fall-2{
  0%   { transform: translate3d(0, 0, 0) rotate(207deg);             opacity: 0; }
  1%   { opacity: 0; }
  3%   { opacity: 0.95; }
  9%   { transform: translate3d(70vw, 35vh, 0) rotate(207deg);       opacity: 0; }
  100% { transform: translate3d(70vw, 35vh, 0) rotate(207deg);       opacity: 0; }
}


@keyframes ca-meteor-fall-3{
  0%   { transform: translate3d(0, 0, 0) rotate(121deg);             opacity: 0; }
  1%   { opacity: 0; }
  2.5% { opacity: 0.9; }
  6%   { transform: translate3d(-30vw, 50vh, 0) rotate(121deg);      opacity: 0; }
  100% { transform: translate3d(-30vw, 50vh, 0) rotate(121deg);      opacity: 0; }
}

/* ════ Containment supplémentaire sur l'atmosphère globale (perf) ════ */
.ca-atmo{ contain: layout style paint; }

/* ════ Pause auto en background : classe togglée par JS visibilitychange ══
   Quand l'onglet est inactif, on stoppe TOUTES les animations infinies pour
   économiser CPU/GPU. Aucune coupure visuelle car l'utilisateur n'est pas là. */
body.ca-paused .ca-aurora-ribbon,
body.ca-paused .ca-meteor,
body.ca-paused .ca-star,
body.ca-paused .ca-atmo-ember,
body.ca-paused .ca-atmo-halo,
body.ca-paused .ca-atmo-bolt{ animation-play-state: paused !important; }

/* ════ Pause animations hero quand hero hors viewport (CPU/GPU saver) ════
   Classe body.ca-hero-out togglée par JS via IntersectionObserver sur .hero-landing.
   Les animations qui sont DANS le hero (donc invisibles quand on scrolle dessous)
   sont mises en pause pour libérer le compositor GPU. Aucun changement visuel :
   l'utilisateur ne voit plus ces éléments quand la classe est active. */
body.ca-hero-out .hero-h1,
body.ca-hero-out .hero-h1-line1,
body.ca-hero-out .hero-h1-grad,
body.ca-hero-out .hero-h1::before,
body.ca-hero-out .hero-h1::after,
body.ca-hero-out .hero-tagline,
body.ca-hero-out .hero-cta-row,
body.ca-hero-out .ca-hero-art-svg .crack-main,
body.ca-hero-out .ca-hero-art-svg .crack-branch,
body.ca-hero-out .ca-hero-art-svg .crack-fine,
body.ca-hero-out .ca-hero-art-svg .spark,
body.ca-hero-out .ca-hero-art-svg .dust-p{ animation-play-state: paused !important; }

/* Pause atmosphère "deep scroll" : quand l'utilisateur est très bas dans la page
   (plus de ~2 viewports), les éléments fixed restent techniquement visibles mais
   leur mouvement est imperceptible (cycles 16-44s, déjà discrets). On freeze pour
   libérer compositor. La classe body.ca-deep-scroll est togglée par JS au-delà
   d'un seuil. Aucune coupure visible car ces animations sont quasi-statiques à
   l'œil sur le bas de page. */
body.ca-deep-scroll .ca-aurora-ribbon,
body.ca-deep-scroll .ca-meteor,
body.ca-deep-scroll .ca-atmo-ember,
body.ca-deep-scroll .ca-atmo-halo,
body.ca-deep-scroll .ca-atmo-bolt,
body.ca-deep-scroll .ca-star{ animation-play-state: paused !important; }

/* ════ Pause atmosphère pendant scroll actif (2026-05-21) ════════════════════
   Cause principale du lag scroll sur iGPU Intel : pendant un scroll normal
   (pas deep), les animations infinies de l'atmosphère continuent de tourner
   et le compositor doit re-blender les layers blurrés à chaque frame.
   Embers translate3d + halos opacity pulse + bolt lightning + stars twinkle
   = 4 layers d'animation actifs en plus du scroll lui-meme.
   Pendant is-scrolling (100ms after dernier scroll event), on freeze ces
   animations. L'oeil de l'utilisateur suit le scroll, pas la derive subtile
   d'un ember de 0.5px/frame. Au repos, les animations reprennent immediate.
   Cible specifique : Accueil page (atmosphere unique a cette page) sur
   GPU faible (iGPU Intel). Sur dGPU desktop = imperceptible. */
body.is-scrolling .ca-meteor,
body.is-scrolling .ca-atmo-ember,
body.is-scrolling .ca-atmo-halo,
body.is-scrolling .ca-atmo-bolt,
body.is-scrolling .ca-star{ animation-play-state: paused !important; }

/* ════ backdrop-filter OFFSCREEN OPT (perf scroll iGPU Intel) ═════════════════
   backdrop-filter coûte un GPU shader pass à CHAQUE frame de scroll, même
   si l'élément est sous le viewport. Sur iGPU Intel avec 14+ éléments
   backdrop-filter, c'est le bottleneck #1 du scroll lag.
   Une classe .ca-bf-off togglée par JS (IntersectionObserver avec rootMargin
   généreux 300px haut/bas) désactive backdrop-filter quand l'élément est
   hors viewport étendu. Quand il rentre → backdrop-filter ré-active.
   Le rootMargin large (300px) garantit que la transition off→on a lieu
   pendant que l'élément n'est PAS encore visible → 0 changement perçu. */
.ca-tile.ca-bf-off,
.ca-map.ca-bf-off,
.ca-news-item.ca-bf-off,
.ca-spec.ca-bf-off,
.ca-ticker.ca-bf-off,
.ca-explore.ca-bf-off{
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* ════ Atmospheres CACHEES par defaut 2026-05-21 round 7 ══════════════════
   User a confirme que ?lite=1 est "beaucoup mieux" → ces elements (.ca-atmo
   incl. grain SVG + .ca-stars + reliques aurora/meteors) etaient les derniers
   poids GPU significatifs en mode normal. Application des memes regles par
   defaut, sans necessite du ?lite=1. */
.ca-atmo,
.ca-stars,
.ca-sky-aurora,
.ca-meteors,
.hero-h1::before,
.hero-h1::after,
html.ca-lite .ca-atmo,
html.ca-lite .ca-stars,
html.ca-lite .ca-sky-aurora,
html.ca-lite .ca-meteors,
html.ca-lite .hero-h1::before,
html.ca-lite .hero-h1::after{
  display: none !important;
}
html.ca-lite .ca-tile,
html.ca-lite .ca-map,
html.ca-lite .ca-news-item,
html.ca-lite .ca-spec,
html.ca-lite .ca-ticker,
html.ca-lite .ca-explore,
html.ca-lite .navbar.navbar-default,
html.ca-lite .ca-topbar,
html.ca-lite .ca-tempete,
html.ca-lite .ca-seal,
html.ca-lite .hero-cta{
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
html.ca-lite .hero-h1-line1,
html.ca-lite .hero-h1-grad{
  animation: none !important;
  /* Garde le gradient, mais filter statique (pas d'anim drop-shadow infinie) */
  filter:
    drop-shadow(0 0 14px rgba(255,217,110,0.32))
    drop-shadow(0 4px 22px rgba(0,0,0,0.78)) !important;
}

/* ════ SCROLL-OPTIMIZED RENDERING (key fix 2026-05-19) ════════════════════════
   Pattern utilisé par Apple, Stripe, etc. : pendant le scroll actif, on
   désactive les effets compositor les plus chers (backdrop-filter blur,
   mix-blend-mode screen). Dès que le scroll s'arrête (~100ms après dernier
   scroll event), tout revient.

   Pourquoi c'est invisible à l'œil : pendant le scroll, l'utilisateur navigue
   et son œil ne fixe pas les détails de blur/mix-blend. Quand le scroll
   s'arrête, l'utilisateur regarde la page statique → les effets reviennent
   instantanément (~16ms = 1 frame) pour le rendu complet en mode "lecture".

   Gain : sur iGPU Intel, ~60-80% moins de GPU work pendant les frames de
   scroll → 60fps natif au lieu de 20-40fps. */
body.is-scrolling .ca-tile,
body.is-scrolling .ca-map,
body.is-scrolling .ca-news-item,
body.is-scrolling .ca-spec,
body.is-scrolling .ca-ticker,
body.is-scrolling .ca-explore,
body.is-scrolling .navbar.navbar-default,
body.is-scrolling .ca-topbar,
body.is-scrolling .ca-tempete,
body.is-scrolling .ca-seal,
body.is-scrolling .hero-cta{
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
/* Aurora ribbons : mix-blend-mode screen + blur 60px = le pire offender GPU
   sur iGPU Intel. Pendant scroll, on les rend en blend normal → 5-10x moins
   cher. Différence visuelle pendant scroll = imperceptible (focus user
   ailleurs). En statique → mix-blend revient pour le rendu auroral complet. */
body.is-scrolling .ca-aurora-ribbon{
  mix-blend-mode: normal !important;
  filter: blur(20px) saturate(1.2) !important;
}

/* ════ Backdrop-filter retiré du bento + maps + ticker + news + spec + explore
   ════ (2026-05-19, round 3) ═══════════════════════════════════════════════
   Le verre dépoli (blur 10-14px) sur ces éléments coûtait ~15-25% du GPU
   restant après la suppression des aurora ribbons. Test A/B ?lite=1 a
   montré que sans backdrop-filter la page atteint la fluidité des autres
   onglets. Sacrifice : le fond derrière les tuiles devient opaque uniforme
   au lieu du blur live. Le gradient coloré, les bordures, l'aurore atmo
   restent identiques. Tuiles légèrement plus "flat" mais lisibles. */
.ca-tile,
.ca-map,
.ca-news-item,
.ca-spec,
.ca-ticker,
.ca-explore{
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* prefers-reduced-motion : on coupe tout */
@media (prefers-reduced-motion: reduce){
  .ca-atmo-halo, .ca-atmo-bolt, .ca-atmo-ember,
  .ca-star, .ca-sources-track, .ca-hero-art-svg .spark, .ca-hero-art-svg path,
  .ca-live-dot,
  .ca-aurora-ribbon, .ca-meteor{ animation: none !important; }
  .ca-atmo-bolt{ opacity: 0.10; }
  .ca-atmo-ember{ opacity: 0.35; }
  .ca-meteor{ opacity: 0; }
  html{ scroll-behavior: auto; }
  .ca-tile, .ca-source, .ca-btn, .ca-bubble{ transition: none !important; }
}
/* Mobile : aurore plus discrète (perf + lisibilité), météores conservés */


.ca-topbar, .ca-main{ position: relative; z-index: 3; }

.ca-lab{ font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.28em; text-transform: uppercase; color: var(--muted); }




/* TOPBAR identité */

/* Scroll progress bar (thin gold line at top, GPU-composited via transform) */
.ca-scroll-progress{ position: fixed; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, #6cddff 0%, #a78bfa 50%, #ff6b9a 100%); transform-origin: left center; transform: scaleX(0); z-index: 51; pointer-events: none; opacity: 0.9; will-change: transform; box-shadow: 0 0 8px rgba(108, 221, 255, 0.4); }
/* Roman folios : numerotation flottante en marge droite, change avec la section visible */


/* Perf 2026-05-21 round 7 : backdrop-filter blur(18px) retire — il s'activait
   DES LE DEBUT du scroll (classe .is-scrolled togglee a y>24px) creant un shader
   pass GPU permanent pendant tout le scroll. Remplace par opacite forte 0.96.
   = le coupable principal du "lag pendant scroll" trouve via test ?lite=1. */
.ca-topbar.is-scrolled{ background: rgba(5, 10, 22, 0.96); border-bottom-color: rgba(108, 221, 255, 0.10); box-shadow: 0 14px 36px -18px rgba(0,0,0,0.55); }
/* L'Accueil est un showcase editorial dark intentionnel : on garde la palette warm-gold dark
   quel que soit le toggle global dark/light du site (le toggle reste fonctionnel sur les autres onglets). */









body.ca-storm .ca-pulse{ background: var(--neg); box-shadow: 0 0 0 0 rgba(196, 96, 74, 0.6); animation-duration: 0.8s; }
body.ca-storm .ca-tempete-label::after{ content: 'TEMPÊTE'; }
body:not(.ca-storm) .ca-tempete-label::after{ content: 'CLÉMENT'; }
@keyframes caPulse{ 0% { box-shadow: 0 0 0 0 rgba(155, 180, 106, 0.5); } 70% { box-shadow: 0 0 0 12px rgba(155, 180, 106, 0); } 100% { box-shadow: 0 0 0 0 rgba(155, 180, 106, 0); } }

/* HERO */


/* ── Hero v7 : image arbre antifragile (titre baked) + CTAs gold/cyan ── */
/* L'image doit coller PILE sous la navbar (qui fait 64px de min-height) */
/* 2026-05-21 v9.1 : hero full viewport (100vh), navbar transparente overlay
   par-dessus l'image arbre cyan. Plus de gap 64px en haut. */
body:has(.hero-landing){ padding-top: 0 !important; }
body:has(.hero-landing) .main-container{
  padding-top: 0 !important;
  margin-top: 0 !important;
}
.hero-landing{
  position: relative;
  height: 100vh;
  min-height: 620px;
  padding: 0;
  margin-top: -2px;
  display: flex;
  align-items: stretch;
  justify-content: center;
  overflow: hidden;
  /* 2026-07-14 v2 : HERO PANORAMA SOURIS (mécanisme /savoir). Fond = canvas
     peint depuis un frame-cache de la vidéo globe (hero_globe.mp4) ; au repos
     image FIXE, la souris gauche/droite fait glisser la position temporelle
     (cf assets/js/hero_interactive.js). AUCUN zoom : cover natif, image telle
     quelle. Le background-image ci-dessous = POSTER (frame MILIEU de la vidéo
     = point de départ du panorama) affiché avant le pré-décodage et en
     fallback (no-JS, tactile, reduced-motion, échec réseau). */
  background-color: #050b1a;
  background-image:
    linear-gradient(180deg, rgba(5,11,26,0.0) 0%, rgba(5,11,26,0.0) 55%, rgba(5,11,26,0.45) 86%, #050b1a 100%),
    url("assets/hero_globe_poster.webp");
  background-repeat: no-repeat, no-repeat;
  background-size: cover, cover;
  background-position: center center, center center;
  background-attachment: scroll, scroll;
}
/* ── Fond panorama hero ──────────────────────────────────────────────────────
   .hero-bg : calque plein cadre derrière les scrims (::before/::after z-index:1)
   et le contenu (z-index:3). PAS de transform (pas de zoom, pas de translation :
   demande utilisateur — l'image telle quelle, seul le contenu vidéo « glisse »). */
.hero-bg{
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
}
.hero-bg-canvas{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  pointer-events: none;
}
/* Mobile : hero image arbre dédiée (hero_mobile.jpg) → pas de panorama. */
@media (max-width: 767px){
  .hero-bg{ display: none; }
}
/* Overlay : scrim derriere le titre centre pour lisibilite du H1 par-dessus
   les branches lumineuses de l'arbre + fade-out renforce vers le navy en bas. */
.hero-landing::after{
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 720px 360px at 50% 42%, rgba(5, 11, 26, 0.55) 0%, rgba(5, 11, 26, 0.22) 55%, transparent 80%),
    radial-gradient(ellipse 1400px 800px at 50% 50%, transparent 0%, rgba(5, 11, 26, 0.30) 75%),
    linear-gradient(180deg, transparent 0%, transparent 62%, rgba(5, 11, 26, 0.55) 86%, #050b1a 100%);
  z-index: 1; pointer-events: none;
}
/* Contenu hero : colonne flex decalee a droite (refonte 2026-05-21 v9.1, image
   arbre cyan = arbre lumineux dans la moitie gauche, donc on pousse le texte
   a droite pour ne pas le masquer). Le decalage est responsive : 6vw min,
   12vw max, capé pour ne pas pousser hors viewport. Le media query (max-width:
   900px) re-centre completement sur mobile. */
.hero-content{
  position: relative !important;
  z-index: 3 !important;
  width: 100% !important;
  max-width: 1100px !important;
  padding: clamp(13vh, 16vh, 19vh) 3vw clamp(8vh, 11vh, 13vh) 3vw !important;
  text-align: center !important;
  margin-left: auto !important;
  margin-right: auto !important;
  /* translateX = décalage droite (globe à gauche). --hshift/--hscale = glissement
     droite + léger rétrécissement pilotés par hero_interactive.js quand la souris
     s'écarte du centre (laisse la vedette à la terre) ; au repos 0px/1 → net. */
  transform: translateX(clamp(100px, 16vw, 280px)) translateX(var(--hshift, 0px)) scale(var(--hscale, 1)) !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: center !important;
  align-items: center !important;
  gap: clamp(28px, 4vh, 56px) !important;
}

/* Stat line MASQUÉE (user demande titre + boutons seulement) */
.hero-sub{ display: none !important; }

/* ── Titre CAPITAL ANTIFRAGILE : SINGLE LINE, effets cosmique-aurore premium ──
   Multi-couches de glow + shimmer + breath + aurora halo derriere + accent thread. */
.hero-h1{
  /* override clip SR-only */
  position: relative !important;
  clip: auto !important; clip-path: none !important;
  width: auto !important; height: auto !important;
  margin: 0 !important; padding: 0 !important;
  overflow: visible !important;
  white-space: normal !important;     /* refonte 2026-05-21 v9 : autorise wrap pour stack image */
  border: 0;
  /* refonte 2026-05-21 v9 : Inter Black uppercase, DA dashboard maquette */
  font-family: 'Inter', -apple-system, sans-serif !important;
  font-weight: 900 !important;
  font-style: normal !important;
  font-size: clamp(56px, 8.2vw, 132px);
  line-height: 0.95;
  letter-spacing: -0.025em;
  text-transform: uppercase !important;
  text-align: center;
  opacity: 0;
  animation: heroFadeUp 1.4s cubic-bezier(.2,.8,.25,1) 0.25s forwards;
}
/* Aurora halo derrière le titre RETIRÉ 2026-05-19 (round 3) :
   filter: blur(50px) sur un layer 140%×400% = rastérisation constante ~5-10%
   du GPU sur le hero. Drop-shadows autour du texte gardés → le titre garde
   son glow doux. Visuel : plus "clean", moins "cosmic explosion". */
.hero-h1::before{
  display: none !important;
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 140%; height: 400%;
  transform: translate(-50%, -50%);
  background:
    radial-gradient(ellipse 32% 55% at 18% 50%,
      rgba(255,217,110,0.18) 0%,
      rgba(255,157,61,0.10) 30%,
      transparent 75%),
    radial-gradient(ellipse 30% 50% at 42% 50%,
      rgba(108,221,255,0.16) 0%,
      rgba(163,244,212,0.11) 40%,
      transparent 78%),
    radial-gradient(ellipse 30% 50% at 62% 50%,
      rgba(163,244,212,0.13) 0%,
      rgba(108,221,255,0.10) 45%,
      transparent 78%),
    radial-gradient(ellipse 32% 55% at 84% 50%,
      rgba(167,139,250,0.18) 0%,
      rgba(196,181,253,0.10) 30%,
      transparent 75%);
  /* PERF 2026-05-21 : blur 50px -> 32px. Layer statique mais 50px sur un
     element 140%x400% generait un buffer GPU enorme (~32 MB sur 1440p).
     32px conserve l'effet d'aura diffuse, divise la consommation memoire
     du compositor par ~2.4x. */
  filter: blur(32px);
  pointer-events: none;
  /* Animations titleAuraPulse + titleAuraDrift retirées 2026-05-19 :
     coûteuses sur iGPU Intel (recompositing constant d'un layer 140%×400%
     avec blur 50px). Halo reste statique → visuel identique à chaque instant. */
}
/* ::after bloom retire — trop intense, halo ::before seul suffit. */
@keyframes titleAuraPulse{
  0%, 100% { opacity: 0.65; }
  50%      { opacity: 0.85; }
}
@keyframes titleAuraDrift{
  0%, 100% { transform: translate(-50%, -50%) scale(1)    rotate(0deg); }
  33%      { transform: translate(-50%, -50%) scale(1.06) rotate(0.6deg); }
  66%      { transform: translate(-52%, -50%) scale(1.03) rotate(-0.4deg); }
}
/* Refonte 2026-05-21 v9 : "CAPITAL" blanc + "ANTIFRAGILE" cyan solide stacked vertical.
   Suppression du gradient aurore rainbow (or/violet/teal/magenta) qui clashait avec
   la palette navy/cyan dashboard de la maquette. */
.hero-h1-line1, .hero-h1-grad{
  display: block !important;
  position: relative;
  z-index: 1;
  background: none;
  -webkit-background-clip: initial; background-clip: initial;
  -webkit-text-fill-color: initial;
}
.hero-h1-line1{
  color: #ffffff !important;
  margin-right: 0 !important;
  filter: drop-shadow(0 2px 16px rgba(0, 8, 24, 0.65));
}
.hero-h1-grad{
  /* Cyan solide. Perf 2026-05-21 round 5 : 3 drop-shadow filters animes -> 1 statique.
     Chaque drop-shadow cree un buffer GPU separe ; 3 chains x animation infinite = 6
     re-rasterizations par seconde au pic. Le glow cyan principal preserve, profondeur
     legerement reduite (compromis acceptable, hero non-flashy). */
  background: linear-gradient(180deg, #74aeff 0%, #3d8bff 55%, #1a5fd0 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  text-shadow: 0 0 24px rgba(61, 139, 255, 0.35), 0 4px 18px rgba(0, 8, 24, 0.65);
  margin-top: 0 !important;
}
/* titleShimmer retire 2026-05-21 round 5 : animation background-position 14s
   infinite forcait paint+composite continu du gradient + 3 drop-shadow chains.
   Visuel statique = identique a l'oeil arrete sur le titre. */
/* titleBreath retire (refonte 2026-05-21 v9) : etait utilise par l'ancien
   degrade aurore multicolore qui n'existe plus. Le nouveau titre cyan utilise
   un drop-shadow statique. */

/* ── Groupe titre + tagline : ensemble en haut, tagline directement sous le titre ── */
.hero-title-group{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(14px, 1.6vw, 24px);
}
.hero-tagline{
  position: relative !important;
  clip: auto !important; clip-path: none !important;
  width: auto !important; height: auto !important;
  margin: 0 !important;
  padding: 0 !important;
  overflow: visible !important;
  /* Refonte 2026-05-21 v9 : Inter sans cyan light (matche maquette) */
  font-family: 'Inter', -apple-system, sans-serif !important;
  font-style: normal !important;
  font-size: clamp(18px, 1.95vw, 26px);
  font-weight: 500;
  letter-spacing: 0.005em;
  color: #74aeff;
  text-shadow:
    0 2px 18px rgba(0, 8, 24, 0.65),
    0 0 24px rgba(61, 139, 255, 0.30);
  opacity: 0;
  animation: heroFadeUp 1s cubic-bezier(.2,.8,.25,1) 0.7s forwards;
}

/* ── CTAs : groupes en bas ── */
.hero-cta-row{
  justify-content: center !important;
  display: inline-flex !important;
  gap: 14px !important;
  opacity: 0;
  animation: heroFadeUp 1s cubic-bezier(.2,.8,.25,1) 0.95s forwards;
}
.hero-cta{
  padding: 12px 26px !important;
  font-size: 10.5px !important;
  letter-spacing: 0.20em !important;
  font-weight: 600 !important;
  text-transform: uppercase !important;
}

@media (prefers-reduced-motion: reduce){
  .hero-h1, .hero-h1-line1, .hero-h1-grad,
  .hero-tagline, .hero-cta-row, .hero-title-group{
    opacity: 1 !important; animation: none !important; transform: none !important;
  }
  .hero-h1::before, .hero-h1::after{ animation: none !important; }
}

/* Mobile : recentre tout le contenu, titre peut wrap si trop large */
@media (max-width: 900px){
  .hero-landing{ justify-content: center; }
  .hero-content{
    width: 96% !important;
    max-width: 640px !important;
    padding: 12vh 16px 8vh !important;
    text-align: center !important;
    margin-right: auto !important;
    transform: none !important;
  }
  .hero-h1{
    white-space: normal !important;
    font-size: clamp(34px, 9vw, 64px) !important;
  }
  .hero-h1, .hero-tagline{ text-align: center !important; }
  .hero-cta-row{ justify-content: center !important; flex-wrap: wrap; }
}

.hero-landing::before{ content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 0%, transparent 62%, rgba(5,11,26,0.40) 86%, #050b1a 100%); pointer-events: none; z-index: 1; }

/* ── Scroll cue : "SCROLLEZ POUR EXPLORER" + chevron anime en bas du hero ──
   Apparait apres un court delai au load (cue subtil, pas in-your-face),
   chevron bounce vertical infini, fade-out quand le hero quitte le viewport
   (body.ca-hero-out) pour ne pas reapparaitre en flottant au scroll. */
.hero-scroll-cue{
  position: absolute;
  left: 50%;
  bottom: clamp(22px, 4vh, 44px);
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: rgba(186, 220, 255, 0.78);
  text-decoration: none !important;
  pointer-events: auto;
  opacity: 0;
  animation: hero-scroll-cue-in 0.9s ease-out 1.4s forwards;
  transition: opacity 0.35s ease;
}
.hero-scroll-cue:hover{ color: #6cddff; }
.hero-scroll-cue__label{
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: inherit;
}
.hero-scroll-cue__chevron{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: inherit;
  animation: hero-scroll-cue-bounce 1.8s ease-in-out infinite;
  filter: drop-shadow(0 0 6px rgba(61, 139, 255, 0.35));
}
@keyframes hero-scroll-cue-in{
  from{ opacity: 0; transform: translate(-50%, 8px); }
  to  { opacity: 0.9; transform: translate(-50%, 0); }
}
@keyframes hero-scroll-cue-bounce{
  0%, 100% { transform: translateY(0);    opacity: 0.55; }
  50%      { transform: translateY(7px);  opacity: 1; }
}
/* Disparait des qu'on quitte le hero — coherent avec le reste de la nav. */
body.ca-hero-out .hero-scroll-cue{
  opacity: 0 !important;
  pointer-events: none;
}
/* Respect reduced-motion : pas de bounce, juste l'opacite finale. */
@media (prefers-reduced-motion: reduce){
  .hero-scroll-cue{ animation: none; opacity: 0.85; }
  .hero-scroll-cue__chevron{ animation: none; opacity: 1; }
}
/* Mobile : un peu plus haut pour pas chevaucher la home indicator iOS. */
@media (max-width: 900px){
  .hero-scroll-cue{ bottom: clamp(40px, 7vh, 60px); }
  .hero-scroll-cue__label{ font-size: 9.5px; letter-spacing: 0.18em; }
}
#hero-logos{ display: none; }
/* Refonte 2026-05-21 v9 : CTA Inter sans serif, primary cyan filled, ghost cyan border */
/* Perf 2026-05-21 round 5 : backdrop-filter retire (2 boutons hero, blur 8px sur
   un fond uni navy = effet imperceptible mais cout GPU non nul). Transitions
   reduites a transform+border+box-shadow seulement. */
.hero-cta{ display: inline-flex; align-items: center; gap: 10px; border-radius: 12px; font-family: 'Inter', -apple-system, sans-serif; text-decoration: none; transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; }
/* Primary : cyan filled solid avec sub-gradient + glow (echo maquette "Explorer la plateforme") */
.hero-cta--primary{
  /* 2026-08-13 : le dégradé partait encore du CYAN #2cd4ff (et sa bordure
     cyan) — dernier vestige de la palette d'avant le 14/07, quand l'accueil
     est passé au bleu électrique #3d8bff pour épouser le hero. Sur le globe
     bleu, ce départ turquoise faisait sortir le bouton de la DA. Ramené sur
     la rampe bleue de la page (--gold-l → --gold → --gold-d). */
  background: linear-gradient(135deg, #3d8bff 0%, #2470ea 55%, #10469f 100%);
  /* Rampe partant du bleu SIGNATURE plutôt que d'un tint plus clair : le
     libellé blanc passe de 2,3:1 (sur l'ancien départ cyan/clair) à 3,3→4,6:1
     mesurés, et la couleur de marque reste la teinte dominante du bouton. */
  color: #ffffff;
  border: 1px solid rgba(116, 174, 255, 0.62);
  box-shadow:
    0 8px 26px -8px rgba(61, 139, 255, 0.62),
    0 2px 6px -1px rgba(0, 8, 24, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.30),
    inset 0 -1px 0 rgba(0, 8, 24, 0.25);
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 8, 24, 0.40);
}
.hero-cta--primary:hover{
  transform: translateY(-2px);
  filter: brightness(1.08);
  box-shadow:
    0 14px 34px -10px rgba(61, 139, 255, 0.78),
    0 4px 10px -2px rgba(0, 8, 24, 0.50),
    inset 0 1px 0 rgba(255, 255, 255, 0.42),
    inset 0 -1px 0 rgba(0, 8, 24, 0.25);
}
/* Ghost : transparent navy avec border cyan (echo "Voir les analyses") */
.hero-cta--ghost{
  background: rgba(10, 21, 48, 0.55);
  color: #eaf2fb;
  border: 1px solid rgba(70, 140, 240, 0.55);
  font-weight: 600;
}
.hero-cta--ghost:hover{
  border-color: #3d8bff;
  color: #ffffff;
  background: rgba(61, 139, 255, 0.12);
  box-shadow: 0 10px 26px -10px rgba(61, 139, 255, 0.55);
  transform: translateY(-2px);
}
@keyframes heroFadeUp{ to { opacity: 1; transform: translateY(0); } from { opacity: 0; transform: translateY(8px); } }
/* Hero main : 1 colonne, le SVG kintsugi part en absolute derriere */

/* Image arbre antifragile en background hero. Active si /assets/hero_tree.jpg existe. */









.ca-hero-eyebrow .bar{ flex: 0 0 32px; height: 1px; background: var(--gold); }












/* Masthead magazine : ligne kicker + rule + issue + Live badge */








@keyframes ca-pulse{ 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }

/* Hairline rule sous le titre, signature editoriale, proportionnee au titre */


/* Drop cap : T initial du lede en serif gold 3 lignes, baseline alignee cap-height */


/* Point final du titre Capital. — en or, immobile (un magazine ne clignote pas). Glow statique discret. */


/* Lede explicatif sous le titre */





/* CTA primary + ghost */









/* Citation Taleb : signature en bas du hero (presence ressentie, pas dominante) */





/* Hero art : SVG kintsugi en filigrane ABSOLU derriere le texte (duotone champagne/charbon) */

/* Image arbre s'active quand assets/hero_tree.jpg est sauve via JS check (evite 404 console) */

.ca-hero-art-img.is-loaded{ opacity: 0.85; }


/* Couche SVG kintsugi : craquelures or qui se dessinent au load */






/* Poussiere doree : derive lente + scintillement, GPU composite */

@keyframes dust-drift{
  0%   { transform: translate(0, 0); opacity: 0; }
  15%  { opacity: 0.7; }
  85%  { opacity: 0.7; }
  100% { transform: translate(var(--dx, 6px), var(--dy, -10px)); opacity: 0; }
}

@keyframes kintsugi-draw{ to { stroke-dashoffset: 0; } }
@keyframes spark-pulse{ 0%, 100% { opacity: 0.15; transform: scale(0.8); } 50% { opacity: 0.85; transform: scale(1.2); } }
/* Anneau or subtil derriere */








.ca-hero-stat .ca-lab{ display: block; margin-top: 10px; }







@keyframes caRotateHl{ from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
















/* Kintsugi divider */
.ca-kintsugi{ max-width: var(--max-w); margin: 0 auto; padding: 80px 44px 0; text-align: center; position: relative; }
/* Editorial divider : remplace l'ancien SVG kintsugi par un ornement type magazine */
.ca-kintsugi svg{ display: none; }
.ca-kintsugi::before, .ca-kintsugi::after{
  content: '';
  display: inline-block;
  vertical-align: middle;
  height: 1px;
  width: 80px;
  background: linear-gradient(90deg, transparent, var(--gold) 50%, transparent);
  opacity: 0.45;
}
.ca-kintsugi::before{ margin-right: 16px; }
.ca-kintsugi::after{ margin-left: 16px; }
.ca-kintsugi::marker{ display: none; }
/* Divider simple cyan hairline */
.ca-kintsugi-ornament{ display: inline-block; vertical-align: middle; width: 6px; height: 6px; border-radius: 50%; background: var(--gold); opacity: 0.5; }
.ca-kintsugi svg{ display: block; margin: 0 auto; width: 100%; max-width: 280px; height: 32px; }

/* Sections — content-visibility retiré entièrement 2026-05-19 : causait
   un stutter perceptible au scroll rapide (paint just-in-time des sections
   entrant dans le viewport). Page reste fluide sans cette opt. */
.ca-section{ max-width: var(--max-w); margin: 0 auto; padding: 80px 44px 60px; position: relative; }












/* § I Verdict */





















.ca-verdict-meta .ca-lab{ display: block; margin-top: 8px; }

/* § II Cartographie */
.ca-maps{ display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
/* 2026-05-21 v9.1 : harmonisation .ca-map sur la DA des tiles .ca-tile
   (radius 14px, accent cyan au lieu d'ornements gold L-shape, head en mono
   uppercase comme les widgets). Bento + bubble charts = meme famille visuelle. */
.ca-map{ background: linear-gradient(145deg, rgba(15, 32, 58, 0.85) 0%, rgba(10, 22, 42, 0.92) 100%); border: 1px solid rgba(108, 221, 255, 0.18); border-radius: 14px; padding: 22px 24px 20px; min-height: 520px; position: relative; overflow: hidden; transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease); }
.ca-map:hover{ border-color: rgba(108, 221, 255, 0.4); box-shadow: 0 0 32px -8px rgba(108, 221, 255, 0.22); }
/* L-shape gold corner marks retires (DA editoriale -> dashboard). */
.ca-map::before, .ca-map::after{ display: none !important; }
/* min-height + align-content : la carte actions a 2 rangees d'onglets (zone + metrique),
   la crypto 1 seule. On reserve la meme hauteur de tete pour les deux et on centre
   verticalement -> les canvas demarrent au meme Y (cartes parfaitement alignees). */
.ca-map-head{ display: flex; justify-content: space-between; align-items: center; align-content: center; margin-bottom: 16px; gap: 12px; flex-wrap: wrap; min-height: 66px; }
.ca-map-title{ font-family: 'Inter', -apple-system, sans-serif; font-style: normal; font-weight: 600; font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-2); opacity: 0.9; }
/* Section tight : padding-top serre pour la section qui suit le bento, apres
   suppression du divider kintsugi entre les deux. */
.ca-section--tight{ padding-top: 14px !important; padding-bottom: 40px !important; }







/* ── Bento Vue d'ensemble : 9 tuiles signal/onglet ─────────── */
.ca-bento{ display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 14px; margin-top: 40px; position: relative; }  /* 1fr x 4 (au lieu de 1.6/1/1/1) : refonte 2026-05-26, garantit que les paires de wide-2 (gauche+droite) ont strictement la meme largeur (50/50). Spotlight Radar v1 reste differencie par min-height 408px et grid-row span 2. */
/* Voile atmospherique derriere le bento.
   Perf 2026-05-21 (round 4 bis) : filter:blur(60px) sur surface ~110%x110% du
   bento = un des plus gros couts GPU encore en place. Le voile etait subtil
   sous les tuiles (transparency 0.10-0.22) donc le retirer est imperceptible
   sur iGPU Intel + supprime un blur kernel enorme a chaque compositing. */
.ca-bento::before{ display: none !important; }
.ca-bento > *{ position: relative; z-index: 1; }
/* Glassmorph v8 : bg semi-transparente + backdrop-blur + radial aurora spill du haut */
.ca-tile{ position: relative; display: flex; flex-direction: column; padding: 22px 24px 20px; border: 1px solid rgba(108, 221, 255, 0.18); border-radius: 14px;
  /* Perf 2026-05-21 round 6 : 4 background layers (sheen + 2 radial-gradients + body)
     -> 1 single linear-gradient. 19 tiles x 4 layers = 76 paint computations par scroll.
     Reduit a 19. Sheen + halos imperceptibles sur iGPU Intel de toute facon. */
  background: linear-gradient(145deg, rgba(15, 32, 58, 0.85) 0%, rgba(10, 22, 42, 0.92) 100%);
  /* PERF 2026-05-21 : blur 18px -> 10px + saturate 180% -> 150%. Sur iGPU
     Intel les 14+ tiles avec backdrop-filter etaient un des plus gros
     couts au repos. Kernel 10px reste perceptible comme verre depoli,
     l'opacite du body (0.30/0.42) compense la perte de diffusion. */
  /* Perf 2026-05-21 round 5 : backdrop-filter inline retire (deja override par
     line 580+ a none), transition reduite a transform+border-color uniquement.
     box-shadow + background dans transition forcent un compositor layer permanent
     sur iGPU Intel meme au repos. */
  text-decoration: none; color: inherit; min-height: 184px; transition: transform 0.25s var(--ease), border-color 0.25s var(--ease); overflow: hidden; contain: layout style paint; opacity: 1; transform: translateY(0); }
/* Top accent bar : gradient cyan -> cyan clair (refonte 2026-05-21 v9, palette unifiee) */
.ca-tile::before{ content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, transparent 0%, #3d8bff 25%, #74aeff 50%, #3d8bff 75%, transparent 100%); opacity: 0.65; transition: opacity 0.35s var(--ease); }
/* Ombres cool-cast + hairlines aurora top/bottom (echo aurora ciel + reflet lac) */
/* Refonte 2026-05-20 v6 : passage matte -> vernis brillant / verre laque.
   Box-shadow stack avec specular highlight clair en haut + ombre profonde
   en bas + reflexion subtile, donne une impression de surface convex/glossy.
   Pas de backdrop-filter dynamique au hover (iGPU Intel). */
/* Perf 2026-05-21 (round 4 bis) : box-shadow stack reduit de 9 a 3 layers.
   Le 70px blur sur 14+ tiles etait un cout GPU enorme a chaque scroll/composite.
   Garde le specular top + l'ombre projettee principale + une fine bordure
   interne. Visuel : tres proche de l'original, profondeur preservee. */
.ca-tile{ box-shadow:
    inset 0 1px 0 rgba(186, 220, 255, 0.18),
    0 8px 20px -8px rgba(0, 8, 24, 0.55),
    0 2px 4px -1px rgba(0, 0, 0, 0.30) !important;
}
/* Hover : lift + glow simplifie (perf 2026-05-21 round 4 bis : 10 shadows -> 3) */
.ca-tile:hover{
  border-color: rgba(61, 139, 255, 0.45);
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(186, 220, 255, 0.28),
    0 12px 24px -8px rgba(0, 8, 24, 0.65),
    0 0 24px -8px rgba(61, 139, 255, 0.32) !important;
}
.ca-tile:hover::after{ opacity: 1; }
.ca-tile:hover::before{ opacity: 0.95; }
/* Featured tiles : override retire 2026-06-03 (donnait un petit carre bleu 3x2px haut-gauche visible sur le radar spotlight, pas sur les autres). Les featured tiles utilisent desormais la meme aurora line haute que les autres. */
.ca-tile.is-visible{ opacity: 1; transform: translateY(0); }
/* Perf 2026-05-21 round 5 : pulse anime box-shadow (paint-expensive sur iGPU
   Intel). Remplace par opacity+outline animation, GPU-friendly, visuel similaire. */
.ca-tile.is-updated{ animation: ca-tile-pulse 1.4s ease-out; }
@keyframes ca-tile-pulse{
  0%   { outline: 0 solid rgba(61, 139, 255, 0); }
  25%  { outline: 2px solid rgba(61, 139, 255, 0.45); }
  100% { outline: 0 solid rgba(61, 139, 255, 0); }
}
@media (prefers-reduced-motion: reduce){ .ca-tile{ opacity: 1; transform: none; } }
/* Info icon ⓘ cyan + tooltip methodologique */
.ca-tile[data-hint] .ca-tile-info{ position: absolute; top: 14px; right: 16px; font-family: var(--mono); font-size: 11px; color: var(--gold); opacity: 0.5; pointer-events: none; transition: opacity 0.3s; z-index: 4; }
/* info hover supprime */
/* Tooltip remplace le ::after deja utilise pour le glow ambient; on utilise un span via JS plutot */
/* Accent vertical gauche — deplace en ::after pour ne pas ecraser le top bar aurora (::before, ligne 805) */
.ca-tile::after{ content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: linear-gradient(180deg, #6cddff 0%, transparent 70%); opacity: 0.32; transition: opacity 0.3s, width 0.3s var(--ease); pointer-events: none; }
.ca-tile:hover::after{ opacity: 0.7; width: 3px; }
/* Refonte 2026-05-20 : taille reduite (consigne user "tres gros, reduire").
   Avant : featured 240px / spotlight 504px. Apres : 200px / 408px. */
.ca-tile--featured{ grid-column: span 2; min-height: 200px; padding: 20px 24px 16px; }
/* Variant featured-wide : 3 cols (pour Sentiment a cote du Radar spotlight) */
.ca-tile--featured-wide{ grid-column: span 3; }
/* Spotlight : Radar v1 grosse colonne gauche (1.6fr) sur 2 lignes — reduit */
.ca-tile--spotlight{ grid-column: 1 / span 1; grid-row: span 2; min-height: 408px; padding: 20px 22px 16px; }
/* spotlight::before height override retire 2026-06-03 (aurora line standard 2px comme les autres tiles) */
.ca-tile--spotlight .ca-tile-name{ font-size: 10.5px; letter-spacing: 0.22em; }
.ca-tile--spotlight .ca-tile-spark--spotlight{ width: 100%; height: 36px; margin: 6px 0 4px; opacity: 0.6; }

/* Radar v1 spotlight : gauge semi-arc + score below + sous-signaux compact.
   Refonte 2026-05-20 : gap reduit 14->10, margin-top retire pour gagner ~30px. */
.ca-radar-body{ flex: 1; display: flex; flex-direction: column; gap: 10px; min-height: 0; margin-top: 0; }
/* Variant horizontale pour featured tiles plus courtes (Crisis Index) */
.ca-radar-body--row{ flex-direction: row; gap: 20px; align-items: stretch; }
.ca-radar-body--row .ca-radar-gauge-wrap{ flex: 0 0 200px; }
.ca-radar-body--row .ca-radar-signals{ flex: 1; }
.ca-radar-body--row .ca-radar-big{ font-size: clamp(20px, 2.2vw, 28px); }
.ca-radar-body--row .ca-radar-gauge-wrap svg{ max-width: 150px; }
.ca-radar-body--row .ca-radar-gauge-wrap{ flex: 0 0 170px !important; }
/* Sentiment Marché : 3 cols (gauge / radar / signals) — refonte 2026-05-26.
   Chart 24M supprime : le body remplit la hauteur via flex:1 + align-items:center
   pour un centrage vertical naturel des 3 colonnes. Jauge agrandie (max-width
   260 au lieu de 150 par defaut) car la widget wide a la place pour respirer. */
.ca-radar-body--with-radar{ display: grid !important; grid-template-columns: 260px 1fr 240px; gap: 28px; align-items: center; justify-content: center; flex: 1; min-height: 0; padding: 10px 8px; }
.ca-radar-body--with-radar .ca-radar-gauge-wrap{ flex: none !important; }
.ca-radar-body--with-radar .ca-radar-gauge-wrap svg{ max-width: 250px !important; }
.ca-radar-body--with-radar .ca-radar-big{ font-size: clamp(28px, 2.8vw, 36px); }
.ca-radar-body--with-radar .ca-radar-signals{ flex: none !important; }
.ca-sent-radar-wrap{ display: flex; align-items: center; justify-content: center; min-width: 0; width: 100%; }
.ca-sent-radar{ width: 100%; max-width: 280px; aspect-ratio: 1; height: auto; display: block; }
/* Scene = radar + fiche detail superposes (cf bloc DRILL-DOWN plus bas). C'est
   ELLE qui est l'enfant de la grille depuis 2026-07-25, d'ou les media queries
   qui ciblent .ca-sent-stage et non plus .ca-sent-radar-wrap. */
/* min-height : la fiche detail (contenu le plus haut des deux) donne le ton.
   Hauteur FIXE au repos comme ouvert → le clic ne deplace jamais rien. */
.ca-sent-stage{ position: relative; display: flex; align-items: center; justify-content: center;
  min-width: 0; min-height: 264px; }
@media (max-width: 1100px){
  .ca-radar-body--with-radar{ grid-template-columns: 1fr 1fr; }
  .ca-sent-stage{ grid-column: span 2; max-width: 300px; margin: 0 auto; width: 100%; }
}
.ca-radar-gauge-wrap{ display: flex; flex-direction: column; align-items: center; gap: 6px; }
.ca-radar-gauge-wrap svg{ display: block; max-width: 100%; height: auto; }
.ca-radar-score-stack{ text-align: center; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.ca-radar-big{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: clamp(30px, 3.5vw, 44px); line-height: 1; color: var(--fg); letter-spacing: -0.035em; font-variant-numeric: tabular-nums; }
.ca-radar-big sup{ font-family: 'Inter', sans-serif; font-size: 13px; font-weight: 400; color: var(--muted); letter-spacing: 0; margin-left: 3px; vertical-align: top; }
/* Pastille d'etat — UNE SEULE source de verite pour sa couleur : les variables
   --pill-c / --pill-bg / --pill-bd, posees en JS par paintStateBadge() depuis la
   MEME fonction classify() qui teinte la jauge et la courbe. Consequence : aucun
   libelle ne peut retomber en gris "sans etat" (bug user 2026-08-19 : le
   « GREED » du CNN F&G etait gris parce que 55-75 ne declenchait aucun
   data-state). Les regles data-state ci-dessous ne posent plus que les MEMES
   variables : elles restent le repli des tuiles que le JS ne peint pas. */
.ca-radar-label{ display: inline-block; padding: 4px 11px; border-radius: 100px; background: var(--pill-bg, rgba(116, 185, 255, 0.06)); border: 1px solid var(--pill-bd, rgba(116, 185, 255, 0.16)); font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--pill-c, var(--fg-2)); font-weight: 500; }
.ca-tile[data-state="risk-on"]  .ca-radar-label{ --pill-c: #4dd092; --pill-bg: rgba(39,174,96,0.08);  --pill-bd: rgba(39,174,96,0.28); }
.ca-tile[data-state="risk-off"] .ca-radar-label{ --pill-c: #ed7567; --pill-bg: rgba(231,76,60,0.08);  --pill-bd: rgba(231,76,60,0.28); }
.ca-tile[data-state="warn"]     .ca-radar-label{ --pill-c: #f6b86b; --pill-bg: rgba(245,166,35,0.08); --pill-bd: rgba(245,166,35,0.28); }

.ca-radar-signals{ display: flex; flex-direction: column; flex: 1; min-height: 0; }
.ca-radar-signals-head{ font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); padding-bottom: 8px; border-bottom: 1px solid rgba(116, 185, 255, 0.08); margin-bottom: 6px; }
.ca-radar-signals-list{ list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 1px; }
.ca-radar-sig{ display: grid; grid-template-columns: 14px 1fr auto; gap: 10px; align-items: center; padding: 4px 4px; }
.ca-radar-sig-dot{ width: 8px; height: 8px; border-radius: 50%; justify-self: center; }
.ca-radar-sig.is-bull .ca-radar-sig-dot{ background: #4dd092; box-shadow: 0 0 6px rgba(77,208,146,0.6); }
.ca-radar-sig.is-bear .ca-radar-sig-dot{ background: #ed7567; box-shadow: 0 0 6px rgba(237,117,103,0.6); }
.ca-radar-sig.is-neutral .ca-radar-sig-dot{ background: #6e7989; }
.ca-radar-sig-name{ font-family: 'Inter', sans-serif; font-weight: 500; font-size: 11.5px; color: var(--fg-2); }
.ca-radar-sig-state{ font-family: var(--mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.12em; }
.ca-radar-sig.is-bull .ca-radar-sig-state{ color: #4dd092; }
.ca-radar-sig.is-bear .ca-radar-sig-state{ color: #ed7567; }
.ca-radar-sig.is-neutral .ca-radar-sig-state{ color: var(--muted); }

/* ──── Variante Sentiment Marché CNN F&G ──── */
/* Refonte 2026-05-26 : palette CONTRARIAN alignee pixel-perfect sur la nouvelle
   classifySentiment() (accueil.js L841). Logique trader-centric :
   VERT = bullish (opportunite), ROUGE = bearish (warning).
   Sentiment Marche etant CONTRARIAN, low value = bullish, high = bearish.
     v < 25  : vert    #34d399 (peur extreme = buy opp)
     v 25-45 : cyan    #5eaff6 (peur = buy lean)
     v 45-55 : gris    #94a3b8 (neutre)
     v 55-75 : orange  #f59e0b (greed = caution)
     v >= 75 : rouge   #ff4d6a (euphorie = sell warning) */
.ca-radar-sig.is-fng-fear-ext .ca-radar-sig-dot{ background: #34d399; box-shadow: 0 0 6px rgba(52,211,153,0.55); }
.ca-radar-sig.is-fng-fear .ca-radar-sig-dot{ background: #5eaff6; box-shadow: 0 0 6px rgba(94,175,246,0.50); }
.ca-radar-sig.is-fng-neutral .ca-radar-sig-dot{ background: #94a3b8; }
.ca-radar-sig.is-fng-greed .ca-radar-sig-dot{ background: #f59e0b; box-shadow: 0 0 6px rgba(245,158,11,0.45); }
.ca-radar-sig.is-fng-overheat .ca-radar-sig-dot{ background: #ff4d6a; box-shadow: 0 0 6px rgba(255,77,106,0.55); }
.ca-radar-sig.is-fng-fear-ext .ca-radar-sig-state{ color: #34d399; }
.ca-radar-sig.is-fng-fear .ca-radar-sig-state{ color: #5eaff6; }
.ca-radar-sig.is-fng-neutral .ca-radar-sig-state{ color: var(--muted); }
.ca-radar-sig.is-fng-greed .ca-radar-sig-state{ color: #f59e0b; }
.ca-radar-sig.is-fng-overheat .ca-radar-sig-state{ color: #ff4d6a; }

/* Mini-bar de visualisation 0-100 a droite du nom. Active uniquement pour les
   sentiments rows qui ont la classe modifier .ca-radar-sig--with-bar. Le grid
   passe a 4 colonnes : dot (14px) | name (auto) | bar (1fr) | state (auto). */
.ca-radar-sig--with-bar{ grid-template-columns: 14px auto 1fr auto; gap: 10px; }
.ca-radar-sig-bar{ position: relative; height: 4px; background: rgba(148,163,184,0.10); border-radius: 2px; overflow: hidden; }
.ca-radar-sig-bar-fill{ display: block; height: 100%; border-radius: 2px; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); }

/* ═══════════════════════════════════════════════════════════════════════════
   DRILL-DOWN SENTIMENT CNN F&G (2026-07-25)
   ═══════════════════════════════════════════════════════════════════════════
   Clic sur un sous-signal (ou sur un axe du radar) → une fiche detail prend la
   place du radar : score, phrase d'explication, courbe 36 mois, deltas, valeurs
   BRUTES du jour, formule + source. La fiche est en position:absolute DANS
   .ca-sent-stage → la hauteur de la tuile ne bouge pas d'un pixel (pas de saut
   dans le bento). Aucun blur/backdrop-filter (iGPU Intel).                   */

/* ── Liste des sous-signaux : lignes cliquables ── */
.ca-radar-signals-hint{ float: right; font-size: 8px; letter-spacing: 0.14em; color: rgba(148,163,184,0.55); text-transform: none; }
.ca-radar-signals-list--clickable .ca-radar-sig--with-bar{ grid-template-columns: 14px auto 1fr auto 9px; }
.ca-radar-sig--btn{ cursor: pointer; border-radius: 7px; -webkit-tap-highlight-color: transparent;
  transition: background 0.16s var(--ease), box-shadow 0.16s var(--ease); }
.ca-radar-sig--btn:hover{ background: rgba(116,185,255,0.07); }
.ca-radar-sig--btn:focus-visible{ outline: 1px solid rgba(116,185,255,0.55); outline-offset: 1px; }
.ca-radar-sig--btn.is-active{ background: rgba(116,185,255,0.11); }
.ca-radar-sig--btn.is-active .ca-radar-sig-name{ color: var(--fg); font-weight: 600; }
/* Liseré gauche = couleur de l'etat F&G de la composante ouverte */
.ca-radar-sig--btn.is-active.is-fng-fear-ext{ box-shadow: inset 2px 0 0 #34d399; }
.ca-radar-sig--btn.is-active.is-fng-fear{ box-shadow: inset 2px 0 0 #5eaff6; }
.ca-radar-sig--btn.is-active.is-fng-neutral{ box-shadow: inset 2px 0 0 #94a3b8; }
.ca-radar-sig--btn.is-active.is-fng-greed{ box-shadow: inset 2px 0 0 #f59e0b; }
.ca-radar-sig--btn.is-active.is-fng-overheat{ box-shadow: inset 2px 0 0 #ff4d6a; }
.ca-radar-sig-chev{ font-family: var(--mono); font-size: 12px; line-height: 1; color: var(--muted);
  opacity: 0; transform: translateX(-2px); transition: opacity 0.16s var(--ease), transform 0.16s var(--ease); }
.ca-radar-sig--btn:hover .ca-radar-sig-chev,
.ca-radar-sig--btn:focus-visible .ca-radar-sig-chev{ opacity: 0.7; transform: translateX(0); }
.ca-radar-sig--btn.is-active .ca-radar-sig-chev{ opacity: 1; transform: translateX(0) rotate(90deg); }

/* ── Axes du radar cliquables ── */
.ca-sr-axis{ cursor: pointer; }
.ca-sr-axis text{ transition: fill 0.16s var(--ease); }
.ca-sr-axis:hover text{ fill: #eaf3ff; }
.ca-sr-axis:focus-visible{ outline: none; }
.ca-sr-axis:focus-visible text{ fill: #eaf3ff; text-decoration: underline; }

/* ── La fiche elle-meme ── */
.ca-sent-stage .ca-sent-radar-wrap{ transition: opacity 0.18s var(--ease), transform 0.18s var(--ease); }
.ca-sent-stage.is-detail .ca-sent-radar-wrap{ opacity: 0; transform: scale(0.96); pointer-events: none; }
.ca-sent-detail{ position: absolute; inset: 0; display: flex; flex-direction: column; gap: 3px;
  padding: 9px 11px 7px; border-radius: 12px; overflow: hidden;
  background: linear-gradient(178deg, rgba(17,31,56,0.96), rgba(9,18,36,0.98));
  border: 1px solid rgba(116,185,255,0.18); box-shadow: 0 12px 30px rgba(3,8,20,0.45);
  animation: caSdIn 0.20s var(--ease) both; }
.ca-sent-detail[hidden]{ display: none; }
@keyframes caSdIn{ from{ opacity: 0; transform: translateY(6px) scale(0.985); } to{ opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce){
  .ca-sent-detail{ animation: none; }
  .ca-sent-stage .ca-sent-radar-wrap{ transition: none; }
}

.ca-sd-head{ display: flex; align-items: center; gap: 6px; min-width: 0; }
.ca-sd-dot{ width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.ca-sd-name{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 12.5px; color: var(--fg); letter-spacing: 0.01em; }
.ca-sd-en{ font-family: var(--mono); font-size: 8px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ca-sd-close{ flex: 0 0 auto; width: 18px; height: 18px; display: grid; place-items: center; padding: 0;
  border-radius: 5px; border: 1px solid rgba(116,185,255,0.16); background: rgba(116,185,255,0.05);
  color: var(--muted); font-size: 9px; line-height: 1; cursor: pointer;
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease), background 0.15s var(--ease); }
.ca-sd-close:hover{ color: var(--fg); border-color: rgba(116,185,255,0.4); background: rgba(116,185,255,0.12); }

.ca-sd-scoreline{ display: flex; align-items: baseline; gap: 7px; }
.ca-sd-score{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 23px; line-height: 1;
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.ca-sd-score-u{ font-family: var(--mono); font-size: 9px; color: var(--muted); margin-left: -4px; }
.ca-sd-chip{ border: 1px solid; border-radius: 100px; padding: 2px 8px; font-family: var(--mono);
  font-size: 8.5px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.ca-sd-weight{ margin-left: auto; font-family: var(--mono); font-size: 8px; letter-spacing: 0.08em; color: var(--muted); }

/* flex:0 0 auto = la phrase d'explication ne se fait JAMAIS ecraser par les
   blocs voisins (sans ca, le flex la comprimait a une ligne tronquee). */
.ca-sd-explain{ margin: 0; flex: 0 0 auto; font-family: 'Inter', sans-serif; font-size: 10.5px; line-height: 1.4;
  color: var(--fg-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Graphe + calque de survol superposes : le calque capte la souris et dessine
   le curseur, la courbe reste intacte dessous. */
.ca-sd-chartwrap{ position: relative; flex: 0 0 auto; }
.ca-sd-chart{ width: 100%; height: 44px; display: block; }
.ca-sd-chart-hover{ position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; }
.ca-sd-cap{ display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-top: -1px;
  font-family: var(--mono); font-size: 8px; letter-spacing: 0.08em; color: var(--muted); }
/* Fenetres 1A / 3A / 10A — meme grammaire que les segments des autres tuiles */
.ca-sd-ranges{ display: inline-flex; gap: 2px; flex: 0 0 auto; }
.ca-sd-ranges button{ font-family: var(--mono); font-size: 8px; font-weight: 700; letter-spacing: 0.08em;
  color: var(--muted); background: rgba(116,185,255,0.06); border: 1px solid transparent;
  border-radius: 4px; padding: 1px 5px; line-height: 1.5; cursor: pointer;
  transition: color 0.15s var(--ease), background 0.15s var(--ease), border-color 0.15s var(--ease); }
.ca-sd-ranges button:hover{ color: var(--fg-2); background: rgba(116,185,255,0.12); }
.ca-sd-ranges button.is-on{ color: #cfe3ff; background: rgba(116,185,255,0.16); border-color: rgba(116,185,255,0.32); }
.ca-sd-readout{ text-align: right; font-variant-numeric: tabular-nums; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ca-sd-readout b{ color: var(--fg-2); font-weight: 700; }

/* Bas de fiche : evolution du score (gauche) | valeurs brutes du jour (droite).
   Deux colonnes = la fiche complete tient dans la hauteur du radar. */
.ca-sd-grid{ display: grid; grid-template-columns: 0.85fr 1.15fr; gap: 8px; align-items: start; }
.ca-sd-stats{ display: flex; flex-direction: column; gap: 2px; }
.ca-sd-stat{ display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  padding: 1px 6px; border-radius: 5px; background: rgba(116,185,255,0.05); }
.ca-sd-stat b{ font-family: var(--mono); font-size: 7.5px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); }
.ca-sd-stat i{ font-family: var(--mono); font-style: normal; font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* Palette CONTRARIAN (identique aux barres/points de la tuile) : score qui monte
   = plus de greed = orange ; score qui baisse = detente = cyan. */
.ca-sd-stat i.up{ color: #f59e0b; }
.ca-sd-stat i.dn{ color: #5eaff6; }
.ca-sd-stat i.neut{ color: var(--muted); }

.ca-sd-raw{ display: flex; flex-direction: column; gap: 1px; padding: 5px 7px; border-radius: 7px;
  background: rgba(116,185,255,0.045); border: 1px solid rgba(116,185,255,0.08); }
.ca-sd-raw-row{ display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-family: var(--mono); font-size: 9px; line-height: 1.5; }
.ca-sd-raw-row span{ color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ca-sd-raw-row b{ color: var(--fg); font-weight: 700; font-variant-numeric: tabular-nums; }
.ca-sd-raw-date{ font-family: var(--mono); font-size: 7.5px; letter-spacing: 0.06em; color: var(--muted); opacity: 0.65; text-align: right; }
.ca-sd-raw--empty{ font-family: 'Inter', sans-serif; font-size: 9.5px; line-height: 1.35; color: var(--muted); }

.ca-sd-foot{ margin-top: auto; display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  padding-top: 5px; border-top: 1px solid rgba(116,185,255,0.09);
  font-family: var(--mono); font-size: 8px; letter-spacing: 0.04em; color: var(--muted); }
.ca-sd-formula{ color: #8fb4e8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ca-sd-src{ flex: 0 0 auto; opacity: 0.8; }

/* Mobile / phablet : la colonne centrale tombe a ~300px → la fiche passe en
   une seule colonne (deltas puis valeurs brutes) et la scene s'allonge pour
   tout accueillir sans troncature. Cibles tactiles des lignes agrandies. */
@media (max-width: 767px){
  /* Sur mobile la fiche n'est PLUS superposee : elle remplace le radar dans le
     flux. La tuile s'ajuste a son contenu (comportement d'accordeon attendu au
     doigt) plutot que de tronquer le texte dans une hauteur figee. */
  .ca-sent-detail{ position: static; inset: auto; width: 100%; flex: 1 1 auto; }
  .ca-sent-stage.is-detail{ min-height: 0; }
  .ca-sent-stage.is-detail .ca-sent-radar-wrap{ display: none; }
  .ca-sd-grid{ grid-template-columns: 1fr; gap: 6px; }
  .ca-sd-chart{ height: 52px; }
  .ca-sd-ranges button{ font-size: 9px; padding: 2px 7px; }
  .ca-sd-explain{ font-size: 11px; -webkit-line-clamp: 3; }
  .ca-sd-raw-row{ font-size: 10px; }
  .ca-sd-stat i{ font-size: 11px; }
  /* Cible tactile confortable (la regle scopee data-tile impose 2px sinon) */
  .ca-tile[data-tile="sentiment"] .ca-radar-sig--btn{ padding: 7px 6px !important; }
  .ca-radar-signals-hint{ font-size: 8.5px; }
}

/* Ecrans larges : la colonne centrale depasse 550px → on aere la fiche. La
   scene gagne la hauteur correspondante DANS LA MEME media query, sinon le
   contenu grossit sans place pour lui (bug constate a 1512px). */
@media (min-width: 1700px){
  .ca-sent-stage{ min-height: 300px; }
  .ca-sent-detail{ padding: 11px 14px 9px; gap: 5px; }
  .ca-sd-explain{ font-size: 11.5px; }
  .ca-sd-chart{ height: 54px; }
  .ca-sd-raw-row{ font-size: 10.5px; }
  .ca-sd-stat i{ font-size: 11px; }
  .ca-sd-foot, .ca-sd-cap{ font-size: 8.5px; }
}

/* ─── Radar v1 sous-signaux dérivés — VRAIS signaux du score (refonte 2026-05-29) ──
   Affiche les signaux backtestables renvoyés par buildRadar (id/type/head/val/weight).
   Couleur = contribution au score : opp=vert / risk=rouge / info|neutral=gris.
   Poids du signal ●●○ (currentColor) + valeur mono. Liste scrollable si nombreux. */
#bt-radar-signals{ max-height: 232px; overflow-y: auto; overflow-x: hidden; }
#bt-radar-signals::-webkit-scrollbar{ width: 5px; }
#bt-radar-signals::-webkit-scrollbar-thumb{ background: rgba(116,185,255,0.18); border-radius: 3px; }
.ca-radar-sig--v2{ grid-template-columns: 8px 1fr auto auto; gap: 9px; padding: 4px 7px; border-radius: 7px; transition: background 0.15s var(--ease); }
.ca-radar-sig--v2:hover{ background: rgba(116,185,255,0.05); }
.ca-radar-sig--v2 .ca-radar-sig-name{ font-size: 11px; font-weight: 600; letter-spacing: 0.01em; color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ca-radar-sig-w{ display: inline-flex; gap: 2px; align-items: center; }
.ca-radar-sig-w i{ width: 4px; height: 4px; border-radius: 50%; background: rgba(148,163,184,0.22); }
.ca-radar-sig-w i.on{ background: currentColor; }
.ca-radar-sig-val{ font-family: var(--mono); font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; min-width: 58px; }
.ca-radar-sig--v2.is-bull{ color: #28e07e; }
.ca-radar-sig--v2.is-bear{ color: #ff5570; }
.ca-radar-sig--v2.is-neutral{ color: var(--muted); }
.ca-radar-sig--v2.is-bull .ca-radar-sig-val{ color: #28e07e; }
.ca-radar-sig--v2.is-bear .ca-radar-sig-val{ color: #ff5570; }
.ca-radar-sig--v2.is-neutral .ca-radar-sig-val{ color: var(--fg-2); }
.ca-radar-sig-empty{ font-family: var(--mono); font-size: 10px; color: var(--muted); padding: 8px 4px; list-style: none; }

/* Mini gauge pour standard tiles (F&G, Altseason) : compact 160x90 */
.ca-tile--has-gauge .ca-tile-body{ display: none; }
.ca-mini-gauge-wrap{ display: flex; justify-content: center; margin: 6px 0 0; flex: 0 0 auto; }
.ca-mini-gauge-wrap svg{ display: block; max-width: 100%; }
.ca-mini-score-stack{ display: flex; flex-direction: column; align-items: center; gap: 4px; margin-top: -2px; margin-bottom: 4px; min-height: 70px; justify-content: flex-start; }
.ca-mini-big{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 30px; line-height: 1; color: var(--fg); letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
/* Alignement uniforme des 3 tiles F&G / Altseason / AI Bubble :
   - badge etat (FEAR/NEUTRE/SURCHAUFFE) CENTRE et min-width fixe
   - footer colle en bas via margin-top: auto pour neutraliser les ecarts
     de hauteur de contenu entre les 3 tiles */
.ca-tile--has-gauge .ca-mini-score-stack .ca-tile-sub{ align-self: center !important; min-width: 96px; justify-content: center; }
.ca-tile--has-gauge .ca-hist90-cap{ margin-top: auto; }
.ca-tile--has-gauge .ca-tile-foot{ flex: 0 0 auto; }
.ca-tile--spotlight .ca-tile-head{ margin-bottom: 32px; }
/* spotlight::after retire 2026-06-03 : creait un carre cyan 22x22 colle au bord gauche (left:0 de la base non resette) — la fameuse "petit bande bleu" du radar */
.ca-tile--spotlight::after{ display: none; }
.ca-tile--wide{ grid-column: span 2; }
.ca-tile--full{ grid-column: 1 / -1; }  /* refonte 2026-05-26 : tile pleine largeur (4 cols) — force la ligne dédiée sans auto-pairing */
.ca-tile-head{ display: flex; align-items: center; gap: 12px; margin-bottom: 16px; font-family: var(--mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); position: relative; z-index: 2; }
.ca-tile-name{ letter-spacing: 0.16em !important; color: var(--fg-2); font-weight: 600; opacity: 0.85; }

/* Icone d'identite visuelle : badge en haut-gauche de chaque tuile, couleur par categorie */
.ca-tile-icon{ display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 9px; flex-shrink: 0; font-size: 16px; line-height: 1; transition: transform 0.3s var(--ease); }
.ca-tile-icon i{ font-size: 16px; }
.ca-tile-icon img{ width: 18px; height: 18px; object-fit: contain; border-radius: 50%; }
.ca-tile--featured .ca-tile-icon{ width: 38px; height: 38px; font-size: 19px; }
.ca-tile--featured .ca-tile-icon i{ font-size: 19px; }
.ca-tile--featured .ca-tile-icon img{ width: 22px; height: 22px; }
.ca-tile--spotlight .ca-tile-icon{ width: 44px; height: 44px; font-size: 22px; }
.ca-tile--spotlight .ca-tile-icon i{ font-size: 22px; }
/* Couleurs par categorie (data-cat) */
.ca-tile-icon[data-cat="signal"]{ background: rgba(116, 185, 255, 0.10); border: 1px solid rgba(116, 185, 255, 0.25); color: #74b9ff; }
.ca-tile-icon[data-cat="macro"]{ background: rgba(245, 166, 35, 0.10);  border: 1px solid rgba(245, 166, 35, 0.28);  color: #f5a623; }
.ca-tile-icon[data-cat="sentiment"]{ background: rgba(167, 139, 250, 0.10); border: 1px solid rgba(167, 139, 250, 0.28); color: #a78bfa; }
.ca-tile-icon[data-cat="onchain"]{ background: rgba(0, 196, 216, 0.10);   border: 1px solid rgba(0, 196, 216, 0.28);   color: #00c4d8; }
.ca-tile-icon[data-cat="crypto"]{ background: rgba(247, 147, 26, 0.10);  border: 1px solid rgba(247, 147, 26, 0.28);  color: #f7931a; }
.ca-tile-icon[data-cat="news"]{ background: rgba(116, 185, 255, 0.10); border: 1px solid rgba(116, 185, 255, 0.25); color: #93c5fd; }
.ca-tile-icon[data-cat="movers"]{ background: rgba(94, 209, 132, 0.10);  border: 1px solid rgba(94, 209, 132, 0.28);  color: #5ed184; }
/* .ca-tile-num : badge numerote masque 2026-06-03 (demande user — supprimer les mini widgets numero sur toutes les tiles) */
.ca-tile-num{ display: none !important; }
.ca-tile-arrow{ color: var(--gold); opacity: 0.4; font-size: 14px; font-weight: 400; transition: transform 0.3s var(--ease), opacity 0.3s var(--ease); }
.ca-tile:hover .ca-tile-arrow{ opacity: 0.85; transform: translateX(3px); }
.ca-tile-name{ flex: 1; color: var(--fg-2); }
/* Doublon arrow rule supprime */
.ca-tile-body{ flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 6px; position: relative; z-index: 2; }
.ca-tile-big{ font-family: 'Inter', 'Montserrat', sans-serif; font-weight: 600; font-size: clamp(34px, 3.8vw, 48px); line-height: 1.02; color: var(--fg); letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
/* Featured big numbers : gradient aurora complet (gold du titre baked → cyan → violet → magenta) */
.ca-tile--featured .ca-tile-big{ font-weight: 500; font-size: clamp(28px, 5vw, 62px); background: linear-gradient(135deg, #ffd96e 0%, #6cddff 35%, #a78bfa 70%, #ff6b9a 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; filter: drop-shadow(0 2px 16px rgba(108, 221, 255, 0.15)); }
.ca-tile-big sup{ font-family: 'Inter', sans-serif; font-size: 14px; color: var(--muted); font-style: normal; font-weight: 400; margin-left: 2px; }
.ca-tile--featured .ca-tile-big sup{ -webkit-text-fill-color: var(--muted); color: var(--muted); }
/* State pill : badge coloré semantique pour 'RISK-ON', 'STRESS FAIBLE', 'NEUTRE' etc */
.ca-tile-sub{ display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; margin-top: 8px; border-radius: 100px; background: var(--pill-bg, rgba(116, 185, 255, 0.06)); border: 1px solid var(--pill-bd, rgba(116, 185, 255, 0.16)); font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--pill-c, var(--fg-2)); width: fit-content; align-self: flex-start; font-weight: 500; }
.ca-tile[data-state="risk-on"]  .ca-tile-sub{ --pill-c: #4dd092; --pill-bg: rgba(39, 174, 96, 0.08);  --pill-bd: rgba(39, 174, 96, 0.28); }
.ca-tile[data-state="risk-off"] .ca-tile-sub{ --pill-c: #ed7567; --pill-bg: rgba(231, 76, 60, 0.08);  --pill-bd: rgba(231, 76, 60, 0.28); }
.ca-tile[data-state="warn"]     .ca-tile-sub{ --pill-c: #f6b86b; --pill-bg: rgba(245, 166, 35, 0.08); --pill-bd: rgba(245, 166, 35, 0.28); }
/* Override pill pour narrative/tradfi (texte mixte avec logo, pas un etat) */

.ca-tile-spark{ width: 100%; height: 44px; margin: 14px 0 6px; opacity: 0.7; transition: opacity 0.3s; pointer-events: none; position: relative; z-index: 1; }

/* Mini-historique 90j sous les jauges (F&G, Altseason, Crisis, Radar, AI Bubble).
   Refonte 2026-05-20 : courbe segmentee par classe d'indice, lignes de seuils,
   plus dense (~90 points journaliers) au lieu des sparklines 5-7 points. */
.ca-hist90{ width: 100%; height: var(--hist90-h); margin: 8px 0 2px; display: block; opacity: 0.92; pointer-events: none; position: relative; z-index: 1; }
.ca-hist90--tall{ height: var(--hist90-h-tall); }
.ca-hist90-wrap{ width: 100%; }
.ca-hist90-cap{ display: flex; justify-content: space-between; align-items: center; margin-top: -2px; font-family: var(--mono); font-size: 9px; letter-spacing: 0.8px; color: var(--muted); text-transform: uppercase; opacity: 0.7; }
.ca-hist90-cap b{ color: var(--gold-l); font-weight: 600; }
/* Variant: hist90 integre dans une grille a 2 colonnes a cote de la jauge */
.ca-tile--has-gauge .ca-hist90{ height: 38px; margin: 4px 6px 0; }

/* Foot vertical (2 lignes) — utilise pour AI Bubble qui doit afficher
   le dernier modele IA + une meta line. */
.ca-tile-foot--col{ flex-direction: column; align-items: flex-start; gap: 2px; }
.ca-tile-foot--col .ca-tile-meta--strong{ color: var(--gold-l); font-weight: 600; letter-spacing: 0.2px; text-transform: none; font-size: 11px; opacity: 1; }
.ca-tile-foot--col .ca-tile-meta{ font-size: 9px; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.8px; }

/* ═══ ETF flows 30j (refonte 2026-05-20) ════════════════════════════════
   Bars verticaux journaliers (inflow cyan / outflow or) + ligne cumulative
   violet. KPIs en haut. Hauteur compacte pour ne pas dominer le bento. */
.ca-tile--etf .ca-etf-body{ display: flex; flex-direction: column; gap: 10px; padding: 4px 4px 0; }
.ca-tile--etf .ca-etf-kpis{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; padding: 0 4px; }
.ca-tile--etf .ca-etf-kpi{ display: flex; flex-direction: column; gap: 2px; }
.ca-tile--etf .ca-etf-kpi-val{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 18px; color: var(--fg); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.ca-tile--etf .ca-etf-kpi-lab{ font-family: var(--mono); font-size: 9px; letter-spacing: 0.6px; color: var(--muted); text-transform: uppercase; }
.ca-tile--etf .ca-etf-chart{ width: 100%; height: 110px; display: block; }
.ca-tile--etf .ca-etf-kpi-val.is-inflow{ color: #93c5fd; }
.ca-tile--etf .ca-etf-kpi-val.is-outflow{ color: #f5a623; }
/* Tooltip ETF (interactif, refonte 2026-05-20 v9) — flotte sur curseur */
.ca-etf-tooltip{
  position: fixed; z-index: 9999; pointer-events: none;
  padding: 9px 12px 10px; min-width: 158px; max-width: 240px;
  background: linear-gradient(145deg, rgba(13, 28, 50, 0.94), rgba(8, 20, 38, 0.96));
  border: 1px solid rgba(116, 185, 255, 0.30);
  border-radius: 9px;
  box-shadow:
    0 14px 36px -10px rgba(0, 8, 24, 0.85),
    0 0 24px -6px rgba(116, 185, 255, 0.20),
    inset 0 1px 0 rgba(186, 220, 255, 0.18);
  opacity: 0; transition: opacity 0.12s ease;
  font-family: 'Inter', sans-serif;
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
}
.ca-etf-tooltip .etf-tip-date{
  font-family: var(--mono); font-size: 10.5px; color: var(--gold-l);
  letter-spacing: 0.6px; font-weight: 700; margin-bottom: 6px;
  padding-bottom: 5px; border-bottom: 1px solid rgba(116, 185, 255, 0.10);
}
.ca-etf-tooltip .etf-tip-row{
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; font-size: 11px; color: var(--muted); margin-top: 3px;
}
.ca-etf-tooltip .etf-tip-row b{
  font-weight: 700; font-size: 12.5px; color: var(--fg);
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
.ca-etf-tooltip b.is-inflow{ color: #93c5fd; }
.ca-etf-tooltip b.is-outflow{ color: #f5a623; }
/* Bar hover : cursor pointer + transition smooth */
.ca-tile--etf .ca-etf-chart{ cursor: crosshair; }
.ca-tile--etf .ca-etf-chart .etf-bars rect{ transition: opacity 0.12s ease; }

/* ═══ Mode marche (ALPHA / CAUTION / ZEN) ═════════════════════════════
   Widget compacte (1-col) qui affiche le regime BTC vs MA100 / S&P vs MA200.
   3 etats : ALPHA = cyan, CAUTION = or, ZEN = bleu fonce. Aucun rouge/vert. */
.ca-tile--mode .ca-mode-body{ display: flex; flex-direction: column; gap: 8px; padding: 4px 2px 0; }
.ca-tile--mode .ca-mode-badge{ display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 10px; background: rgba(116,185,255,0.06); border: 1px solid rgba(116,185,255,0.20); width: max-content; max-width: 100%; transition: all 0.25s; }
.ca-tile--mode .ca-mode-icon{ font-size: 14px; line-height: 1; width: 16px; text-align: center; }
.ca-tile--mode .ca-mode-lbl{ font-family: 'Inter', sans-serif; font-weight: 700; font-size: 13px; letter-spacing: 1px; text-transform: uppercase; }
.ca-tile--mode .ca-mode-ref{ font-family: var(--mono); font-size: 10px; color: var(--muted); letter-spacing: 0.5px; text-transform: uppercase; }
.ca-tile--mode .ca-mode-stats{ display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; margin-top: 2px; }
.ca-tile--mode .ca-mode-stat{ display: flex; flex-direction: column; gap: 1px; }
.ca-tile--mode .ca-mode-stat-v{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 16px; color: var(--fg); font-variant-numeric: tabular-nums; line-height: 1.1; }
.ca-tile--mode .ca-mode-stat-l{ font-family: var(--mono); font-size: 9px; letter-spacing: 0.6px; color: var(--muted); text-transform: uppercase; }
.ca-tile--mode .ca-mode-hist{ height: 44px; margin-top: 2px; }
/* Variantes de badge selon mode */
/* Refonte 2026-05-21 v9 : alpha=vert (positif), caution=orange (warn), zen=cyan (defensif) */
.ca-tile--mode .ca-mode-badge.is-alpha{ background: rgba(40,224,126,0.10); border-color: rgba(40,224,126,0.40); color: #5dffaf; }
.ca-tile--mode .ca-mode-badge.is-alpha .ca-mode-icon{ color: #28e07e; }
.ca-tile--mode .ca-mode-badge.is-caution{ background: rgba(245,166,35,0.08); border-color: rgba(245,166,35,0.40); color: #f5a623; }
.ca-tile--mode .ca-mode-badge.is-caution .ca-mode-icon{ color: #f5a623; }
.ca-tile--mode .ca-mode-badge.is-zen{ background: rgba(61,139,255,0.10); border-color: rgba(61,139,255,0.40); color: #74aeff; }
.ca-tile--mode .ca-mode-badge.is-zen .ca-mode-icon{ color: #3d8bff; }
.ca-tile--mode .ca-mode-stat-v.is-pos{ color: #28e07e; }
.ca-tile--mode .ca-mode-stat-v.is-neg{ color: #ff5570; }

/* ═══ Mode widget — Editorial Premium (refonte 2026-05-20 v4) ═══════════
   Drop des stats redondants. Visuel principal : gros emblem glow + state name
   sculpte + UN SEUL chiffre (ecart % vs MA) en grand. Barre seuil retravaillee
   en pied, taller + plus contrastee. Style editorial premium. */
.ca-tile--mode-editorial{ padding: 18px 26px 16px !important; }
.ca-tile--mode-editorial .ca-tile-head{
  display: flex; align-items: baseline; gap: 12px; margin-bottom: 16px;
}
.ca-tile--mode-editorial .ca-tile-tagline{
  font-family: var(--mono); font-size: 9px; color: var(--muted);
  letter-spacing: 1px; text-transform: uppercase; opacity: 0.65;
  margin-left: 2px;
}
.ca-tile--mode-editorial .ca-tile-arrow{ margin-left: auto; }

/* ── Sélecteur d'actif (tuile Mode TradFi) ──────────────────────────────
   Le bouton remplace la tagline "S&P 500 · MA200j". Le popover est rendu en
   position:fixed attaché au <body> par accueil.js car .ca-tile a overflow:hidden
   + contain:paint (un enfant absolu serait clippé). Aucun backdrop-filter
   (iGPU Intel, cf [[user_hardware_macbook_intel]]). */
.ca-modepick{ display: inline-flex; align-items: baseline; gap: 6px; margin-left: 2px; }
.ca-modepick-btn{
  display: inline-flex; align-items: center; gap: 5px; line-height: 1;
  font-family: var(--mono); font-size: 9px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--fg-2); background: rgba(61,139,255,0.06);
  border: 1px solid rgba(61,139,255,0.22); border-radius: 6px;
  padding: 3px 8px; cursor: pointer;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.ca-modepick-btn:hover{ background: rgba(61,139,255,0.13); border-color: rgba(61,139,255,0.45); color: var(--fg); }
.ca-modepick-btn[aria-expanded="true"]{ background: rgba(61,139,255,0.16); border-color: rgba(61,139,255,0.55); color: var(--fg); }
.ca-modepick-btn.is-loading{ opacity: 0.55; cursor: progress; }
.ca-modepick-btn.is-loading .ca-modepick-caret{ animation: ca-modepick-spin 0.7s linear infinite; }
.ca-modepick-caret{ width: 8px; height: 5px; opacity: 0.75; transition: transform 0.2s var(--ease); }
.ca-modepick-btn[aria-expanded="true"] .ca-modepick-caret{ transform: rotate(180deg); }
@keyframes ca-modepick-spin{ to{ transform: rotate(360deg); } }
.ca-modepick-ma{
  font-family: var(--mono); font-size: 9px; color: var(--muted);
  letter-spacing: 1px; text-transform: uppercase; opacity: 0.6;
}
/* Source injoignable pour l'actif choisi : on l'affiche au lieu de retomber en
   silence sur le S&P 500 (le silence masquait la panne). */
.ca-modepick-ma.is-err{ color: var(--neg); opacity: 0.95; }
/* Popover (attaché au body, position:fixed posée par le JS) */
/* max-height : 320px coupait la liste à 10 lignes sur 16 — Or, Argent et WTI
   tombaient hors champ. On donne la hauteur du viewport disponible (placePop
   bascule le popover au-dessus du bouton s'il déborde en bas). */
.ca-modepick-pop{
  position: fixed; z-index: 9999; min-width: 190px; max-height: min(78vh, 560px); overflow-y: auto;
  /* Sans `contain`, arriver en bout de liste propage la molette à la PAGE :
     celle-ci défile et le popover se referme au milieu du geste. */
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: #0b1524; border: 1px solid rgba(61,139,255,0.22); border-radius: 11px;
  padding: 6px; box-shadow: 0 16px 40px -10px rgba(0,0,0,0.65), 0 0 0 1px rgba(0,0,0,0.3);
  display: grid; gap: 2px;
}
.ca-modepick-pop[hidden]{ display: none; }
.ca-modepick-grp{
  font-family: var(--mono); font-size: 8px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted); opacity: 0.65; padding: 8px 10px 3px;
}
.ca-modepick-grp:first-child{ padding-top: 3px; }
.ca-modepick-opt{
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; padding: 7px 10px; border: none; border-radius: 7px;
  background: transparent; cursor: pointer;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--fg-2); transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.ca-modepick-opt:hover{ background: rgba(61,139,255,0.09); color: var(--fg); }
.ca-modepick-opt.is-current{ color: var(--gold); background: rgba(61,139,255,0.06); }
.ca-modepick-opt .ca-modepick-tk{ font-size: 8.5px; color: var(--muted); opacity: 0.7; letter-spacing: 0.04em; }
/* Hero row : emblem | state | key number — 3 colonnes flex */
.ca-tile--mode-editorial .ca-mode-hero{
  display: grid; grid-template-columns: auto 1fr auto;
  gap: 18px; align-items: center;
}
/* Emblem : disque (radius 50%) avec triple layer — ambient halo + ring concentrique
   + icone vectorielle centree. Refonte 2026-05-20 v5 : passage emoji -> FontAwesome
   pour centrage pixel-perfect et meilleur rendu cross-OS. */
.ca-tile--mode-editorial .ca-mode-emblem{
  position: relative; width: 64px; height: 64px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; isolation: isolate; transition: all 0.4s var(--ease);
  background: radial-gradient(circle at 30% 25%, rgba(116,185,255,0.10), rgba(7,17,29,0.6) 75%);
  border: 1px solid rgba(116, 185, 255, 0.18);
}
/* Ring concentrique externe (halo) */
.ca-tile--mode-editorial .ca-mode-emblem::before{
  content: ''; position: absolute; inset: -6px; border-radius: 50%;
  border: 1px solid currentColor; opacity: 0.18; pointer-events: none;
  z-index: -1;
}
/* Ring interieur fin */
.ca-tile--mode-editorial .ca-mode-emblem::after{
  content: ''; position: absolute; inset: 6px; border-radius: 50%;
  border: 1px solid currentColor; opacity: 0.10; pointer-events: none;
  z-index: 0;
}
.ca-tile--mode-editorial .ca-mode-icon{
  /* FontAwesome glyph : le <i> est block donc remplit la largeur du cercle ;
     text-align: center recentre le glyphe lui-meme (sinon ancrage gauche par defaut). */
  font-size: 22px; line-height: 1; display: block;
  text-align: center; width: 100%;
  filter: drop-shadow(0 0 6px currentColor);
  position: relative; z-index: 1;
}
/* Variantes mode : color + glow par etat. La couleur courante (currentColor)
   est utilisee par les rings + drop-shadow pour coherence visuelle totale. */
/* Refonte v6 : emblèmes vernis. On ajoute un specular highlight en surface
   (linear-gradient blanc 15% transparent) qui simule la lumiere reflechie
   sur une perle de verre laque. + inset highlights + drop-shadows externes. */
/* Refonte 2026-05-21 v9 : alpha=vert (positif), caution=orange (avertissement),
   zen=cyan (defensif). Aligne sur palette dashboard maquette. */
.ca-tile--mode-editorial .ca-mode-emblem.is-alpha{
  color: #28e07e;
  background:
    radial-gradient(circle at 28% 22%, rgba(255,255,255,0.32) 0%, transparent 28%),
    radial-gradient(circle at 30% 25%, rgba(40,224,126,0.38), rgba(61,139,255,0.14) 55%, rgba(5,11,26,0.65) 80%);
  border-color: rgba(40,224,126,0.55);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.30),
    inset 0 -2px 6px rgba(0, 0, 0, 0.35),
    0 0 36px -4px rgba(40,224,126,0.55),
    0 0 18px -2px rgba(40,224,126,0.35),
    0 6px 14px -4px rgba(0, 0, 0, 0.50);
}
.ca-tile--mode-editorial .ca-mode-emblem.is-caution{
  color: #f5a623;
  background:
    radial-gradient(circle at 28% 22%, rgba(255,255,255,0.32) 0%, transparent 28%),
    radial-gradient(circle at 30% 25%, rgba(245,166,35,0.40), rgba(255,217,61,0.16) 55%, rgba(5,11,26,0.65) 80%);
  border-color: rgba(245,166,35,0.55);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.30),
    inset 0 -2px 6px rgba(0, 0, 0, 0.35),
    0 0 36px -4px rgba(245,166,35,0.55),
    0 0 18px -2px rgba(245,166,35,0.35),
    0 6px 14px -4px rgba(0, 0, 0, 0.50);
}
.ca-tile--mode-editorial .ca-mode-emblem.is-zen{
  color: #3d8bff;
  background:
    radial-gradient(circle at 28% 22%, rgba(255,255,255,0.32) 0%, transparent 28%),
    radial-gradient(circle at 30% 25%, rgba(61,139,255,0.38), rgba(26,95,208,0.20) 55%, rgba(5,11,26,0.65) 80%);
  border-color: rgba(61,139,255,0.55);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.30),
    inset 0 -2px 6px rgba(0, 0, 0, 0.35),
    0 0 36px -4px rgba(61,139,255,0.55),
    0 0 18px -2px rgba(61,139,255,0.35),
    0 6px 14px -4px rgba(0, 0, 0, 0.50);
}
/* Hover : amplifier le glow */
.ca-tile--mode-editorial:hover .ca-mode-emblem{
  transform: scale(1.04);
}
.ca-tile--mode-editorial:hover .ca-mode-emblem::before{ opacity: 0.32; }
/* State name : grosse typo sculptee */
.ca-tile--mode-editorial .ca-mode-state-name{
  font-family: 'Inter', sans-serif; font-weight: 800;
  font-size: clamp(22px, 2.4vw, 28px); line-height: 1.05;
  letter-spacing: 0.05em; color: var(--fg);
}
.ca-tile--mode-editorial .ca-mode-state-sub{
  font-family: var(--mono); font-size: 9.5px; color: var(--muted);
  letter-spacing: 0.8px; text-transform: uppercase;
  margin-top: 4px; opacity: 0.75;
}
/* Key : un seul gros chiffre (l'ecart vs MA) */
.ca-tile--mode-editorial .ca-mode-key{ text-align: right; }
.ca-tile--mode-editorial .ca-mode-key-val{
  font-family: 'Inter', sans-serif; font-weight: 700;
  font-size: clamp(24px, 2.6vw, 30px); line-height: 1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.ca-tile--mode-editorial .ca-mode-key-val.is-pos{ color: #93c5fd; }
.ca-tile--mode-editorial .ca-mode-key-val.is-neg{ color: #4a78c4; }
.ca-tile--mode-editorial .ca-mode-key-lbl{
  font-family: var(--mono); font-size: 9px; color: var(--muted);
  letter-spacing: 0.8px; text-transform: uppercase; margin-top: 3px; opacity: 0.7;
}
/* Threshold bar : taller + plus contrastee */
.ca-tile--mode-editorial .ca-mode-threshold{ margin: 14px 0 0; }
.ca-tile--mode-editorial .ca-mode-thresh-svg{
  width: 100%; height: 18px; display: block;
}
.ca-tile--mode-editorial .ca-mode-thresh-labels{
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 8.5px; color: var(--muted);
  opacity: 0.65; letter-spacing: 1.2px; text-transform: uppercase;
  margin-top: 5px;
}
.ca-tile--mode-editorial .ca-mode-thresh-labels .is-zero{
  color: var(--gold-l); font-weight: 700; opacity: 1;
}
/* Mobile : pile la grille */
@media (max-width: 780px){
  .ca-tile--mode-editorial .ca-mode-hero{
    grid-template-columns: auto 1fr; gap: 14px;
  }
  .ca-tile--mode-editorial .ca-mode-key{
    grid-column: 1 / -1; text-align: left; margin-top: 4px;
  }
}

/* Legacy compact (gardé pour compat, plus utilisé) */
.ca-tile--mode-compact{ padding: 14px 22px 12px !important; }
.ca-tile--mode-compact .ca-tile-head{ margin-bottom: 8px; }
.ca-tile--mode-compact .ca-mode-row{ display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.ca-tile--mode-compact .ca-mode-badge{ padding: 6px 14px; border-radius: 8px; }
.ca-tile--mode-compact .ca-mode-lbl{ font-size: 13px; }
.ca-tile--mode-compact .ca-mode-ref{ font-size: 10px; opacity: 0.85; letter-spacing: 0.4px; }
.ca-tile--mode-compact .ca-mode-stats--inline{ display: flex; gap: 28px; margin-left: auto; }
.ca-tile--mode-compact .ca-mode-stat{ flex-direction: column-reverse; align-items: flex-end; gap: 1px; }
.ca-tile--mode-compact .ca-mode-stat-v{ font-size: 15px; font-weight: 700; }
.ca-tile--mode-compact .ca-mode-stat-l{ font-size: 8.5px; opacity: 0.7; }

/* ═══ Widget Actualites refonte 2026-05-20 ═════════════════════════════
   Multi-items (top 4-5 signaux). Chaque ligne : barre de score sur la
   gauche (cyan -> or), pole icon, source pill, age, titre tronque. Pas de
   rouge/vert (consigne DA). Cliquable item-par-item. */
.ca-tile--news{ flex-direction: column; }
.ca-tile--news .ca-news-feed-link{ margin-left: auto; font-family: var(--mono); font-size: 10px; letter-spacing: 0.4px; color: var(--gold); text-decoration: none; opacity: 0.7; transition: opacity 0.2s; }
.ca-tile--news .ca-news-feed-link:hover{ opacity: 1; }
/* 2026-07-30 : le fil remplit toute la hauteur de la tuile (la rangée est étirée par la tuile
   Calendrier ~508px) au lieu d'être figé à 300px et de laisser un vide en bas.
   flex:1 1 0 + min-height = plancher quand la tuile n'est PAS étirée (mobile, 1 colonne). */
.ca-news-feed{ list-style: none; margin: 6px 0 4px; padding: 0; display: flex; flex-direction: column; gap: 0; flex: 1 1 0; min-height: 300px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: rgba(116,185,255,0.25) transparent; }
.ca-news-feed::-webkit-scrollbar{ width: 6px; }
.ca-news-feed::-webkit-scrollbar-track{ background: transparent; }
.ca-news-feed::-webkit-scrollbar-thumb{ background: rgba(116,185,255,0.22); border-radius: 3px; }
.ca-news-feed::-webkit-scrollbar-thumb:hover{ background: rgba(116,185,255,0.4); }
.ca-news-feed li{ display: grid; grid-template-columns: 3px auto auto 1fr auto; gap: 10px; align-items: center; padding: 5px 8px 5px 0; border-bottom: 1px solid rgba(116,185,255,0.05); transition: background 0.18s; }
.ca-news-feed li:last-child{ border-bottom: none; }
.ca-news-feed li:hover{ background: rgba(116,185,255,0.04); }
.ca-news-feed a.ca-news-row{ display: contents; text-decoration: none; color: inherit; }
.ca-news-feed .ca-news-bar{ width: 3px; height: 28px; border-radius: 2px; background: linear-gradient(180deg, var(--gauge-mid-hi), var(--gauge-mid)); box-shadow: 0 0 6px rgba(116,185,255,0.20); }
.ca-news-feed .ca-news-bar.is-hot{ background: linear-gradient(180deg, var(--gauge-high), var(--gauge-mid-hi)); box-shadow: 0 0 6px rgba(245,166,35,0.30); }
.ca-news-feed .ca-news-bar.is-cool{ background: linear-gradient(180deg, var(--gauge-mid), var(--gauge-low)); box-shadow: 0 0 4px rgba(37,88,217,0.20); }
.ca-news-feed .ca-news-pole{ font-size: 10px; color: var(--gold); opacity: 0.75; width: 16px; text-align: center; line-height: 1; }
.ca-news-feed .ca-news-pole.is-macro{ color: var(--orange); }
.ca-news-feed .ca-news-src{ display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 9.5px; padding: 2px 8px; border-radius: 6px; background: rgba(116,185,255,0.06); border: 1px solid rgba(116,185,255,0.18); color: var(--gold-l); white-space: nowrap; max-width: 110px; overflow: hidden; text-overflow: ellipsis; }
.ca-news-feed .ca-news-title{ font-family: var(--serif-body); font-size: 13px; font-weight: 500; line-height: 1.4; color: var(--fg-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ca-news-feed li:hover .ca-news-title{ color: var(--fg); }
.ca-news-feed .ca-news-age{ font-family: var(--mono); font-size: 9.5px; color: var(--muted); white-space: nowrap; opacity: 0.7; }
.ca-news-feed .ca-news-empty{ padding: 16px 8px; text-align: center; font-family: var(--mono); font-size: 11px; color: var(--muted); }
/* Fil mixe (2026-07-28) : Coin Academie se distingue de FinancialJuice par un
   badge plus dense + une barre pleine, sans sortir de la palette bleue. */
.ca-news-feed .ca-news-row.is-ca .ca-news-src{ background: rgba(116,185,255,0.14); border-color: rgba(116,185,255,0.34); color: var(--fg-2); max-width: 118px; }
.ca-news-feed .ca-news-row.is-ca .ca-news-bar{ background: linear-gradient(180deg, var(--cyan-l), var(--cyan-d)); box-shadow: 0 0 6px rgba(61,139,255,0.30); }
/* Responsive : sur petit ecran on cache la source pill et raccourcit */
@media (max-width: 760px){
  .ca-news-feed li{ grid-template-columns: 3px auto 1fr auto; gap: 8px; }
  .ca-news-feed .ca-news-src{ display: none; }
  .ca-news-feed .ca-news-title{ -webkit-line-clamp: 2; font-size: 12.5px; }
}

/* ═══ Compactage widgets 07-14 (refonte 2026-05-20) ═════════════════════
   Avant : grandes typos + grandes marges + grands gap = beaucoup d'espace
   vide pour peu d'info. Apres : on resserre les tiles standard (non-featured
   et non-spotlight) sans toucher au radar/crisis qui sont les tiles "phares".
   On retire aussi le rouge/vert vif des badges data-state (consigne DA hero). */

/* Standard tile : padding + body gap reduits */
.ca-tile:not(.ca-tile--featured):not(.ca-tile--spotlight):not(.ca-tile--wide):not(.ca-tile--has-gauge):not(.ca-tile--mode){
  padding: 18px 20px 14px;
}
/* tile-big : reduire la grosse typo des chiffres principaux (Stable, OI, Funding) */
.ca-tile:not(.ca-tile--featured):not(.ca-tile--spotlight) .ca-tile-big{
  font-size: clamp(26px, 2.8vw, 34px);
  line-height: 1.05;
}
.ca-tile:not(.ca-tile--featured):not(.ca-tile--spotlight) .ca-tile-body{ gap: 4px; }
.ca-tile:not(.ca-tile--featured):not(.ca-tile--spotlight) .ca-tile-sub{ margin-top: 4px; padding: 3px 9px; font-size: 9px; }
/* spark : moins de margin verticale */
.ca-tile:not(.ca-tile--featured):not(.ca-tile--spotlight) .ca-tile-spark{ height: 38px; margin: 8px 0 4px; }
/* foot : moins de margin + padding-top */
.ca-tile:not(.ca-tile--featured):not(.ca-tile--spotlight) .ca-tile-foot{ margin-top: 8px; padding-top: 8px; font-size: 9px; }

/* Movers wide tile : reduire la grille + ligne plus fine */
.ca-tile--wide .ca-movers-list li{ padding: 2px 0 !important; font-size: 11px !important; line-height: 1.3 !important; }
.ca-tile--wide .ca-movers-col-head{ font-size: 9px !important; letter-spacing: 0.14em; padding-bottom: 4px !important; margin-bottom: 4px !important; }
.ca-tile--wide{ padding: 18px 22px 14px; }

/* ═══ Refonte 2026-05-21 v9 : palette finance dashboard semantique ═══
   Vert/rouge classiques pour les indicateurs financiers (gain/perte, risk-on/off,
   bull/bear), cyan pour neutre, orange pour warning. Aligne sur la maquette. */
/* Refonte 2026-08-19 : ces regles posaient les couleurs FINALES en !important,
   donc aucune teinte calculee en JS ne pouvait passer devant. Elles ne posent
   plus que --pill-* (memes teintes v9) : le repli reste, l'inline JS gagne. */
.ca-tile[data-state="risk-on"]  .ca-tile-sub,
.ca-tile[data-state="risk-on"]  .ca-radar-label{ --pill-c: #28e07e; --pill-bg: rgba(40,224,126,0.10); --pill-bd: rgba(40,224,126,0.32); }
.ca-tile[data-state="risk-off"] .ca-tile-sub,
.ca-tile[data-state="risk-off"] .ca-radar-label{ --pill-c: #ff5570; --pill-bg: rgba(255,85,112,0.10); --pill-bd: rgba(255,85,112,0.32); }
.ca-tile[data-state="warn"]     .ca-tile-sub,
.ca-tile[data-state="warn"]     .ca-radar-label{ --pill-c: #f5a623; --pill-bg: rgba(245,166,35,0.08); --pill-bd: rgba(245,166,35,0.32); }
/* Tile delta : vert pour gain, rouge pour perte (semantique finance standard) */
.ca-tile-delta.pos{ color: #28e07e !important; }
.ca-tile-delta.neg{ color: #ff5570 !important; }
.ca-tile-delta.warn{ color: var(--orange); }
/* Top bar tile : gradient cyan -> cyan clair pur (pas de violet/rose/orange) */
.ca-tile::before{ background: linear-gradient(90deg, transparent 0%, #3d8bff 25%, #74aeff 50%, #3d8bff 75%, transparent 100%) !important; opacity: 0.7 !important; }
/* Radar signal dots : vert pour bull, rouge pour bear */
.ca-radar-sig.is-bull .ca-radar-sig-dot{ background: #28e07e !important; box-shadow: 0 0 6px rgba(40,224,126,0.55) !important; }
.ca-radar-sig.is-bear .ca-radar-sig-dot{ background: #ff5570 !important; box-shadow: 0 0 6px rgba(255,85,112,0.50) !important; }
.ca-radar-sig.is-bull .ca-radar-sig-state{ color: #5dffaf !important; }
.ca-radar-sig.is-bear .ca-radar-sig-state{ color: #ff8095 !important; }
/* Top bar etat : risk-on=vert, risk-off=rouge, warn=orange */
.ca-tile[data-state="risk-on"]::before{ background: linear-gradient(180deg, #28e07e, transparent 70%) !important; }
.ca-tile[data-state="risk-off"]::before{ background: linear-gradient(180deg, #ff5570, transparent 70%) !important; }
.ca-tile[data-state="warn"]::before{ background: linear-gradient(180deg, #f5a623, transparent 70%) !important; }

/* Movers gainers/losers : vert / rouge */
.ca-movers-col-head--up{   background: rgba(40,224,126,0.10) !important; color: #28e07e !important; border-color: rgba(40,224,126,0.28) !important; }
.ca-movers-col-head--down{ background: rgba(255,85,112,0.10) !important; color: #ff5570 !important; border-color: rgba(255,85,112,0.28) !important; }
.ca-narr-pct.up{   color: #28e07e !important; }
.ca-narr-pct.down{ color: #ff5570 !important; }
.ca-movers-pct.up{   color: #28e07e !important; }
.ca-movers-pct.down{ color: #ff5570 !important; }
/* Scroll progress + sources : gradient cyan unifie */
.ca-scroll-progress{ background: linear-gradient(90deg, #3d8bff 0%, #74aeff 50%, #3d8bff 100%) !important; }
.ca-sources::before{ background: linear-gradient(90deg, transparent 0%, #3d8bff 30%, #74aeff 55%, #3d8bff 80%, transparent 100%) !important; }
/* Featured tile big number gradient : cyan -> bleu (palette unifiee) */
.ca-tile--featured .ca-tile-big{ background: linear-gradient(135deg, #74aeff 0%, #3d8bff 50%, #1a5fd0 100%) !important; -webkit-background-clip: text !important; background-clip: text !important; -webkit-text-fill-color: transparent !important; }
/* featured::before background override retire 2026-06-03 (heritait aurora line horizontale standard) */

/* News empty state : ne pas heriter de la grille du li parent */
.ca-news-feed li.ca-news-empty{ display: block !important; grid-template-columns: none !important; padding: 20px 12px !important; text-align: center !important; }

/* ═══ Item AI release epingle (refonte 2026-05-21 v2) ══════════════════
   Doit etre VISUELLEMENT distinct des news standards. Background marque,
   border-top accent, padding plus genereux, logo plus grand, tag "MODÈLE IA".
   Source : artificialanalysis.ai/leaderboards/models (auto-refresh 3x/jour). */
.ca-news-feed li.ca-news-pinned{
  position: relative;
  /* Background dégradé pourpre/cyan + border accentuee */
  background:
    radial-gradient(ellipse 80% 60% at 20% 50%, rgba(167,139,250,0.14), transparent 65%),
    linear-gradient(90deg, rgba(167,139,250,0.10), rgba(116,185,255,0.05) 60%, rgba(245,166,35,0.05));
  border: 1px solid rgba(167,139,250,0.30);
  border-radius: 8px;
  padding: 12px 12px !important;
  margin-bottom: 8px;
  /* Hairline gradient au-dessus pour mark "section AI" */
  box-shadow:
    inset 0 1px 0 rgba(167,139,250,0.30),
    0 4px 14px -4px rgba(167,139,250,0.20);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.ca-news-feed li.ca-news-pinned:hover{
  transform: translateY(-1px);
  border-color: rgba(167,139,250,0.45);
  box-shadow:
    inset 0 1px 0 rgba(167,139,250,0.45),
    0 8px 22px -6px rgba(167,139,250,0.35);
}
/* Label "MODÈLE IA · artificialanalysis.ai" retire 2026-05-26 (consigne user) */
.ca-news-row--ai{ display: contents; }
.ca-news-feed .ca-news-bar.is-ai{
  width: 4px; height: 38px; border-radius: 2px;
  box-shadow: 0 0 12px rgba(167,139,250,0.50);
}
.ca-news-feed .ca-news-ai-logo{
  width: 26px; height: 26px; border-radius: 50%;
  background: rgba(255,255,255,0.08); padding: 2px;
  object-fit: contain; flex-shrink: 0;
  border: 1px solid rgba(167,139,250,0.30);
  box-shadow: 0 0 10px -2px rgba(167,139,250,0.35);
}
/* Src pill specifique AI : violet au lieu de cyan */
.ca-news-feed .ca-news-src--ai{
  background: rgba(167,139,250,0.18) !important;
  border-color: rgba(167,139,250,0.45) !important;
  color: #c4b5fd !important;
  font-weight: 700;
}
/* Tag "nouveau modèle IA" inline, discret */
.ca-news-feed .ca-news-ai-tag{
  display: inline-block; margin-left: 4px;
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  letter-spacing: 0.3px; color: var(--muted); opacity: 0.75;
  vertical-align: middle;
}
.ca-news-feed li.ca-news-pinned .ca-news-title{
  font-size: 14px; line-height: 1.4;
}
.ca-news-feed li.ca-news-pinned .ca-news-title strong{
  color: #e2e8f0; font-weight: 700;
  background: linear-gradient(135deg, #f5a623 0%, #a78bfa 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* Badge Intelligence Index — code couleur 5 niveaux */
.ca-news-intel{
  display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 5px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.3px; vertical-align: middle;
  background: rgba(116,185,255,0.10); border: 1px solid rgba(116,185,255,0.25);
  color: var(--gold-l);
}
.ca-news-intel.is-low     { background: rgba(30,58,138,0.18);  border-color: rgba(30,58,138,0.40);  color: #93c5fd; }
.ca-news-intel.is-mid     { background: rgba(37,88,217,0.18);  border-color: rgba(37,88,217,0.40);  color: #74b9ff; }
.ca-news-intel.is-cyan    { background: rgba(116,185,255,0.18);border-color: rgba(116,185,255,0.42);color: #93c5fd; }
.ca-news-intel.is-hot     { background: rgba(245,166,35,0.16); border-color: rgba(245,166,35,0.45); color: #f5a623; }
.ca-news-intel.is-frontier{ background: rgba(167,139,250,0.18);border-color: rgba(167,139,250,0.55);color: #a78bfa; text-shadow: 0 0 8px rgba(167,139,250,0.45); }

/* ═══ Compactage radical Order Flow + Stablecoin (refonte 2026-05-20 v2) ═══
   Consigne user : "juste order flow surtout et stable coin" -> reduire encore.
   Cible : widgets data-tile="stable", "oi", "fr-btc", "fr-eth". Pas ETF. */
.ca-tile[data-tile="stable"], .ca-tile[data-tile="oi"],
.ca-tile[data-tile="fr-btc"], .ca-tile[data-tile="fr-eth"]{
  padding: 14px 18px 10px !important;
  min-height: 0 !important;
}
.ca-tile[data-tile="stable"] .ca-tile-big,
.ca-tile[data-tile="oi"] .ca-tile-big,
.ca-tile[data-tile="fr-btc"] .ca-tile-big,
.ca-tile[data-tile="fr-eth"] .ca-tile-big{
  font-size: clamp(22px, 2.4vw, 28px) !important;
  line-height: 1.05 !important;
}
.ca-tile[data-tile="stable"] .ca-tile-body,
.ca-tile[data-tile="oi"] .ca-tile-body,
.ca-tile[data-tile="fr-btc"] .ca-tile-body,
.ca-tile[data-tile="fr-eth"] .ca-tile-body{ gap: 2px !important; }
.ca-tile[data-tile="stable"] .ca-tile-sub,
.ca-tile[data-tile="oi"] .ca-tile-sub,
.ca-tile[data-tile="fr-btc"] .ca-tile-sub,
.ca-tile[data-tile="fr-eth"] .ca-tile-sub{
  margin-top: 2px !important; padding: 2px 8px !important; font-size: 8.5px !important;
}
.ca-tile[data-tile="stable"] .ca-tile-spark,
.ca-tile[data-tile="oi"] .ca-tile-spark{
  height: 26px !important; margin: 4px 0 2px !important;
}
.ca-tile[data-tile="stable"] .ca-tile-foot,
.ca-tile[data-tile="oi"] .ca-tile-foot,
.ca-tile[data-tile="fr-btc"] .ca-tile-foot,
.ca-tile[data-tile="fr-eth"] .ca-tile-foot{
  margin-top: 6px !important; padding-top: 6px !important; font-size: 8.5px !important;
}
.ca-tile[data-tile="stable"] .ca-tile-head,
.ca-tile[data-tile="oi"] .ca-tile-head,
.ca-tile[data-tile="fr-btc"] .ca-tile-head,
.ca-tile[data-tile="fr-eth"] .ca-tile-head{ margin-bottom: 4px !important; }

/* ═══ Stablecoins widget (10) — refonte 2026-05-20 v3 ══════════════════════
   Ajout d'une rangee de logos top 4 stablecoins (USDT, USDC, DAI, USDe...)
   + gradient subtil sur le grand chiffre (au lieu de blanc plein). */
.ca-tile-big--stable{
  background: linear-gradient(135deg, #93c5fd 0%, #a78bfa 55%, #f5a623 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  filter: drop-shadow(0 1px 8px rgba(167, 139, 250, 0.18));
}
.ca-stable-coins{
  list-style: none; padding: 0; margin: 6px 0 2px;
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.ca-stable-coins li{
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px 3px 4px; border-radius: 100px;
  background: rgba(116, 185, 255, 0.05);
  border: 1px solid rgba(116, 185, 255, 0.14);
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  letter-spacing: 0.04em; color: var(--fg-2);
}
.ca-stable-coins .ca-stable-coin-logo{
  width: 16px; height: 16px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; object-fit: contain;
  background: rgba(255,255,255,0.06);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
}
.ca-stable-coins .ca-stable-coin-logo--initial{
  font-family: 'Inter', sans-serif; font-weight: 700; font-size: 8px;
  letter-spacing: 0; color: #07111d;
}
.ca-stable-coins .ca-stable-coin-sym{ color: var(--fg); }
.ca-stable-coins .ca-stable-coin-pct{ color: var(--muted); opacity: 0.85; }

/* ═══ Open Interest widget (11) — refonte 2026-05-20 v3 ════════════════════
   Pivot du focus : evolution (trend %) > chiffre absolu. KPI principal = %
   7j, chiffre absolu mis en sous-info. Spark agrandi + zero baseline. */
.ca-oi-row{
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin: 2px 0 6px;
}
.ca-oi-kpi{
  display: flex; flex-direction: column; gap: 1px; min-width: 0;
}
.ca-oi-kpi-val{
  font-family: 'Inter', sans-serif; font-weight: 700;
  font-size: clamp(22px, 2.4vw, 28px); line-height: 1.02;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.ca-oi-kpi-val.is-pos{ color: #f5a623; }   /* hausse OI = surchauffe levier */
.ca-oi-kpi-val.is-neg{ color: #74b9ff; }   /* baisse OI = deleverage */
.ca-oi-kpi-lab{
  font-family: var(--mono); font-size: 8.5px; color: var(--muted);
  letter-spacing: 0.10em; text-transform: uppercase; opacity: 0.75;
}
.ca-oi-meta{
  display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
  text-align: right; min-width: 0;
}
.ca-oi-now{
  font-family: 'Inter', sans-serif; font-weight: 600;
  font-size: 13px; line-height: 1; color: var(--fg-2);
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
.ca-oi-sub{
  font-family: var(--mono); font-size: 8.5px; color: var(--muted);
  letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.7;
}
.ca-tile[data-tile="oi"] .ca-tile-spark--oi{
  height: 46px !important; margin: 4px 0 4px !important; opacity: 0.85 !important;
}

/* ═══ Funding widgets — Editorial v12 (refonte 2026-05-20) ════════════════
   v12 : distribution verticale via flex column + space-between pour
   eliminer le vide en bas sans ajouter d'info inutile. */
.ca-tile--funding{
  padding: 14px 22px 14px !important;
  display: flex !important; flex-direction: column;
  justify-content: space-between;
}
.ca-tile--funding .ca-tile-head{
  display: flex; align-items: center; gap: 10px; margin-bottom: 0;
}
.ca-tile--funding .ca-fund-body{ margin-bottom: 0 !important; }
.ca-tile--funding .ca-tile-name{ flex: 1; }
.ca-tile--funding .ca-fund-state{
  display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 6px;
  font-family: var(--mono); font-size: 8.5px; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase;
  background: rgba(116,185,255,0.10); border: 1px solid rgba(116,185,255,0.25);
  color: var(--gold-l);
}
.ca-tile--funding .ca-fund-state.is-hot{
  background: rgba(245,166,35,0.12); border-color: rgba(245,166,35,0.45); color: #f5a623;
}
.ca-tile--funding .ca-fund-state.is-cold{
  background: rgba(37,88,217,0.12); border-color: rgba(37,88,217,0.45); color: #74b9ff;
}
.ca-tile--funding .ca-fund-state.is-neutral{
  background: rgba(116,185,255,0.10); border-color: rgba(116,185,255,0.30); color: #93c5fd;
}

/* Body : emblem + rate cote a cote */
.ca-tile--funding .ca-fund-body{
  display: flex; align-items: center; gap: 14px; margin-bottom: 12px;
}
/* Emblem brand : disque avec icone FontAwesome (fa-bitcoin / fa-ethereum) */
.ca-tile--funding .ca-fund-emblem{
  position: relative; width: 44px; height: 44px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; isolation: isolate;
  background: radial-gradient(circle at 28% 22%, rgba(255,255,255,0.18) 0%, transparent 30%),
              radial-gradient(circle at 30% 28%, rgba(7,17,29,0.4) 60%, rgba(7,17,29,0.7) 100%);
  border: 1px solid rgba(116,185,255,0.20);
}
.ca-tile--funding .ca-fund-emblem i{
  font-size: 22px; line-height: 1; display: block;
  filter: drop-shadow(0 0 4px currentColor);
}
/* Inline SVG logo (BTC/ETH) — alternative robuste aux FA brand icons */
.ca-tile--funding .ca-fund-emblem svg{
  width: 26px; height: 26px; display: block;
  filter: drop-shadow(0 0 4px currentColor);
}
.ca-tile--funding .ca-fund-emblem.is-btc{
  color: #f5a623;  /* orange BTC */
  background: radial-gradient(circle at 28% 22%, rgba(255,255,255,0.25) 0%, transparent 30%),
              radial-gradient(circle at 30% 28%, rgba(245,166,35,0.18) 0%, rgba(7,17,29,0.6) 70%);
  border-color: rgba(245,166,35,0.40);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.25),
    inset 0 -2px 5px rgba(0,0,0,0.30),
    0 0 24px -6px rgba(245,166,35,0.40),
    0 4px 10px -3px rgba(0,0,0,0.45);
}
.ca-tile--funding .ca-fund-emblem.is-eth{
  color: #a78bfa;  /* violet ETH (palette site) */
  background: radial-gradient(circle at 28% 22%, rgba(255,255,255,0.25) 0%, transparent 30%),
              radial-gradient(circle at 30% 28%, rgba(167,139,250,0.20) 0%, rgba(7,17,29,0.6) 70%);
  border-color: rgba(167,139,250,0.40);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.25),
    inset 0 -2px 5px rgba(0,0,0,0.30),
    0 0 24px -6px rgba(167,139,250,0.40),
    0 4px 10px -3px rgba(0,0,0,0.45);
}

.ca-tile--funding .ca-fund-main{ display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ca-tile--funding .ca-fund-rate{
  font-family: 'Inter', sans-serif; font-weight: 700;
  font-size: clamp(26px, 2.8vw, 32px); line-height: 1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
  color: var(--fg);
}
/* Refonte 2026-05-21 v2 : code couleur 9 niveaux (band neutre etroite ±0.001%).
   Aucun rouge/vert (palette site cosmique). Text-shadow glow proportionnel
   a l'intensite : leger 6px → extreme 14px. */
.ca-tile--funding .ca-fund-rate.lv-ext-pos{ color: #a78bfa; text-shadow: 0 0 14px rgba(167,139,250,0.55); }
.ca-tile--funding .ca-fund-rate.lv-hi-pos { color: #f5a623; text-shadow: 0 0 12px rgba(245,166,35,0.50);  }
.ca-tile--funding .ca-fund-rate.lv-mod-pos{ color: #f6c97a; text-shadow: 0 0 10px rgba(246,201,122,0.40); }
.ca-tile--funding .ca-fund-rate.lv-lt-pos { color: #e9c389; text-shadow: 0 0 6px  rgba(233,195,137,0.30); }
.ca-tile--funding .ca-fund-rate.lv-neutral{ color: var(--fg); }
.ca-tile--funding .ca-fund-rate.lv-lt-neg { color: #b0d4ff; text-shadow: 0 0 6px  rgba(176,212,255,0.30); }
.ca-tile--funding .ca-fund-rate.lv-mod-neg{ color: #93c5fd; text-shadow: 0 0 10px rgba(147,197,253,0.40); }
.ca-tile--funding .ca-fund-rate.lv-hi-neg { color: #74b9ff; text-shadow: 0 0 12px rgba(116,185,255,0.50);  }
.ca-tile--funding .ca-fund-rate.lv-ext-neg{ color: #2558d9; text-shadow: 0 0 14px rgba(37,88,217,0.55);   }
.ca-tile--funding .ca-fund-cycle{
  font-family: var(--mono); font-size: 9px; color: var(--muted);
  letter-spacing: 0.7px; text-transform: uppercase; opacity: 0.7;
}

.ca-tile--funding .ca-fund-thresh{
  width: 100%; height: 14px; display: block; margin-top: 4px;
}
.ca-tile--funding .ca-fund-thresh-labels{
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 8px; color: var(--muted);
  opacity: 0.65; letter-spacing: 0.9px; text-transform: uppercase;
  margin-top: 4px;
}
.ca-tile--funding .ca-fund-thresh-labels .is-zero{
  color: var(--gold-l); font-weight: 700; opacity: 1;
}
/* ─── Stablecoins Bento KPI widget (refonte 2026-05-26) ─────────────────
   Refonte 2026-05-26 : remplace l'ancienne tile big number + chips list par
   un bento KPI grid : 1 total card (full-width) + 6 mini-cards des stables
   les plus capitalises (dynamique - top 6 par mcap, auto-update toutes les 5min).
   Chaque mini-card : logo + symbol + $value + Δ7d% (positive vert / negative rouge).
   Source DefiLlama stablecoins endpoint (live, same que l'onglet Stablecoins_Flows). */
.ca-tile--stable-bento{ padding: 12px 16px 10px; }
/* Toggle fenêtre 24H/7J/30J du widget Stablecoins (2026-05-29) — calqué sur .ca-tvl-toggle */
.ca-stbb-seg{ display: inline-flex; gap: 1px; background: rgba(7,13,24,0.55); border: 1px solid rgba(148,163,184,0.15); border-radius: 100px; padding: 1px; margin-right: 8px; }
.ca-stbb-seg button{ background: none; border: none; color: var(--muted); font-family: var(--mono); font-size: 8.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; padding: 4px 10px; border-radius: 100px; cursor: pointer; transition: background 0.15s, color 0.15s; }
.ca-stbb-seg button:hover{ color: #cbd5e1; }
.ca-stbb-seg button.is-on{ background: rgba(94,175,246,0.18); color: var(--accent); box-shadow: inset 0 0 0 1px rgba(94,175,246,0.35); }
.ca-stbb-grid{ display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: auto 1fr 1fr; gap: 8px; flex: 1; min-height: 0; }
.ca-stbb-total{ grid-column: span 3; display: flex; align-items: center; gap: 14px; padding: 10px 16px; background: linear-gradient(90deg, rgba(167,139,250,0.10) 0%, rgba(245,166,35,0.08) 100%); border: 1px solid rgba(167,139,250,0.30); border-radius: 10px; }
.ca-stbb-total .info{ display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ca-stbb-total .lab{ font-family: var(--mono); font-size: 9.5px; color: var(--muted); letter-spacing: 0.10em; text-transform: uppercase; }
.ca-stbb-total .val{ font-family: 'Inter', sans-serif; font-weight: 900; font-size: 26px; line-height: 1; background: linear-gradient(135deg, #93c5fd 0%, #a78bfa 55%, #f5a623 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: -0.02em; }
.ca-stbb-total .d{ margin-left: auto; font-family: var(--mono); font-size: 11.5px; font-weight: 700; padding: 5px 12px; border-radius: 100px; white-space: nowrap; }
.ca-stbb-total .d.pos{ color: var(--moss-l); background: rgba(40,224,126,0.10); border: 1px solid rgba(40,224,126,0.30); }
.ca-stbb-total .d.neg{ color: var(--crimson); background: rgba(255,85,112,0.10); border: 1px solid rgba(255,85,112,0.30); }
.ca-stbb-total .d.neut{ color: var(--muted); background: rgba(116,185,255,0.06); border: 1px solid var(--hair); }
.ca-stbb-card{ display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: rgba(70,140,240,0.04); border: 1px solid var(--hair); border-radius: 8px; transition: all 0.2s var(--ease); min-width: 0; min-height: 0; }
.ca-stbb-card:hover{ background: rgba(61,139,255,0.06); border-color: var(--hair-3); }
.ca-stbb-card.is-empty{ background: rgba(70,140,240,0.02); border-style: dashed; opacity: 0.4; }
.ca-stbb-card .ic{ width: 32px; height: 32px; border-radius: 50%; background: var(--bg-elev); border: 1px solid var(--hair-3); flex-shrink: 0; object-fit: cover; display: block; }
.ca-stbb-card .ic--fallback{ display: flex; align-items: center; justify-content: center; font-family: 'Inter', sans-serif; font-weight: 700; font-size: 12px; color: #0a1530; }
.ca-stbb-card .info{ display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.ca-stbb-card .nm{ font-family: var(--mono); font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.10em; font-weight: 700; }
.ca-stbb-card .v{ font-family: 'Inter', sans-serif; font-size: 15px; font-weight: 700; color: var(--fg); line-height: 1.05; letter-spacing: -0.01em; white-space: nowrap; }
.ca-stbb-card .d{ font-family: var(--mono); font-size: 10.5px; font-weight: 700; margin-top: 1px; white-space: nowrap; }
.ca-stbb-card .d.pos{ color: var(--moss-l); }
.ca-stbb-card .d.neg{ color: var(--crimson); }
.ca-stbb-card .d.neut{ color: var(--muted); }

/* ─── TVL DeFi Ranking widget (refonte 2026-05-26) ──────────────────────
   Wide tile (span 2) à côté de Stablecoins (rangée 4.5). Style "pro trader"
   ranking-bars : 4 entités (ETH, SOL, HYPE chains + AAVE protocol), bars
   horizontales proportionnelles au TVL, share% du leader intégré dans la bar.
   Source DefiLlama API gratuite (v2/chains, v2/historicalChainTvl, protocol/aave-v3). */
.ca-tile--tvl{ padding: 14px 18px 12px; }
.ca-tvl-top{ display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; padding-bottom: 9px; border-bottom: 1px solid var(--hair); }
.ca-tvl-top .lab{ font-family: var(--mono); font-size: 9.5px; color: var(--muted); letter-spacing: 0.10em; text-transform: uppercase; }
.ca-tvl-top .num{ font-family: 'Inter', sans-serif; font-weight: 900; font-size: 26px; color: var(--fg); letter-spacing: -0.01em; line-height: 1; }
.ca-tvl-top .d-pair{ display: inline-flex; align-items: baseline; gap: 4px; margin-left: auto; font-family: var(--mono); flex-wrap: nowrap; }
.ca-tvl-top .d-pair .d{ font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.ca-tvl-top .d-pair .d-lab{ font-size: 8.5px; color: var(--muted-2); letter-spacing: 0.08em; text-transform: uppercase; margin-right: 6px; }
.ca-tvl-top .d-pair .d.pos, .ca-tvl-top .d.pos{ color: var(--moss-l); }
.ca-tvl-top .d-pair .d.neg, .ca-tvl-top .d.neg{ color: var(--crimson); }
.ca-tvl-bars{ display: flex; flex-direction: column; gap: 8px; flex: 1; min-height: 0; }
/* Liste scrollable : on montre ~5 rows, le reste defile. gutter stable pour ne pas
   desaligner le header quand la scrollbar apparait. */
.ca-tvl-rows{ display: flex; flex-direction: column; gap: 8px; overflow-y: auto; min-height: 0; max-height: 152px; flex: 1; padding-right: 4px; scrollbar-width: thin; scrollbar-color: var(--hair-3) transparent; scrollbar-gutter: stable; }
.ca-tvl-rows::-webkit-scrollbar{ width: 6px; }
.ca-tvl-rows::-webkit-scrollbar-track{ background: transparent; }
.ca-tvl-rows::-webkit-scrollbar-thumb{ background: var(--hair-3); border-radius: 3px; }
.ca-tvl-rows::-webkit-scrollbar-thumb:hover{ background: var(--muted-2); }
.ca-tvl-head{ display: grid; grid-template-columns: 68px 1fr 76px 42px 42px; gap: 8px; font-family: var(--mono); font-size: 8.5px; color: var(--muted-2); letter-spacing: 0.10em; text-transform: uppercase; padding: 0 2px; padding-right: 12px; }
.ca-tvl-head span{ text-align: right; }
.ca-tvl-row{ display: grid; grid-template-columns: 68px 1fr 76px 42px 42px; gap: 8px; align-items: center; font-family: var(--mono); }
.ca-tvl-row .nm-wrap{ display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.ca-tvl-row .nm-wrap img{ width: 18px; height: 18px; border-radius: 50%; object-fit: cover; background: var(--bg-elev); border: 1px solid var(--hair-3); flex-shrink: 0; }
.ca-tvl-row .nm{ font-size: 11.5px; font-weight: 700; color: var(--fg); letter-spacing: 0.04em; }
.ca-tvl-row .barwrap{ height: 20px; background: rgba(70,140,240,0.06); border: 1px solid var(--hair); border-radius: 5px; overflow: hidden; position: relative; min-width: 0; }
.ca-tvl-row .bar{ height: 100%; border-radius: 4px; display: flex; align-items: center; padding-left: 8px; font-size: 10px; font-weight: 700; color: #0a1530; white-space: nowrap; transition: width 0.5s var(--ease); }
.ca-tvl-row .v{ font-size: 12px; font-weight: 700; color: var(--fg); text-align: right; letter-spacing: 0.01em; white-space: nowrap; }
.ca-tvl-row .d{ font-size: 11px; font-weight: 700; text-align: right; white-space: nowrap; }
.ca-tvl-row .d.pos{ color: var(--moss-l); }
.ca-tvl-row .d.neg{ color: var(--crimson); }
.ca-tvl-row .d.neut{ color: var(--muted); }

/* Toggle pills Chains/Protocoles (refonte 2026-05-26) — compact, dans tile-head */
.ca-tvl-toggle{
  display: inline-flex; gap: 1px;
  background: rgba(7,13,24,0.55);
  border: 1px solid rgba(148,163,184,0.15);
  border-radius: 100px; padding: 1px;
  margin-right: 8px;
}
.ca-tvl-toggle button{
  background: none; border: none; color: var(--muted);
  font-family: var(--mono); font-size: 8.5px;
  font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 100px; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.ca-tvl-toggle button:hover{ color: #cbd5e1; }
.ca-tvl-toggle button.active{
  background: rgba(94,175,246,0.18); color: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(94,175,246,0.35);
}

/* Pin emoji retire 2026-05-26 (consigne user) — top 4 pur sans visualisation pin */

/* ─── Open Interest Bento Grid widget (refonte 2026-05-26) ─────────────
   Wide tile (span 2) avec 2×2 bento de KPI cards (BTC/ETH/SOL/HYPE).
   Cohabite avec .ca-tile--frhm sur la meme ligne (Funding + OI = full row).
   Source commutable Binance/Bybit/Hyperliquid (HL = current only, pas d'API
   d'historique gratuite → sparkline vide + pct = "—"). */
.ca-tile--oibg{ padding: 12px 16px 10px; }
.ca-oibg-ctrls{ display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; margin-bottom: 10px; position: relative; z-index: 5; }
.ca-oibg-seg,
.ca-etf-seg{ display: inline-flex; background: rgba(61,139,255,0.04); border: 1px solid rgba(70,140,240,0.28); border-radius: 5px; padding: 1px; flex: 0 0 auto; }
.ca-oibg-seg button,
.ca-etf-seg button{ appearance: none; background: transparent; border: 0; color: var(--fg-2); font-family: var(--mono); font-size: 9px; letter-spacing: 0.06em; padding: 2px 7px; border-radius: 4px; cursor: pointer; transition: all 0.2s var(--ease); text-transform: uppercase; white-space: nowrap; }
.ca-oibg-seg button.is-on,
.ca-etf-seg button.is-on{ background: linear-gradient(180deg, rgba(61,139,255,0.22) 0%, rgba(61,139,255,0.12) 100%); color: var(--cyan-l); box-shadow: 0 0 0 1px rgba(61,139,255,0.35) inset, 0 2px 8px rgba(61,139,255,0.16); }
.ca-oibg-seg button:hover:not(.is-on),
.ca-etf-seg button:hover:not(.is-on){ color: var(--cyan); }
/* Tile ETF avec switcher : laisser de la place au seg dans le head + pointeur */
.ca-tile--etf[data-href]{ cursor: pointer; }
.ca-tile--etf .ca-tile-head{ display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; }
.ca-tile--etf .ca-etf-seg{ margin-left: 8px; }
.ca-tile--etf .ca-tile-arrow{ margin-left: auto; }
.ca-oibg-total{ margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.ca-oibg-total b{ color: var(--fg-2); font-weight: 600; }
.ca-oibg-total .dot{ display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 8px var(--cyan); }
/* Grille 2x2 etiree verticalement pour matcher la hauteur de Funding sur la
   meme rangee. flex:1 + min-height:0 + grid-template-rows:1fr 1fr = bento
   plein de la place dispo. Sparklines grandissent avec les cards. */
.ca-oibg-grid{ display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 10px; flex: 1; min-height: 0; }
.ca-oibg-card{ display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto 1fr; gap: 8px 14px; background: rgba(70,140,240,0.04); border: 1px solid var(--hair); border-radius: 10px; padding: 12px 16px; transition: all 0.2s var(--ease); min-height: 0; align-items: center; }
.ca-oibg-card:hover{ background: rgba(61,139,255,0.06); border-color: var(--hair-3); }
.ca-oibg-card .ic{ grid-row: span 2; width: 40px; height: 40px; border-radius: 50%; object-fit: cover; background: var(--bg-elev); border: 1px solid rgba(70,140,240,0.20); align-self: center; }
.ca-oibg-card .top{ display: flex; align-items: baseline; gap: 10px; font-family: var(--mono); min-width: 0; }
.ca-oibg-card .nm{ font-size: 12px; font-weight: 700; color: var(--fg); letter-spacing: 0.04em; }
.ca-oibg-card .v{ font-size: 17px; font-weight: 700; color: var(--fg); letter-spacing: 0.01em; margin-left: auto; white-space: nowrap; }
.ca-oibg-card .bottom{ display: flex; align-items: center; gap: 10px; font-family: var(--mono); font-size: 10.5px; color: var(--muted); min-width: 0; align-self: stretch; }
.ca-oibg-card .spk{ flex: 1; height: 100%; min-width: 0; min-height: 36px; display: block; }
.ca-oibg-card .d{ font-weight: 700; white-space: nowrap; font-size: 11.5px; }
.ca-oibg-card .d.pos{ color: var(--moss-l); }
.ca-oibg-card .d.neg{ color: var(--crimson); }
.ca-oibg-card .d.neut{ color: var(--muted); }

/* Hover interactif sparkline OI (2026-05-29) : lecture INTEGREE dans la card.
   Crosshair + point sur la courbe (overlay pixels car SVG etire), et la date du
   point survole apparait pres du ticker. Le grand chiffre $ est mis a jour en JS. */
.ca-oibg-card{ position: relative; }
.ca-oibg-hair{ position: absolute; top: 2px; bottom: 2px; width: 1px; pointer-events: none; z-index: 3; opacity: 0; transition: opacity 0.12s var(--ease);
  background: linear-gradient(180deg, rgba(255,255,255,0.40), rgba(255,255,255,0.08)); }
.ca-oibg-dot{ position: absolute; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%; pointer-events: none; z-index: 4; opacity: 0; transition: opacity 0.12s var(--ease);
  background: var(--bg-elev, #0a121e); border: 2px solid currentColor; box-shadow: 0 0 7px rgba(0,0,0,0.6); }
.ca-oibg-hovdate{ display: none; font-family: var(--mono); font-size: 9.5px; font-weight: 500; color: var(--muted); letter-spacing: 0.02em; white-space: nowrap; }
.ca-oibg-card.is-hover .ca-oibg-hovdate{ display: inline; }
.ca-oibg-card.is-hover .ca-oibg-hair,
.ca-oibg-card.is-hover .ca-oibg-dot{ opacity: 1; }
.ca-oibg-card.is-hover .v{ color: var(--cyan); }

/* ─── Funding Rate Heatmap widget (refonte 2026-05-26) ───────────────────
   Remplace les 2 anciennes tiles Funding BTC/ETH par une wide tile heatmap
   4 actifs (BTC, ETH, SOL, HYPE) × 21-90 cycles 8h, source commutable
   (Binance/Bybit/Hyperliquid), slider d'intensite couleur (style OrderFlow). */
.ca-tile--frhm{ padding: 12px 16px 10px; }
.ca-frhm-ctrls{ display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; margin-bottom: 8px; position: relative; z-index: 5; }
.ca-frhm-seg{ display: inline-flex; background: rgba(61,139,255,0.04); border: 1px solid rgba(70,140,240,0.28); border-radius: 5px; padding: 1px; flex: 0 0 auto; }
.ca-frhm-seg button{ appearance: none; background: transparent; border: 0; color: var(--fg-2); font-family: var(--mono); font-size: 9px; letter-spacing: 0.06em; padding: 2px 7px; border-radius: 4px; cursor: pointer; transition: all 0.2s var(--ease); text-transform: uppercase; white-space: nowrap; }
.ca-frhm-seg button.is-on{ background: linear-gradient(180deg, rgba(61,139,255,0.22) 0%, rgba(61,139,255,0.12) 100%); color: var(--cyan-l); box-shadow: 0 0 0 1px rgba(61,139,255,0.35) inset, 0 2px 8px rgba(61,139,255,0.16); }
.ca-frhm-seg button:hover:not(.is-on){ color: var(--cyan); }
.ca-frhm-intens{ display: inline-flex; align-items: center; gap: 7px; background: rgba(61,139,255,0.04); border: 1px solid rgba(70,140,240,0.28); border-radius: 5px; padding: 2px 9px; margin-left: auto; flex: 0 0 auto; }
.ca-frhm-intens label{ font-family: var(--mono); font-size: 8.5px; color: var(--muted); letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap; }
.ca-frhm-intens input[type=range]{ appearance: none; width: 90px; height: 3px; background: linear-gradient(90deg, var(--cyan) 0%, var(--cyan-l) 50%, var(--orange) 100%); border-radius: 2px; outline: none; cursor: pointer; }
.ca-frhm-intens input[type=range]::-webkit-slider-thumb{ appearance: none; width: 11px; height: 11px; border-radius: 50%; background: var(--fg); border: 2px solid var(--cyan); cursor: pointer; box-shadow: 0 0 0 2px rgba(61,139,255,0.18); }
.ca-frhm-intens input[type=range]::-moz-range-thumb{ width: 11px; height: 11px; border-radius: 50%; background: var(--fg); border: 2px solid var(--cyan); cursor: pointer; }
.ca-frhm-intens .val{ font-family: var(--mono); font-size: 9.5px; color: var(--cyan-l); font-weight: 600; min-width: 34px; text-align: right; }
.ca-frhm-grid{ display: grid; grid-template-columns: 72px 1fr 64px; gap: 4px 10px; align-items: center; }
.ca-frhm-head-spacer{ display: block; }
.ca-frhm-head{ font-family: var(--mono); font-size: 8.5px; color: var(--muted-2); letter-spacing: 0.10em; text-transform: uppercase; display: flex; justify-content: space-between; padding: 0 2px 2px; }
.ca-frhm-lbl{ display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 11px; color: var(--fg); font-weight: 600; letter-spacing: 0.04em; }
.ca-frhm-lbl img{ width: 17px; height: 17px; border-radius: 50%; object-fit: cover; display: block; background: var(--bg-elev); border: 1px solid rgba(70,140,240,0.28); }
.ca-frhm-cells{ display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 2px; height: 38px; }
.ca-frhm-cell{ border-radius: 2px; cursor: pointer; transition: transform 0.12s, box-shadow 0.12s; border: 1px solid rgba(0,0,0,0.20); background: rgba(70,140,240,0.06); }
.ca-frhm-cell:hover{ transform: scale(1.25) translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.5); z-index: 2; position: relative; }
.ca-frhm-cell.is-empty{ background: rgba(70,140,240,0.05); border-color: rgba(70,140,240,0.10); }
.ca-frhm-now{ font-family: var(--mono); font-size: 11.5px; font-weight: 700; text-align: right; letter-spacing: 0.01em; color: var(--fg); }
.ca-frhm-scale{ display: flex; align-items: center; gap: 10px; font-family: var(--mono); font-size: 9px; color: var(--muted); margin-top: 8px; padding-top: 7px; border-top: 1px solid rgba(116,185,255,0.08); }
.ca-frhm-scale .bar{ flex: 1; height: 5px; border-radius: 3px; background: linear-gradient(90deg, var(--cyan) 0%, rgba(61,139,255,0.3) 30%, rgba(70,140,240,0.10) 50%, rgba(255,217,61,0.4) 70%, var(--orange) 100%); }
.ca-frhm-tip{ position: fixed; pointer-events: none; background: var(--bg-elev); border: 1px solid rgba(70,140,240,0.28); border-radius: 6px; padding: 6px 10px; font-family: var(--mono); font-size: 10.5px; color: var(--fg); box-shadow: 0 8px 24px rgba(0,0,0,0.45); opacity: 0; transition: opacity 0.12s; z-index: 99; }
.ca-frhm-tip.is-show{ opacity: 1; }
.ca-frhm-tip b{ color: var(--cyan-l); }

/* spark hover supprime */
.ca-tile-foot{ display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; padding-top: 12px; border-top: 1px solid rgba(116, 185, 255, 0.08); font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em; text-transform: uppercase; position: relative; z-index: 2; }
.ca-tile-delta{ color: var(--fg-2); font-weight: 600; }
.ca-tile-delta.pos{ color: var(--moss-l); }
.ca-tile-delta.neg{ color: var(--crimson); }
.ca-tile-delta.warn{ color: var(--gold); }
/* Variante de tuile par état signal */
.ca-tile[data-state="risk-on"]::before{ background: linear-gradient(180deg, var(--moss-l), transparent 70%); }
.ca-tile[data-state="risk-off"]::before{ background: linear-gradient(180deg, var(--crimson), transparent 70%); }
.ca-tile[data-state="warn"]::before{ background: linear-gradient(180deg, var(--gold), transparent 70%); }
/* state hover supprime */
.ca-tile-meta{ color: var(--muted); opacity: 0.7; }
/* Movers grid : 2 colonnes (gainers / losers), chacune une liste de 5 lignes avec logo+sym+% */
.ca-movers-grid{ display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 4px; flex: 1; }
.ca-movers-col{ display: flex; flex-direction: column; }
.ca-movers-col-head{ font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; padding: 6px 10px; border-radius: 6px; margin-bottom: 8px; display: inline-flex; align-items: center; gap: 6px; }
.ca-movers-col-head--up{ background: rgba(39, 174, 96, 0.10);  color: #4dd092; border: 1px solid rgba(39, 174, 96, 0.25); }
.ca-movers-col-head--down{ background: rgba(231, 76, 60, 0.10);  color: #ed7567; border: 1px solid rgba(231, 76, 60, 0.25); }
.ca-movers-list{ list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.ca-movers-row{ display: grid; grid-template-columns: 18px 1fr auto; gap: 8px; align-items: center; padding: 5px 8px; border-radius: 6px; transition: background 0.2s; }
.ca-movers-row:hover{ background: rgba(116, 185, 255, 0.04); }
.ca-movers-row img{ width: 18px; height: 18px; object-fit: contain; border-radius: 50%; background: rgba(255,255,255,0.04); }
.ca-movers-sym{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 12px; color: var(--fg); letter-spacing: 0.01em; }
.ca-movers-pct{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 12px; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
/* Refonte 2026-05-20 : cyan up / navy down (palette hero, jamais de rouge/vert) */
.ca-movers-pct.up{ color: #93c5fd; }
.ca-movers-pct.down{ color: #4a78c4; }
/* Narrative grid : 2 colonnes top 3 / bot 3 avec nom long + leader logo + perf */
.ca-narr-grid{ display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 4px; flex: 1; }
.ca-narr-col{ display: flex; flex-direction: column; }
.ca-narr-list{ list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.ca-narr-row{ display: grid; grid-template-columns: 16px 1fr auto; gap: 8px; align-items: center; padding: 6px 8px; border-radius: 6px; }
.ca-narr-row img{ width: 16px; height: 16px; object-fit: contain; border-radius: 50%; background: rgba(255,255,255,0.04); }
.ca-narr-name{ font-family: 'Inter', sans-serif; font-weight: 500; font-size: 12px; color: var(--fg); letter-spacing: -0.005em; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ca-narr-leader{ display: block; font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); margin-top: 2px; }
.ca-narr-pct{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 12px; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.ca-narr-pct.up{ color: #4dd092; }
.ca-narr-pct.down{ color: #ed7567; }
.ca-narr-pct.neut{ color: var(--muted); }
/* Etat "donnees indisponibles" (garde-fou 2026-07-31) : pas de logo, donc 2
   colonnes au lieu de 3, et le nom passe en muted pour ne pas se lire comme
   un vrai narratif. */
/* !important : l'override mobile (~ligne 3250) reimpose 3 colonnes avec !important. */
.ca-narr-row--na{ grid-template-columns: 1fr auto !important; opacity: 0.72; }
.ca-narr-row--na .ca-narr-name{ color: var(--muted); font-style: italic; }
.ca-tile-news-title{ font-family: 'Inter', sans-serif; font-weight: 500; font-size: 15px; line-height: 1.45; color: var(--fg); margin: 4px 0 8px; max-height: 4.3em; overflow: hidden; letter-spacing: -0.005em; }
.ca-tile-news-meta{ font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.ca-tile-news-meta span[style*="color"]{ padding: 2px 7px; background: rgba(116, 185, 255, 0.1); border: 1px solid rgba(116, 185, 255, 0.22); border-radius: 4px; color: var(--gold) !important; }
/* Calendrier macro rows */
.ca-cal-row{ display: grid; grid-template-columns: 130px 1fr; gap: 16px; padding: 6px 12px; border-radius: 8px; background: rgba(116, 185, 255, 0.03); border: 1px solid rgba(26, 51, 85, 0.4); align-items: center; margin-bottom: 4px; transition: background 0.25s, border-color 0.25s; }
.ca-cal-row:last-child{ margin-bottom: 0; }
/* cal-row hover supprime */
.ca-cal-when-day{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 14px; line-height: 1.1; color: var(--fg); letter-spacing: -0.01em; }
.ca-cal-when-rel{ font-family: var(--mono); font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin-top: 4px; }
.ca-cal-event-name{ font-family: 'Inter', sans-serif; font-weight: 500; font-size: 13.5px; line-height: 1.3; color: var(--fg); margin-bottom: 3px; letter-spacing: -0.005em; }
.ca-cal-event-meta{ font-family: var(--mono); font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.ca-cal-row--high{ background: rgba(245, 166, 35, 0.05); border-color: rgba(245, 166, 35, 0.2); }
.ca-cal-row--high .ca-cal-when-day{ color: var(--orange); }
.ca-cal-row--high .ca-cal-event-name{ color: var(--fg); font-weight: 600; }
/* Refonte 2026-05-21 : 5 events + chaque ligne cliquable vers la source.
   Le link wrapper hérite la grille de .ca-cal-row, on ajoute un picto ext. */
.ca-cal-link{ display: block; text-decoration: none; color: inherit; }
.ca-cal-link .ca-cal-row{ position: relative; padding-right: 28px; cursor: pointer; }
.ca-cal-link:hover .ca-cal-row{ background: rgba(116, 185, 255, 0.07); border-color: rgba(116, 185, 255, 0.30); }
.ca-cal-link:hover .ca-cal-row--high{ background: rgba(245, 166, 35, 0.10); border-color: rgba(245, 166, 35, 0.45); }
.ca-cal-link .ca-cal-extlink{ position: absolute; right: 10px; top: 50%; transform: translateY(-50%); font-size: 10px; color: var(--muted); opacity: 0.45; transition: opacity 0.2s, color 0.2s; pointer-events: none; }
.ca-cal-link:hover .ca-cal-extlink{ opacity: 1; color: var(--gold-l); }
.ca-cal-link .ca-cal-row{ margin-bottom: 4px; }
.ca-cal-link:last-child .ca-cal-row{ margin-bottom: 0; }
/* ── Calendrier macro — refonte 2026-07-12 : liste scrollable, groupée par jour,
   colonnes Actuel / Prév. / Préc. (Investing.com), clic → donnée exacte. ── */
.ca-cal-scroll{ max-height: 360px; overflow-y: auto; overflow-x: hidden; margin: 4px -8px 0; padding: 0 8px 2px;
  scrollbar-width: thin; scrollbar-color: rgba(61,139,255,0.35) transparent; overscroll-behavior: contain; }
.ca-cal-scroll::-webkit-scrollbar{ width: 6px; }
.ca-cal-scroll::-webkit-scrollbar-thumb{ background: rgba(61,139,255,0.28); border-radius: 3px; }
.ca-cal-scroll::-webkit-scrollbar-thumb:hover{ background: rgba(61,139,255,0.5); }
.ca-cal-scroll::-webkit-scrollbar-track{ background: transparent; }
.ca-cal-daygroup{ margin-bottom: 8px; }
.ca-cal-daygroup:last-child{ margin-bottom: 0; }
/* Jour révolu (2026-08-02) : la liste s'ouvre sur aujourd'hui mais la veille
   reste au-dessus (un résultat publié y vit encore 1 jour). On l'atténue pour
   qu'un chiffre d'hier ne se lise jamais comme l'échéance qui vient ; le survol
   la rend intégralement lisible. */
.ca-cal-daygroup--past{ opacity: 0.55; transition: opacity .2s; }
.ca-cal-daygroup--past:hover{ opacity: 1; }
.ca-cal-daygroup--past .ca-cal-dayrel{ color: var(--muted-2); }
/* Aujourd'hui : repère visuel du point d'ouverture de la liste. */
.ca-cal-daygroup--today .ca-cal-dayhdr{ border-bottom-color: rgba(61,139,255,0.45); }
.ca-cal-daygroup--today .ca-cal-dayhdr b{ color: var(--gold-l); }
.ca-cal-dayhdr{ position: sticky; top: 0; z-index: 4; display: flex; align-items: baseline; gap: 10px;
  padding: 7px 10px 6px; margin-bottom: 5px; background: var(--bg-card); border-bottom: 1px solid var(--hair-2); }
.ca-cal-dayhdr b{ font-family: 'Inter', sans-serif; font-weight: 700; font-size: 11px; letter-spacing: 0.02em;
  color: var(--fg); text-transform: uppercase; }
.ca-cal-dayrel{ font-family: var(--mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-l); margin-left: auto; }
.ca-cal-link{ display: block; text-decoration: none; color: inherit; }
.ca-cal-row2{ position: relative; display: grid; grid-template-columns: 52px 30px 1fr auto; gap: 10px; align-items: center;
  padding: 8px 30px 8px 10px; border-radius: 9px; background: rgba(61,139,255,0.028);
  border: 1px solid var(--hair-2); margin-bottom: 4px; transition: background .2s, border-color .2s; }
.ca-cal-link:last-child .ca-cal-row2{ margin-bottom: 0; }
.ca-cal-link[href]:hover .ca-cal-row2{ background: rgba(61,139,255,0.075); border-color: var(--hair-3); }
.ca-cal-time{ display: flex; flex-direction: column; align-items: flex-start; line-height: 1; }
.ca-cal-hh{ font-family: var(--mono); font-weight: 600; font-size: 13px; color: var(--fg); letter-spacing: -0.01em; }
.ca-cal-tz{ font-family: var(--mono); font-size: 8px; letter-spacing: 0.12em; color: var(--muted-2); margin-top: 3px; }
.ca-cal-mid{ min-width: 0; }
.ca-cal-ev-name{ font-family: 'Inter', sans-serif; font-weight: 600; font-size: 12.5px; line-height: 1.25;
  color: var(--fg); letter-spacing: -0.005em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ca-cal-ev-meta{ display: flex; align-items: center; gap: 6px; margin-top: 4px; }
/* Code pays seul depuis 2026-08-02 : le drapeau est passé dans la colonne emblème
   (.ca-cal-logo--flag), le répéter ici ne faisait que doubler l'information. */
.ca-cal-flag{ display: inline-flex; align-items: center; font-family: var(--mono); font-size: 8.5px;
  font-weight: 600; letter-spacing: 0.08em; color: var(--gold-l); background: rgba(61,139,255,0.09);
  border: 1px solid rgba(61,139,255,0.2); padding: 1px 5px; border-radius: 4px; }
.ca-cal-stars{ font-size: 9px; line-height: 1; letter-spacing: 1px; color: var(--neg); }
.ca-cal-star-off{ color: rgba(255,85,112,0.22); }
.ca-cal-btc{ font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.06em; color: var(--muted); }
.ca-cal-vals{ display: grid; grid-template-columns: repeat(3, minmax(34px, auto)); gap: 4px; text-align: right; }
.ca-cal-val{ display: flex; flex-direction: column; align-items: flex-end; gap: 2px; padding: 2px 6px;
  border-radius: 5px; background: rgba(255,255,255,0.015); min-width: 40px; }
.ca-cal-val-lbl{ font-family: var(--mono); font-size: 7.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-2); }
.ca-cal-val-num{ font-family: var(--mono); font-weight: 600; font-size: 11.5px; color: var(--fg-2); letter-spacing: -0.01em; }
.ca-cal-val--empty .ca-cal-val-num{ color: var(--muted-2); font-weight: 400; }
.ca-cal-val--act{ background: rgba(61,139,255,0.06); }
.ca-cal-val--act .ca-cal-val-lbl{ color: var(--gold); }
.ca-cal-val--act .ca-cal-val-num{ color: var(--gold-l); }
.ca-cal-val--act.ca-cal-val--empty{ background: rgba(255,255,255,0.015); }
.ca-cal-val--act.ca-cal-val--empty .ca-cal-val-lbl{ color: var(--muted-2); }
.ca-cal-row2 .ca-cal-extlink{ position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  font-size: 10px; color: var(--muted); opacity: 0.4; transition: opacity .2s, color .2s; pointer-events: none; }
.ca-cal-link[href]:hover .ca-cal-extlink{ opacity: 1; color: var(--gold-l); }

/* ── Résultats d'entreprises (2026-07-28) ────────────────────────────────
   Fusionnés chronologiquement avec les events macro dans la même liste. Le
   violet reprend EXACTEMENT la couleur de catégorie « earnings » de l'onglet
   Actualités (#a855f7) pour que la même donnée se lise pareil des deux côtés. */
.ca-cal-row2--earn{ background: rgba(168,85,247,0.045); border-color: rgba(168,85,247,0.16);
  border-left: 2px solid rgba(168,85,247,0.55); }
/* ── Logo société (2026-08-02) ───────────────────────────────────────────────
   Chip CLAIR volontairement : les PNG bakés sont les marques officielles, et
   beaucoup sont dessinées en noir sur fond transparent (AMD, Berkshire, Uber).
   Sur le fond sombre de la tuile elles disparaissent purement et simplement.
   Un fond clair unique pour toutes rend chaque logo lisible et donne une colonne
   régulière à l'œil, là où un fond par marque ferait vibrer la liste. */
.ca-cal-logo{ width: 28px; height: 28px; flex: 0 0 auto; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
  background: #eceff5; border: 1px solid rgba(255,255,255,0.16);
  box-shadow: 0 1px 3px rgba(0,0,0,0.35); }
.ca-cal-logo img{ width: 26px; height: 26px; object-fit: contain; display: block; }
/* Ticker absent du manifeste (aucun PNG baké) : monogramme dans le violet des
   résultats. Jamais d'image devinée — cf. logoCell() dans accueil.js. */
.ca-cal-logo--mono{ background: rgba(168,85,247,0.14); border-color: rgba(168,85,247,0.3);
  box-shadow: none; color: #c99bff; font-family: var(--mono); font-weight: 700;
  font-size: 9px; letter-spacing: 0.02em; }
/* Lignes macro : le drapeau du pays tient la même colonne que le logo, pour que
   toute la liste ait UN seul bord gauche. Fond sombre (le drapeau se suffit) —
   le chip clair reste le signe distinctif d'un résultat d'entreprise. */
.ca-cal-logo--flag{ background: rgba(61,139,255,0.10); border-color: rgba(61,139,255,0.22);
  box-shadow: none; font-size: 15px; line-height: 1; }
.ca-cal-link[href]:hover .ca-cal-row2--earn{ background: rgba(168,85,247,0.10); border-color: rgba(168,85,247,0.3);
  border-left-color: #a855f7; }
/* Chiffre déjà publié : la ligne s'allume, c'est l'information du jour. */
.ca-cal-row2--pub{ background: rgba(168,85,247,0.085); border-left-color: #a855f7; }
.ca-cal-row2--earn .ca-cal-hh{ color: var(--fg-2); }
.ca-cal-tick{ display: inline-block; font-family: var(--mono); font-weight: 700; font-size: 9.5px;
  letter-spacing: 0.06em; color: #c99bff; background: rgba(168,85,247,0.14);
  border: 1px solid rgba(168,85,247,0.26); padding: 1px 5px; border-radius: 4px; margin-right: 6px;
  vertical-align: 1px; }
.ca-cal-earnbadge{ font-family: var(--mono); font-size: 8px; font-weight: 700; letter-spacing: 0.12em;
  color: #a855f7; background: rgba(168,85,247,0.12); border: 1px solid rgba(168,85,247,0.24);
  padding: 1px 5px; border-radius: 4px; }
.ca-cal-row2--pub .ca-cal-earnbadge{ color: #0f0c17; background: #a855f7; border-color: #a855f7; }
/* Date non confirmée (2026-08-07) : la source repousse l'échéance de jour en jour
   sans jamais publier et le recoupement Nasdaq n'a rien donné. Ambre — ce n'est ni
   un résultat publié (violet plein) ni une échéance fiable (violet clair) : dire
   « À VENIR » sur une date fantôme, c'est affirmer ce qu'on ne sait pas. */
.ca-cal-earnbadge--tba{ color: #f59e0b; background: rgba(245,158,11,0.12);
  border-color: rgba(245,158,11,0.28); }
/* Date rétablie par le calendrier Nasdaq : la puce le dit, la donnée reste auditable. */
.ca-cal-datesrc{ font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.06em;
  color: var(--muted-2); }
.ca-cal-sess, .ca-cal-mcap{ font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.06em; color: var(--muted); }
.ca-cal-mcap{ color: var(--muted-2); }
/* Meta (badge, créneau, capi, ±BTC) : la colonne centrale ne fait que 230 px et
   25 lignes sur 65 demandent jusqu'à 272 px (mesuré). On laisse donc le groupe
   passer à la ligne ENTRE deux éléments, jamais À L'INTÉRIEUR de l'un d'eux :
   un « capi 26… » tronqué se lirait comme un nombre faux là où la valeur est
   263 Md$. La hauteur de la ligne est de toute façon fixée par le bloc de
   chiffres (2 lignes), donc ce repli ne coûte quasiment rien en vertical. */
.ca-cal-row2--earn .ca-cal-ev-meta{ flex-wrap: wrap; row-gap: 3px; }
.ca-cal-row2--earn .ca-cal-ev-meta > *{ flex: 0 0 auto; white-space: nowrap; }
/* Bloc valeurs : 2 lignes (bénéfice puis CA) × 4 colonnes alignées sur la légende
   du jour. Largeurs FIXES et identiques dans .ca-cal-legend et .ca-cal-eline :
   c'est ce qui fait que « publié / attendu / écart » tombe pile au-dessus des
   bons nombres. Toute modif de l'un doit être reportée sur l'autre. */
.ca-cal-vals--earn{ display: flex; flex-direction: column; gap: 3px; width: 254px; }
.ca-cal-legend{ display: grid; grid-template-columns: 84px 58px 58px 54px; width: 254px;
  margin: 0 31px 4px auto; column-gap: 0;
  font-family: var(--mono); font-size: 7.5px; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--muted-2); text-align: right; }
.ca-cal-eline{ display: grid; grid-template-columns: 84px 58px 58px 54px; column-gap: 0;
  align-items: baseline; }
.ca-cal-elbl{ font-family: 'Inter', sans-serif; font-size: 9.5px; font-weight: 500; letter-spacing: 0;
  text-transform: none; color: var(--muted); text-align: left; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; padding-right: 6px; }
.ca-cal-eact{ font-family: var(--mono); font-weight: 700; font-size: 11.5px; color: var(--fg);
  letter-spacing: -0.01em; text-align: right; }
.ca-cal-eact--wait{ color: var(--muted-2); font-weight: 400; }
.ca-cal-efc{ font-family: var(--mono); font-size: 10px; color: var(--muted); text-align: right;
  white-space: nowrap; }
.ca-cal-esurp{ text-align: right; }
.ca-cal-surp{ display: inline-block; font-family: var(--mono); font-weight: 700; font-size: 9.5px;
  letter-spacing: 0.02em; padding: 1px 4px; border-radius: 4px; text-align: right; white-space: nowrap; }
.ca-cal-surp--up{ color: var(--pos); background: rgba(40,224,126,0.11); }
.ca-cal-surp--dn{ color: var(--neg); background: rgba(255,85,112,0.11); }
/* Horodatage source (2026-07-29) : hors de la zone scrollable, toujours visible.
   Sans lui, un « – » ne dit pas s'il manque parce que le résultat n'est pas sorti
   ou parce que la copie est vieille. */
.ca-cal-stamp{ margin: 6px 0 0; padding-top: 5px; border-top: 1px solid var(--hair);
  font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--muted-2); text-align: right; }
@media (max-width: 767px){
  .ca-cal-scroll{ max-height: 320px; }
  /* Mobile : la ligne MACRO reprend sa grille à 3 colonnes et perd son drapeau
     d'emblème (il reste en méta, sous le nom). 34 px de plus pour le libellé, qui
     est déjà tronqué à cette largeur — un « ISM Manufa… » vaut mieux qu'un drapeau.
     Les lignes résultats, elles, gardent leur logo : c'est la colonne qui identifie
     la société d'un coup d'œil, et leur bloc de chiffres passe à la ligne. */
  .ca-cal-row2{ grid-template-columns: 46px 1fr auto; gap: 8px; padding: 8px 22px 8px 8px; }
  .ca-cal-logo--flag{ display: none; }
  .ca-cal-vals{ gap: 3px; }
  .ca-cal-val{ min-width: 33px; padding: 2px 4px; }
  .ca-cal-val-num{ font-size: 10.5px; }
  .ca-cal-btc{ display: none; }
  /* Mobile : la ligne résultats passe en 2 rangées, le bloc chiffres sous le nom.
     Le bloc devient fluide (1fr sur la colonne intitulé) et la légende s'aligne
     dessus en reprenant EXACTEMENT la même grille. */
  .ca-cal-row2--earn{ grid-template-columns: 46px 26px 1fr; row-gap: 6px; }
  .ca-cal-logo{ width: 26px; height: 26px; border-radius: 7px; }
  .ca-cal-logo img{ width: 24px; height: 24px; }
  .ca-cal-logo--flag{ font-size: 14px; }
  .ca-cal-vals--earn{ grid-column: 1 / -1; width: auto; }
  .ca-cal-legend{ grid-template-columns: 1fr 56px 60px 56px; width: auto;
    margin: 0 22px 4px 8px; font-size: 7px; }
  .ca-cal-eline{ grid-template-columns: 1fr 56px 60px 56px; }
  .ca-cal-elbl{ font-size: 9px; }
  .ca-cal-eact{ font-size: 11px; }
  .ca-cal-efc{ font-size: 9px; }
  .ca-cal-mcap{ display: none; }
}
/* Sparkline plus discrète sur standard tiles */
.ca-tile:not(.ca-tile--featured) .ca-tile-spark{ height: 32px; margin: 8px 0 4px; }
@media (max-width: 960px){
  .ca-bento{ grid-template-columns: repeat(2, 1fr); }
  .ca-tile--featured, .ca-tile--wide{ grid-column: span 2; }
}
@media (max-width: 540px){
  .ca-bento{ grid-template-columns: 1fr; }
  .ca-tile, .ca-tile--featured, .ca-tile--wide{ grid-column: 1; }
  
}

/* ── Live ticker tape (entre hero et bento) ─────────────────── */


.ca-ticker-track.is-offscreen{ animation-play-state: paused; }
@keyframes ca-ticker-scroll{ from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* Coloration ticker par categorie : visuel hiérarchie crypto/stock/index */






   /* moss desature pour cote boursiere imprimee */
   /* crimson desature */

.ca-ticker-track.is-refreshed{ animation: ca-ticker-flash 1.4s ease-out; }
@keyframes ca-ticker-flash{ 0% { filter: brightness(1.25) drop-shadow(0 0 8px rgba(124, 147, 88, 0.45)); } 100% { filter: brightness(1) drop-shadow(0 0 0 transparent); } }

/* ── Marquee sources (powered by) ──────────────────────────── */
.ca-sources{ padding: 80px 0 90px; max-width: 1280px; margin: 0 auto; text-align: center; position: relative; }
.ca-sources::before{ content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 80px; height: 1px; background: linear-gradient(90deg, transparent 0%, #6cddff 30%, #a78bfa 50%, #ff6b9a 70%, transparent 100%); opacity: 0.6; }
.ca-sources-eyebrow{ display: inline-flex; align-items: center; gap: 18px; margin-bottom: 36px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.25em; text-transform: uppercase; color: var(--muted); }
.ca-sources-eyebrow .bar{ width: 36px; height: 1px; background: linear-gradient(90deg, transparent, #6cddff 40%, #a78bfa 60%, transparent); opacity: 0.7; }
.ca-sources-marquee{ position: relative; overflow: hidden; padding: 18px 0; mask-image: linear-gradient(90deg, transparent 0%, black 8%, black 92%, transparent 100%); -webkit-mask-image: linear-gradient(90deg, transparent 0%, black 8%, black 92%, transparent 100%); contain: layout style paint; }
/* Perf 2026-05-21 round 5 : will-change retire (iGPU Intel = layer permanent meme
   au repos). L'animation transform est auto-promotee par le compositor de toute
   facon, will-change etait redondant ici. */
.ca-sources-track{ display: inline-flex; gap: 56px; animation: ca-marquee 48s linear infinite; }
.ca-sources-marquee:hover .ca-sources-track{ animation-play-state: paused; }
/* Pause marquee si off-screen (toggle via JS IntersectionObserver) */
.ca-sources-track.is-offscreen{ animation-play-state: paused; }
@keyframes ca-marquee{ from { transform: translateX(0); } to { transform: translateX(-50%); } }
.ca-source{ display: inline-flex; align-items: center; gap: 11px; padding: 10px 18px; border: 1px solid transparent; border-radius: 100px; text-decoration: none; transition: border-color 0.25s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease); white-space: nowrap; flex-shrink: 0; }
.ca-source:hover{ border-color: rgba(108, 221, 255, 0.28); background: rgba(108, 221, 255, 0.05); box-shadow: 0 0 18px -4px rgba(108, 221, 255, 0.22); }
.ca-source img{ width: 22px; height: 22px; object-fit: contain; filter: grayscale(1) brightness(1.2) sepia(0.15); opacity: 0.7; transition: filter 0.3s, opacity 0.3s; }
.ca-source:hover img{ filter: grayscale(0); opacity: 1; }
.ca-source span{ font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-2); }



/* Footer minimal : 1 ligne meta + Live pill */









/* ── Bubble canvas (port v5, restyle warm-gold) ─────────────── */
#bubble-canvas-wrap, #stock-canvas-wrap{ position: relative; border-radius: 4px; overflow: hidden; background: linear-gradient(180deg, #07050b 0%, #100712 100%); border: 1px solid var(--hair-2); min-height: 420px; contain: layout style paint; }
/* Brackets editoriaux supprimes */
#bubble-canvas, #stock-canvas{ width: 100%; display: block; cursor: crosshair; }
#bubble-tooltip, #stock-tooltip{ position: absolute; pointer-events: none; background: rgba(5, 10, 22, 0.96); border: 1px solid rgba(108, 221, 255, 0.25); border-radius: 6px; padding: 9px 13px; font-family: var(--mono); font-size: 11px; color: var(--fg); display: none; z-index: 10; white-space: nowrap; line-height: 1.7; box-shadow: 0 12px 32px -10px rgba(0,0,0,0.6); backdrop-filter: blur(8px); }
#bubble-tooltip b, #stock-tooltip b{ color: var(--gold); font-weight: 500; }
/* ── Barre de contrôles des cartes bulles (refonte 2026-08-09) ──────────────
   Onze réglages à loger (7 fenêtres + MCap + 4 zones + 3 profondeurs) sans que
   l'en-tête n'avale la carte. Réponse : des SEGMENTS soudés — un seul contour
   par groupe, des séparateurs internes d'un pixel — au lieu de onze pilules
   détachées. On y gagne ~90 px de large et le groupe se lit comme un choix
   unique, ce qu'il est.
   Les deux en-têtes ont EXACTEMENT deux rangées (même quand la carte crypto n'a
   pas de zone à proposer) : c'est ce qui garantit que les deux canvas démarrent
   au même Y. L'ancienne astuce du min-height 66px ne tenait plus avec des
   rangées de hauteurs différentes. */
/* ── Plein écran d'une carte à bulles ───────────────────────────────────────
   MESURE à l'origine de cette fonction : la référence donne 11 512 px² de canvas
   par bulle (1439×800 pour 100), notre carte en demi-largeur seulement 2 088 —
   5,5× moins, donc un rayon 2,3× plus petit et un texte 2,3× plus petit à
   proportions égales. La géométrie des bulles était juste, elles étaient
   simplement minuscules. En plein écran on retrouve la surface de la référence. */
.ca-map--plein{ position: fixed; inset: 0; z-index: 9000; margin: 0; max-width: none;
  border-radius: 0; border-width: 0; padding: 14px 18px 10px;
  display: flex; flex-direction: column; background: #05070d; }
.ca-map--plein > div[id$="-canvas-wrap"]{ flex: 1 1 auto; min-height: 0; border-radius: 6px; }
.ca-map--plein > div[id$="-canvas-wrap"] > canvas{ height: 100%; }
body.ca-plein-actif{ overflow: hidden; }
.bub-expand{ margin-left: 8px; flex: 0 0 auto; width: 26px; height: 22px; display: inline-flex;
  align-items: center; justify-content: center; padding: 0; border-radius: 6px;
  border: 1px solid var(--hair-2); background: transparent; color: var(--muted);
  font-size: 12px; line-height: 1; cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease); }
.bub-expand:hover{ color: var(--gold); border-color: var(--gold); }
/* Sortie du plein écran (2026-08-11, retour user : « pas moyen de revenir à la normale »).
   Le bouton d'entrée est volontairement discret dans la vignette ; une fois la carte
   étendue à tout l'écran, il devient la SEULE porte de sortie visible et doit se
   comporter comme telle : ancré en haut à droite (la place où on cherche une fermeture),
   élargi, en or sur fond opaque, et il nomme l'action ET le raccourci. */
.bub-expand-lbl{ display: none; }
.ca-map--plein .bub-expand{ position: absolute; top: 14px; right: 18px; z-index: 3;
  width: auto; height: 26px; gap: 7px; padding: 0 11px; color: var(--gold);
  border-color: var(--gold); background: rgba(5, 7, 13, 0.82);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; }
.ca-map--plein .bub-expand .bub-expand-lbl{ display: inline; }
.ca-map--plein .bub-expand:hover{ background: var(--gold); color: var(--bg-base); }

.ca-map-head--v2{ flex-direction: column; align-items: stretch; gap: 8px; min-height: 0; }
.bub-row{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-height: 26px; }
/* ALIGNEMENT DES DEUX CARTES (fix 2026-08-10, décalage signalé sur Chine et Europe)
   Les deux têtes doivent faire EXACTEMENT la même hauteur, sinon les canvas ne
   démarrent pas au même Y. Mesuré avant fix : rangée 1 de la carte actions passait
   à 2 lignes dès que le titre s'allongeait — « Actions Chine · top 100 » (197 px) et
   « Actions Europe · top 100 » (210 px) débordaient les 599 px de la rangée, alors
   que « Actions US » (171) et « Actions Inde » (186) tenaient. Résultat : tête 93 px
   au lieu de 61, canvas 32,5 px plus bas que celui de la carte crypto.
   Deux verrous : (1) rangées en nowrap + hauteur fixe -> la tête ne peut plus grandir,
   quel que soit le libellé ; (2) le titre est le SEUL élément qui cède (ellipse),
   jamais la mise en page. Réservé au desktop : sous 768 px les cartes s'empilent,
   l'alignement n'a plus de sens et le repli sur 2 lignes reste préférable. */
@media (min-width: 768px){
  .ca-map-head--v2 > .bub-row{ flex-wrap: nowrap; height: 27px; min-height: 27px; }
  .ca-map-head--v2 .ca-map-title{ min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
/* Rangée 1 = IDENTITÉ (titre, badge de marché, zone) ; rangée 2 = MESURE
   (fenêtre, MCap, profondeur). Le titre et son badge restent soudés à gauche,
   zone et profondeur se calent à droite de leur rangée. */
.bub-row > .bub-seg--zone,
.bub-row > .bub-seg--spectrum{ margin-left: auto; }
.bub-row .ca-mkt--map{ margin-right: 0; }

.bub-seg{ display: inline-flex; align-items: stretch; border: 1px solid var(--hair-2); border-radius: 100px; overflow: hidden; }
.bub-seg > button{ border: 0; border-radius: 0; padding: 4px 11px; background: transparent; color: var(--muted); font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.13em; text-transform: uppercase; cursor: pointer; transition: color 0.2s var(--ease), background 0.2s var(--ease); }
.bub-seg > button + button{ box-shadow: inset 1px 0 0 var(--hair-2); }
.bub-seg > button:hover{ color: var(--gold); background: rgba(108, 221, 255, 0.07); }
.bub-seg > button.active{ color: var(--bg-base); background: var(--gold); }
/* Un onglet actif garde son propre fond : le séparateur du voisin de droite le
   traverserait sinon d'un trait clair au milieu de la pilule dorée. */
.bub-seg > button.active + button{ box-shadow: none; }
.bub-seg--spectrum > button{ padding: 4px 9px; letter-spacing: 0.08em; }
/* Segment de zone resserré : c'est le plus large de la rangée 1 (283 px sur 599).
   Le rendre compact rend au titre les ~28 px qui lui manquaient en Chine/Europe,
   pour qu'il s'affiche EN ENTIER au lieu de tomber sur son ellipse de secours. */
.bub-seg--zone > button{ display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; }
.bub-flag{ font-size: 11px; line-height: 1; filter: saturate(0.9); }
.bub-seg--zone > button.active .bub-flag{ filter: none; }
/* MCap n'est pas une durée : il change ce que la TAILLE représente. Il reste donc
   détaché du segment des fenêtres, sinon on le lit comme une huitième durée. */
.bub-mcap{ padding: 4px 12px; border-radius: 100px; border: 1px solid var(--hair-2); background: transparent; color: var(--muted); font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.13em; text-transform: uppercase; cursor: pointer; transition: border-color 0.25s var(--ease), color 0.25s var(--ease), background 0.25s var(--ease); }
.bub-mcap:hover{ border-color: var(--gold); color: var(--gold); }
.bub-mcap.active{ color: var(--bg-base); background: var(--gold); border-color: var(--gold); }

.bubble-tab-row, .stock-tab-row{ display: flex; gap: 6px; flex-wrap: wrap; }
.bubble-tab, .stock-tab, .stock-zone-tab, .stock-mv-tab{ padding: 4px 12px; border-radius: 100px; border: 1px solid var(--hair-2); background: transparent; color: var(--muted); font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.15em; text-transform: uppercase; cursor: pointer; transition: border-color 0.25s var(--ease), color 0.25s var(--ease), background 0.25s var(--ease); }
.bubble-tab:hover, .stock-tab:hover, .bubble-tab.active, .stock-tab.active, .stock-zone-tab:hover, .stock-mv-tab:hover, .stock-zone-tab.active, .stock-mv-tab.active{ border-color: var(--gold); color: var(--gold); background: rgba(108, 221, 255, 0.06); }
.bubble-tab.active, .stock-tab.active, .stock-zone-tab.active, .stock-mv-tab.active{ color: var(--bg-base); background: var(--gold); }
/* Fenêtre 1H/4H neutralisée : la place est fermée, ces deux mesures ne rendraient que
   la dernière plage cotée (un chiffre de la séance précédente). Le bouton reste LISIBLE
   et garde son infobulle — c'est elle qui explique le grisage ; un bouton invisible ne
   dit rien. La règle passe après .active pour gagner sur un onglet actif au moment où
   la place ferme, le temps que la bascule sur 24H s'applique. */
.stock-tab.is-off, .stock-tab.is-off:hover, .stock-tab.is-off.active{ opacity: 0.42; cursor: not-allowed; border-color: var(--hair-2); color: var(--muted); background: transparent; }
/* Zone switcher de la tuile movers : pilules compactes pour tenir dans le head (.ca-tile-head 9.5px) */
.stock-mv-tabs{ display: flex; gap: 4px; flex-wrap: wrap; }
.stock-mv-tab{ padding: 2px 9px; font-size: 8.5px; letter-spacing: 0.12em; }
[data-tile="movers-tradfi"] .ca-tile-head{ flex-wrap: wrap; }

/* ── News : signal du jour ──────────────────────────────────── */




















/* Foot aligne sur .ca-tile-foot pour cohérence avec les widgets bento. */
.ca-map-foot{ margin-top: 14px; padding-top: 12px; border-top: 1px solid rgba(116, 185, 255, 0.08); display: flex; justify-content: space-between; align-items: center; gap: 12px; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em; text-transform: uppercase; }
.ca-map-foot .stat{ font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.ca-map-foot .stat b{ color: var(--fg); font-weight: 700; }
.ca-map-foot .ca-lab{ font-size: 9.5px !important; letter-spacing: 0.16em !important; }



/* § III Spectre */


/* Top accent aurora */
























/* § IV Explorer */














/* Footer */

/* Image philosophe kintsugi en background footer. Active si /assets/foot_philosopher.jpg existe. */

.ca-foot.has-bg::before{ opacity: 0.14; }


/* Seal final : 3 anneaux concentriques aurora (cyan exterieur, violet milieu, magenta interieur) + glow multicouche */











@media (max-width: 1100px){
  html, body{ cursor: auto !important; } .ca-cursor{ display: none; }
  
  
  
  
  
  
  
  .ca-section{ padding: 60px 28px 50px; }
  .ca-maps{ grid-template-columns: 1fr; }
  
  
  
  
  
  
  
  
}
@media (max-width: 640px){
  
  
  
  
  
  
  
  
  
  .ca-section{ padding: 60px 20px 40px; }
  
  
  
  
}

/* ═══════════════════════════════════════════════════════════════════════════
   MACRO · INDICATEURS US — board "variation" (tuile 13, rangée 2b)
   17 séries FRED live (macro_indicators_cache.js). Optique analyste : chaque
   carte = sa dynamique (tendance ~3 ans colorée par sens risk-on + Δ1M/3M/1Y +
   range 12m + percentile). Survol type OrderFlow ; clic carte → son graphe.
   ═══════════════════════════════════════════════════════════════════════════ */
.ca-tile--full{ grid-column: 1 / -1; }
.ca-tile--macroind{ cursor: default; }
.ca-tile--macroind .ca-mi-legend{ display: inline-flex; gap: 12px; margin-left: auto; margin-right: 14px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em; color: var(--muted); align-items: center; }
.ca-tile--macroind .ca-mi-legend .up{ color: var(--pos); }
.ca-tile--macroind .ca-mi-legend .dn{ color: var(--neg); }
.ca-mi-grid{ display: grid; grid-template-columns: repeat(auto-fill, minmax(214px, 1fr)); gap: 10px; margin-top: 6px; }

.ca-mi-card{ position: relative; display: flex; flex-direction: column; padding: 11px 12px 10px;
  background: rgba(70,140,240,0.035); border: 1px solid rgba(108,221,255,0.13); border-radius: 11px;
  cursor: pointer; transition: border-color .18s var(--ease), transform .15s var(--ease), background .18s var(--ease); }
.ca-mi-card:hover{ border-color: rgba(108,221,255,0.32); transform: translateY(-2px); background: rgba(70,140,240,0.06); }
.ca-mi-card .mi-top{ display: flex; align-items: flex-start; justify-content: space-between; gap: 7px; }
.ca-mi-card .mi-cat{ font-family: var(--mono); font-size: 7px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--cyan-l); opacity: .72; margin-bottom: 2px; }
.ca-mi-card .mi-nm{ font-size: 12px; font-weight: 700; color: var(--fg); line-height: 1.12; }
.ca-mi-card .mi-pp{ font-family: var(--mono); font-size: 8.5px; font-weight: 700; padding: 2px 5px;
  border-radius: 5px; border: 1px solid currentColor; white-space: nowrap; line-height: 1; flex: 0 0 auto; }
.ca-mi-card .mi-valrow{ display: flex; align-items: baseline; gap: 7px; margin-top: 6px; flex-wrap: wrap; }
.ca-mi-card .mi-val{ font-family: var(--mono); font-size: 21px; font-weight: 700; line-height: .9;
  letter-spacing: -.01em; font-variant-numeric: tabular-nums; color: var(--fg); }
.ca-mi-card .mi-hl{ font-family: var(--mono); font-size: 12px; font-weight: 700; display: inline-flex; align-items: center; gap: 3px; }
.ca-mi-card .mi-hl .ar{ font-size: 9px; }
.ca-mi-card .mi-hl .hz{ color: var(--muted); font-size: 8px; font-weight: 600; }
.ca-mi-card .mi-hovdate{ font-family: var(--mono); font-size: 9px; font-weight: 600; color: var(--cyan-l);
  margin-left: auto; opacity: 0; transition: opacity .12s; }
.ca-mi-card.is-hover .mi-hovdate{ opacity: .9; }

.ca-mi-card .mi-chart{ position: relative; height: 48px; margin: 8px 0 2px; }
.ca-mi-card .mi-chart svg{ display: block; width: 100%; height: 48px; }
/* Bornes haut/bas 12m posées sur le tracé : depuis le passage des courbes à la
   fréquence native (2026-07-28) la ligne balaie beaucoup plus souvent les coins
   droits (pic VIX, choc WTI) et avalait le libellé. Fond translucide = lisible
   dans tous les cas, sans déplacer quoi que ce soit dans la carte. */
.ca-mi-card .mi-bl{ position: absolute; right: 0; font-family: var(--mono); font-size: 7.5px; font-weight: 600; color: var(--muted); pointer-events: none;
  padding: 0 3px; border-radius: 3px; background: rgba(8,17,38,0.78); }
.ca-mi-card .mi-bl.hi{ top: 0; } .ca-mi-card .mi-bl.lo{ bottom: 0; }
.ca-mi-hair{ position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(108,221,255,0.45);
  pointer-events: none; opacity: 0; transition: opacity .1s; }
.ca-mi-dot{ position: absolute; width: 7px; height: 7px; border-radius: 50%; background: currentColor;
  transform: translate(-50%,-50%); pointer-events: none; opacity: 0; transition: opacity .1s; box-shadow: 0 0 0 2px #0a1530; }
.ca-mi-card.is-hover .ca-mi-hair, .ca-mi-card.is-hover .ca-mi-dot{ opacity: 1; }

.ca-mi-card .mi-rng{ display: flex; align-items: center; gap: 6px; margin-top: 6px;
  font-family: var(--mono); font-size: 8px; color: var(--muted); }
.ca-mi-card .mi-rng .tk{ flex: 1; height: 4px; border-radius: 3px; background: rgba(70,140,240,0.12); position: relative; }
.ca-mi-card .mi-rng .tk i{ position: absolute; top: 50%; width: 8px; height: 8px; border-radius: 50%;
  transform: translate(-50%,-50%); border: 1.5px solid #0a1530; }
.ca-mi-card .mi-chips{ display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 4px; margin-top: 8px; }
.ca-mi-card .mi-chip{ display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px 2px;
  border-radius: 6px; background: rgba(108,221,255,0.05); border: 1px solid rgba(108,221,255,0.10); }
.ca-mi-card .mi-chip .k{ font-size: 7px; font-weight: 800; letter-spacing: .1em; color: var(--muted); }
.ca-mi-card .mi-chip .v{ font-family: var(--mono); font-size: 10.5px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
@media (max-width: 720px){ .ca-mi-grid{ grid-template-columns: repeat(2, 1fr); } }

/* CTA qui comble le reliquat de la dernière ligne du board macro (pas d'espace vide). */
.ca-mi-cta{ display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  text-align: center; padding: 14px 16px; border-radius: 11px; text-decoration: none;
  background: linear-gradient(160deg, rgba(61,139,255,0.06), rgba(61,139,255,0.02));
  border: 1px dashed rgba(108,221,255,0.30); transition: border-color .18s var(--ease), background .18s var(--ease), transform .15s var(--ease); }
.ca-mi-cta:hover{ border-color: rgba(108,221,255,0.55); background: linear-gradient(160deg, rgba(61,139,255,0.10), rgba(61,139,255,0.03)); transform: translateY(-2px); }
.ca-mi-cta .t{ font-size: 13px; font-weight: 700; color: var(--fg); letter-spacing: .01em; }
.ca-mi-cta .s{ font-size: 10.5px; color: var(--muted); line-height: 1.35; max-width: 220px; }
.ca-mi-cta .ar{ font-family: var(--mono); font-size: 18px; font-weight: 700; color: var(--cyan); margin-top: 2px; }

/* Sentiment Marché · CNN F&G (tuile 02) : tuile un peu trop haute (radar 280px
   pilotait la hauteur). Réductions SCOPÉES à cette tuile uniquement (le Radar #01
   partage .ca-radar-* et ne doit PAS bouger). */
.ca-tile[data-tile="sentiment"] .ca-sent-radar{ max-width: 208px; }
/* le wrap GRANDIT pour occuper la colonne centrale → le spider se centre vraiment */
.ca-tile[data-tile="sentiment"] .ca-sent-radar-wrap{ flex: 1 1 auto; max-width: none; }
.ca-tile[data-tile="sentiment"] .ca-radar-sig{ padding: 2px 4px; }
.ca-tile[data-tile="sentiment"] .ca-radar-signals-head{ padding-bottom: 5px; margin-bottom: 4px; }
.ca-tile[data-tile="sentiment"] .ca-radar-body--row{ gap: 16px; align-items: center; }

/* ═══════════════════════════════════════════════════════════════════════════
   ÉCRAN JAUGES — les 6 indicateurs tiennent sur UN écran (user 2026-08-03)
   ═══════════════════════════════════════════════════════════════════════════
   Avant : 3 rangées empilées dans .ca-bento = 1130 px, soit ~1,5 écran sur un
   1280x800 → il fallait scroller pour voir les 6. Maintenant une sous-grille
   dédiée 4 cols x 2 rangées dont les HAUTEURS SONT EN vh : le bloc s'ajuste à
   la fenêtre. Les min des clamp() sont le plancher où le contenu tient encore
   sans être rogné ; les max évitent des tuiles géantes sur grand écran.
     rangée 1 : Radar v1 (1 col) | Sentiment (3 cols)
     rangée 2 : F&G | Altseason | AI Bubble | Position de cycle              */
.ca-bento-signals{
  grid-column: 1 / -1;
  display: grid;
  /* 15 colonnes (2026-08-04, ajout de la tuile Concentration) : c'est le plus
     petit nombre qui découpe la rangée 2 en CINQ parts égales (5 x 3) tout en
     gardant la rangée 1 quasi inchangée (6 + 9 = 40/60, contre 5 + 7 = 41,7/58,3
     en 12 colonnes). Repasser à 12 rendrait les 5 minis inégales. */
  grid-template-columns: repeat(15, 1fr);
  /* Les min sont le plancher MESURÉ où le contenu tient encore sans être rogné
     (tuile Cycle = la plus dense de la rangée 2). Ne pas les baisser sans
     repasser le contrôle de débordement. */
  grid-template-rows: clamp(300px, 40vh, 440px) clamp(298px, 34vh, 370px);
  gap: 14px;
}
.ca-bento-signals > *{ position: relative; z-index: 1; min-height: 0; }
/* Les tuiles ne pilotent plus leur hauteur : c'est la rangée qui décide. */
.ca-bento-signals .ca-tile{ min-height: 0 !important; overflow: hidden; }
/* 5 + 7 (et non 4 + 8) : à 4 colonnes le Radar tombait à 401 px et trois noms
   de signaux passaient en ellipse (« STABLECOINS STABLES »…). Le Sentiment, lui,
   tient très bien sur 7 colonnes. */
.ca-bento-signals .ca-tile--spotlight{
  grid-column: span 6; grid-row: 1; padding: 15px 18px 11px;
}
.ca-bento-signals .ca-tile--featured-wide{ grid-column: span 9; grid-row: 1; padding: 15px 20px 11px; }
/* Rangée 2 : CINQ minis à 3 colonnes chacune (20 % de la largeur, contre 25 %
   quand elles étaient quatre). Les tailles de police de la rangée 2 sont
   resserrées plus bas pour absorber ces ~60 px perdus par tuile. */
.ca-bento-signals .ca-tile--has-gauge{ grid-column: span 3; grid-row: 2; }

/* ── Rangée 1 · Radar v1 : disposition HORIZONTALE (jauge à gauche, les 7
      signaux à droite). En colonne, la liste débordait de la tuile — or les 7
      signaux sont l'information de la tuile, hors de question de les rogner. ── */
.ca-bento-signals .ca-tile--spotlight .ca-tile-head{ margin-bottom: 8px; }
.ca-bento-signals .ca-tile--spotlight .ca-radar-body{
  flex-direction: row; gap: 16px; align-items: center; flex: 1;
}
.ca-bento-signals .ca-tile--spotlight .ca-radar-gauge-wrap{
  /* Colonne jauge volontairement étroite : c'est la liste des 7 signaux qui a
     besoin de la largeur (« STABLECOINS STABLES » était coupé en ellipse). */
  flex: 0 0 clamp(112px, 11vw, 152px); gap: 4px;
}
.ca-bento-signals .ca-tile--spotlight .ca-radar-gauge-wrap svg{ max-height: clamp(72px, 10vh, 112px); width: auto; }
.ca-bento-signals .ca-tile--spotlight .ca-radar-big{ font-size: clamp(22px, 2.1vw, 32px); }
.ca-bento-signals .ca-tile--spotlight .ca-radar-label{ font-size: 8.5px; padding: 3px 8px; letter-spacing: 0.1em; }
.ca-bento-signals .ca-tile--spotlight .ca-radar-signals{ flex: 1 1 auto; min-width: 0; }
.ca-bento-signals .ca-radar-signals-head{ padding-bottom: 4px; margin-bottom: 2px; }
.ca-bento-signals .ca-radar-signals-list{ overflow: hidden; }
.ca-bento-signals .ca-tile--spotlight .ca-radar-sig{ padding: 0 3px; gap: 7px; }
.ca-bento-signals .ca-tile--spotlight .ca-radar-sig-name{ font-size: 9.5px; letter-spacing: -0.01em; }
.ca-bento-signals .ca-tile--spotlight .ca-radar-sig-val{ font-size: 9.5px; }
.ca-bento-signals .ca-tile--spotlight .ca-radar-sig-w{ gap: 1px; }
.ca-bento-signals .ca-hist90--tall{ flex: 0 0 auto; height: clamp(44px, 6.2vh, 76px); margin: 6px 0 0; }
.ca-bento-signals .ca-hist90-cap{ margin-top: 1px; }
/* ...sauf sur les minis a jauge : la depuis 2026-08-19 c'est la courbe qui
   s'etire (flex:1), la legende reste collee sous elle. */
.ca-bento-signals .ca-tile--has-gauge .ca-hist90-cap{ margin-top: 2px; }
.ca-bento-signals .ca-tile-foot{ margin-top: 5px; padding-top: 5px; }

/* ── Rangée 1 · Sentiment : le spider et la fiche détail se calent sur la
      hauteur de rangée au lieu d'imposer 264 px fixes. ── */
.ca-bento-signals .ca-tile--featured-wide .ca-tile-head{ margin-bottom: 8px; }
.ca-bento-signals .ca-radar-body--with-radar{ gap: 18px; padding: 2px 4px; grid-template-columns: 200px 1fr 230px; }
.ca-bento-signals .ca-radar-body--with-radar .ca-radar-gauge-wrap svg{ max-width: 100% !important; max-height: clamp(84px, 12vh, 132px); width: auto; }
.ca-bento-signals .ca-radar-body--with-radar .ca-radar-big{ font-size: clamp(24px, 2.4vw, 34px); }
.ca-bento-signals .ca-sent-stage{ min-height: 0; height: 100%; }
.ca-bento-signals .ca-sent-radar{ max-width: clamp(150px, 22vh, 230px); }
.ca-bento-signals .ca-tile[data-tile="sentiment"] .ca-radar-sig{ padding: 1px 3px; }

/* ── Rangée 2 · les 4 minis : jauge + score + viz + pied, sans air perdu. ── */
.ca-bento-signals .ca-tile--has-gauge{ padding: 14px 16px 10px; }
.ca-bento-signals .ca-tile--has-gauge .ca-tile-head{ margin-bottom: 4px; }
.ca-bento-signals .ca-mini-gauge-wrap{ margin: 0; }
.ca-bento-signals .ca-mini-gauge-wrap svg{ max-height: clamp(64px, 9vh, 100px); width: auto; }
/* flex: 0 0 auto est INDISPENSABLE : avec min-height:0 seul, la pile du score
   se faisait écraser à 9 px de haut par le flex-shrink et son contenu (« 22 » +
   la pastille d'état) se peignait PAR-DESSUS la liste en dessous. Aucun message
   d'erreur, juste un chevauchement silencieux. */
.ca-bento-signals .ca-mini-score-stack{ min-height: 0; flex: 0 0 auto; gap: 2px; margin: 1px 0 2px; }
.ca-bento-signals .ca-mini-gauge-wrap,
.ca-bento-signals .ca-hist90-cap{ flex: 0 0 auto; }
.ca-bento-signals .ca-mini-big{ font-size: clamp(21px, 2.1vw, 30px); }
.ca-bento-signals .ca-tile--has-gauge .ca-tile-sub{ white-space: nowrap; }
/* Refonte 2026-08-19 — le vide du bas devient de la HAUTEUR DE COURBE.
   Avant : `.ca-bento-signals .ca-hist90-cap{margin-top:1px}` (plus bas) annulait
   le `margin-top:auto` de la regle generique, la colonne flex ne repartissait
   donc rien et ~90 px de tuile restaient vides sous le pied, pendant que la
   sparkline etouffait dans 43 px — d'ou l'impression d'aplati ET de vide.
   Maintenant la courbe est le SEUL bloc extensible de la tuile : elle absorbe
   tout l'espace libre. `min-height` = plancher mesure, `flex-shrink: 1` la
   laisse ceder si la fenetre est courte (le piege du memo est l'ecrasement
   SILENCIEUX d'un bloc a contenu non compressible — une courbe SVG, elle,
   se redessine a sa taille reelle via le ResizeObserver de renderHistChart). */
.ca-bento-signals .ca-tile--has-gauge .ca-hist90{
  /* `height` = taille SOUHAITEE (elle sert de flex-basis), `min-height` = plancher
     dur. Poser le souhait en min-height bloquait le retrecissement : a 1440x900
     la rangee ne fait que 306 px et les 4 tuiles etaient rognees de 6 px, pied
     coupe (audit de debordement 2026-08-19). Avec ce couple, la courbe rend les
     quelques pixels manquants au lieu de faire deborder la tuile. */
  flex: 1 1 auto; height: clamp(46px, 6vh, 74px); min-height: 34px; margin: 4px 2px 0;
}
/* Meme principe pour la tuile Cycle, qui montre 4 barres au lieu d'une courbe :
   la liste s'etire et aere ses lignes plutot que de laisser un trou sous le pied. */
.ca-bento-signals .ca-tile--cycle .ca-cyc-dims-list{
  flex: 1 1 auto; justify-content: center; gap: clamp(1px, 0.6vh, 7px);
}

/* ═══ Position de cycle (tuile 06) ═══════════════════════════════════════
   Même gabarit que ses 3 voisines ; à la place de la sparkline 90j, ses
   4 dimensions décorrélées — c'est là qu'est l'information. Le pied porte la
   formule exacte pour que le score soit reconstructible à la main.        */
.ca-cyc-dims-list{ list-style: none; padding: 0; margin: 2px 4px 0; display: flex; flex-direction: column; gap: 1px; }
.ca-cyc-dim{ display: grid; grid-template-columns: 6px minmax(0, auto) 1fr 18px; gap: 6px; align-items: center; line-height: 1.35; }
.ca-cyc-dim-dot{ width: 6px; height: 6px; border-radius: 50%; }
.ca-cyc-dim-name{ font-family: 'Inter', sans-serif; font-weight: 500; font-size: 9.5px; color: var(--fg-2); white-space: nowrap; }
.ca-cyc-dim-val{ font-family: var(--mono); font-size: 9.5px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
/* Pied de la tuile Cycle : variation 3 mois à gauche, formule + date du cache à
   droite. Tout doit tenir sur UNE ligne dans ~265 px utiles → police réduite et
   nowrap (sans ça les deux blocs passaient sur 2 lignes chacun). */
.ca-bento-signals .ca-tile--cycle .ca-tile-foot{ font-size: 8px; gap: 8px; }
.ca-bento-signals .ca-tile--cycle .ca-tile-foot > span{ white-space: nowrap; }
.ca-bento-signals .ca-tile--cycle .ca-tile-meta{ font-family: var(--mono); letter-spacing: 0; }

/* Badge d'état par indicateur (libellé + couleur identiques à Macro_Trends). */
.ca-mi-card .mi-state{ margin-top: 6px; }
.ca-mi-card .mi-state-badge{ display: inline-block; font-family: var(--mono); font-size: 8.5px; font-weight: 700;
  letter-spacing: .05em; padding: 2px 9px; border-radius: 11px; line-height: 1.5; }

/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE UNIFIÉ — Session 2 (2026-06-08)
   ═══════════════════════════════════════════════════════════════════════════
   Système de breakpoints cohérent en complément des @media legacy éparpillées.
   Objectif : zéro casse desktop (rien ici n'active >1023px), site utilisable
   sur tablette portrait (768-1023px), phablet (480-767px), mobile (<480px).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── TABLETTE & SOUS-DESKTOP (≤ 1023px) ──────────────────────────────────
   Couvre notamment le gap critique 900-960px où le bento restait en 4 cols.
   Ici on force 2 cols dès qu'on est sous 1024px (laptops compacts inclus). */
@media (max-width: 1023px){
  /* Bento : 4 cols → 2 cols dès qu'on quitte le desktop standard */
  .ca-bento{ grid-template-columns: repeat(2, 1fr) !important; }
  .ca-tile--featured,
  .ca-tile--wide,
  .ca-tile--full,
  .ca-tile--featured-wide,
  .ca-tile--spotlight{ grid-column: span 2 !important; }

  /* Sections : padding latéral réduit pour gagner de la largeur utile */
  .ca-section{ padding: 60px 24px 50px; }

  /* Radar sentiment : reflow plus doux que le 1100px brutal existant.
     Étape intermédiaire qui empêche les colonnes 260px/240px de craquer. */
  .ca-radar-body--with-radar{
    grid-template-columns: 1fr 1fr !important;
    gap: 14px !important;
  }
  .ca-sent-stage{ grid-column: span 2 !important; }

  /* Écran jauges : sous 1024px on repasse à 2 colonnes et on rend la main à la
     hauteur du contenu (la contrainte vh n'a plus de sens quand chaque tuile
     occupe une demi-largeur). */
  .ca-bento-signals{
    grid-template-columns: repeat(2, 1fr) !important;
    grid-template-rows: none !important;
    grid-auto-rows: minmax(240px, auto) !important;
  }
  .ca-bento-signals .ca-tile--spotlight,
  .ca-bento-signals .ca-tile--featured-wide{ grid-column: span 2 !important; grid-row: auto !important; }
  .ca-bento-signals .ca-tile--has-gauge{ grid-column: span 1 !important; grid-row: auto !important; }
  .ca-bento-signals .ca-tile--spotlight .ca-radar-body{ flex-direction: row !important; }
  .ca-bento-signals .ca-tile{ overflow: visible; }
}

/* ─── TABLETTE PORTRAIT & PHABLET (≤ 767px) ───────────────────────────────
   iPad portrait, grand téléphone. Bento en 1 colonne, navbar compacte. */
@media (max-width: 767px){
  /* Bento : 1 colonne pleine largeur */
  .ca-bento{ grid-template-columns: 1fr !important; }
  .ca-tile,
  .ca-tile--featured,
  .ca-tile--wide,
  .ca-tile--full,
  .ca-tile--featured-wide,
  .ca-tile--spotlight{ grid-column: 1 !important; }

  /* Écran jauges : 1 colonne, hauteur au contenu */
  .ca-bento-signals{ grid-template-columns: 1fr !important; }
  .ca-bento-signals .ca-tile--spotlight,
  .ca-bento-signals .ca-tile--featured-wide,
  .ca-bento-signals .ca-tile--has-gauge{ grid-column: 1 !important; }
  .ca-bento-signals .ca-tile--spotlight .ca-radar-body{ flex-direction: column !important; }

  /* Navbar : reduit padding (32px → 14px) pour libérer ~36px utile */
  .navbar .container{ padding: 0 14px !important; }
  .navbar-brand{ padding-left: 8px !important; padding-right: 8px !important; }

  /* Sections plus serrées */
  .ca-section{ padding: 48px 16px 40px; }

  /* Maps : 1 col (déjà géré par @1100px existante mais on consolide) */
  .ca-maps{ grid-template-columns: 1fr !important; }

  /* Macro Indicators value : 21px fixe → responsive */
  .ca-mi-card .mi-val{ font-size: clamp(16px, 4vw, 21px) !important; }

  /* CTA text qui débordait à 220px */
  .ca-mi-cta .s{ max-width: clamp(140px, 80%, 220px) !important; }

  /* Sentiment radar SVG : max-width 208px / 280px réduits sur petite tablette */
  .ca-tile[data-tile="sentiment"] .ca-sent-radar{ max-width: 180px !important; }
  .ca-sent-radar{ max-width: 180px !important; }
  .ca-radar-gauge-wrap svg{ max-width: 160px !important; }
}

/* ─── MOBILE LANDSCAPE / PHABLET (≤ 600px) ────────────────────────────────
   Niveau intermédiaire pour le bubble canvas qui sinon prendrait 64% du
   viewport mobile. Et override hero transform qui pousse hors viewport. */
@media (max-width: 600px){
  /* Bubble canvas : 420px → 280px (gagne 140px d'espace utile) */
  #bubble-canvas-wrap,
  #stock-canvas-wrap{ min-height: 280px !important; }

  /* Hero content : le transform translateX(clamp(100px, 16vw, 280px)) du
     desktop pousse le contenu hors viewport sur mobile. On annule. */
  .hero-content{
    transform: translateX(0) !important;
    padding-left: 4vw !important;
    padding-right: 4vw !important;
    max-width: 100% !important;
  }

  /* Logos floating dans le hero : peuvent déborder, on cache (purement déco) */
  #hero-logos{ display: none !important; }
}

/* ─── MOBILE STRICT (≤ 480px) ─────────────────────────────────────────────
   iPhone portrait, Android compact. Compactage maximal. */
@media (max-width: 480px){
  /* Sections ultra-compactes */
  .ca-section{ padding: 36px 12px 32px; }

  /* Navbar encore plus serrée */
  .navbar .container{ padding: 0 10px !important; }

  /* Hero title : réduit pour que 'ANTIFRAGILE' tienne entier sur 390px (était rogné). */
  .hero-h1{ font-size: clamp(23px, 7.6vw, 52px) !important; line-height: 1.04 !important; letter-spacing: -0.01em !important; }
  .hero-tagline{ font-size: clamp(14px, 4vw, 18px) !important; }

  /* CTAs : full width stack pour zone de tap confortable */
  .hero-cta-row{
    flex-direction: column !important;
    width: 100% !important;
    gap: 12px !important;
  }
  .hero-cta{ width: 100% !important; text-align: center !important; }

  /* Tile-info icon : peut chevaucher titre quand le titre wrap */
  .ca-tile-info{ display: none !important; }

  /* Bubble canvas encore plus bas */
  #bubble-canvas-wrap,
  #stock-canvas-wrap{ min-height: 240px !important; }

  /* News pinned : 14px → 13px */
  .ca-news-feed li.ca-news-pinned .ca-news-title{ font-size: 13px !important; }

  /* Stablecoins grid : 3 cols → 1 col.
     FIX 2026-06-16 : .ca-stbb-total a grid-column:span 3 → forçait 3 colonnes
     implicites malgré 1fr (cellules 26px, logo par-dessus la valeur). On fait
     spanner le total sur la seule colonne existante. */
  .ca-stbb-grid{ grid-template-columns: 1fr !important; gap: 8px !important; }
  .ca-stbb-total{ grid-column: 1 / -1 !important; }

  /* Narratives / Movers : 2 sous-colonnes → 1 (la colonne droite 'Top 3 Baisses'
     débordait/était coupée hors viewport). */
  .ca-narr-grid, .ca-movers-grid{ grid-template-columns: 1fr !important; }

  /* TVL row : 5 cols trop serré → cacher colonnes secondaires */
  .ca-tvl-head,
  .ca-tvl-row{ grid-template-columns: 56px 1fr 70px !important; }
  .ca-tvl-row > *:nth-child(n+4){ display: none !important; }
  .ca-tvl-head > *:nth-child(n+4){ display: none !important; }

  /* Funding heatmap grid */
  .ca-frhm-grid{ grid-template-columns: 60px 1fr 56px !important; }

  /* Mode stats : 2 cols → 1 col stack vertical */
  .ca-tile--mode .ca-mode-stats{ grid-template-columns: 1fr !important; gap: 10px !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE POLISH — Session 3 (2026-06-08)
   ═══════════════════════════════════════════════════════════════════════════
   Affinages tablette (768-1023px) + mobile (<480px) après baseline S2.
   - Tablet : aspect-ratio des featured tiles full-width, alignement spider
   - Mobile : movers/narr 2 cols mais fonts réduites, calendrier stack,
              pinned news layout, histos plus petits, ca-mi-grid prévisible
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── TABLETTE PURE (768-1023px) ──────────────────────────────────────────
   Le span 2 du bloc S2 fait que les featured tiles deviennent pleine largeur
   sur tablette. Sans tweak elles paraissent disproportionnées. */
@media (min-width: 768px) and (max-width: 1023px){
  /* Spotlight Radar v1 : limit hauteur pour éviter qu'elle s'étire
     en colonne (~600px+) sur tablette quand elle est pleine largeur */
  .ca-tile--spotlight{ min-height: auto !important; }
  .ca-tile--spotlight .ca-hist90--tall{ height: 50px !important; }

  /* Sentiment featured : spider chart un peu plus grand profite de la
     largeur ajoutée par le span 2 */
  .ca-tile[data-tile="sentiment"] .ca-sent-radar{ max-width: 220px !important; }

  /* Macro Indicators : passer en 3 colonnes (auto-fill minmax(214px,1fr)
     donne ~3 cols à 768-960px mais inconsistant). On force 3. */
  .ca-mi-grid{ grid-template-columns: repeat(3, 1fr) !important; }

  /* News feed : on garde le layout 5 cols (768px tient encore), mais
     on s'assure que la source pill ne déborde pas */
  .ca-news-feed .ca-news-src{ max-width: 90px !important; }

  /* Calendar : 130px first col est ok à 768px mais réduire à 110px */
  .ca-cal-row{ grid-template-columns: 110px 1fr !important; gap: 12px !important; }

  /* Mode editorial : reflow déjà géré par @780px existant.
     Featured wide content : gap réduit */
  .ca-tile--featured-wide .ca-radar-body{ gap: 12px !important; }
}

/* ─── MOBILE STRICT FINE-GRAINED (≤ 480px) ────────────────────────────────
   Compléments du bloc S2 pour widgets qui restaient juste à la limite. */
@media (max-width: 480px){
  /* Movers + Narratives : garder 2 cols (sinon trop de scroll) mais
     compacter les fonts et le padding */
  .ca-movers-sym,
  .ca-movers-pct,
  .ca-narr-name,
  .ca-narr-pct{ font-size: 11px !important; }
  .ca-movers-row{ grid-template-columns: 14px 1fr auto !important; gap: 6px !important; padding: 4px 6px !important; }
  .ca-movers-row img{ width: 14px !important; height: 14px !important; }
  .ca-narr-row{ grid-template-columns: 14px 1fr auto !important; gap: 6px !important; padding: 4px 6px !important; }
  .ca-narr-row img{ width: 14px !important; height: 14px !important; }
  .ca-movers-col-head,
  .ca-narr-col-head{ font-size: 8px !important; padding: 4px 6px !important; }

  /* Calendar : stack vertical (date dessus, event dessous) */
  .ca-cal-row{
    grid-template-columns: 1fr !important;
    gap: 4px !important;
    padding: 8px 12px !important;
  }
  .ca-cal-when-day{ font-size: 13px !important; }
  .ca-cal-event-name{ font-size: 12.5px !important; }
  .ca-cal-link .ca-cal-row{ padding-right: 28px !important; }

  /* News pinned : layout simplifié, masquer image si présente */
  .ca-news-feed li.ca-news-pinned{ padding: 8px 6px !important; }
  .ca-news-feed li.ca-news-pinned .ca-news-title{ font-size: 12.5px !important; line-height: 1.35 !important; }

  /* Histogrammes 90j : réduire la hauteur pour gagner espace vertical */
  .ca-hist90{ height: 36px !important; }
  .ca-hist90--tall{ height: 48px !important; }

  /* Sparklines tile */
  .ca-tile:not(.ca-tile--featured) .ca-tile-spark{ height: 24px !important; }

  /* Macro Indicators : 1 colonne pleine largeur sur téléphone étroit (≤480px).
     En 2 cols à 390px, chaque carte (~180px) entassait valeur+sparkline+3 stats
     = écrasé. 1 colonne = cartes aérées et lisibles (refonte mobile 2026-06-15). */
  .ca-mi-grid{ grid-template-columns: 1fr !important; gap: 10px !important; }
  .ca-mi-card{ padding: 12px 14px !important; }
  .ca-mi-card .mi-nm{ font-size: 12px !important; }
  .ca-mi-card .mi-val{ font-size: clamp(18px, 6vw, 24px) !important; }

  /* Mode hero (Crypto/TradFi badges) : compactage */
  .ca-tile--mode-editorial .ca-mode-emblem{ width: 50px !important; height: 50px !important; }
  .ca-tile--mode-editorial .ca-mode-state-name{ font-size: clamp(18px, 5vw, 22px) !important; }
  .ca-tile--mode-editorial .ca-mode-key-val{ font-size: clamp(20px, 5.5vw, 24px) !important; }

  /* OI bento : 2x2 reste mais cellules + compactes */
  .ca-oibg-grid{ gap: 8px !important; }
  .ca-oibg-card{ padding: 8px !important; }
  .ca-oi-kpi-val{ font-size: clamp(16px, 4vw, 22px) !important; }

  /* Funding heatmap : padding compact */
  .ca-frhm-now{ font-size: 10px !important; }
  .ca-frhm-lbl{ font-size: 10px !important; }

  /* Tile heads compactés (numéro + nom + arrow) */
  .ca-tile-head{ gap: 8px !important; }
  .ca-tile-name{ font-size: 11px !important; }
  .ca-tile-num{ font-size: 10px !important; }

  /* Foot meta : super compact */
  .ca-tile-foot{ font-size: 8.5px !important; margin-top: 10px !important; padding-top: 8px !important; }

  /* Ticker live : ralentir le scroll pour lisibilité tactile + font + */
  .ca-ticker-track{ animation-duration: 90s !important; }
  .ca-tick-sym{ font-size: 11px !important; }
  .ca-tick-val{ font-size: 11px !important; }

  /* Sources marquee */
  .ca-sources-marquee{ animation-duration: 60s !important; }
}

/* ─── PHABLET FINE-TUNE (481-767px) ───────────────────────────────────────
   Entre mobile strict (480px) et tablette (768px). Pour grands téléphones
   en landscape ou petits tablets. */
@media (min-width: 481px) and (max-width: 767px){
  /* Movers/Narratives : garder 2 cols (large enough) */
  .ca-movers-sym,
  .ca-movers-pct,
  .ca-narr-name,
  .ca-narr-pct{ font-size: 11.5px !important; }

  /* Macro Indicators : 2 cols nette */
  .ca-mi-grid{ grid-template-columns: repeat(2, 1fr) !important; }

  /* Calendar : garder 2 cols (assez de place) */
  .ca-cal-row{ grid-template-columns: 100px 1fr !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE POLISH FINAL — Session 4 (2026-06-08)
   ═══════════════════════════════════════════════════════════════════════════
   - Navbar Bootstrap burger : dark theme propre quand menu déployé sur mobile
   - Modal bulles cliquables : fullscreen vrai sur <480px (override .bm-*)
   - Wide viewport : centrage déjà via .ca-section max-width, on s'assure rien
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── NAVBAR BURGER (≤ 767px) ─────────────────────────────────────────────
   Bootstrap 3.3.5 switche en mode burger sous 767px par défaut. On stylise
   le menu déroulé pour qu'il s'aligne avec le dark theme du site. */
@media (max-width: 767px){
  /* Burger button visible à droite */
  .navbar-toggle{
    display: block !important;
    margin: 12px 8px !important;
    padding: 8px 10px !important;
    border: 1px solid rgba(61, 139, 255, 0.30) !important;
    border-radius: 4px !important;
    background: rgba(15, 29, 51, 0.6) !important;
    backdrop-filter: blur(4px) !important;
    -webkit-backdrop-filter: blur(4px) !important;
  }
  .navbar-toggle:hover,
  .navbar-toggle:focus{
    background: rgba(61, 139, 255, 0.10) !important;
    border-color: rgba(61, 139, 255, 0.6) !important;
  }
  .navbar-toggle .icon-bar{
    background: #74aeff !important;
    width: 22px !important;
    height: 2px !important;
    margin-top: 4px !important;
  }
  .navbar-toggle .icon-bar:first-child{ margin-top: 0 !important; }

  /* Menu déroulé : background dark + bordure cyan subtile */
  .navbar-collapse.in,
  .navbar-collapse.collapsing{
    background: linear-gradient(180deg, rgba(10, 20, 36, 0.97) 0%, rgba(15, 29, 51, 0.97) 100%) !important;
    backdrop-filter: blur(12px) !important;
    -webkit-backdrop-filter: blur(12px) !important;
    border-top: 1px solid rgba(61, 139, 255, 0.18) !important;
    box-shadow: 0 12px 28px -8px rgba(0, 0, 0, 0.65) !important;
    max-height: calc(100vh - 60px) !important;
    overflow-y: auto !important;
  }

  /* Liens nav stack vertical en mode collapsed */
  .navbar-nav{
    float: none !important;
    margin: 0 !important;
  }
  .navbar-nav > li{
    float: none !important;
    border-bottom: 1px solid rgba(61, 139, 255, 0.06) !important;
  }
  .navbar-nav > li:last-child{
    border-bottom: none !important;
  }
  .navbar-nav > li > a{
    padding: 14px 22px !important;
    font-size: 13px !important;
  }

  /* Active : underline → border-left cyan dans la liste verticale */
  .navbar-default .navbar-nav > li.active > a::after,
  .navbar-inverse .navbar-nav > li.active > a::after{
    left: 0 !important;
    right: auto !important;
    top: 0 !important;
    bottom: 0 !important;
    width: 3px !important;
    height: auto !important;
    background: linear-gradient(180deg, #3d8bff 0%, #74aeff 100%) !important;
    border-radius: 0 2px 2px 0 !important;
    box-shadow: 0 0 8px rgba(61, 139, 255, 0.4) !important;
  }
  /* Hover non-actifs : pas d'underline en mode mobile (le hover bg suffit) */
  .navbar-nav > li:not(.active) > a:hover::before{
    display: none !important;
  }
  .navbar-nav > li:not(.active) > a:hover{
    background: rgba(61, 139, 255, 0.05) !important;
  }
}

/* ─── BUBBLE MODAL FULLSCREEN MOBILE (≤ 480px) ────────────────────────────
   bubble_canvas.js injecte ses propres styles .bm-* avec @media @900px et
   @600px. Sur petit mobile, on pousse en fullscreen vrai pour donner toute
   la place au graph. !important pour overrider les styles injectés JS. */
@media (max-width: 480px){
  .bm-overlay{
    padding: 0 !important;
    align-items: stretch !important;
    justify-content: stretch !important;
  }
  .bm-card{
    width: 100vw !important;
    height: 100vh !important;
    max-width: 100vw !important;
    max-height: 100vh !important;
    border-radius: 0 !important;
    border: none !important;
    padding: 14px 14px 12px !important;
  }
  .bm-close{
    top: 8px !important;
    right: 8px !important;
    width: 32px !important;
    height: 32px !important;
  }
  .bm-name{ font-size: 15px !important; }
  .bm-price{ font-size: 17px !important; }
  .bm-logo{ width: 36px !important; height: 36px !important; }
  .bm-head{ padding-bottom: 10px !important; padding-right: 40px !important; }
  .bm-maintabs{ gap: 14px !important; margin-bottom: 12px !important; }
  .bm-maintab{ font-size: 10px !important; padding: 8px 0 !important; }
  .bm-chartwrap{ min-height: 200px !important; }
  .bm-kpis{ gap: 4px !important; }
  .bm-kpi{ font-size: 10px !important; padding: 5px 6px !important; }
  .bm-stats{ grid-template-columns: 1fr 1fr !important; gap: 6px !important; }
  .bm-stat-val{ font-size: 14px !important; }
  .bm-actions{ flex-direction: column !important; gap: 8px !important; }
  .bm-action{ min-width: 0 !important; font-size: 10px !important; padding: 10px 12px !important; }
}

/* ─── WIDE VIEWPORT (≥ 1920px) ────────────────────────────────────────────
   Pour les très grands écrans, on s'assure que le contenu reste centré et
   ne s'étire pas démesurément. .ca-section a déjà max-width: var(--max-w).
   Ajoute juste un petit padding latéral pour éviter le contenu collé au bord
   sur écrans ultra-wide. */
@media (min-width: 1920px){
  .ca-main{ padding-left: 24px; padding-right: 24px; }
  .ca-section{ max-width: 1600px !important; margin: 0 auto !important; }
  .navbar .container{ max-width: 1600px !important; }
}

/* ═════════════════════════════════════════════════════════════════════════
   NAVBAR MOBILE BURGER — Refonte 2026-06-08 (post-deploy public)
   ════════════════════════════════════════════════════════════════════════
   Avant : burger Bootstrap caché par .navbar-toggle-btn (œil hide/show) et
   navbar transparente sur hero → tap impossible + invisible.
   Après : burger badge cyan visible partout, contraste fort, label "MENU".
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767px){
  /* Booster la visibilité du burger MÊME sur le hero (où la navbar est transparente)
     en surcharge des règles body:has(.hero-landing) qui mettent tout en transparent */
  .navbar-toggle,
  body:has(.hero-landing):not(.ca-hero-out) .navbar-toggle,
  .navbar-default .navbar-toggle,
  .navbar-inverse .navbar-toggle{
    display: flex !important;
    align-items: center !important;
    gap: 6px !important;
    position: relative !important;
    margin: 10px 12px !important;
    padding: 9px 14px 9px 12px !important;
    border: 1.5px solid rgba(61, 139, 255, 0.55) !important;
    border-radius: 8px !important;
    background: rgba(7, 17, 29, 0.85) !important;
    backdrop-filter: blur(8px) !important;
    -webkit-backdrop-filter: blur(8px) !important;
    box-shadow: 0 4px 12px -2px rgba(0, 0, 0, 0.6),
                0 0 0 1px rgba(61, 139, 255, 0.10) !important;
    z-index: 100 !important;
    float: right !important;
    cursor: pointer !important;
  }
  .navbar-toggle:hover,
  .navbar-toggle:focus{
    background: rgba(61, 139, 255, 0.18) !important;
    border-color: rgba(61, 139, 255, 0.85) !important;
    box-shadow: 0 4px 16px -2px rgba(61, 139, 255, 0.4),
                0 0 0 1px rgba(61, 139, 255, 0.30) !important;
  }

  /* Les 3 barres : cyan vif, plus épaisses */
  .navbar-toggle .icon-bar,
  .navbar-default .navbar-toggle .icon-bar,
  .navbar-inverse .navbar-toggle .icon-bar{
    background-color: #74aeff !important;
    background: #74aeff !important;
    width: 18px !important;
    height: 2.5px !important;
    margin-top: 4px !important;
    border-radius: 1.5px !important;
    box-shadow: 0 0 4px rgba(116, 174, 255, 0.4) !important;
  }
  .navbar-toggle .icon-bar:first-child{ margin-top: 0 !important; }

  /* Label "MENU" via pseudo-élément (pas besoin de toucher au HTML) */
  .navbar-toggle::after{
    content: 'MENU';
    display: inline-block !important;
    font-family: 'JetBrains Mono', 'Inter', monospace !important;
    font-size: 9.5px !important;
    font-weight: 700 !important;
    letter-spacing: 0.18em !important;
    color: #74aeff !important;
    margin-left: 4px !important;
  }

  /* Wrap pour les 3 barres → flex column pour qu'elles soient empilées proprement */
  .navbar-toggle > span.sr-only + .icon-bar,
  .navbar-toggle .icon-bar{
    display: block !important;
  }

  /* Navbar header : pour que le burger reste accessible même quand la navbar
     est transparente sur le hero. On ne touche PAS au fond de la navbar (resté
     transparent pour préserver l'effet hero) — juste le burger devient lisible. */
  .navbar-header{
    position: relative !important;
    z-index: 100 !important;
  }

  /* Quand la navbar est cachée (body.navbar-hidden), le burger doit rester
     accessible quand même (on a caché .navbar-toggle-btn sur mobile, donc
     le seul moyen d'ouvrir le menu reste ce burger). */
  body.navbar-hidden .navbar-toggle{
    display: flex !important;
  }
}

/* ───── EXTRA : sur très petit mobile (<480px) ───────────────────────────
   Le burger légèrement plus discret pour laisser la place au logo brand */
@media (max-width: 480px){
  .navbar-toggle{
    margin: 8px 8px !important;
    padding: 7px 11px 7px 10px !important;
  }
  .navbar-toggle::after{
    font-size: 9px !important;
    letter-spacing: 0.16em !important;
  }
  .navbar-toggle .icon-bar{
    width: 16px !important;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   HERO MOBILE — Refonte 2026-06-08 (image dédiée portrait)
   ════════════════════════════════════════════════════════════════════════
   Image desktop hero_tree.png est paysage → crop mal en portrait mobile.
   Solution : image dédiée hero_mobile.jpg (608x1080, 9:16, 350KB) générée
   ChatGPT : arbre cosmique cyan + racines comme data streams.
   Desktop ≥768px : image arbre originale conservée (intacte).
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 767px){
  .hero-landing{
    background-image:
      linear-gradient(180deg, rgba(5,11,26,0) 0%, rgba(5,11,26,0) 60%, rgba(5,11,26,0.55) 88%, #050b1a 100%),
      url("assets/hero_mobile.jpg") !important;
    background-size: cover, cover !important;
    background-position: center top, center center !important;
    background-repeat: no-repeat, no-repeat !important;
    background-attachment: scroll, scroll !important;
    background-color: #050b1a !important;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   MOBILE NAVBAR FULL-SCREEN OVERLAY — Refonte 2026-06-08
   ════════════════════════════════════════════════════════════════════════
   Pour iPhone/Android : vraie expérience app native (overlay slide-in depuis
   la droite, large tap targets 56px, scrollable, close button, animation).
   Desktop ≥768px : pas touché (rules @media (max-width: 767px) seulement).
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767px){
  /* Bootstrap collapse legacy : on overrride pour faire un VRAI overlay
     fullscreen au lieu du dropdown sous la navbar */
  .navbar-collapse{
    /* Hidden par défaut, slide-in quand .in */
    position: fixed !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
    max-height: 100vh !important;
    margin: 0 !important;
    padding: 0 !important;
    /* Background dark gradient style brand */
    background: linear-gradient(135deg, #07111d 0%, #0a1424 60%, #0f1d33 100%) !important;
    /* Animation : slide-in depuis la droite */
    transform: translateX(100%) !important;
    transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1) !important;
    /* Cache initialement */
    display: block !important;
    visibility: hidden !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    -webkit-overflow-scrolling: touch !important;
    z-index: 1100 !important;
    /* Pas de transition Bootstrap height/max-height */
    box-shadow: none !important;
    border: none !important;
  }
  /* Quand le menu est ouvert (Bootstrap ajoute .in) : slide-in visible */
  .navbar-collapse.in,
  .navbar-collapse.collapsing{
    visibility: visible !important;
    transform: translateX(0) !important;
  }

  /* Container interne pour respecter le safe area iPhone (notch) */
  .navbar-collapse .navbar-nav{
    padding: max(env(safe-area-inset-top, 16px), 16px) 0
             max(env(safe-area-inset-bottom, 24px), 24px) 0 !important;
    margin: 0 !important;
    list-style: none !important;
  }

  /* Header avec brand + close en haut du menu (via ::before sur navbar-nav) */
  .navbar-collapse .navbar-nav::before{
    content: '';
    display: block;
    height: 64px;
    margin: 0 20px 16px;
    border-bottom: 1px solid rgba(61, 139, 255, 0.12);
    /* Logo Capital Antifragile inline en bg */
    background-image:
      linear-gradient(90deg,
        transparent 0,
        transparent 0,
        rgba(61, 139, 255, 0) 100%);
    /* Le close button est géré séparément ci-dessous */
  }

  /* Brand text "CAPITAL ANTIFRAGILE" en haut du menu (via ::after) */
  .navbar-collapse::before{
    content: 'CAPITAL ANTIFRAGILE';
    position: absolute !important;
    top: max(env(safe-area-inset-top, 22px), 22px) !important;
    left: 24px !important;
    font-family: 'Inter', sans-serif !important;
    font-weight: 800 !important;
    font-size: 13.5px !important;
    letter-spacing: 0.18em !important;
    color: #eaf2fb !important;
    z-index: 2 !important;
    pointer-events: none !important;
  }

  /* Close button (X) en haut à droite du menu — on style le burger lui-même
     qui reste accessible quand le menu est ouvert (Bootstrap ne le cache pas).
     On le re-positionne et change l'icone en X. */
  .navbar-collapse.in ~ .navbar-header .navbar-toggle,
  .navbar-header:has(+ .navbar-collapse.in) .navbar-toggle{
    position: fixed !important;
    top: max(env(safe-area-inset-top, 14px), 14px) !important;
    right: 14px !important;
    margin: 0 !important;
    z-index: 1200 !important;
  }

  /* Items du menu : grands, tap-friendly, séparés */
  .navbar-collapse .navbar-nav > li{
    float: none !important;
    margin: 0 !important;
    border: none !important;
    border-bottom: 1px solid rgba(61, 139, 255, 0.06) !important;
    position: relative !important;
  }
  .navbar-collapse .navbar-nav > li:last-child{
    border-bottom: none !important;
  }
  .navbar-collapse .navbar-nav > li > a,
  .navbar-default .navbar-collapse .navbar-nav > li > a,
  .navbar-inverse .navbar-collapse .navbar-nav > li > a{
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    padding: 18px 24px !important;
    font-family: 'Inter', sans-serif !important;
    font-size: 15px !important;
    font-weight: 500 !important;
    letter-spacing: 0 !important;
    text-transform: none !important;
    color: #cfd8e8 !important;
    background: transparent !important;
    border: none !important;
    line-height: 1.3 !important;
    min-height: 56px !important;
    box-sizing: border-box !important;
    transition: background 0.15s ease, color 0.15s ease, padding 0.15s ease !important;
  }
  /* Petit arrow ">" à droite de chaque item */
  .navbar-collapse .navbar-nav > li > a::after{
    content: '›';
    display: inline-block !important;
    font-family: 'Inter', sans-serif !important;
    font-size: 22px !important;
    font-weight: 300 !important;
    color: rgba(116, 185, 255, 0.35) !important;
    line-height: 1 !important;
    transition: transform 0.2s ease, color 0.2s ease !important;
  }
  /* Hover/active */
  .navbar-collapse .navbar-nav > li > a:hover,
  .navbar-collapse .navbar-nav > li > a:active,
  .navbar-collapse .navbar-nav > li > a:focus{
    background: rgba(61, 139, 255, 0.06) !important;
    color: #ffffff !important;
    padding-left: 28px !important;
  }
  .navbar-collapse .navbar-nav > li > a:hover::after{
    color: rgba(116, 185, 255, 0.85) !important;
    transform: translateX(3px) !important;
  }

  /* Page active : accent cyan border-left + texte brighter */
  .navbar-collapse .navbar-nav > li.active > a,
  .navbar-default .navbar-collapse .navbar-nav > li.active > a,
  .navbar-inverse .navbar-collapse .navbar-nav > li.active > a{
    color: #74aeff !important;
    background: rgba(61, 139, 255, 0.08) !important;
    font-weight: 600 !important;
  }
  .navbar-collapse .navbar-nav > li.active > a::before{
    content: '';
    position: absolute !important;
    left: 0 !important;
    top: 12px !important;
    bottom: 12px !important;
    width: 3px !important;
    background: linear-gradient(180deg, #3d8bff 0%, #74aeff 100%) !important;
    border-radius: 0 2px 2px 0 !important;
    box-shadow: 0 0 12px rgba(61, 139, 255, 0.6) !important;
  }
  /* Override la règle desktop ::after underline (sinon on a 2 marqueurs) */
  .navbar-default .navbar-collapse .navbar-nav > li.active > a::after,
  .navbar-inverse .navbar-collapse .navbar-nav > li.active > a::after{
    content: '›' !important;
    position: static !important;
    left: auto !important;
    right: auto !important;
    top: auto !important;
    bottom: auto !important;
    width: auto !important;
    height: auto !important;
    background: none !important;
    box-shadow: none !important;
    color: #74aeff !important;
    font-size: 22px !important;
    font-weight: 300 !important;
    line-height: 1 !important;
    border-radius: 0 !important;
  }

  /* Footer subtle en bas du menu */
  .navbar-collapse .navbar-nav::after{
    content: 'Capital Antifragile · 2026';
    display: block !important;
    text-align: center !important;
    padding: 32px 24px max(env(safe-area-inset-bottom, 20px), 20px) !important;
    font-family: 'JetBrains Mono', monospace !important;
    font-size: 9.5px !important;
    letter-spacing: 0.18em !important;
    color: rgba(116, 185, 255, 0.4) !important;
    text-transform: uppercase !important;
  }

  /* Quand menu ouvert : empêche scroll body derrière (mais Bootstrap collapse
     ne le fait pas tout seul). Approximation via overflow sur html. */
  body:has(.navbar-collapse.in){
    overflow: hidden !important;
  }

  /* Disable Bootstrap collapse height transition qui peut conflicter */
  .navbar-collapse.collapse,
  .navbar-collapse.collapsing{
    transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1) !important;
    height: 100vh !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   TUILE ADVISOR — "Ta Lecture du jour" (carte signal bento + modal)
   Local uniquement (window.__ADVISOR__ via advisor_cache.js, gitignoré).
   Pas de blur (iGPU Intel). Masquée si pas de données.
   ═══════════════════════════════════════════════════════════════════════ */
.ca-tile--advisor{
  border-color: rgba(61,139,255,0.34);
  background: linear-gradient(135deg, #0c1c3c 0%, #0a1530 60%, #0d1a35 100%);
  cursor: pointer;
}
.ca-tile--advisor:hover{ border-color: rgba(61,139,255,0.55); background: linear-gradient(135deg,#102449 0%,#0c1a38 100%); }
.ca-tile--advisor .ca-tile-num{ font-size: 14px; }

/* ── Variante bandeau fin pleine largeur (clic → modal rapport complet) ── */
.ca-tile--advisor-bar{
  grid-column: 1 / -1;
  display: flex; flex-direction: row; align-items: center; gap: 13px;
  padding: 0 18px; min-height: 0; height: 52px;
}
.ca-tile--advisor-bar .ca-tile-num{ display: inline-block !important; font-size: 15px; flex: 0 0 auto; }
.ca-adv-bar-name{ font-family: var(--mono); font-size: 11.5px; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg); white-space: nowrap; flex: 0 0 auto; }
.ca-adv-bar-sub{ font-family: 'Inter', sans-serif; font-size: 12.5px; color: var(--muted-2); flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ca-adv-bar-sub::before{ content: "·"; color: var(--muted); margin-right: 12px; }
.ca-tile--advisor-bar .ca-adv-updated{ font-family: var(--mono); font-size: 9px; letter-spacing: 0.12em; color: var(--muted-2); text-transform: uppercase; white-space: nowrap; flex: 0 0 auto; }
.ca-tile--advisor-bar .ca-tile-cta{ white-space: nowrap; flex: 0 0 auto; }
.ca-tile--advisor-bar .ca-adv-refresh--tile{ margin: 0 0 0 4px; font-size: 8.5px; padding: 3px 8px; flex: 0 0 auto; }
/* Garde-fou fraîcheur : rapport pas daté d'aujourd'hui → tuile en alerte rouge (couleurs pleines, pas de blur — Mac Intel). */
.ca-tile--advisor-bar.ca-adv-tile--stale{ border-color: #ff5b6e; background: linear-gradient(135deg,#3a1220 0%,#1a0d18 100%); }
.ca-tile--advisor-bar.ca-adv-tile--stale .ca-adv-updated{ color: #ff8a97; font-weight: 800; font-size: 9.5px; }
@media (max-width: 767px){
  .ca-tile--advisor-bar{ flex-wrap: wrap; gap: 8px 13px; }
  .ca-adv-bar-sub{ flex-basis: 100%; order: 5; white-space: normal; }
  .ca-adv-bar-sub::before{ content: none; }
}
.ca-tile-cta{ font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cyan); }

/* ══ LA CARTE DU RAPPORT PUBLIC — « Le marché ce matin » ═════════════════════════════════
   REFONTE 2026-08-13. Auparavant : un bandeau de 52 px calqué sur la tuile voisine, au motif
   que deux voisines qui ne se ressemblent pas coûtent une hésitation à chaque passage. Ce motif
   est tombé — sur la page que lisent les visiteurs, cette carte n'a plus de voisine : elle se
   contentait d'être une ligne de plus alors qu'elle est la SEULE chose que ce site publie
   chaque matin. Elle est maintenant une carte : un sceau, une origine annoncée, un titre, les
   sections réellement écrites ce matin, la longueur du texte, et une seule action.

   PALETTE : celle de Claude / Anthropic — terre cuite #d97757 et ses deux voisines. Elle ne
   dit pas « regarde-moi », elle dit UNE ORIGINE : cette page-là n'est pas écrite par la même
   main que le reste du site. C'est la seule zone orange de l'accueil, et elle doit le rester —
   le bleu est l'accent du site partout ailleurs ; si l'orange se répandait il ne signifierait
   plus rien.

   CONTRAINTE MACHINE (MacBook Intel, cf le blur retiré de la navbar et les rubans du hero) :
   aucun flou, aucun filtre, aucun reflet spéculaire. Les volumes se font en dégradés LINÉAIRES
   et en liserés ; le mouvement se limite à deux transformations (la rosace qui tourne, la
   flèche qui glisse) et à une opacité qui respire. */

/* Hors bento : la carte n'est dans aucune grille, mais elle garde les MARGES LATÉRALES des
   sections qui la suivent. Elle était auparavant à padding zéro, donc 44 px plus large que
   tout le reste de la page de chaque côté : une bande fine le supportait, une carte à coins
   arrondis non — elle débordait visiblement du bloc en dessous, et sur mobile elle touchait
   les deux bords de l'écran. Les valeurs suivent exactement celles de `.ca-section`.

   ⚠ `margin: 0` (jusqu'au 13/08/2026) ANNULAIT le `margin: 0 auto` de `.ca-section` : la
   bande gardait bien son `max-width: 1400px`, mais collée À GAUCHE. Au-delà de 1400 px de
   fenêtre, elle était donc décalée de toute la gouttière droite par rapport au bento centré
   juste en dessous — l'axe de la page cassait sur la seule chose publiée chaque matin.
   `auto` sur les côtés : la carte retrouve l'axe des sections. */
.ca-section--marche{ padding: 0 44px 22px; margin: 0 auto; }
@media (max-width: 1100px){ .ca-section--marche{ padding: 0 28px 20px; } }
@media (max-width: 767px){  .ca-section--marche{ padding: 0 16px 18px; } }
@media (max-width: 480px){  .ca-section--marche{ padding: 0 12px 16px; } }

.ca-rapport{
  --cl:         #d97757;   /* terre cuite Claude — accent principal        */
  --cl-clair:   #eda88f;   /* éclairci : texte d'accent sur fond sombre    */
  --cl-profond: #b8532f;   /* assombri : fin de dégradé, jamais du texte   */
  --cl-creme:   #f7ece5;   /* blanc chaud du titre (pas le blanc bleuté du site) */
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 26px;
  padding: 24px 28px 24px 30px;
  border: 1px solid rgba(217, 119, 87, 0.28);
  border-radius: 18px;
  /* Deux couches : un lavis chaud qui part du sceau et s'éteint avant le milieu, posé sur un
     navy réchauffé. Le fond ne devient jamais orange — il est TEINTÉ, ce qui suffit à ce que
     l'œil range la carte ailleurs que dans le reste du tableau de bord. */
  background:
    linear-gradient(112deg, rgba(217,119,87,0.125) 0%, rgba(217,119,87,0.045) 27%, rgba(217,119,87,0) 56%),
    linear-gradient(135deg, #17182f 0%, #101429 52%, #0c1124 100%);
  overflow: hidden;
  text-decoration: none;
  transition: border-color 0.28s var(--ease), transform 0.28s var(--ease);
}
/* Tranche de reliure : le seul aplat pleinement saturé de la carte. */
.ca-rapport::before{
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, var(--cl-clair) 0%, var(--cl) 45%, var(--cl-profond) 100%);
}
/* Filet supérieur : il s'allume au départ de la reliure et s'éteint au tiers. */
.ca-rapport::after{
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, rgba(217,119,87,0.70) 0%, rgba(217,119,87,0.16) 32%, rgba(217,119,87,0) 68%);
}
.ca-rapport:hover{
  border-color: rgba(217, 119, 87, 0.58);
  transform: translateY(-2px);
}

/* ── Le filigrane ────────────────────────────────────────────────────────────────────────
   La même rosace, en grand, débordant du bord droit et coupée par l'`overflow` de la carte.
   À 5,5 % elle ne se lit pas comme un logo : elle donne de la matière au vide à droite du
   texte. Elle NE TOURNE PAS — une surface de 330 px repeinte à chaque frame se paierait sur
   cette machine, et le mouvement est déjà porté par le sceau. */
.ca-rapport-filigrane{
  position: absolute; right: -62px; top: 50%;
  transform: translateY(-50%);
  color: var(--cl);
  opacity: 0.055;
  pointer-events: none;
  line-height: 0;
}

/* ── Le sceau ────────────────────────────────────────────────────────────────────────────
   Une plaque mate, pas une pastille vernie : dégradé linéaire, liseré fin, aucun reflet. */
.ca-rapport-sceau{
  position: relative;
  flex: 0 0 auto;
  width: 70px; height: 70px;
  /* Le sceau se pose EN HAUT, à hauteur du titre — centré dans une carte devenue haute, il
     flottait au milieu de rien. */
  align-self: start; margin-top: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(217, 119, 87, 0.32);
  border-radius: 19px;
  background: linear-gradient(150deg, rgba(217,119,87,0.22) 0%, rgba(217,119,87,0.07) 56%, rgba(217,119,87,0.02) 100%);
  color: var(--cl-clair);
  transition: border-color 0.28s var(--ease), color 0.28s var(--ease);
}
.ca-rapport:hover .ca-rapport-sceau{ border-color: rgba(217,119,87,0.62); color: #f3c0aa; }

/* ── Le corps ────────────────────────────────────────────────────────────────────────── */
.ca-rapport-corps{ display: block; min-width: 0; }
.ca-rapport-kicker{
  display: flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--cl-clair);
}
/* Le point ne respire que parce que le rapport est du jour — c'est un ÉTAT, pas un ornement.
   Périmé, il devient rouge et s'immobilise (règle posée plus bas sur .ca-marche--vieux). */
.ca-rapport-vif{
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--cl); flex: 0 0 auto;
  animation: ca-rapport-vif 2.9s ease-in-out infinite;
}
@keyframes ca-rapport-vif{ 0%,100%{ opacity: 1; } 50%{ opacity: 0.3; } }

.ca-rapport-titre{
  display: block;
  font-family: var(--serif-display); font-weight: 700;
  font-size: 27px; line-height: 1.16; letter-spacing: -0.005em;
  color: var(--cl-creme);
  margin: 9px 0 7px;
}
.ca-rapport-sub{
  display: block;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 13.5px; line-height: 1.5; font-weight: 400;
  color: #9aa6bd;
  max-width: 68ch;
}
/* ── Le chapô du jour ────────────────────────────────────────────────────────────────────
   Les deux phrases d'ambiance qui ouvrent le rapport, citées VERBATIM depuis `chapo` de
   rapport_marche_meta.js. C'est le seul endroit de l'accueil où le visiteur lit la couleur du
   jour sans cliquer — et c'est du texte repris tel quel, jamais résumé ici : cette carte n'a
   pas le droit d'écrire une phrase que le rapport n'a pas écrite.
   Champ absent (fichier meta d'avant le 13/08/2026) → l'élément reste vide et ne prend aucune
   place : `:empty` retire la marge et le liseré. */
.ca-rapport-chapo{
  margin: 13px 0 0;
  padding-left: 13px;
  border-left: 2px solid rgba(217, 119, 87, 0.34);
  font-family: var(--serif-body);
  font-size: 14.5px; line-height: 1.52; font-style: italic;
  color: #c3cde0;
  max-width: 88ch;
  /* Trois lignes au plus : la carte annonce, elle ne publie pas. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.ca-rapport-chapo:empty{ display: none; }

/* ── Ce que le rapport contient CE MATIN ─────────────────────────────────────────────────
   Les puces sont écrites par accueil.js à partir des titres réellement présents dans le
   rapport publié (`sections` de rapport_marche_meta.js). Aucune liste en dur : le jour où
   une section manque, la carte cesse de la promettre — et si le fichier est absent, il n'y a
   PAS de puces plutôt que six puces fausses. */
.ca-rapport-chips{ display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.ca-rapport-chip{
  font-family: var(--mono); font-size: 9px; font-weight: 500;
  letter-spacing: 0.11em; text-transform: uppercase;
  color: rgba(237, 168, 143, 0.92);
  border: 1px solid rgba(217, 119, 87, 0.22);
  background: rgba(217, 119, 87, 0.06);
  border-radius: 999px;
  padding: 5px 11px;
  white-space: nowrap;
}

/* ── La colonne d'action ─────────────────────────────────────────────────────────────── */
.ca-rapport-aside{
  position: relative;      /* au-dessus du filigrane */
  display: flex; flex-direction: column; align-items: flex-end; gap: 9px;
  flex: 0 0 auto; text-align: right;
}
.ca-rapport .ca-adv-updated{
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--cl-clair);
  border: 1px solid rgba(217, 119, 87, 0.26);
  border-radius: 999px;
  padding: 4px 11px;
  white-space: nowrap;
}
.ca-rapport-mesure{
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.07em;
  color: var(--muted); white-space: nowrap;
}
.ca-rapport-cta{
  display: inline-flex; align-items: center; gap: 9px;
  margin-top: 4px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.11em; text-transform: uppercase;
  color: #1c0e07;                      /* texte sombre SUR l'orange : c'est le seul aplat plein */
  background: linear-gradient(135deg, #e08a68 0%, var(--cl) 48%, var(--cl-profond) 100%);
  border-radius: 999px;
  padding: 11px 19px;
  white-space: nowrap;
  transition: background 0.28s var(--ease);
}
.ca-rapport:hover .ca-rapport-cta{
  background: linear-gradient(135deg, #f0a184 0%, #e08464 48%, #c25e37 100%);
}
.ca-rapport-fleche{ display: inline-block; transition: transform 0.28s var(--ease); }
.ca-rapport:hover .ca-rapport-fleche{ transform: translateX(4px); }

/* Rapport pas daté d'aujourd'hui : la carte le DIT, et cesse de faire semblant d'être vivante.
   Un rapport d'hier lu comme celui du matin est le défaut que tout ce site combat. */
.ca-rapport.ca-marche--vieux{ border-color: rgba(255, 91, 110, 0.45); }
.ca-rapport.ca-marche--vieux .ca-rapport-vif{ background: #ff5b6e; animation: none; }
.ca-rapport.ca-marche--vieux .ca-adv-updated{
  color: #ff8a97; border-color: rgba(255, 91, 110, 0.45); font-weight: 800;
}

/* ── Écrans étroits : la colonne d'action passe sous le texte, en ligne ─────────────── */
@media (max-width: 900px){
  .ca-rapport{
    grid-template-columns: auto minmax(0, 1fr);
    gap: 16px 18px;
    padding: 20px 20px 20px 22px;
  }
  .ca-rapport-titre{ font-size: 22px; }
  .ca-rapport-sceau{ width: 54px; height: 54px; border-radius: 16px; }
  .ca-rapport-sceau svg{ width: 28px; height: 28px; }
  .ca-rapport-aside{
    grid-column: 1 / -1;
    flex-direction: row; align-items: center; justify-content: flex-start;
    flex-wrap: wrap; gap: 10px 12px; text-align: left;
  }
  .ca-rapport-cta{ margin-top: 0; margin-left: auto; }
  .ca-rapport-filigrane{ display: none; }
}
@media (max-width: 560px){
  .ca-rapport-titre{ font-size: 19px; }
  .ca-rapport-sub{ font-size: 12.5px; }
  .ca-rapport-cta{ margin-left: 0; }
}

/* ── LE LOGO CLAUDE ──────────────────────────────────────────────────────────────────────
   LE TRACÉ EST L'OFFICIEL, pas une reconstitution : `logos_svg/claude.svg`, repris tel quel
   et posé une seule fois en <symbol> dans l'accueil (`#ca-claude-mark`), réutilisé par le
   sceau et par le filigrane. La version précédente était une rosace redessinée à la main —
   douze branches pointues et parfaitement régulières là où la vraie marque est une gerbe
   irrégulière, tracée à main levée. Ça se voyait immédiatement : un logo « presque » est un
   faux logo, et il datait la carte plus qu'il ne la signait.
   Toujours du SVG, jamais une vidéo : ~2,4 ko, net à toutes les tailles, une seule couleur
   qui suit celle du texte. Sur ce Mac : aucune ombre, aucun flou, aucun filtre.

   L'ANIMATION NE TOURNE PLUS. Une marque asymétrique et manuscrite mise en rotation continue
   ne lit pas comme « ça vit », elle lit comme un logo qui tourne — le défaut de la première
   version. Au repos : une RESPIRATION, 5 % d'échelle et 4° d'inclinaison sur sept secondes,
   assez pour qu'on la sente vivante, trop lente pour qu'on la regarde. Au survol seulement,
   une seule révolution franche : le mouvement devient une réponse, plus un tic de fond. */
.ca-claude{ display: block; }
/* Le porte-tracé : il ne doit peser ni un pixel ni une ligne dans le flux. */
.ca-claude-defs{ position: absolute; width: 0; height: 0; overflow: hidden; }
/* ⚠ `transform-origin: 50% 50%` NE VISE PAS le centre de la forme dans un SVG : par défaut le
   repère est la `view-box`, et le pourcentage se résout dans SES coordonnées. La marque
   pivotait donc autour d'un coin et sortait entièrement de son cadre : la géométrie était bien
   là, mesurable au pixel près, et il ne se peignait RIEN. `transform-box: fill-box` rebase le
   repère sur la forme elle-même, et « center » vise alors vraiment son centre. */
.ca-claude-g{ transform-box: fill-box; transform-origin: center;
  animation: ca-claude-souffle 7s ease-in-out infinite; }
@keyframes ca-claude-souffle{
  0%, 100%{ transform: scale(1) rotate(0deg); }
  50%     { transform: scale(1.055) rotate(4deg); }
}
@keyframes ca-claude-tour{ from{ transform: rotate(0deg); } to{ transform: rotate(360deg); } }
.ca-rapport:hover .ca-claude-g,
.nav-claude:hover .ca-claude-g{
  animation: ca-claude-tour 1.05s cubic-bezier(0.22, 0.72, 0.2, 1);
}

/* ══ LE SCEAU CLAUDE DANS LA BARRE DE NAVIGATION ═════════════════════════════════════════
   Posé par navbar_regroup.js à la fin de la barre, donc à DROITE de « Pensée Antifragile »,
   et sur l'accueil seulement. Il n'ajoute pas un onglet de plus : après le regroupement des
   liens en six menus, le rapport du matin n'avait plus aucune entrée dans la barre — le sceau
   lui rend sa porte. Le filet vertical qui le précède dit qu'il n'est pas de la même nature
   que les menus : ce n'est pas une rubrique du site, c'est une page écrite par quelqu'un
   d'autre, et son orange le signe. */
.navbar-nav > li.nav-claude-li{ position: relative; }
.navbar-nav > li.nav-claude-li > a.nav-claude,
.navbar-inverse .navbar-nav > li.nav-claude-li > a.nav-claude,
.navbar-default .navbar-nav > li.nav-claude-li > a.nav-claude{
  display: inline-flex !important; align-items: center; gap: 9px;
  padding: 19px 2px 19px 20px !important;
  color: #d97757 !important;
  transition: color 0.25s var(--ease) !important;
}
.navbar-nav > li.nav-claude-li > a.nav-claude:hover,
.navbar-inverse .navbar-nav > li.nav-claude-li > a.nav-claude:hover,
.navbar-default .navbar-nav > li.nav-claude-li > a.nav-claude:hover{ color: #f3a888 !important; }
/* Le filet de séparation. */
.navbar-nav > li.nav-claude-li::before{
  content: ''; position: absolute; left: 7px; top: 50%;
  transform: translateY(-50%);
  width: 1px; height: 17px;
  background: rgba(217, 119, 87, 0.32);
}
/* ⚠ La barre dessine un soulignement bleu au survol de TOUT lien non actif
   (`.navbar-nav > li:not(.active) > a::before`). Sur le sceau il tomberait sous la rosace,
   en bleu, et à contretemps de sa couleur. On le supprime explicitement. */
.navbar-nav > li.nav-claude-li > a.nav-claude::before{ content: none !important; }
.nav-claude-svg{ display: block; }
/* Le libellé n'existe que pour le menu mobile plein écran, où une icône seule ne se lit pas.
   (En pratique mobile_nav_enhance.js reconstruit la liste par fichier ; le libellé est là pour
   ne rien casser si cette couche ne s'applique pas.) */
.nav-claude-txt{ display: none; }
@media (max-width: 767px){
  .nav-claude-txt{
    display: inline; font-family: 'Inter', -apple-system, sans-serif;
    font-size: 13px; font-weight: 600; color: #eda88f;
  }
  .navbar-nav > li.nav-claude-li::before{ display: none; }
  .navbar-nav > li.nav-claude-li > a.nav-claude{ padding-left: 14px !important; }
}
/* L'étiquette au survol : une icône sans mot est une devinette. Elle n'apparaît qu'au survol,
   donc elle ne pèse rien sur la barre au repos.
   ⚠ SÉLECTEUR LONG, ET C'EST NÉCESSAIRE : `custom.css` pose déjà un `::after` sur TOUT lien de
   la barre (`.navbar-nav > li > a::after`, spécificité 0-1-2) — le soulignement bleu animé. Un
   simple `.nav-claude::after` (0-1-0) perd contre lui : le contenu de l'étiquette était bien
   posé, mais elle héritait `height: 2px`, `width: 0` et le dégradé bleu, et s'affichait comme
   une petite pastille bleue vide sous le logo. Les propriétés de ce soulignement sont donc
   toutes remises à zéro ici, une par une. */
.navbar-nav > li.nav-claude-li > a.nav-claude::after{
  content: attr(data-tip) !important;
  position: absolute;
  top: calc(100% - 8px); bottom: auto; left: auto; right: 0;
  width: auto; height: auto;
  font-family: var(--mono); font-size: 8.5px; font-weight: 500;
  letter-spacing: 0.13em; text-transform: uppercase; line-height: 1.2;
  color: #eda88f;
  background: #0c1124;
  border: 1px solid rgba(217, 119, 87, 0.34);
  border-radius: 999px;
  box-shadow: none;
  padding: 5px 11px;
  white-space: nowrap;
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease);
}
.navbar-nav > li.nav-claude-li > a.nav-claude:hover::after{
  width: auto; opacity: 1; transform: translateY(0);
}
@media (max-width: 767px){
  .navbar-nav > li.nav-claude-li > a.nav-claude::after{ display: none; }
}

/* Un lecteur qui a demandé moins de mouvement n'en reçoit aucun : le logo reste, figé. */
@media (prefers-reduced-motion: reduce){
  .ca-claude-g,
  .ca-rapport:hover .ca-claude-g,
  .nav-claude:hover .ca-claude-g{ animation: none; }
  .ca-rapport-vif{ animation: none; }
  .ca-rapport{ transition: none; }
  .ca-rapport-fleche{ transition: none; }
  .nav-claude::after{ transition: none; }
}

/* ── Modal plein écran ── */
.ca-adv-modal{ position: fixed; inset: 0; z-index: 9999; display: none; }
.ca-adv-modal.open{ display: block; }
.ca-adv-modal-bd{ position: absolute; inset: 0; background: rgba(3,7,17,0.82); }
.ca-adv-modal-panel{
  position: relative; max-width: 880px; margin: 4vh auto; max-height: 92vh; overflow-y: auto;
  background: var(--bg-elev); border: 1px solid rgba(61,139,255,0.30); border-radius: 16px;
  padding: 32px 38px 40px; box-shadow: 0 24px 80px rgba(0,0,0,0.6);
}
.ca-adv-modal-x{
  position: sticky; top: 0; float: right; margin: -10px -14px 0 0;
  background: none; border: none; color: var(--muted); font-size: 28px; line-height: 1; cursor: pointer;
}
.ca-adv-modal-x:hover{ color: var(--cyan); }
body.ca-adv-noscroll{ overflow: hidden; }

/* ── Rendu du rapport markdown dans le modal ── */
.ca-adv-modal-body{ color: var(--fg); font-family: 'Inter', sans-serif; font-size: 14px; line-height: 1.62; }
.ca-adv-modal-body h1{ font-size: 22px; font-weight: 800; color: #fff; margin: 0 0 6px; }
.ca-adv-modal-body h2{ font-size: 16px; font-weight: 700; color: var(--cyan-l); margin: 26px 0 10px; padding-bottom: 6px; border-bottom: 1px solid rgba(61,139,255,0.16); }
.ca-adv-modal-body h3{ font-size: 14px; font-weight: 700; color: var(--fg); margin: 18px 0 8px; }
.ca-adv-modal-body p{ margin: 8px 0; }
.ca-adv-modal-body strong{ color: var(--cyan-l); font-weight: 700; }
.ca-adv-modal-body code{ font-family: var(--mono); font-size: 12px; background: rgba(61,139,255,0.10); color: var(--cyan-l); padding: 1px 5px; border-radius: 4px; }
.ca-adv-modal-body a{ color: var(--cyan); }
.ca-adv-modal-body ul, .ca-adv-modal-body ol{ margin: 8px 0; padding-left: 22px; }
.ca-adv-modal-body li{ margin: 4px 0; }
.ca-adv-modal-body blockquote{ margin: 12px 0; padding: 10px 16px; border-left: 3px solid var(--cyan-d); background: rgba(61,139,255,0.06); color: var(--muted); font-size: 13px; border-radius: 0 8px 8px 0; }
.ca-adv-modal-body hr{ border: none; border-top: 1px solid rgba(108,221,255,0.12); margin: 22px 0; }
.ca-adv-modal-body table.adv-tbl{ width: 100%; border-collapse: collapse; margin: 14px 0; font-size: 12.5px; }
.ca-adv-modal-body .adv-tbl th{ text-align: left; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); padding: 8px 10px; border-bottom: 1px solid rgba(61,139,255,0.22); }
.ca-adv-modal-body .adv-tbl td{ padding: 8px 10px; border-bottom: 1px solid rgba(108,221,255,0.08); vertical-align: top; }
.ca-adv-modal-body .adv-tbl tr:hover td{ background: rgba(61,139,255,0.04); }
@media (max-width: 640px){ .ca-adv-modal-panel{ margin: 0; max-height: 100vh; border-radius: 0; padding: 24px 18px 32px; } }

/* ── Advisor modal V1.1 : hiérarchie + callouts cartes (pas de blur, iGPU Intel) ── */
.ca-adv-modal-body h1 + p{
  font-size: 15px; line-height: 1.55; color: #d6e6f7;
  background: rgba(61,139,255,0.08); border-left: 3px solid var(--cyan);
  padding: 13px 17px; border-radius: 0 10px 10px 0; margin: 6px 0 16px;
}
.ca-adv-modal-body h1 + p strong{ color: #ffffff; }
.ca-adv-modal-body h1 + p + p{ font-size: 11.5px; color: var(--muted); font-style: italic; margin-top: -8px; } /* ligne convention */
.ca-adv-modal-body h2{ display: flex; align-items: center; gap: 8px; font-size: 16.5px; margin-top: 30px; }
.ca-adv-modal-body blockquote{
  background: rgba(13,26,53,0.55); border-left: 3px solid var(--cyan-d);
  border-radius: 0 12px 12px 0; padding: 13px 18px; margin: 14px 0;
  color: #c0cfe2; font-size: 13.5px; line-height: 1.6;
}
.ca-adv-modal-body blockquote strong{ color: var(--cyan-l); }
.ca-adv-modal-body blockquote p{ margin: 4px 0; }
.ca-adv-modal-body .adv-tbl td:first-child{ font-weight: 600; color: #e6eefb; }
.ca-adv-modal-body .adv-tbl td strong{ color: #fff; }
/* scrollbar discrète */
.ca-adv-modal-panel::-webkit-scrollbar{ width: 10px; }
.ca-adv-modal-panel::-webkit-scrollbar-thumb{ background: rgba(61,139,255,0.25); border-radius: 6px; }

/* ════════════════════════════════════════════════════════════════════
   ADVISOR MODAL — MODE "TERMINAL PRO" (densité quant, monospace, Bloomberg-like)
   Surcharge le rendu note-de-recherche. Pas de blur (iGPU Intel).
   ════════════════════════════════════════════════════════════════════ */
.ca-adv-modal-panel{ max-width: 1060px; padding: 26px 30px 34px; background: #060d1c; border-color: rgba(61,139,255,0.28); }
.ca-adv-modal-body{ font-family: var(--mono); font-size: 12.5px; line-height: 1.5; color: #b7c6da; letter-spacing: 0.1px; }

/* Titre + bandeau "En bref" facon ligne de commande */
.ca-adv-modal-body h1{ font-family: var(--mono); font-size: 16px; font-weight: 700; color: #fff; letter-spacing: 0.5px; margin: 0 0 8px; }
.ca-adv-modal-body h1::before{ content: "▌ "; color: var(--cyan); }
.ca-adv-modal-body h1 + p{
  font-family: var(--mono); font-size: 12.5px; line-height: 1.55; color: #d4e6f6;
  background: linear-gradient(90deg, rgba(61,139,255,0.12), rgba(61,139,255,0.03));
  border: 1px solid rgba(61,139,255,0.22); border-left: 3px solid var(--cyan);
  padding: 11px 14px; border-radius: 4px; margin: 6px 0 14px;
}
.ca-adv-modal-body h1 + p strong{ color: #fff; }
.ca-adv-modal-body h1 + p + p{ font-size: 10.5px; color: var(--muted-2); font-style: normal; }

/* En-têtes de section facon ligne terminal */
.ca-adv-modal-body h2{
  font-family: var(--mono); font-size: 12.5px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  color: var(--cyan-l); margin: 22px 0 9px; padding: 4px 0 5px; border: none;
  border-top: 1px solid rgba(61,139,255,0.16); border-bottom: 1px solid rgba(61,139,255,0.16);
  display: block; background: rgba(61,139,255,0.04);
}
.ca-adv-modal-body h2::before{ content: "▓▓ "; color: var(--cyan-d); }
.ca-adv-modal-body h3{ font-family: var(--mono); font-size: 11.5px; color: var(--cyan); text-transform: uppercase; letter-spacing: 0.6px; margin: 14px 0 6px; }

/* Tables ultra-denses */
.ca-adv-modal-body table.adv-tbl{ font-family: var(--mono); font-size: 11.5px; margin: 9px 0; border: 1px solid rgba(61,139,255,0.14); }
.ca-adv-modal-body .adv-tbl th{ background: rgba(61,139,255,0.10); color: var(--cyan-l); font-size: 9px; letter-spacing: 0.8px; padding: 5px 9px; border-bottom: 1px solid rgba(61,139,255,0.25); }
.ca-adv-modal-body .adv-tbl td{ padding: 4px 9px; border-bottom: 1px solid rgba(108,221,255,0.06); white-space: nowrap; }
.ca-adv-modal-body .adv-tbl tr:nth-child(even) td{ background: rgba(255,255,255,0.012); }
.ca-adv-modal-body .adv-tbl tr:hover td{ background: rgba(61,139,255,0.06); }
.ca-adv-modal-body .adv-tbl td:first-child{ color: #eaf2fc; font-weight: 700; }
.ca-adv-modal-body .adv-tbl td strong{ color: #fff; }

/* Callouts (Ce qui a changé / Scénarios) facon bloc terminal */
.ca-adv-modal-body blockquote{
  font-family: var(--mono); font-size: 11.8px; line-height: 1.55; color: #aebfd4;
  background: rgba(10,18,36,0.7); border: 1px solid rgba(61,139,255,0.12); border-left: 3px solid var(--cyan-d);
  border-radius: 4px; padding: 11px 15px; margin: 11px 0;
}
/* facettes aérées de la Synthèse intégrée : 1 <p> par facette, séparées par une ligne ">" vide */
.ca-adv-modal-body blockquote p{ margin: 0 0 9px; }
.ca-adv-modal-body blockquote p:last-child{ margin: 0; }
.ca-adv-modal-body blockquote strong{ color: var(--cyan-l); }
.ca-adv-modal-body strong{ color: #e8f1fc; }
.ca-adv-modal-body code{ background: rgba(61,139,255,0.12); color: var(--cyan-l); font-size: 11px; }
.ca-adv-modal-body hr{ border-top: 1px dashed rgba(108,221,255,0.14); margin: 16px 0; }
.ca-adv-modal-body ul, .ca-adv-modal-body ol{ font-size: 12px; }

/* ════ Advisor modal : PLEIN ÉCRAN au clic sur la widget ════ */
.ca-adv-modal.open{ display: block; }
.ca-adv-modal-panel{
  max-width: 100% !important; width: 100% !important; height: 100vh !important; max-height: 100vh !important;
  margin: 0 !important; border-radius: 0 !important; border: none !important; box-shadow: none !important;
  /* contenu centré ≤1280px sur grand écran, marge mini 32px sur petit */
  padding: 30px max(32px, calc((100vw - 1280px) / 2)) 56px !important;
  background: #060d1c;
}
.ca-adv-modal-x{
  position: fixed !important; top: 16px; right: 24px; z-index: 5; float: none !important; margin: 0 !important;
  width: 34px; height: 34px; border-radius: 8px; background: rgba(61,139,255,0.10);
  border: 1px solid rgba(61,139,255,0.25); color: var(--cyan); font-size: 22px; line-height: 30px;
}
.ca-adv-modal-x:hover{ background: rgba(61,139,255,0.22); color: #fff; }
@media (max-width: 640px){ .ca-adv-modal-panel{ padding: 24px 16px 40px !important; } }

/* Encadré "🎯 Décision du jour" / "🎯 LE PLAN" — doit sauter aux yeux */
.ca-adv-modal-body blockquote.adv-decision{
  background: linear-gradient(135deg, rgba(61,139,255,0.18), rgba(46,213,115,0.07));
  border: 1px solid rgba(61,139,255,0.5); border-left: 4px solid var(--cyan);
  border-radius: 8px; padding: 15px 20px; margin: 12px 0 18px;
  font-size: 13.5px; line-height: 1.65; color: #e8f4ff;
}
.ca-adv-modal-body blockquote.adv-decision strong{ color: #fff; }

/* ════ Bandeau VISUEL en tête du modal advisor (donut, jauge, BTC/zone, chips) ════ */
.ca-adv-modal-body .adv-viz{ margin: 2px 0 24px; }
.adv-chips{ display: grid; grid-template-columns: repeat(auto-fit, minmax(118px,1fr)); gap: 8px; margin-bottom: 14px; }
.adv-chip{ background: rgba(13,26,53,0.7); border: 1px solid rgba(61,139,255,0.16); border-radius: 7px; padding: 8px 11px; display: flex; flex-direction: column; gap: 3px; }
.adv-chip .k{ font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.12em; color: var(--muted); text-transform: uppercase; }
.adv-chip .v{ font-family: var(--mono); font-size: 15px; font-weight: 700; color: #eaf2fc; }
.adv-chip.ok .v{ color: #2ed573; } .adv-chip.bad .v{ color: #ff6b81; } .adv-chip.mid .v{ color: var(--cyan-l); }
.adv-chip.ok{ border-color: rgba(46,213,115,0.3); } .adv-chip.bad{ border-color: rgba(255,107,129,0.3); }
.adv-vrow{ display: grid; grid-template-columns: 250px 1fr; gap: 14px; }
.adv-vbox{ background: rgba(8,16,32,0.6); border: 1px solid rgba(61,139,255,0.14); border-radius: 9px; padding: 12px 14px; }
.adv-vtit{ font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.14em; color: var(--muted); text-transform: uppercase; margin-bottom: 8px; }
.adv-donwrap{ display: flex; justify-content: center; }
.adv-don{ width: 124px; height: 124px; }
.adv-legs{ display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 10px; }
.adv-leg{ font-family: var(--mono); font-size: 9.5px; color: #aebfd4; display: inline-flex; align-items: center; gap: 4px; }
.adv-leg i{ width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.adv-zonebar{ position: relative; height: 28px; border-radius: 6px; margin: 18px 0 7px; background: linear-gradient(90deg,#1a2a4a,#11203f); border: 1px solid rgba(108,221,255,0.1); }
.adv-zoneband{ position: absolute; top: 0; bottom: 0; background: rgba(46,213,115,0.22); border: 1px solid rgba(46,213,115,0.5); border-radius: 4px; }
.adv-btcmark{ position: absolute; top: -4px; bottom: -4px; width: 3px; background: #ffb454; box-shadow: 0 0 8px #ffb454; border-radius: 2px; }
.adv-zonelbl{ display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9.5px; color: var(--muted); }
.adv-zonelbl .in{ color: #2ed573; font-weight: 700; }
@media (max-width: 680px){ .adv-vrow{ grid-template-columns: 1fr; } }

/* Jauge cycle (arc) + sparklines */
.adv-vrow3{ display: grid; grid-template-columns: 230px 152px 1fr; gap: 12px; margin-bottom: 12px; }
.adv-gauge{ width: 100%; height: auto; }
.adv-spk{ width: 100px; height: 24px; }
.adv-spkrow{ display: flex; align-items: center; gap: 10px; padding: 3px 0; }
.adv-spkrow .l{ font-family: var(--mono); font-size: 9.5px; color: var(--muted); width: 42px; text-transform: uppercase; }
.adv-spkrow .c{ font-family: var(--mono); font-size: 11px; font-weight: 700; color: #eaf2fc; margin-left: auto; }
@media (max-width: 760px){ .adv-vrow3{ grid-template-columns: 1fr; } }

/* Bouton « Actualiser » de l'advisor — V1 locale uniquement (tuile + modal) */
.ca-adv-refresh{ font-family: var(--mono, monospace); font-size: 10px; letter-spacing: .03em; color: var(--cyan-l, #6cddff);
  background: rgba(61,139,255,0.10); border: 1px solid rgba(61,139,255,0.35); border-radius: 6px;
  padding: 3px 9px; cursor: pointer; transition: background .15s, border-color .15s, opacity .15s; white-space: nowrap; }
.ca-adv-refresh:hover{ background: rgba(61,139,255,0.20); border-color: rgba(61,139,255,0.60); }
.ca-adv-refresh:disabled, .ca-adv-refresh.busy{ opacity: .65; cursor: progress; }
.ca-adv-refresh--tile{ margin-left: 8px; flex: 0 0 auto; }
.ca-adv-refresh--modal{ position: absolute; top: 14px; right: 54px; z-index: 6; }

/* Cartes d'opportunité Radar Value (#### → carte) — UX visuelle */
.ca-adv-modal-body .adv-vcard{ background: linear-gradient(135deg, rgba(13,26,53,0.65), rgba(8,16,32,0.5));
  border: 1px solid rgba(61,139,255,0.18); border-left: 3px solid var(--cyan,#3d8bff); border-radius: 9px;
  padding: 11px 15px; margin: 10px 0; }
.ca-adv-modal-body .adv-vcard-h{ font-family: var(--mono,monospace); font-size: 13.5px; font-weight: 700; color: #eaf4ff; margin-bottom: 7px; }
.ca-adv-modal-body .adv-vcard p{ margin: 4px 0; font-size: 12px; line-height: 1.55; color: #c9d6e8; }
.ca-adv-modal-body .adv-vcard strong{ color: #fff; }
.ca-adv-modal-body .adv-vcard .adv-tbl{ margin: 6px 0; font-size: 11px; }

/* Lien "Page complète" (Terminal) dans le modal advisor — V1 locale */
.ca-adv-fullpage{ position:absolute; top:14px; right:185px; z-index:6; text-decoration:none; }
.ca-adv-refresh--modal{ right:54px; }
@media(max-width:700px){ .ca-adv-fullpage{ position:static; display:inline-block; margin:8px; } }

/* ═══════════════════════════════════════════════════════════════════════════
   OÙ VA L'ARGENT ? — podium 13 classes d'actifs (tuile 20, rangée 2c)
   Barres divergentes autour de l'axe zéro, triées par perf sur la fenêtre
   choisie (seg 24H/7J/30J/YTD/1AN). Source moneyflow_cache.js (launchd 4h).
   100% statique — aucune animation/transition de barre (iGPU Intel).
   Couleurs = conventions site : var(--pos) entrées / var(--neg) sorties.
   ═══════════════════════════════════════════════════════════════════════════ */
.ca-tile--moneyflow{ cursor: pointer; }
.ca-tile--moneyflow .ca-mf-seg{ margin-left: auto; margin-right: 12px; }
.ca-mf-axislab{ display: flex; justify-content: space-between; margin: 5px 2px 3px;
  font-family: var(--mono); font-size: 8px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.ca-mf-axislab .out{ color: var(--neg); opacity: .75; }
.ca-mf-axislab .in{ color: var(--pos); opacity: .75; }
.ca-mf-rows{ display: flex; flex-direction: column; gap: 1px; }
/* 250px (et non 218) pour que la pastille « périmé Xh » / « repli » tienne à côté
   du sous-titre sans être rognée par l'overflow du nom. */
.ca-mf-row{ display: grid; grid-template-columns: 250px 1fr 70px; align-items: center; gap: 10px;
  padding: 1.5px 6px; border-radius: 6px; }
.ca-mf-row:hover{ background: rgba(70,140,240,0.06); }
.ca-mf-row.is-clickable{ cursor: pointer; }
.ca-mf-row.is-clickable:hover{ background: rgba(70,140,240,0.12); }
.ca-mf-row.is-clickable:hover .nm{ color: #6fb0ff; }
.ca-mf-row .nm{ display: flex; align-items: center; gap: 7px; font-size: 11.5px; font-weight: 600; color: var(--fg);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ca-mf-row .nm .ic{ width: 17px; height: 17px; flex: 0 0 17px; border-radius: 50%; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 1px rgba(148,163,184,0.20), 0 1px 2px rgba(0,0,0,0.35); }
.ca-mf-row .nm .ic svg{ width: 100%; height: 100%; display: block; }
.ca-mf-row .nm i{ font-style: normal; font-weight: 400; font-family: var(--mono); font-size: 9px; color: var(--muted); margin-left: 4px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; min-width: 0; }   /* le sous-titre cède la place à la pastille, jamais l'inverse */
.ca-mf-row .zone{ position: relative; height: 10px; }
.ca-mf-row .zone::before{ content:''; position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px;
  background: rgba(148,163,184,0.35); }
.ca-mf-row .bar{ position: absolute; top: 1px; bottom: 1px; border-radius: 2px; }
.ca-mf-row .bar.pos{ background: linear-gradient(90deg, rgba(40,224,126,0.30), rgba(40,224,126,0.95)); box-shadow: 0 0 6px rgba(40,224,126,0.22); }
.ca-mf-row .bar.neg{ background: linear-gradient(270deg, rgba(255,85,112,0.30), rgba(255,85,112,0.95)); box-shadow: 0 0 6px rgba(255,85,112,0.18); }
.ca-mf-row .pv{ font-family: var(--mono); font-size: 11px; font-weight: 700; text-align: right; }
.ca-mf-row .pv.up{ color: var(--pos); }
.ca-mf-row .pv.dn{ color: var(--neg); }
.ca-mf-row.is-na{ opacity: .45; }
/* Fiabilité par ligne : « périmé Xh » (source tombée, valeurs du run précédent) et
   « repli » (classe recalculée depuis la source de secours). Avant 2026-07-25 un
   simple ⚠ en ::after signalait le gel — invisible en pratique : btc & alts ont
   affiché des chiffres vieux de 24h sans que rien ne le montre. */
.ca-mf-row .mf-flag{ margin-left: 6px; flex: 0 0 auto; font-family: var(--mono); font-size: 8px;
  font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 1px 5px;
  border-radius: 100px; white-space: nowrap; }
.ca-mf-row .mf-flag.is-old{ color: #fbbf24; background: rgba(251,191,36,0.13); box-shadow: inset 0 0 0 1px rgba(251,191,36,0.35); }
.ca-mf-row .mf-flag.is-fb{ color: #93b7e0; background: rgba(147,183,224,0.12); box-shadow: inset 0 0 0 1px rgba(147,183,224,0.28); }
.ca-mf-row.is-stale .nm{ color: #cbb47a; }
.ca-mf-row.is-stale .pv{ opacity: .6; }
.ca-mf-verdict{ margin-top: 6px; padding: 2px 6px 0; font-size: 11.5px; color: #b9c8da; line-height: 1.4; }
.ca-mf-verdict b.up{ color: var(--pos); font-weight: 700; }
.ca-mf-verdict b.dn{ color: var(--neg); font-weight: 700; }
#mf-update.is-stale{ color: #fbbf24; }

/* ── Mode COURBE (toggle Barres/Courbe) ──────────────────────────────────── */
.ca-mf-modes{ display: inline-flex; gap: 1px; background: rgba(7,13,24,0.55); border: 1px solid rgba(148,163,184,0.15); border-radius: 100px; padding: 1px; margin-right: 8px; }
.ca-mf-modes button{ background: none; border: none; color: var(--muted); font-family: var(--mono); font-size: 8.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 4px 12px; border-radius: 100px; cursor: pointer; transition: background .15s, color .15s; }
.ca-mf-modes button:hover{ color: #cbd5e1; }
.ca-mf-modes button.is-on{ background: rgba(94,175,246,0.18); color: var(--accent); box-shadow: inset 0 0 0 1px rgba(94,175,246,0.35); }
.ca-stbb-seg button.is-disabled{ opacity: .3; cursor: default; }
.ca-stbb-seg button.is-disabled:hover{ color: var(--muted); }

.ca-mf-curve{ margin-top: 4px; }
.ca-mf-chart-wrap{ position: relative; padding: 6px 6px 0 40px; }
.ca-mf-svg{ width: 100%; height: 256px; display: block; overflow: visible; cursor: crosshair; }
.ca-mf-svg .mf-grid{ stroke: rgba(148,163,184,0.08); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ca-mf-svg .mf-grid0{ stroke: rgba(148,163,184,0.30); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ca-mf-svg .mf-line{ stroke-width: 2.4; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.ca-mf-svg .mf-hot{ stroke-width: 3.2 !important; }
.ca-mf-svg .mf-enddot{ stroke: #0a1120; stroke-width: 1.4; }
.ca-mf-svg .mf-crossline{ stroke: rgba(226,240,255,0.28); stroke-width: 1; vector-effect: non-scaling-stroke; stroke-dasharray: 3 3; }
.ca-mf-yaxis{ position: absolute; left: 0; top: 6px; width: 36px; height: 256px; pointer-events: none; }
.ca-mf-yaxis .ca-mf-yl{ position: absolute; right: 5px; transform: translateY(-50%); font-family: var(--mono); font-size: 9px; color: var(--muted); white-space: nowrap; }
.ca-mf-xaxis{ display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9px; color: var(--muted); padding: 3px 4px 0 0; }
/* Tooltip flottant qui suit le curseur */
.ca-mf-tip{ position: absolute; z-index: 6; min-width: 132px; max-width: 220px; padding: 7px 9px; border-radius: 9px;
  background: rgba(9,15,28,0.94); border: 1px solid rgba(148,163,184,0.22); box-shadow: 0 8px 22px rgba(0,0,0,0.45);
  pointer-events: none; opacity: 0; transition: opacity .1s; font-size: 11px; }
.ca-mf-tip.on{ opacity: 1; }
.ca-mf-tip .d{ font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em; color: #8fa3bd; text-transform: uppercase; margin-bottom: 5px; padding-bottom: 4px; border-bottom: 1px solid rgba(148,163,184,0.14); }
.ca-mf-tip .r{ display: flex; align-items: center; gap: 6px; padding: 1.5px 0; }
.ca-mf-tip .r .dot{ width: 7px; height: 7px; border-radius: 50%; flex: 0 0 7px; }
.ca-mf-tip .r .nm{ color: #d6e2f0; flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ca-mf-tip .r .v{ font-family: var(--mono); font-weight: 700; font-size: 10.5px; margin-left: 6px; }
.ca-mf-tip .r .v.up{ color: var(--pos); }
.ca-mf-tip .r .v.dn{ color: var(--neg); }
.ca-mf-hint{ position: absolute; top: 44%; left: 50%; transform: translate(-50%,-50%); font-family: var(--mono); font-size: 11px; color: var(--muted); pointer-events: none; }
.ca-mf-legend{ display: flex; flex-wrap: wrap; gap: 5px 6px; margin-top: 10px; }
.ca-mf-lg{ display: inline-flex; align-items: center; gap: 5px; background: rgba(7,13,24,0.5); border: 1px solid rgba(148,163,184,0.14); border-radius: 100px; padding: 3px 9px 3px 7px; cursor: pointer; font-size: 11px; color: #9fb0c6; transition: border-color .15s, color .15s, opacity .15s, background .15s; }
.ca-mf-lg:hover{ border-color: rgba(148,163,184,0.4); color: #e3ecf6; }
.ca-mf-lg .dot{ width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; background: var(--c); }
.ca-mf-lg b{ font-family: var(--mono); font-weight: 700; font-size: 10.5px; }
.ca-mf-lg b.up{ color: var(--pos); }
.ca-mf-lg b.dn{ color: var(--neg); }
.ca-mf-lg .proxy{ font-family: var(--mono); font-size: 9px; color: #8091a8; opacity: .9; }
.ca-mf-lg.is-on{ color: var(--fg); border-color: color-mix(in srgb, var(--c) 55%, transparent); background: color-mix(in srgb, var(--c) 12%, transparent); }
.ca-mf-lg:not(.is-on){ opacity: .48; }
.ca-mf-lg:not(.is-on) .dot{ opacity: .55; }
.ca-mf-help{ margin-top: 8px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .02em; color: rgba(148,163,184,0.6); }
.ca-mf-loading{ font-family: var(--mono); font-size: 11px; color: var(--muted); padding: 46px 4px; display: block; text-align: center; }

@media (max-width: 767px){
  .ca-mf-row{ grid-template-columns: 118px 1fr 56px; gap: 7px; }
  .ca-mf-row .nm{ font-size: 11px; }
  .ca-mf-row .nm i{ display: none; }
  /* Colonne nom réduite à 118px : la pastille passe en version compacte
     (« 25h » / « ≈ ») via data-short, sinon elle serait rognée. */
  .ca-mf-row .mf-flag{ font-size: 0; margin-left: 5px; padding: 1px 4px; }
  .ca-mf-row .mf-flag::after{ content: attr(data-short); font-size: 8px; letter-spacing: .04em; }
  .ca-mf-row .pv{ font-size: 10.5px; }
  .ca-tile--moneyflow .ca-tile-head{ flex-wrap: wrap; }
  .ca-tile--moneyflow .ca-mf-seg{ order: 5; width: 100%; margin: 6px 0 0; justify-content: space-between; }
  .ca-mf-modes{ order: 4; margin: 6px 8px 0 0; }
  .ca-mf-svg{ height: 210px; }
  .ca-mf-chart-wrap{ padding-left: 32px; }
  .ca-mf-yaxis{ width: 28px; height: 210px; }
  .ca-mf-legend{ gap: 4px 5px; }
  .ca-mf-lg{ font-size: 10px; padding: 2px 7px 2px 6px; }
  .ca-mf-tip{ font-size: 10px; min-width: 116px; }
  .ca-mf-help{ font-size: 9px; }
}

/* ════════════════════════════════════════════════════════════════════════
   TUILE 21 — TRÉSORERIES · VEILLE ACHATS  (MSTR / BMNR / PURR)
   Bandeau pleine largeur, 3 cartes égales : logo + dernier mouvement déclaré.
   Le "je veux être au courant" tient en 2 signaux : le badge NOUVEAU (tant que
   le mouvement n'a pas été vu, cf localStorage dans accueil.js) et le point de
   fraîcheur par société. Zéro backdrop-filter / blur animé (iGPU Intel).
   ════════════════════════════════════════════════════════════════════════ */
.ca-tile--tsy{ cursor: pointer; }
.ca-tile--tsy .ca-tile-head{ margin-bottom: 13px; }

/* Pastille d'état globale (dernier mouvement toutes sociétés confondues) */
.ca-tsy-status{ margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 9px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  color: var(--muted); border: 1px solid var(--hair-2); background: rgba(13, 26, 53, 0.6); }
.ca-tsy-status::before{ content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.75; flex: 0 0 auto; }
.ca-tsy-status[data-tone="buy"]{ color: #4ff0a0; border-color: rgba(40, 224, 126, 0.42); background: rgba(40, 224, 126, 0.10); }
.ca-tsy-status[data-tone="sell"]{ color: #ff8494; border-color: rgba(255, 85, 112, 0.42); background: rgba(255, 85, 112, 0.10); }
.ca-tsy-status[data-tone="recent"]{ color: var(--gold-l); border-color: var(--hair-3); background: rgba(61, 139, 255, 0.10); }

/* Badge NOUVEAU : seul élément animé de la tuile (dot 6px, pas de blur) */
.ca-tsy-new{ display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 9px; font-weight: 800;
  letter-spacing: 0.18em; text-transform: uppercase; padding: 3px 10px; border-radius: 999px; color: #061a0f;
  background: linear-gradient(135deg, #28e07e 0%, #4ff0a0 100%); box-shadow: 0 0 0 0 rgba(40, 224, 126, 0.55);
  animation: ca-tsy-ping 2.2s ease-out infinite; }
.ca-tsy-new[hidden]{ display: none; }
@keyframes ca-tsy-ping{
  0%   { box-shadow: 0 0 0 0 rgba(40, 224, 126, 0.50); }
  70%  { box-shadow: 0 0 0 9px rgba(40, 224, 126, 0); }
  100% { box-shadow: 0 0 0 0 rgba(40, 224, 126, 0); }
}
.ca-tsy-new.is-sell{ color: #2a0710; background: linear-gradient(135deg, #ff5570 0%, #ff8494 100%); box-shadow: 0 0 0 0 rgba(255, 85, 112, 0.55); animation-name: ca-tsy-ping-sell; }
@keyframes ca-tsy-ping-sell{
  0%   { box-shadow: 0 0 0 0 rgba(255, 85, 112, 0.50); }
  70%  { box-shadow: 0 0 0 9px rgba(255, 85, 112, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 85, 112, 0); }
}
.ca-tile--tsy.is-unseen{ border-color: rgba(40, 224, 126, 0.34); }
.ca-tile--tsy.is-unseen::before{ background: linear-gradient(90deg, transparent 0%, #28e07e 30%, #4ff0a0 50%, #28e07e 70%, transparent 100%); opacity: 0.9; }
.ca-tile--tsy.is-unseen-sell{ border-color: rgba(255, 85, 112, 0.34); }
.ca-tile--tsy.is-unseen-sell::before{ background: linear-gradient(90deg, transparent 0%, #ff5570 30%, #ff8494 50%, #ff5570 70%, transparent 100%); opacity: 0.9; }

/* Grille des 3 sociétés */
.ca-tsy-grid{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ca-tsy-card{ position: relative; display: flex; flex-direction: column; gap: 9px; padding: 13px 14px 11px;
  border: 1px solid var(--hair); border-radius: 11px; background: rgba(7, 16, 31, 0.55); transition: border-color 0.25s var(--ease), background 0.25s var(--ease); }
.ca-tile--tsy:hover .ca-tsy-card{ border-color: var(--hair-2); }
.ca-tsy-card.is-fresh{ border-color: rgba(40, 224, 126, 0.30); background: rgba(10, 32, 27, 0.42); }
.ca-tsy-card.is-sell{ border-color: rgba(255, 85, 112, 0.30); background: rgba(38, 12, 20, 0.46); }

.ca-tsy-head{ display: flex; align-items: center; gap: 9px; min-width: 0; }
.ca-tsy-logo{ width: 26px; height: 26px; border-radius: 7px; flex: 0 0 auto; object-fit: cover;
  background: #0a1530; border: 1px solid var(--hair-2); }
.ca-tsy-tk{ font-family: var(--mono); font-size: 12px; font-weight: 800; letter-spacing: 0.08em; color: var(--fg); flex: 0 0 auto; }
.ca-tsy-nm{ font-family: var(--mono); font-size: 9px; letter-spacing: 0.10em; text-transform: uppercase; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.ca-tsy-dot{ margin-left: auto; width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  background: var(--muted-2); }
.ca-tsy-card.is-fresh .ca-tsy-dot{ background: #28e07e; animation: ca-tsy-ping 2.2s ease-out infinite; }
.ca-tsy-card.is-sell .ca-tsy-dot{ background: var(--neg); animation: ca-tsy-ping-sell 2.2s ease-out infinite; }

/* Ligne héros : le mouvement. space-between → la quantité tient la colonne
   gauche et le montant $ s'aligne verticalement avec l'âge du pied de carte
   (colonne droite = "combien / quand"), sinon la carte paraît vide à droite. */
.ca-tsy-move{ display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ca-tsy-amt{ font-family: var(--mono); font-size: 21px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.05; color: var(--pos); }
.ca-tsy-amt.neg{ color: var(--neg); }
.ca-tsy-amt .u{ font-size: 12px; font-weight: 700; opacity: 0.72; margin-left: 3px; }
.ca-tsy-usd{ font-family: var(--mono); font-size: 12.5px; font-weight: 700; color: var(--fg-2); white-space: nowrap; }
.ca-tsy-usd .est{ font-size: 8.5px; font-weight: 700; letter-spacing: 0.10em; text-transform: uppercase; color: var(--muted-2); margin-left: 4px; }

/* Pied de carte : quand + trésor total */
.ca-tsy-meta{ display: flex; align-items: center; gap: 8px; padding-top: 8px; border-top: 1px solid var(--hair);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.04em; color: var(--muted); }
.ca-tsy-meta b{ color: var(--fg-2); font-weight: 700; }
.ca-tsy-age{ margin-left: auto; white-space: nowrap; color: var(--muted-2); }
.ca-tsy-card.is-fresh .ca-tsy-age{ color: #4ff0a0; }
.ca-tsy-empty{ font-family: var(--mono); font-size: 11px; color: var(--muted); padding: 26px 4px; text-align: center; grid-column: 1 / -1; }

@media (prefers-reduced-motion: reduce){
  .ca-tsy-new, .ca-tsy-card.is-fresh .ca-tsy-dot, .ca-tsy-card.is-sell .ca-tsy-dot{ animation: none; }
}
@media (max-width: 1023px){
  .ca-tsy-amt{ font-size: 18px; }
}
.ca-tsy-foot-long{ font-style: normal; }

@media (max-width: 767px){
  .ca-tsy-grid{ grid-template-columns: 1fr; gap: 8px; }
  /* Le pied passe en 2 lignes empilées : en 2 colonnes de 9,5px sur 390px,
     source et horodatage s'entrelaçaient et devenaient illisibles. */
  .ca-tile--tsy .ca-tile-foot{ flex-direction: column; align-items: flex-start; gap: 3px; }
  .ca-tile--tsy #tsy-upd{ margin-left: 0 !important; }
  .ca-tsy-foot-long{ display: none; }
  .ca-tile--tsy .ca-tile-head{ flex-wrap: wrap; row-gap: 7px; }
  .ca-tsy-status{ margin-left: 0; order: 5; }
  .ca-tsy-new{ order: 4; }
  .ca-tsy-card{ padding: 11px 12px 10px; }
  .ca-tsy-amt{ font-size: 19px; }
}
#tsy-upd.is-stale{ color: #fbbf24; font-weight: 700; }

/* ═══════════════════════════════════════════════════════════════════════
   STATUT D'OUVERTURE DES MARCHÉS (badge .ca-mkt) — 2026-07-28
   Portage du principe des chips .nar-mkt de TradFi_Tracker.Rmd sur les
   cartes ACTIONS de l'accueil (bulle actions, movers actions, Mode TradFi,
   Narratives TradFi). Les cartes crypto n'en ont pas : 24/7, le badge y
   serait du bruit.
   Rendu + horaires : accueil.js, IIFE caMarketHours (source unique).
   4 états : open / preopen / lunch / closed. Jours fériés NON gérés
   (même limite assumée que le tracker — cf. TradFi_Tracker.Rmd §Limites).
   ═══════════════════════════════════════════════════════════════════════ */
.ca-mkt{
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 10px;
  font-family: var(--mono); font-size: 8.5px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap;
  border: 1px solid var(--hair-2); background: rgba(70,140,240,0.04);
  color: var(--muted); cursor: help;
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
  flex: 0 0 auto;
}
/* Tant que accueil.js n'a pas peint (JS différé), le badge reste invisible :
   pas de pastille grise fantôme au premier paint. */
.ca-mkt:empty{ display: none; }
.ca-mkt .dot{
  width: 5px; height: 5px; border-radius: 50%; flex: 0 0 auto;
  background: var(--muted-2);
}
/* Dans .ca-map-head (justify-content:space-between), le badge doit rester
   collé au titre — sinon il part au centre entre le titre et les rangées
   d'onglets. */
.ca-mkt--map{ margin-right: auto; }

.ca-mkt.is-open{ color: #9df0c4; border-color: rgba(40,224,126,0.30); background: rgba(40,224,126,0.09); }
.ca-mkt.is-open .dot{ background: var(--pos); box-shadow: 0 0 6px rgba(40,224,126,0.75); animation: caMktPulse 2s ease-in-out infinite; }
.ca-mkt.is-preopen{ color: var(--gold-l); border-color: rgba(61,139,255,0.30); background: rgba(61,139,255,0.09); }
.ca-mkt.is-preopen .dot{ background: var(--gold); opacity: 0.8; }
.ca-mkt.is-lunch{ color: #f7cf8e; border-color: rgba(245,166,35,0.30); background: rgba(245,166,35,0.08); }
.ca-mkt.is-lunch .dot{ background: var(--orange); }
.ca-mkt.is-closed{ color: var(--muted); border-color: var(--hair-2); background: rgba(70,140,240,0.03); }
.ca-mkt.is-closed .dot{ background: var(--muted-2); }

@keyframes caMktPulse{
  0%, 100%{ box-shadow: 0 0 5px rgba(40,224,126,0.55); }
  50%     { box-shadow: 0 0 10px rgba(40,224,126,0.95); }
}
/* Accessibilité + iGPU Intel : pas d'animation si l'utilisateur la refuse. */
@media (prefers-reduced-motion: reduce){
  .ca-mkt.is-open .dot{ animation: none; }
}

@media (max-width: 767px){
  .ca-mkt{ font-size: 8px; padding: 2px 6px; letter-spacing: 0.08em; }
  .ca-mkt--map{ margin-right: 0; }
}

/* ═══ BANDEAU NOUVELLES COTATIONS (radar IPO, 2026-07-28) ══════════════════
   Point de sortie visible du radar fetch_new_listings.py. Né du fait que CXMT
   (688825.SS), devenue 1re capi chinoise le 27/07/2026, n'apparaissait nulle
   part sur le site : les pools d'actions étaient aveugles aux introductions.
   Sobre et STATIQUE côté fond (MacBook Intel : pas de blur, pas de filtre
   coûteux) ; seul le point du badge pulse, comme la tuile Trésoreries. */
.ca-newlist{ max-width: 1500px; margin: 0 auto 18px; padding: 0 26px; }
.ca-newlist[hidden]{ display: none; }
.ca-newlist-in{ display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: linear-gradient(120deg, rgba(61,139,255,0.14) 0%, rgba(13,26,53,0.92) 45%);
  border: 1px solid var(--hair-3); border-left: 3px solid var(--gold);
  border-radius: 12px; padding: 12px 16px; }
.ca-newlist-badge{ display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto;
  font-family: var(--mono); font-size: 9px; font-weight: 800; letter-spacing: 0.18em;
  text-transform: uppercase; padding: 4px 11px; border-radius: 999px; color: #041226;
  background: linear-gradient(135deg, var(--gold) 0%, var(--gold-l) 100%); }
.ca-newlist-badge::before{ content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: #041226; animation: ca-newlist-ping 2.4s ease-out infinite; }
@keyframes ca-newlist-ping{
  0%   { box-shadow: 0 0 0 0 rgba(4,18,38,0.55); }
  70%  { box-shadow: 0 0 0 7px rgba(4,18,38,0); }
  100% { box-shadow: 0 0 0 0 rgba(4,18,38,0); }
}
.ca-newlist-items{ display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
  list-style: none; margin: 0; padding: 0; flex: 1 1 auto; }
.ca-newlist-item{ display: flex; align-items: baseline; gap: 8px; }
.ca-newlist-name{ color: var(--fg); font-size: 13px; font-weight: 700; }
.ca-newlist-tick{ font-family: var(--mono); font-size: 10px; color: var(--muted); }
.ca-newlist-mc{ font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--gold-l); }
.ca-newlist-zone{ font-size: 10px; color: var(--muted); }
.ca-newlist-upd{ font-family: var(--mono); font-size: 9px; color: var(--muted-2);
  letter-spacing: 0.06em; margin-left: auto; }
.ca-newlist-close{ flex: 0 0 auto; background: none; border: 1px solid var(--hair-2);
  color: var(--muted); border-radius: 6px; width: 26px; height: 26px; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 0; }
.ca-newlist-close:hover{ color: var(--fg); border-color: var(--hair-strong); }

@media (prefers-reduced-motion: reduce){
  .ca-newlist-badge::before{ animation: none; }
}
@media (max-width: 767px){
  .ca-newlist{ padding: 0 14px; margin-bottom: 14px; }
  .ca-newlist-in{ gap: 10px; padding: 10px 12px; }
  .ca-newlist-items{ gap: 10px; width: 100%; }
  .ca-newlist-item{ width: 100%; flex-wrap: wrap; gap: 6px; }
  .ca-newlist-name{ font-size: 12px; }
  .ca-newlist-upd{ margin-left: 0; }
  .ca-newlist-close{ position: absolute; right: 18px; }
}
