﻿/* =========================================================================
   tokens.css - Variables globales (single source of truth)
   Toute valeur de couleur / typo / spacing / layout / effet doit passer
   par un token déclaré ici. Le mode sombre redéfinit uniquement les
   tokens de couleur via [data-theme="dark"].
   ========================================================================= */

/* Préchargement des fonts Google avant l'@import (latence DNS réduite) */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap');

:root {
    /* ------- Couleurs (Light Mode par défaut) ------- */
    --color-bg-body: #F8FAFC;
    --color-bg-surface: #FFFFFF;
    --color-border-subtle: #E2E8F0;
    --color-text-primary: #0F172A;
    --color-text-muted: #64748B;
    --color-text-on-accent: #FFFFFF; /* Texte sur fond d'accent saturé (boutons CTA sélectionnés) */
    --color-accent-primary: #059669;
    --color-accent-hover: #047857;
    --color-danger: #DC2626;
    --color-warning: #D97706;
    --color-success: #059669;
    /* ------- Couleurs sémantiques d'alerte ------- */
    --color-alert-bg-unavailable: #FFF7ED; /* Orange.Lighten5 (Tailwind orange-50)  */
    --color-alert-text-unavailable: #7C2D12; /* Orange.Darken4  (Tailwind orange-900) */
    /* ------- Couleurs sémantiques de section (B4) ------- */
    --color-section-ambition: #3B82F6; /* Blue 500 */
    --color-section-team: #F59E0B; /* Amber 500 */
    --color-section-offers: #8B5CF6; /* Violet 500 */
    --color-section-profiles: #F97316; /* Orange 500 - section "Nos profils" */
    --color-section-model: #EC4899; /* Pink 500 */
    --color-section-auto: #10B981; /* Emerald 500 */
    /* ------- Navigation : sidebar « Mon espace » + ancres scroll-spy (design §II) -------
       Surlignage de l'ancre/entrée active et texte des ancres inactives. */
    --color-nav-active: #2563EB; /* Blue 600 — ancre/entrée active */
    --color-nav-text-muted: #6B7280; /* Gray 500 — ancres secondaires inactives */
    --spacing-nav-indent: 24px; /* Indentation des sous-liens d'ancrage (layout invariant) */
    /* ------- Couleurs métier : profil journalier saisonnier (feature Analyse PDL) -------
       Une couleur par saison + bande Heures Creuses overlay. Surchargées en dark mode. */
    --color-season-spring: #22C55E; /* Emerald 500 */
    --color-season-summer: #F59E0B; /* Amber 500  */
    --color-season-autumn: #D97706; /* Amber 600  */
    --color-season-winter: #3B82F6; /* Blue 500   */
    --color-offpeak-band: rgba(99, 102, 241, 0.18);
    --color-offpeak-band-border: rgba(99, 102, 241, 0.40);
    /* ------- Couleurs métier : graphique tarifaire HP/HC (architecture §14.1.E) ------- */
    --color-tariff-hp: #F4C542; /* Heures Pleines : jaune ambre */
    --color-tariff-hc: #BDBDBD; /* Heures Creuses : gris neutre */
    /* ------- Couleurs métier : sous-section BaseLoadSummary (architecture §14.6) -------
       Donut "part du talon" + 3 bandes de l'échelle annuelle (logement optimisé /
       moyenne française / talon élevé). Lues côté JS via getComputedStyle (§2.33). */
    --color-base-load-donut-baseload: var(--color-accent-primary);
    --color-base-load-donut-others: #BDBDBD;
    --color-base-load-band-low: #9DD6AD;
    --color-base-load-band-mid: #EAC98D;
    --color-base-load-band-high: #D99188;
    /* ------- Tableau tarifaire : zebra-striping et ligne de focus (design.md §V.6, code-review F2) -------
       bg1 = teinte grise très claire (Colors.Grey.Lighten4 ≈ #F5F5F5), bg2 = surface blanche.
       La ligne "économie potentielle" (focus) garde un fond constant bg1. */
    --color-tariff-bg1: #F5F5F5;
    --color-tariff-bg2: var(--color-bg-surface);
    --color-tariff-focus: var(--color-tariff-bg1);
    /* ------- Axes et étiquettes de graphiques SVG (lus depuis JS via getComputedStyle).
       Centralisés ici pour éliminer tout littéral couleur côté JS (coding_rules §2.6). */
    --color-chart-axis: #9CA3AF; /* Gray 400 */
    --color-chart-label: #6B7280; /* Gray 500 */
    /* Étiquette de donnée portée par un élément de série (valeur au-dessus
       d'une barre, libellé de catégorie attaché à la série). Distinct de
       --color-chart-label (graduations d'axe) : contraste maximal requis. */
    --color-chart-data-label: var(--color-text-primary);
    /* Halo/contour de lisibilité des étiquettes de données posées sur un fond chart coloré
       (heatmap solaire §46) ; contour de contraste thème-dépendant (clair = blanc, sombre = fond
       sombre), distinct de la dérogation §2.56 (Plasma/iso/chemin). Lu côté JS via getComputedStyle
       (§2.32) et substitué au halo blanc littéral du texte « N ans » (coding_rules §2.66). */
    --color-chart-label-halo: #FFFFFF;
    /* ------- Scatter "Répartition de vos pics de puissance" (architecture §14.3.1, §11 F-MAXPWR-COLORS).
       Lus côté JS via getComputedStyle (coding_rules §2.32). Réutilisation de la palette sémantique
       existante pour cohérence inter-charts ; pas de duplication de teinte. */
    --color-chart-grid: var(--color-border-subtle); /* grille subtile alignée bordures cartes */
    --color-chart-threshold: var(--color-warning); /* ligne pointillée "Puissance souscrite" */
    --color-chart-point: var(--color-accent-primary); /* point standard, cohérent avec donut base-load */
    --color-chart-exceedance: var(--color-danger); /* point en dépassement, sémantique alerte */
    /* ------- Couleurs par phase du 2ᵉ scatter triphasé (P1/P2/P3, design §II.1/§IV.2, F2).
       Lus côté JS via getComputedStyle (coding_rules §2.32) et réutilisés par la légende HTML,
       les pastilles de la mini-comparaison et l'accent de l'encart de rééquilibrage. */
    --color-chart-phase-1: #2563EB; /* P1 — bleu */
    --color-chart-phase-2: #7C3AED; /* P2 — violet */
    --color-chart-phase-3: #D97706; /* P3 — ambre */
    /* ------- Simulation d'investissement solaire (F-SolarInvestmentAnalysis, design §II).
       Couleurs lues côté JS via getComputedStyle (coding_rules §2.32/§2.54). --color-savings
       et --radius-investment-card / --spacing-kpi-gap réutilisent des tokens équivalents
       existants plutôt que de dupliquer la valeur (§8.3 todo). */
    --color-solar-pv: #F59E0B; /* Jaune ambre — thématique panneaux / production */
    --color-battery-storage: #10B981; /* Vert émeraude — thématique batterie / stockage */
    --color-savings: var(--color-success); /* #059669 — économies (alias sémantique) */
    --color-grid-import: #EF4444; /* Rouge soft — électricité importée du réseau */
    --color-progress-bar: #3B82F6; /* Bleu primaire — remplissage barre de progression */
    /* Offres comparatives (Dual Offer Cards, design §II/UI-005). Teintes d'accent des 2 cards.
       HONNÊTETÉ SÉMANTIQUE §45.5 (renommage des slots blue→balanced / green→basic) : le NOM porte
       l'OFFRE (concept métier stable — Équilibre / Basique), la VALEUR porte la TEINTE (révisable
       sans toucher au nom). La dette §11 F-DUAL-COLOR-SlotNaming est ainsi RÉSORBÉE (plus aucune
       contradiction nom↔teinte). Le marqueur heatmap suit automatiquement via lecture tokenisée
       (§2.32/§2.63, 0 JS). */
    --color-offer-balanced: #047857; /* Vert forêt — offre Équilibre (PV + Batterie) */
    --color-offer-basic: #1D4ED8; /* Bleu royal — offre Basique (100% PV, sans batterie) */
    /* Couleurs des 4 KPI d'offre (design §II/UI-005) : une teinte par indicateur pour la lisibilité.
       PV/batterie/économies réutilisent les tokens thématiques existants (zéro duplication, §2.6) ;
       l'autoconsommation reprend le bleu primaire de la page (cohérent avec --color-section-ambition). */
    --color-kpi-pv: var(--color-solar-pv); /* Jaune ambre — puissance PV */
    --color-kpi-battery: var(--color-battery-storage); /* Vert émeraude — stockage batterie */
    --color-kpi-savings: var(--color-savings); /* Vert foncé — économies annuelles */
    --color-kpi-selfconsumption: #3B82F6; /* Bleu primaire — taux d'autoconsommation */
    /* Boutons CTA d'offre (design §II/UI-005, §V) : fond plein coloré thématique très visible
       (correction visibilité utilisateur). 3 états par offre (défaut / hover / active) + texte blanc.
       Renommage §45.5 (honnêteté sémantique) : le nom dit l'offre (Équilibre/Basique), la valeur la teinte. */
    --color-cta-balanced-bg: #047857; /* Vert forêt — fond CTA offre Équilibre (défaut) */
    --color-cta-balanced-hover: #065F46; /* Vert forêt sombre — survol */
    --color-cta-balanced-active: #022C22; /* Vert très sombre — clic/enfoncé */
    --color-cta-basic-bg: #1D4ED8; /* Bleu royal — fond CTA offre Basique (défaut) */
    --color-cta-basic-hover: #1E40AF; /* Bleu royal sombre — survol */
    --color-cta-basic-active: #172554; /* Bleu très sombre — clic/enfoncé */
    --color-cta-text: #FFFFFF; /* Blanc pur — texte CTA (contraste > 4.5:1 sur fonds saturés) */
    --spacing-kpi-gap: var(--spacing-xs); /* 8px — écart resserré entre les lignes KPI d'une offre (hauteur globale réduite, §41.12.3) */
    --spacing-kpi-icon-gap: var(--spacing-xs); /* 8px — écart horizontal entre le picto KPI et sa valeur */
    --spacing-offers-gap: var(--spacing-md); /* 24px — écart entre les 2 cards d'offre (desktop) */
    --spacing-offers-gap-mobile: var(--spacing-xs); /* 8px — écart resserré entre les 2 cards (mobile, 2 colonnes) */
    --padding-offer-card-mobile: var(--spacing-xs); /* 8px — rembourrage interne réduit des cards (mobile) */
    --font-size-kpi-val-mobile: 1.1rem; /* Taille de la valeur chiffrée des KPI (mobile) */
    --font-size-cta-mobile: 0.8rem; /* Taille du texte des boutons CTA (mobile) */
    --radius-investment-card: var(--radius-md); /* 12px — arrondi carte + barre de progression */
    /* Pictogrammes KPI d'offre (design §II/UI-005, §2.64) : SVG monochromes affichés via mask-image
       et colorisés par token (background-color = couleur du KPI). Taille unique à tous les breakpoints
       (ordre utilisateur 2026-06-11 : tailles « mobiles » conservées partout, breakpoint retiré). */
    --size-kpi-icon-mobile: 24px; /* Taille des pictos KPI (uniforme, tous breakpoints) */
    /* Heatmap d'investissement solaire (UI-006, §43/§42.3/§2.54/§2.65/§44.5) : hauteur fluide
       viewport-aware DOUBLEMENT BORNÉE par un plancher ET un plafond (§2.6bis). La hauteur du canvas
       est calculée par soustraction (analysis.css) : height = calc(--solar-viewport-h - --topbar-height -
       --solar-above-chart-h), de sorte que « tête de slider → 2 offres → heatmap » tienne dans la
       hauteur de fenêtre sans scroll interne au simulateur. --solar-viewport-h = visual viewport réel
       mesuré par JS (window.innerHeight) — référentiel fiable cross-device, contrairement à 100dvh qui
       sur-estimait de ~110px (chrome desktop, §42.3). --solar-above-chart-h = hauteur RÉELLE du bloc
       situé au-dessus de la heatmap (tête de slider + 2 offres, regroupés dans le wrapper
       .solar-investment__above-chart), MESURÉE par solar-investment.js via offsetHeight et posée sur
       :root au chargement + au resize (coding_rules §2.65). Réserve MESURÉE (robuste à toute évolution
       du slider/offres : une ligne ajoutée recalibre la hauteur automatiquement), jamais une constante
       calibrée « pour un écran » : l'ancien token --size-heatmap-reserve (valeur magique 390px) est
       SUPPRIMÉ (§43). DOUBLE BORNAGE de la hauteur calculée (§44.5) : --size-heatmap-min = plancher
       anti-aplatissement (axes lisibles), aligné sur les min-height de charts existants (250–320px) ;
       --size-heatmap-max = plafond de compacité (« pas trop haute »), qui empêche la heatmap d'occuper
       une hauteur démesurée sur grand écran (intention utilisateur « éviter qu'elle prenne trop de place »,
       §44.5). Quand la hauteur calculée descend sous le plancher (viewport bas), min-height reprend la
       main et la zone redevient scrollable (§42) ; quand elle dépasse le plafond (grand écran), max-height
       la plafonne. min (300) < max (500) ⇒ pas de conflit de bornes. TERME D'AJUSTEMENT (§44.6) : le
       calc soustrait un 4e terme de réglage --solar-heatmap-fit-adjust (réserve anti-troncature
       ajustable) pour absorber les marges/gaps externes que offsetHeight(wrapper) ne capte pas (marge
       basse de page, gap wrapper↔chart-wrap, margin collapsing — §42.3). Le calc complet devient donc :
       height = calc(--solar-viewport-h - --topbar-height - --solar-above-chart-h - --solar-heatmap-fit-adjust).
       Dimensions invariantes : pas de surcharge dark mode (cf. §1). */
    --size-heatmap-min: 300px; /* Plancher de hauteur de la heatmap (« pas trop plate ») */
    --size-heatmap-max: 500px; /* Plafond de hauteur de la heatmap (« pas trop haute ») */
    /* Réserve d'ajustement anti-troncature de la heatmap (§44.6), soustraite dans le calc de la
       hauteur ; AJUSTABLE pour absorber les marges/gaps externes non captés par offsetHeight du
       wrapper (marge basse de page, gap wrapper↔chart-wrap, margin collapsing — §42.3). Augmenter
       cette valeur jusqu'à ce que la troncature basse disparaisse. Valeur de réglage = 100px
       (ajustée par l'utilisateur §44.10 pour supprimer la troncature basse ; ajustable librement).
       Dimension invariante : pas de surcharge dark mode (§1). */
    --solar-heatmap-fit-adjust: 100px; /* Réserve anti-troncature heatmap, ajustable */
    /* Hauteur RÉELLE du bloc slider + 2 offres (§43/§2.65), MESURÉE par solar-investment.js depuis
       offsetHeight du wrapper .solar-investment__above-chart et posée sur :root au chargement + au
       resize. Repli `0px` neutre (avant la 1re mesure JS / si JS inactif : la heatmap occupe alors la
       quasi-totalité du viewport sous la topbar, dégradation gracieuse sans débordement) ; écrasé en px
       par le `setProperty` JS dès la 1re mesure. Dimension invariante : pas de surcharge dark mode (§1). */
    --solar-above-chart-h: 0px; /* Bloc slider + offres, mesuré JS (offsetHeight du wrapper) */
    /* Hauteur du visual viewport (§42.3) : mesurée par JS depuis window.innerHeight (zone de
       contenu réellement disponible) et posée sur :root au chargement + à chaque resize. Remplace
       100dvh qui sur-estimait le viewport de ~110px sur desktop (chrome navigateur — barres
       onglets/URL/signets — non soustrait par dvh). Repli `100dvh` neutre, écrasé en px par le
       `setProperty` JS dès la 1re mesure ; la sur-estimation §42.3 reste sans effet ici car ce
       repli n'est jamais la valeur finale affichée. Dimension invariante : pas de surcharge dark mode (§1). */
    --solar-viewport-h: 100dvh; /* Visual viewport réel (window.innerHeight), posé par solar-investment.js */
    /* ------- Layout : largeur maximale de la colonne unique du Talon (architecture §14.4.1, A7).
       S'applique quand BaseLoadReference est masquée (PDL PRO) pour préserver la lisibilité
       du tableau 2 colonnes + donut sans étirement excessif. Valeur de layout invariante
       (pas de surcharge dark mode — §1 du présent fichier). */
    --base-load-summary-col-left-max-width: 34rem;
    /* ------- Focus ring (a11y) ------- */
    --focus-ring-width: 2px;
    --focus-ring-offset: 2px;
    --focus-ring-color: var(--color-accent-primary);
    /* ------- Modale (architecture §15.6, design §II) -------
       Overlay assombrissant et ombre portée de la surface (élévation). */
    --color-backdrop-modal: rgba(0, 0, 0, 0.5);
    /* ------- États désactivés (design.md §II) -------
       Opacité réduisant la prédominance visuelle d'un élément interactif inactif. */
    --opacity-disabled: 0.5;
    /* ------- Typographie ------- */
    --font-title: 'Space Grotesk', system-ui, sans-serif;
    --font-body: 'Inter', system-ui, sans-serif;
    --text-h1: 2.5rem; /* 40px */
    --text-h2: 1.875rem; /* 30px */
    --text-h3: 1.25rem; /* 20px */
    --text-body: 0.9375rem; /* 15px */
    --text-caption: 0.875rem; /* 14px */
    --text-nav: 0.875rem; /* 14px */
    --line-height-body: 1.6;
    --line-height-title: 1.25;
    /* ------- Espacements ------- */
    --spacing-xs: 0.5rem; /*  8px */
    --spacing-sm: 1rem; /* 16px */
    --spacing-md: 1.5rem; /* 24px */
    --spacing-lg: 3rem; /* 48px */
    /* ------- Rayons ------- */
    --radius-sm: 6px;
    --radius-md: 12px;
    /* ------- Layout ------- */
    --topbar-height: 64px;
    --sidebar-width: 16rem; /* 256px */
    --content-max-width: 1280px;
    --wizard-max-width: 720px; /* Largeur narrow pour le wizard /interest */
    --auth-max-width: 480px; /* Largeur narrow pour le parcours d'authentification (login, login-sent, magic-link) */
    /* ------- Effets ------- */
    --shadow-card: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
    --shadow-md: 0 8px 24px -4px rgba(0, 0, 0, 0.10), 0 4px 8px -2px rgba(0, 0, 0, 0.06);
    --blur-topbar: blur(8px);
    --bg-topbar-rgba: rgba(255, 255, 255, 0.8);
    /* ------- Breakpoints (référence pour @media) ------- */
    --bp-mobile: 640px;
    --bp-tablet: 1024px;
    --bp-desktop: 1280px;
}

/* ------- Surcharge Dark Mode ------- */
[data-theme="dark"] :root,
:root[data-theme="dark"] {
    --color-bg-body:        #0F172A;
    --color-bg-surface:     #1E293B;
    --color-border-subtle:  #334155;
    --color-text-primary:   #F8FAFC;
    --color-text-muted:     #94A3B8;
    --color-text-on-accent: #0F172A;  /* Texte foncé sur fond d'accent clair (tons 400 dark) */
    --color-accent-primary: #10B981;
    --color-accent-hover:   #34D399;
    --color-danger:         #F87171;
    --color-warning:        #FBBF24;
    --color-success:        #34D399;

    /* Surcharges des couleurs de section pour contraste sur fond sombre.
       Versions légèrement plus claires (Tailwind 400) pour rester WCAG AA. */
    --color-section-ambition: #60A5FA;  /* Blue 400 */
    --color-section-team:    #FBBF24;  /* Amber 400 */
    --color-section-offers:  #A78BFA;  /* Violet 400 */
    --color-section-profiles:#FB923C;  /* Orange 400 - section "Nos profils" (dark) */
    --color-section-model:   #F472B6;  /* Pink 400 */
    --color-section-auto:    #34D399;  /* Emerald 400 */

    /* Navigation (dark) : tons 400 pour contraste WCAG AA sur fond slate.
       --spacing-nav-indent reste invariant (valeur de layout). */
    --color-nav-active:      #60A5FA;  /* Blue 400 */
    --color-nav-text-muted:  #94A3B8;  /* Slate 400 — aligné --color-text-muted dark */

    /* Saisons (dark) : tons 400 pour contraste WCAG AA sur fond sombre. */
    --color-season-spring:   #4ADE80;  /* Emerald 400 */
    --color-season-summer:   #FBBF24;  /* Amber 400   */
    --color-season-autumn:   #FB923C;  /* Orange 400  */
    --color-season-winter:   #60A5FA;  /* Blue 400    */
    --color-offpeak-band:        rgba(165, 180, 252, 0.18);
    --color-offpeak-band-border: rgba(165, 180, 252, 0.45);

    /* Tarifs HP/HC (dark) : versions claires pour contraste sur fond sombre. */
    --color-tariff-hp: #FCD34D;  /* Amber 300 */
    --color-tariff-hc: #D4D4D8;  /* Zinc 300  */

    /* BaseLoadSummary (dark, architecture §14.6) : donut + 3 bandes de l'échelle.
       Tons désaturés pour rester WCAG AA sur fond slate. */
    --color-base-load-donut-baseload: var(--color-accent-primary);
    --color-base-load-donut-others:   #64748B;
    --color-base-load-band-low:       #4D8C68;
    --color-base-load-band-mid:       #B08B4A;
    --color-base-load-band-high:      #A8554C;

    /* Zebra-striping et focus row du tableau tarifaire (dark) : tons slate adaptés. */
    --color-tariff-bg1:   #243248;  /* Slate intermédiaire (≈ Slate 700/800) */
    --color-tariff-bg2:   var(--color-bg-surface);
    --color-tariff-focus: var(--color-tariff-bg1);

    /* Axes et étiquettes de graphiques SVG (dark) : tons clairs pour contraste. */
    --color-chart-axis:  #64748B;  /* Slate 500 */
    --color-chart-label: #94A3B8;  /* Slate 400 */
    /* Étiquette de donnée (alias --color-text-primary dark pour contraste WCAG AA). */
    --color-chart-data-label: var(--color-text-primary);
    /* Halo d'étiquette (dark) : fond sombre sous le texte clair pour restaurer le contraste sur la
       rampe Plasma (§46/§2.66). En clair le halo est blanc ; ici il devient le fond du thème. */
    --color-chart-label-halo: var(--color-bg-body);

    /* Scatter MaxPower (dark, architecture §14.3.1) : surcharge via tokens sémantiques.
       Les 4 tokens sont alias de tokens couleurs déjà redéfinis ci-dessus ; aucune valeur
       hexa dupliquée nécessaire (la résolution se propage automatiquement). */
    --color-chart-grid:       var(--color-border-subtle);
    --color-chart-threshold:  var(--color-warning);
    --color-chart-point:      var(--color-accent-primary);
    --color-chart-exceedance: var(--color-danger);

    /* Couleurs par phase (dark, F2) : tons clairs pour contraste sur fond sombre. */
    --color-chart-phase-1: #60A5FA;  /* P1 — bleu 400 */
    --color-chart-phase-2: #A78BFA;  /* P2 — violet 400 */
    --color-chart-phase-3: #FBBF24;  /* P3 — ambre 400 */

    /* Simulation d'investissement solaire (dark, design §II) : tons 400 pour contraste
       WCAG AA sur fond slate. --color-savings reste alias de --color-success (déjà dark). */
    --color-solar-pv:        #FBBF24;  /* Amber 400 */
    --color-battery-storage: #34D399;  /* Emerald 400 */
    --color-grid-import:     #F87171;  /* Red 400 */
    --color-progress-bar:    #60A5FA;  /* Blue 400 */
    /* Offres comparatives (dark) : tons 400 pour contraste WCAG AA sur fond slate.
       Renommage §45.5 (honnêteté sémantique) : nom = offre (Équilibre/Basique), valeur = teinte. */
    --color-offer-balanced: #34D399;  /* Emerald 400 — offre Équilibre (PV + Batterie) */
    --color-offer-basic:    #60A5FA;  /* Blue 400 — offre Basique (100% PV) */
    /* KPI (dark) : pv/battery/savings sont alias de tokens déjà redéfinis (propagation auto).
       Seul l'autoconsommation (bleu primaire) reçoit un ton 400 pour contraste WCAG AA. */
    --color-kpi-selfconsumption: #60A5FA;  /* Blue 400 — taux d'autoconsommation (dark) */
    /* Boutons CTA (dark) : teintes saturées vives conservées (identité de marque), éclaircies
       pour rester lisibles avec texte blanc sur fond slate sombre. Renommage §45.5 (nom = offre). */
    --color-cta-balanced-bg:      #059669;  /* Emerald 600 — fond CTA offre Équilibre */
    --color-cta-balanced-hover:   #10B981;  /* Emerald 500 — survol (dark) */
    --color-cta-balanced-active:  #047857;  /* Emerald 700 — clic (dark) */
    --color-cta-basic-bg:     #2563EB;  /* Blue 600 — fond CTA offre Basique */
    --color-cta-basic-hover:  #3B82F6;  /* Blue 500 — survol (dark) */
    --color-cta-basic-active: #1D4ED8;  /* Blue 700 — clic (dark) */
    --color-cta-text:         #FFFFFF;  /* Blanc pur conservé : contraste > 4.5:1 sur les fonds saturés */

    --shadow-card:    0 0 0 1px rgba(255, 255, 255, 0.04);
    --shadow-md:      0 8px 24px -4px rgba(0, 0, 0, 0.45), 0 4px 8px -2px rgba(0, 0, 0, 0.35);
    --bg-topbar-rgba: rgba(15, 23, 42, 0.8);
}
