/*
 * Vitrine — layout de base. Consomme les TOKENS de thème (couleurs + polices générés
 * depuis l'app → identité fidèle, zéro dérive) ; la TYPOGRAPHIE est dimensionnée pour
 * une page marketing (clamp), pas aux tailles compactes de l'app.
 * Bi-thème : les --vars vivent sur .theme-commune / .theme-crepuscule (sur <html>).
 */

*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--color-surface-page);
  color: var(--color-text-primary);
  font-family: var(--font-family-body);
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}
body { margin: 0; min-height: 100vh; display: flex; flex-direction: column; }
main { flex: 1; }

a { color: var(--color-text-link); }
h1, h2, h3, .brand-mark { font-family: var(--font-family-title); font-weight: 600; line-height: 1.1; }

/* ── En-tête ─────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: var(--z-sticky);
  display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-4);
  padding: var(--spacing-3) clamp(var(--spacing-4), 5vw, var(--spacing-12));
  background: color-mix(in srgb, var(--color-surface-page) 88%, transparent);
  backdrop-filter: blur(var(--blur-strong));
  border-bottom: 1px solid var(--color-border-subtle);
}
.brand { display: flex; flex-direction: column; text-decoration: none; color: var(--color-text-primary); }
.brand-mark { font-size: 1.05rem; letter-spacing: 0.02em; }
.brand-sub { font-size: 0.7rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.14em; }
.site-nav { display: flex; align-items: center; } /* gap posé plus bas (règle .site-nav { gap: 0 }) */
.site-nav a:not(.btn) { color: var(--color-text-primary); text-decoration: none; font-size: 0.95rem; }
.site-nav a:not(.btn):hover { color: var(--color-text-accent); }

/* ── Boutons ─────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--spacing-2);
  padding: var(--spacing-3) var(--spacing-5); border-radius: var(--radius-lg);
  font-family: var(--font-family-title); font-size: 0.95rem; text-decoration: none;
  border: 1px solid transparent; cursor: pointer; min-height: 44px; transition: transform var(--duration-fast) var(--easing-ease-out);
}
.btn:hover { transform: translateY(-1px); }
.btn-sm { padding: var(--spacing-2) var(--spacing-4); min-height: 38px; font-size: 0.85rem; }
.btn-primary { background: var(--color-intent-primary); color: var(--color-text-inverted); box-shadow: var(--shadow-md); }
.btn-secondary { background: transparent; color: var(--color-text-primary); border-color: var(--color-border-strong); }

.theme-toggle {
  background: transparent; border: 1px solid var(--color-border-default); color: var(--color-text-primary);
  border-radius: var(--radius-full); width: 40px; height: 40px; cursor: pointer; font-size: 1rem;
}

/* ── Hero ────────────────────────────────────────────────── */
.hero { max-width: 1080px; margin: 0 auto; padding: clamp(var(--spacing-12), 8vw, var(--spacing-16)) clamp(var(--spacing-4), 5vw, var(--spacing-12)); display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(var(--spacing-8), 5vw, var(--spacing-16)); align-items: center; }
.hero-eyebrow { font-family: var(--font-family-title); text-transform: uppercase; letter-spacing: 0.18em; font-size: 0.78rem; color: var(--color-text-accent); margin: 0 0 var(--spacing-4); }
.hero h1 { font-size: clamp(2rem, 4.5vw, 3.4rem); margin: 0 0 var(--spacing-5); }
.hero p.lead { font-size: clamp(1rem, 1.4vw, 1.15rem); color: var(--color-text-muted); margin: 0 0 var(--spacing-6); max-width: 44ch; }
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--spacing-3); margin-bottom: var(--spacing-4); }
.hero-reassurance { font-size: 0.82rem; color: var(--color-text-muted); }

/* ── Carte-registre (exemple) ────────────────────────────── */
.registre {
  background: var(--color-surface-card); border: 1px solid var(--color-border-default);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-2xl); padding: var(--spacing-6);
  position: relative;
}
.registre-tag { position: absolute; top: var(--spacing-3); right: var(--spacing-3); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-text-muted); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-full); padding: 2px 10px; }
/* l'eyebrow long (« Ton mois type… TTC ») ne doit pas passer SOUS le badge « Exemple » (absolu, haut-droite) */
.explain .hero-eyebrow { padding-right: 4.5rem; }

/* Carte « explique-moi le calcul » (différenciateur) : montant → dérivation → source */
.explain-amount { display: flex; align-items: baseline; gap: var(--spacing-3); margin: var(--spacing-2) 0 var(--spacing-4); }
.explain-amount b { font-family: var(--font-family-number); font-weight: 600; font-size: 2.6rem; color: var(--color-text-accent); line-height: 1; }
.explain-hint { font-style: italic; color: var(--color-text-muted); font-size: 0.95rem; }
.explain-deriv .dl { display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-4); padding: var(--spacing-2) 0; border-bottom: 1px dashed rgb(var(--color-text-muted-rgb) / 0.3); }
.explain-deriv .dl span { color: var(--color-text-muted); font-size: 0.92rem; }
.explain-deriv .dl b { font-family: var(--font-family-number); font-weight: 600; font-size: 1.15rem; white-space: nowrap; }
.explain-deriv .dl.sub b { color: var(--color-text-muted); }
.explain-deriv .dl.total { border-bottom: none; }
.explain-deriv .dl.total span { color: var(--color-text-primary); font-family: var(--font-family-title); }
.explain-deriv .dl.total b { font-size: 1.5rem; color: var(--color-text-accent); }
.explain-source { display: inline-block; margin-top: var(--spacing-4); font-family: var(--font-family-mono); font-size: 0.75rem; letter-spacing: 0.06em; }

/* Saisie du TJM (la carte devient un mini-calcul vivant — retour PO) */
.explain-input { display: flex; align-items: center; gap: var(--spacing-3); margin: 0 0 var(--spacing-3); font-size: 0.9rem; color: var(--color-text-muted); }
.explain-input input { width: 6.5em; font-family: var(--font-family-number); font-size: 1.15rem; padding: var(--spacing-2) var(--spacing-3); border: 1px solid var(--color-border-default); border-radius: var(--radius-md); background: var(--color-surface-page); color: var(--color-text-primary); min-height: 44px; }
.explain-input input:focus-visible { outline: 2px solid var(--color-text-accent); outline-offset: 1px; }
.explain-deriv .dl.aside { border-bottom: none; }
.explain-deriv .dl.aside span, .explain-deriv .dl.aside b { font-size: 0.85rem; color: var(--color-text-muted); }
.x-inline { font-family: var(--font-family-number); }
@media (prefers-reduced-motion: no-preference) {
  .explain-amount b.pop { display: inline-block; animation: amount-pop 0.45s var(--easing-ease-out); }
}
@keyframes amount-pop { 0% { transform: scale(1); } 40% { transform: scale(1.07); } 100% { transform: scale(1); } }

/* Dépli « d'où sort ce chiffre ? » — SANS JS tout est OUVERT (crawlers/lecteurs servis) ;
   enhance.js pose html.js-explain + replie, le clic déroule ligne à ligne. */
.explain-toggle { display: block; width: 100%; background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left; }
.explain-chev { display: none; font-style: normal; }
html.js-explain .explain-toggle { cursor: pointer; }
html.js-explain .explain-chev { display: inline-block; margin-left: var(--spacing-1-5); color: var(--color-text-accent); }
html.js-explain .explain.is-open .explain-chev { transform: rotate(180deg); }
html.js-explain .explain-hint { text-decoration: underline dotted; text-underline-offset: 3px; }
html.js-explain .explain-more { display: grid; grid-template-rows: 0fr; }
html.js-explain .explain-clip { overflow: hidden; min-height: 0; }
html.js-explain .explain.is-open .explain-more { grid-template-rows: 1fr; }
html.js-explain .explain:not(.is-open) .explain-deriv .dl,
html.js-explain .explain:not(.is-open) .explain-source { opacity: 0; transform: translateY(-4px); }
@media (prefers-reduced-motion: no-preference) {
  html.js-explain .explain-more { transition: grid-template-rows var(--duration-slower) var(--easing-ease-out); }
  html.js-explain .explain-chev { transition: transform var(--duration-base) var(--easing-ease-out); }
  html.js-explain .explain-deriv .dl, html.js-explain .explain-source { transition: opacity var(--duration-slow) var(--easing-ease-out), transform var(--duration-slow) var(--easing-ease-out); }
  html.js-explain .explain.is-open .explain-deriv .dl:nth-child(1) { transition-delay: 60ms; }
  html.js-explain .explain.is-open .explain-deriv .dl:nth-child(2) { transition-delay: 120ms; }
  html.js-explain .explain.is-open .explain-deriv .dl:nth-child(3) { transition-delay: 180ms; }
  html.js-explain .explain.is-open .explain-deriv .dl:nth-child(4) { transition-delay: 240ms; }
  html.js-explain .explain.is-open .explain-deriv .dl:nth-child(5) { transition-delay: 300ms; }
  html.js-explain .explain.is-open .explain-deriv .dl:nth-child(6) { transition-delay: 360ms; }
  html.js-explain .explain.is-open .explain-source { transition-delay: 440ms; }
  /* invite : le montant fait une petite révérence tant que c'est plié */
  html.js-explain .explain:not(.is-open) .explain-amount { animation: hint-nudge 2.4s var(--easing-ease-in-out) infinite; }
}
@keyframes hint-nudge { 0%, 100% { transform: translateY(0); } 10% { transform: translateY(3px); } 20% { transform: translateY(0); } }

/* ── Pied ────────────────────────────────────────────────── */
.site-footer { border-top: 1px solid var(--color-border-subtle); padding: var(--spacing-8) clamp(var(--spacing-4), 5vw, var(--spacing-12)); color: var(--color-text-muted); font-size: 0.85rem; text-align: center; }
.site-footer .devise { font-family: var(--font-family-title); letter-spacing: 0.1em; color: var(--color-text-accent); }

.btn-lg { padding: var(--spacing-4) var(--spacing-8); font-size: 1.05rem; }

/* ── Bandes de section ───────────────────────────────────── */
/* padding VERTICAL sur .band ; padding HORIZONTAL sur .band-inner (→ marche aussi pour les pages
   contenu qui utilisent .band-inner sans .band parent : légal, règles, à-propos, simulateur). */
.band { padding-block: clamp(var(--spacing-12), 7vw, var(--spacing-16)); }
.band.alt { background: color-mix(in srgb, var(--color-surface-card) 55%, var(--color-surface-page)); border-block: 1px solid var(--color-border-subtle); }
.band-inner { max-width: 1080px; margin: 0 auto; padding-inline: clamp(var(--spacing-4), 5vw, var(--spacing-12)); }
.band-inner.narrow { max-width: 760px; }
.band-inner.center { text-align: center; }
.band h2 { font-size: clamp(1.6rem, 3vw, 2.4rem); margin: 0 0 var(--spacing-8); }
.center-lead { margin-left: auto; margin-right: auto; }
.center-cta { justify-content: center; }

/* (sections « preuve » et « étapes » supprimées — retour PO 2026-07-11 : redites) */
.proof-line { color: var(--color-text-muted); font-size: 0.95rem; } /* encore utilisé sous la FAQ */
.article p { color: var(--color-text-muted); margin: 0; }

/* ── Fonctionnalités : MOSAÏQUE de modules (audit mistral.ai « markitecture ») ──
   Chaque carte = <a> au fond de SA couleur + panneau .mos-in qui glisse/pivote
   à sa façon au survol (révèle la couleur) et mène à la section détaillée.
   Modules gris + losanges = déco de respiration, cachés en mobile. */
.mos-head { text-align: center; margin-bottom: var(--spacing-8); }
.mos-head h2 { margin: 0; }
.mos-glyphs { display: flex; justify-content: center; gap: var(--spacing-4); margin-bottom: var(--spacing-4); }
.mos-glyphs svg { width: 26px; height: 26px; }
.mos-glyphs .g1 { color: var(--color-intent-primary); }
.mos-glyphs .g2 { color: var(--color-intent-secondary); }
.mos-glyphs .g3 { color: var(--color-intent-success); }
.mosaic {
  position: relative; display: grid;
  grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(7, 1fr);
  aspect-ratio: 8 / 7; /* cellules carrées → on MIXE des carrés (2×2) ET des rectangles (retour PO) */
  /* Composition « markitecture » à la mistral : 3 étages, FORMES VARIÉES — flagship large (dash 4×3),
     tall (echea 2×3), wide (data 4×2) + carrés (frise/jours/multi/themes) — îlots DISSYMÉTRIQUES,
     ESPACES VIDES pour respirer + blocs-slots gris (g1/g2) = l'effet « la carte a coulissé de son slot ». */
  grid-template-areas:
    "frise  frise  dash   dash   dash   dash   echea  echea"
    "frise  frise  dash   dash   dash   dash   echea  echea"
    "g1     g1     dash   dash   dash   dash   echea  echea"
    "jours  jours  .      data   data   data   data   ."
    "jours  jours  .      data   data   data   data   ."
    "multi  multi  themes themes .      .      g2     g2"
    "multi  multi  themes themes .      .      g2     g2";
}
.m-dash { grid-area: dash; } .m-jours { grid-area: jours; }
.m-data { grid-area: data; }
.m-frise { grid-area: frise; } .m-echea { grid-area: echea; }
.m-multi { grid-area: multi; } .m-themes { grid-area: themes; }
.mos-deco { display: block; background: rgb(var(--color-text-muted-rgb) / 0.1); }
.mos-deco.d1 { grid-area: g1; } .mos-deco.d3 { grid-area: g2; }
.mos-diamond { position: absolute; width: clamp(36px, 4vw, 56px); aspect-ratio: 1; background: rgb(var(--color-text-muted-rgb) / 0.14); transform: rotate(45deg); }
.mos-diamond.dd1 { top: 40%; right: 3%; }
.mos-diamond.dd2 { bottom: 3%; left: 40%; }
.mos-card { display: block; position: relative; text-decoration: none; }
.mos-card.c-primary { background: var(--color-intent-primary); }
.mos-card.c-secondary { background: var(--color-intent-secondary); }
.mos-card.c-success { background: var(--color-intent-success); }
.mos-card.c-info { background: var(--color-intent-info); } /* 4e couleur DISTINCTE dans les 2 thèmes (jamais un slot texte en fond) */
.mos-in {
  display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start;
  height: 100%; padding: var(--spacing-4);
  background: var(--color-surface-card); border: 1px solid var(--color-border-default);
}
.mos-ic { width: 34px; height: 34px; display: grid; place-items: center; color: var(--color-text-inverted); }
.c-primary .mos-ic { background: var(--color-intent-primary); }
.c-secondary .mos-ic { background: var(--color-intent-secondary); }
.c-success .mos-ic { background: var(--color-intent-success); }
.c-info .mos-ic { background: var(--color-intent-info); }
.mos-ic svg { width: 20px; height: 20px; display: block; }
.mos-ic svg rect { transform-box: fill-box; transform-origin: 50% 100%; }
.mos-txt b { display: block; font-family: var(--font-family-title); font-size: 1.05rem; color: var(--color-text-primary); margin-bottom: var(--spacing-1); }
.mos-txt small { display: block; color: var(--color-text-muted); font-size: 0.85rem; line-height: 1.45; }
.mos-card:focus-visible { outline: 3px solid var(--color-text-accent); outline-offset: 2px; z-index: 2; }
/* Desktop : TOUT le bento à 80 % (−20 %, retour PO), centré. Les tuiles restent COLLÉES (elles remplissent
   leurs cellules) → le pattern d'origine est préservé ; les 20 % gagnés passent en marge AUTOUR du bloc,
   pas entre les cartes. width sur le conteneur (PAS transform) → n'interfère ni avec mos-land ni avec le
   survol. Mobile (2-col + gap) : inchangé (règle gatée ≥1080). */
@media (min-width: 1080px) {
  .mosaic { width: 80%; margin-inline: auto; }
}
/* Sous 1080px la mosaïque à modules manque de place (la référence la replie aussi sous lg) :
   grille simple 2 colonnes, grande carte (dash) pleine largeur.
   ⚠ Ce bloc DOIT rester APRÈS TOUTES les règles mosaïque de base (même spécificité →
   l'ordre source décide : sinon `grid-area:<nom>` desktop regagne sur `grid-area:auto` mobile). */
@media (max-width: 1079px) {
  .mosaic { aspect-ratio: auto; grid-template-columns: 1fr 1fr; grid-template-rows: none; grid-template-areas: none; grid-auto-rows: minmax(140px, auto); gap: var(--spacing-3); }
  .m-dash, .m-jours, .m-data, .m-frise, .m-echea, .m-multi, .m-themes { grid-area: auto; }
  .m-dash { grid-column: 1 / -1; } /* flagship pleine largeur */
  .mos-deco, .mos-diamond { display: none; } /* déco du bento hors-jeu en flux 2-col mobile */
}
/* Survol : chaque panneau bouge À SA FAÇON (desktop pointeur, motion ok) —
   même mécanique que la référence : le panneau révèle la couleur de l'ancre. */
@media (hover: hover) and (min-width: 1080px) and (prefers-reduced-motion: no-preference) {
  .mos-in { transition: transform var(--duration-slow) var(--easing-ease-out), box-shadow var(--duration-slow) var(--easing-ease-out); }
  .mos-card:hover { z-index: 2; }
  .hv-left:hover .mos-in, .hv-left:focus-visible .mos-in { transform: translateX(-40px); box-shadow: var(--shadow-xl); }
  .hv-right:hover .mos-in, .hv-right:focus-visible .mos-in { transform: translateX(40px); box-shadow: var(--shadow-xl); }
  .hv-up:hover .mos-in, .hv-up:focus-visible .mos-in { transform: translateY(-30px); box-shadow: var(--shadow-xl); }
  .hv-down:hover .mos-in, .hv-down:focus-visible .mos-in { transform: translateY(30px); box-shadow: var(--shadow-xl); }
  .hv-rotl .mos-in { transform-origin: bottom left; }
  .hv-rotl:hover .mos-in, .hv-rotl:focus-visible .mos-in { transform: rotate(-8deg); box-shadow: var(--shadow-xl); }
  /* micro-animation pixel PAR carte (steps() = mouvement pixel honnête) */
  .m-dash:hover .b1 { animation: mos-grow 0.5s steps(2) infinite alternate; }
  .m-dash:hover .b2 { animation: mos-grow 0.5s steps(2) 0.12s infinite alternate; }
  .m-dash:hover .b3 { animation: mos-grow 0.5s steps(2) 0.24s infinite alternate; }
  .m-jours:hover .cd { animation: mos-blink 0.7s steps(2) infinite; }
  .m-data:hover .mos-ic svg { animation: mos-bounce 0.6s steps(2) infinite alternate; }
  .m-frise:hover .fz1 { animation: mos-nudge 0.5s steps(2) infinite alternate; }
  .m-frise:hover .fz2 { animation: mos-nudge 0.5s steps(2) 0.12s infinite alternate; }
  .m-frise:hover .fz3 { animation: mos-nudge 0.5s steps(2) 0.24s infinite alternate; }
  .m-echea:hover .ec { animation: mos-drop 0.55s steps(3) infinite alternate; }
  .m-multi:hover .mp { animation: mos-blink 0.8s steps(2) infinite; }
  .m-themes:hover .th-r { animation: mos-blink 0.7s steps(2) infinite; }
}
@keyframes mos-drop { from { transform: translateY(-3px); } to { transform: translateY(0); } }
@keyframes mos-grow { from { transform: scaleY(0.55); } to { transform: scaleY(1); } }
@keyframes mos-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.25; } }
@keyframes mos-bounce { from { transform: translateY(0); } to { transform: translateY(-2px); } }
@keyframes mos-nudge { from { transform: translateX(0); } to { transform: translateX(3px); } }

/* ── Charte confidentialité ──────────────────────────────── */
/* Schéma « chez toi » dessiné (mini feuille ↔ mini app) — remplace les nœuds textuels */
/* flex-start + marge sur la flèche : les DEUX vignettes (tableur, dashboard — 132×92
   chacune) s'alignent bord à bord même si leurs légendes n'ont pas la même hauteur */
.flow-visual { display: flex; align-items: flex-start; justify-content: center; gap: clamp(var(--spacing-5), 5vw, var(--spacing-8)); margin: var(--spacing-6) 0 var(--spacing-8); }
.fv-node { margin: 0; display: flex; flex-direction: column; align-items: center; gap: var(--spacing-3); }
.fv-node figcaption { font-family: var(--font-family-title); font-size: 0.95rem; text-align: center; }
.fv-node figcaption small { display: block; margin-top: var(--spacing-1); font-family: var(--font-family-body); font-size: 0.78rem; color: var(--color-text-muted); }
.fv-sheet, .fv-app { width: 132px; height: 92px; border: 1px solid var(--color-border-strong); border-radius: var(--radius-md); background: var(--color-surface-card); box-shadow: var(--shadow-md); overflow: hidden; }
.fv-sheet { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: 18px repeat(2, 1fr); }
.fv-sheet i { border: 0.5px solid var(--color-border-subtle); }
.fv-sheet i.h { grid-column: 1 / -1; background: var(--color-intent-success); opacity: 0.55; border-bottom: 1px solid var(--color-border-default); }
.fv-app { display: flex; align-items: flex-end; gap: var(--spacing-1-5); padding: var(--spacing-3) var(--spacing-3) 0; }
.fv-app .b { flex: 1; height: var(--h); background: rgb(var(--color-intent-secondary-rgb) / 0.45); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.fv-app .b.acc { background: var(--color-intent-primary); }
.fv-arrow { margin-top: 32px; font-size: 1.6rem; color: var(--color-text-accent); font-weight: 700; }
.charte { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-5); }
.article { background: var(--color-surface-card); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-lg); padding: var(--spacing-5); }
.article h3 { margin: 0 0 var(--spacing-2); font-size: 1rem; color: var(--color-text-accent); display: flex; align-items: center; gap: var(--spacing-2-5); }
.art-ic { width: 22px; height: 22px; flex: none; } /* icône pixel de l'article (currentColor = accent du thème) */
.franchise { margin-top: var(--spacing-6); border: 1px dashed var(--color-border-strong); border-radius: var(--radius-lg); padding: var(--spacing-4) var(--spacing-5); color: var(--color-text-muted); font-size: 0.92rem; }

/* ── FAQ ─────────────────────────────────────────────────── */
.faq-item { border-bottom: 1px solid var(--color-border-subtle); padding: var(--spacing-4) 0; }
.faq-item summary { cursor: pointer; font-family: var(--font-family-title); font-size: 1.05rem; list-style-position: inside; }
.faq-item summary:hover { color: var(--color-text-accent); }
.faq-a { color: var(--color-text-muted); margin-top: var(--spacing-3); }
.faq-a a { color: var(--color-text-link); }

/* ── Pages contenu (légal, règles, à-propos) ─────────────── */
.legal, .reference, .apropos { padding-block: clamp(var(--spacing-10), 6vw, var(--spacing-16)); }
.legal h1, .reference h1, .apropos h1 { font-size: clamp(1.8rem, 3.5vw, 2.6rem); margin: var(--spacing-3) 0 var(--spacing-4); }
.legal-updated { color: var(--color-text-muted); font-size: 0.85rem; margin: 0 0 var(--spacing-6); }
.legal-sec { margin-top: var(--spacing-6); }
.legal-sec h2 { font-size: 1.15rem; margin: 0 0 var(--spacing-2); color: var(--color-text-accent); }
.legal-sec p { color: var(--color-text-muted); margin: 0 0 var(--spacing-2); }
.apropos-sec { margin-top: var(--spacing-8); }
.apropos-sec h2 { font-size: 1.3rem; margin: 0 0 var(--spacing-3); }
.apropos-sec p { color: var(--color-text-muted); margin: 0; }
.reference .lead { margin-bottom: var(--spacing-8); }
.ref-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--spacing-5); }
.ref-card { background: var(--color-surface-card); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-lg); padding: var(--spacing-5); }
.ref-v { font-family: var(--font-family-number); font-size: 2rem; color: var(--color-text-accent); line-height: 1.1; }
.ref-sep { color: var(--color-text-muted); }
.ref-card h2 { font-size: 1.05rem; margin: var(--spacing-2) 0; }
.ref-card p { color: var(--color-text-muted); margin: 0 0 var(--spacing-3); font-size: 0.92rem; }
.ref-card a { font-size: 0.85rem; }
.reference .franchise, .reference .hero-cta { margin-top: var(--spacing-8); }

/* ── Hero scroll « 4 zones / 3 axes » (handoff 2026-07-10) ─
   Scrubbing pur : les axes --bx/--gy/--py/--ry sont posés par hero-scroll.js.
   Teintes mosaïque = décor de façade (repli : tokens d'intent) → bi-thème auto.
   Fallback : sans `html.scrolly` (no-JS / reduced-motion) → layout statique. */
body { overflow-x: clip; } /* clip, PAS hidden : hidden casse position: sticky */

.hs-track { position: relative; height: 200vh; }
.hs-stage {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
  --bx: 55%; --gy: 60%; --py: 100%; --ry: 60%; --mx: 77.5%;
  --hs-line: rgb(var(--color-text-muted-rgb) / 0.16);
  --hs-t1: rgb(var(--decor-facade-brick, var(--color-intent-primary-rgb)));
  --hs-t2: rgb(var(--color-intent-primary-rgb));
  --hs-t3: rgb(var(--decor-facade-brick-deep, var(--color-text-accent-rgb)));
  --hs-t4: rgb(var(--color-text-accent-rgb));
  --hs-t5: rgb(var(--decor-facade-amber, var(--color-intent-secondary-rgb)));
  --hs-t6: rgb(var(--color-intent-secondary-rgb));
  background-image: linear-gradient(var(--hs-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--hs-line) 1px, transparent 1px);
  background-size: clamp(96px, 9.2vw, 150px) clamp(96px, 9.2vw, 150px);
}
.hs-zone { position: absolute; overflow: hidden; z-index: var(--z-raised); }
.hs-zA { left: 0; top: 0; width: var(--bx); height: var(--gy); }
.hs-zB { left: var(--bx); top: 0; right: 0; height: var(--ry); background: var(--color-surface-card-elevated); border-left: 1px solid var(--hs-line); }
.hs-zC { left: 0; top: var(--gy); width: var(--bx); bottom: calc(100% - var(--py)); border-right: 1px solid var(--hs-line); }
.hs-zD { left: var(--bx); top: var(--ry); right: 0; bottom: 0; }

/* Mosaïque FULL-BLEED (mesuré au devtools sur la référence : 0 → axe bleu, 60 % → bas). */
.hs-mosaic-shell { position: absolute; inset: 0; }
/* les tuiles de la mosaïque ont disparu : le libellé vit sur le fond de page */
.hs-label { position: absolute; font-family: var(--font-family-mono); font-size: 0.7rem; letter-spacing: 0.12em; color: var(--color-text-muted); white-space: nowrap; }
.hs-label.fl { left: var(--spacing-2); bottom: var(--spacing-2); }

/* ── Hero : l'app qui rétrécit, bureau → poche (GO PO 2026-07-11) ──
   Le cadre est un CONTENEUR (container queries) : le scrub JS ne fait que réduire
   sa largeur, l'intérieur se réorganise seul aux mêmes paliers que le vrai site.
   Métriques intérieures en cqw → tout l'intérieur suit l'échelle du cadre. */
.hs-tile { position: absolute; aspect-ratio: 1; opacity: 0.5; }
.hs-tile.t1 { width: 11%; right: 6%; top: 9%; background: var(--hs-t1); }
.hs-tile.t2 { width: 6.5%; left: 4%; bottom: 28%; background: var(--hs-t6); }
.hs-tile.t3 { width: 4.5%; right: 17%; bottom: 9%; background: var(--hs-t4); }
/* padding-bas : au repos (scrollY=0) la scène sticky est décalée de la hauteur du
   header (~70px) avant de s'épingler — même absorption que la carte « à la une » */
/* couvre tout le stage (le cadre est positionné par JS) : décoratif, laisse passer les clics */
.hs-devwrap { position: absolute; inset: 0; z-index: var(--z-raised); pointer-events: none; }
/* la boîte cadre+relevé : ses dimensions de LAYOUT pilotent les @container ; le
   translate(-50%,-50%) scale() (JS) la place et l'ajuste VISUELLEMENT, hors layout */
.hs-devbox { position: absolute; left: 34%; top: 72%; display: flex; flex-direction: column; align-items: center; gap: var(--spacing-2-5); will-change: transform; }
.hs-device {
  container-type: inline-size;
  width: 580px; height: 362px; /* écrasés à chaque frame par le scrub */
  background: var(--color-surface-page); border: 1px solid var(--color-border-strong);
  border-radius: 10px; box-shadow: var(--shadow-2xl); overflow: hidden;
  display: flex; flex-direction: column;
}
.hd-chrome { flex: none; display: flex; align-items: center; gap: 1.1cqw; padding: 1.2cqw 1.8cqw; border-bottom: 1px solid var(--color-border-default); min-height: 4.6cqw; }
.hd-chrome i { width: 1.3cqw; height: 1.3cqw; border-radius: var(--radius-full); background: rgb(var(--color-text-muted-rgb) / 0.35); }
.hd-url { margin-left: auto; font-family: var(--font-family-mono); font-size: max(1.5cqw, 7px); letter-spacing: 0.08em; color: var(--color-text-muted); }
.hd-speaker { display: none; width: 30%; height: 1.6cqw; border-radius: var(--radius-full); background: rgb(var(--color-text-muted-rgb) / 0.35); margin-inline: auto; }
.hd-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.hd-pager { display: none; flex: none; gap: 1.6cqw; padding: 1.6cqw 2.4cqw; border-bottom: 1px solid var(--color-border-subtle); }
.hd-pager i { flex: 1; height: 4.5cqw; border: 1px solid var(--color-border-default); border-radius: var(--radius-sm); }
.hd-pager i.on { background: rgb(var(--color-intent-primary-rgb) / 0.16); border-color: var(--color-intent-primary); }
.hd-app { flex: 1; min-height: 0; display: flex; }
/* sidebar de navigation gauche (18 % ≈ 256px mesurés — le volet filtres, lui, est un tiroir overlay) */
.hd-rail { flex: none; width: 18cqw; border-right: 1px solid var(--color-border-default); padding: 2cqw 1.6cqw; display: flex; flex-direction: column; gap: 1.6cqw; }
.hd-rail b { height: 4.4cqw; border: 1px solid var(--color-border-default); border-radius: var(--radius-full); }
.hd-rail b.on { background: rgb(var(--color-intent-primary-rgb) / 0.16); border-color: var(--color-intent-primary); }
.hd-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2cqw; padding: 2cqw; }
/* rangée de 4 KPI (bandeau mesuré : 4 cartes de 18,8 %) */
.hd-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.6cqw; }
.hd-kpis i { height: 8.5cqw; background: var(--color-surface-card); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm); }
.hd-kpis i.acc { border-top: 2px solid var(--color-intent-primary); }
/* graphe central (44 %) + side-panel héro (30 %) */
.hd-row { flex: 1; min-height: 0; display: flex; gap: 2cqw; }
.hd-chart { flex: 1.5; display: flex; align-items: flex-end; gap: 1.2cqw; border-bottom: 1px solid var(--color-border-default); }
.hd-chart i { flex: 1; height: var(--h); background: rgb(var(--color-intent-secondary-rgb) / 0.45); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.hd-chart i.acc { background: var(--color-intent-primary); }
.hd-side { flex: 1; border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm); padding: 2cqw; display: flex; flex-direction: column; align-items: center; gap: 2cqw; }
.hd-gauge { width: 100%; height: 2.2cqw; border: 1px solid var(--color-border-strong); border-radius: var(--radius-full); overflow: hidden; }
.hd-gauge i { display: block; width: 62%; height: 100%; background: var(--color-intent-success); }
.hd-donut { width: 38%; aspect-ratio: 1; border-radius: 50%; border: 2.4cqw solid rgb(var(--color-intent-secondary-rgb) / 0.45); border-top-color: var(--color-intent-primary); }
.hd-line { width: 100%; height: 1.8cqw; border-radius: var(--radius-full); background: rgb(var(--color-text-muted-rgb) / 0.18); }
.hd-line.s { width: 68%; }

/* ── Hero — dashboard « télémétrie » : MACHINE À ÉTATS « mécanisme à pièce », pilotée par /assets/dash-telemetry.js.
   Au BOOT et à chaque CLIC : le graphe se lance VITE (≈2×) puis DÉCÉLÈRE jusqu'à s'arrêter complètement à 10 s
   (oscillations de + en + espacées, timing linéaire → « on insère une pièce, le mécanisme s'emballe puis se fige »). 2 s
   APRÈS l'arrêt (à 12 s), le balayage lumineux revient en boucle → invite la pièce suivante (état dt-idle).
   Les animations du graphe sont FINIES (10 s, forwards) et FINISSENT AU REPOS (scaleY/scaleX 1, glow 0, cadran
   sur un tour entier) → l'arrêt est NET et SANS SAUT, et retirer la classe ne fait rien bouger (illusion parfaite).
   dt-active = le mécanisme tourne ; dt-idle = le balayage. Le JS relance le wind-down à chaque clic (reflow) et
   enchaîne le balayage 2 s après l'arrêt.
   Gaté prefers-reduced-motion ; sans classe d'état (no-JS / reduced-motion) → illustration STATIQUE (fail-open).
   Tokens de thème uniquement → 2 thèmes ; anime des enfants + un pseudo-élément → aucun conflit avec le scrub. */
@media (prefers-reduced-motion: no-preference) {
  /* Le mécanisme se LANCE VITE (oscillations SERRÉES) puis DÉCÉLÈRE (oscillations de + en + ESPACÉES)
     jusqu'à l'arrêt à 10 s. La décélération est portée par l'ESPACEMENT des keyframes (timing LINÉAIRE) →
     le mouvement reste PERCEPTIBLE sur toute la durée. (Une courbe ease-out concentrait tout le mouvement
     au début — ~5 s visibles puis rampe imperceptible → « pas 10 s » au chrono.) forwards + fin au repos
     → l'arrêt est net et retirer la classe ne fait rien bouger. */
  .hs-device.dash-telemetry.dt-active .hd-chart i { transform-origin: bottom; animation: dtBarWind 10s linear forwards; }
  .hs-device.dash-telemetry.dt-active .hd-gauge i { transform-origin: left; animation: dtGaugeWind 10s linear forwards; }
  .hs-device.dash-telemetry.dt-active .hd-donut { animation: dtSpinWind 10s linear forwards; }
  .hs-device.dash-telemetry.dt-active .hd-kpis i.acc { animation: dtGlowWind 10s linear forwards; }
  /* oscillations qui RALENTISSENT (gaps croissants) + s'AMORTISSENT, finissant AU REPOS à 100 % (= 10 s) */
  @keyframes dtBarWind {
    0% { transform: scaleY(1); } 5% { transform: scaleY(1.16); } 11% { transform: scaleY(0.88); }
    19% { transform: scaleY(1.12); } 29% { transform: scaleY(0.91); } 41% { transform: scaleY(1.08); }
    55% { transform: scaleY(0.94); } 71% { transform: scaleY(1.04); } 88% { transform: scaleY(0.98); }
    100% { transform: scaleY(1); }
  }
  @keyframes dtGaugeWind {
    0% { transform: scaleX(1); } 7% { transform: scaleX(1.06); } 17% { transform: scaleX(0.95); }
    30% { transform: scaleX(1.04); } 47% { transform: scaleX(0.97); } 68% { transform: scaleX(1.02); }
    100% { transform: scaleX(1); }
  }
  /* le cadran tourne 2 tours en RALENTISSANT (segments de + en + lents), se pose à 720° (= origine) à 10 s */
  @keyframes dtSpinWind {
    0% { transform: rotate(0); } 16% { transform: rotate(280deg); } 38% { transform: rotate(500deg); }
    66% { transform: rotate(650deg); } 100% { transform: rotate(720deg); }
  }
  @keyframes dtGlowWind {
    0% { box-shadow: 0 0 0 0 rgb(var(--color-intent-primary-rgb) / 0); }
    8% { box-shadow: 0 0 0 2px rgb(var(--color-intent-primary-rgb) / .20); }
    19% { box-shadow: 0 0 0 0 rgb(var(--color-intent-primary-rgb) / 0); }
    34% { box-shadow: 0 0 0 1.6px rgb(var(--color-intent-primary-rgb) / .14); }
    54% { box-shadow: 0 0 0 0 rgb(var(--color-intent-primary-rgb) / 0); }
    78% { box-shadow: 0 0 0 1px rgb(var(--color-intent-primary-rgb) / .08); }
    100% { box-shadow: 0 0 0 0 rgb(var(--color-intent-primary-rgb) / 0); }
  }

  /* ── VEILLE (dt-idle) : graphe à l'arrêt ; le balayage revient (2 s après l'arrêt, via le JS) et tourne en boucle ── */
  .hs-device.dash-telemetry .hd-main { position: relative; overflow: hidden; }
  .hs-device.dash-telemetry .hd-main::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(100deg, transparent 42%, rgb(var(--color-intent-secondary-rgb) / .12) 50%, transparent 58%);
    transform: translateX(-120%); /* hors-champ au repos : le balayage ne tourne QU'en veille (dt-idle) */
  }
  .hs-device.dash-telemetry.dt-idle .hd-main::after { animation: dtScan 4.5s ease-in-out infinite; }
  @keyframes dtScan { 0% { transform: translateX(-120%); } 55%,100% { transform: translateX(120%); } }
}
/* palier « petit écran » : MÊME layout, plus dense — FIDÈLE au vrai site, qui garde
   ses 4 KPI en rangée et sa sidebar fixe jusqu'au passage en scènes mobiles */
@container (max-width: 430px) {
  .hd-kpis { gap: 1.2cqw; }
  .hd-kpis i { height: 9.5cqw; }
  .hd-side { flex: 0.85; }
}
/* palier « poche » (le VRAI mobile : chrome téléphone, pager EN HAUT, scène graphe) */
@container (max-width: 270px) {
  .hd-chrome i, .hd-url { display: none; }
  .hd-speaker { display: block; }
  .hd-pager { display: flex; }
  .hd-rail { display: none; }
  .hd-kpis { grid-template-columns: repeat(2, 1fr); }
  .hd-kpis i { height: 14cqw; }
  .hd-row { flex-direction: column; }
  .hd-side { display: none; }
}
.hs-readout { font-family: var(--font-family-mono); font-style: normal; font-size: 0.7rem; letter-spacing: 0.12em; color: var(--color-text-muted); white-space: nowrap; }

.hs-headline {
  position: absolute; left: clamp(16px, 4vw, 56px); bottom: clamp(28px, 7vh, 90px); /* respire au-dessus de la mosaïque */
  width: max-content; margin: 0;
  font-family: var(--font-family-title); font-weight: 700; line-height: 0.98; letter-spacing: -0.012em;
  font-size: clamp(2.2rem, 7vw, 7.5rem); will-change: transform; /* échelle mesurée sur la référence (~7vw) */
}

.hs-layer { position: absolute; inset: 0; z-index: var(--z-dropdown); pointer-events: none; }
.hs-layer > * { pointer-events: auto; }
.hs-message { position: absolute; left: var(--mx); top: 48%; transform: translate(0, -50%); width: min(560px, 40vw); font-size: 1.7rem; text-align: left; will-change: transform, left, font-size, width; }
.hs-icons { display: flex; gap: 0.5em; justify-content: center; margin: 0 auto 0.55em; will-change: transform, opacity; opacity: 0; }
.hs-icons .ic { width: 1.15em; height: 1.15em; display: grid; grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(5, 1fr); gap: 1px; }
.hs-icons .ic b { border-radius: var(--radius-sm); }
.hs-statement { font-family: var(--font-family-title); font-weight: 600; line-height: 1.16; letter-spacing: -0.01em; font-size: 1em; margin: 0; }
.hs-statement .sline { display: block; width: fit-content; max-width: 100%; will-change: transform; }
.hs-statement .sline + .sline { margin-top: 0.08em; }
.hs-statement .sline.key { color: var(--color-text-accent); font-family: var(--font-family-number); font-style: italic; font-weight: 600; }

/* Remontée (retour PO) : la carte entière est lisible AU CHARGEMENT, sans effort.
   Au repos (scrollY=0) la scène est décalée de la hauteur du header sticky (~65-80px)
   avant de s'épingler → le bottom l'absorbe (6vh + 80px). */
.hs-news { position: absolute; left: 2vw; bottom: calc(6vh + 80px); width: min(360px, 30vw); }
.hs-news .kick { font-family: var(--font-family-mono); font-size: 0.65rem; letter-spacing: 0.18em; color: var(--color-text-muted); margin-bottom: var(--spacing-2-5); }
.hs-news-row { display: flex; gap: var(--spacing-2); align-items: stretch; }
/* Mécanique AUDITÉE sur la référence : viewport clippé + PISTE flex qui glisse
   (translateX de −100 % par pas, ~500 ms fort ease-out). Hauteur = carte la plus
   haute (flex row) → zéro saut. Sans JS : la 1re carte reste visible. */
.hs-news-viewport { overflow: hidden; flex: 1; }
.hs-news-track { display: flex; transition: transform var(--duration-slower) var(--easing-ease-out); will-change: transform; }
.hs-news .card { flex: 0 0 100%; display: flex; gap: var(--spacing-3); align-items: center; background: var(--color-surface-page); border: 1px solid var(--hs-line); border-radius: var(--radius-xl); padding: var(--spacing-2-5); text-decoration: none; }
.hs-news .thumb { width: 46px; height: 46px; flex: none; border-radius: var(--radius-lg); background: linear-gradient(135deg, var(--hs-t1), var(--hs-t3)); }
.hs-news .thumb.t2 { background: linear-gradient(135deg, var(--hs-t5), var(--hs-t6)); }
.hs-news .thumb.t3 { background: linear-gradient(135deg, var(--hs-t2), var(--hs-t4)); }
.hs-news .card b { font-family: var(--font-family-number); font-weight: 600; font-size: 1rem; color: var(--color-text-primary); }
.hs-news-nav { display: flex; flex-direction: column; gap: var(--spacing-1-5); justify-content: center; }
.hs-news-btn { width: 44px; flex: 1; min-height: 34px; display: grid; place-items: center; background: var(--color-surface-page); border: 1px solid var(--hs-line); border-radius: var(--radius-md); color: var(--color-text-primary); font-family: var(--font-family-mono); font-size: 1.1rem; cursor: pointer; transition: background var(--duration-base), color var(--duration-base); }
.hs-news-btn:hover { background: var(--color-text-primary); color: var(--color-surface-page); }

.hs-cue { position: absolute; right: 3vw; top: 3vh; font-family: var(--font-family-mono); font-size: 1.25rem; color: var(--color-text-muted); opacity: 0.6; line-height: 0.7; will-change: opacity; } /* à droite : ne chevauche plus « À LA UNE » sur viewport court */
.hs-cue span { display: block; }
.scrolly .hs-cue span { animation: hs-cue 1.6s var(--easing-ease-in-out) infinite; }
.scrolly .hs-cue span:nth-child(2) { animation-delay: 0.15s; }
.scrolly .hs-cue span:nth-child(3) { animation-delay: 0.3s; }
@keyframes hs-cue {
  0%, 100% { opacity: 0.25; transform: translateY(-2px); }
  50% { opacity: 1; transform: translateY(2px); }
}

/* Fallback statique (no-JS / prefers-reduced-motion) : contenu identique, lisible. */
html:not(.scrolly) .hs-track { height: auto; }
html:not(.scrolly) .hs-stage { position: static; height: auto; padding: clamp(40px, 7vh, 90px) clamp(16px, 4vw, 56px); overflow: visible; display: grid; grid-template-columns: 1.05fr 0.95fr; gap: var(--spacing-12); align-items: center; background-image: none; }
html:not(.scrolly) .hs-zone { position: static; overflow: visible; }
html:not(.scrolly) .hs-zB, html:not(.scrolly) .hs-zC, html:not(.scrolly) .hs-zD { display: none; }
html:not(.scrolly) .hs-layer { position: static; display: contents; }
html:not(.scrolly) .hs-headline { position: static; margin: 0; width: auto; }
html:not(.scrolly) .hs-message { position: static; transform: none; width: auto; }
html:not(.scrolly) .hs-icons { display: none; }
html:not(.scrolly) .hs-devwrap { display: none; } /* hors zones désormais → à masquer explicitement sans JS */

/* ── Enrichissements (audit mistral.ai 2026-07-10) ─────────
   Les états MASQUÉS n'existent que sous html.js-reveal / html.js-explain
   (posés par enhance.js) → no-JS et reduced-motion voient TOUT. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
section[id] { scroll-margin-top: 84px; } /* l'en-tête sticky ne recouvre pas la cible d'ancre */

/* Révélations : .rv = fondu+montée · .rv-fall = tombé-en-place (descend + rotation qui se pose) */
html.js-reveal .rv, html.js-reveal .rv-fall {
  opacity: 0;
  transition: opacity var(--duration-slower) var(--easing-ease-out), transform var(--duration-slower) var(--easing-ease-out);
  transition-delay: var(--rv-d, 0s);
}
html.js-reveal .rv { transform: translateY(14px); }
html.js-reveal .rv-fall { transform: translateY(-16px) rotate(var(--rv-rot, -2.5deg)); }
html.js-reveal .rv.rv-in, html.js-reveal .rv-fall.rv-in { opacity: 1; transform: none; }
/* Mosaïque : chaque carte tombe INDIVIDUELLEMENT et rebondit, ÉTAGE PAR ÉTAGE du BAS vers le HAUT
   (retour PO). Le délai --rv-d est recalculé par étage dans enhance.js (mesuré sur offsetTop, bas→haut) ;
   ici une keyframe dédiée `mos-land` (≠ `mos-drop` de l'illustration echea) donne la chute + le rebond :
   chute franche → dépasse la ligne d'arrivée (compression) → rebonds amortis. `both` : la carte reste au
   0% (cachée, en haut) pendant son délai, puis atterrit et se fige au 100%. transition:none avant pose →
   aucun fondu parasite au chargement (seule l'animation, déclenchée par .rv-in, révèle). */
html.js-reveal .mosaic .rv-fall:not(.rv-in) {
  transition: none;
  transform: translateY(-64px) rotate(var(--rv-rot, -3deg));
}
html.js-reveal .mosaic .rv-fall.rv-in {
  /* transition:none INDISPENSABLE : sans lui, la règle de base `.rv-fall` (transition opacity/transform +
     delay) redémarre au moment où .rv-in est posé ; les TRANSITIONS priment sur les ANIMATIONS dans la
     cascade → elles écraseraient mos-land et le rebond (overshoot +14, -8/+4/-2) ne s'afficherait pas.
     [revue adverse — 2 réfuteurs CONFIRMED] */
  transition: none;
  animation: mos-land calc(var(--duration-slower) + var(--duration-base)) var(--easing-ease-out) both;
  animation-delay: var(--rv-d, 0ms);
}
@keyframes mos-land {
  0%   { opacity: 0; transform: translateY(-64px) rotate(var(--rv-rot, 0deg)); }
  45%  { opacity: 1; transform: translateY(14px) rotate(0deg); }
  63%  { transform: translateY(-8px); }
  80%  { transform: translateY(4px); }
  92%  { transform: translateY(-2px); }
  100% { opacity: 1; transform: translateY(0) rotate(0deg); }
}
/* A11y (WCAG 2.4.7 Focus Visible) : une carte-lien focusée au clavier est TOUJOURS visible immédiatement —
   même si la cascade (déclenchée au scroll/centre) n'a pas encore atteint son étage (sinon on tabule sur un
   <a> opacity:0 sans focus visible). Placé APRÈS .rv-in (même spécificité → l'ordre source tranche) : coupe
   l'animation et force l'état posé. Complété par une révélation au focusin côté JS. [revue adverse] */
html.js-reveal .mosaic .rv-fall:focus-visible {
  opacity: 1;
  transform: none;
  animation: none;
}

/* Fondu d'entrée du hero au chargement (A10) */
.scrolly .hs-headline, .scrolly .hs-message { animation: hs-fadein var(--duration-slower) ease both; }
@keyframes hs-fadein { from { opacity: 0; } to { opacity: 1; } }

/* ── Hero — animation d'entrée du TITRE « Tes données, ton cockpit. » (handoff Claude Design 2026-07-13).
   N'affecte QUE le titre ; le scrub (hero-scroll.js) continue de piloter #hs-headline (parallaxe) → les
   transforms se composent. Contrôleur = /assets/title-intro.js (WAAPI) ; anti-FOUC = /assets/title-intro-head.js. */
/* zA cesse de clipper le titre et passe SOUS la fenêtre dashboard (.hs-devwrap = z-raised) → le titre plonge
   DERRIÈRE l'illustration puis remonte. (overflow:visible → surveiller un débordement si tout le scrub est réactivé.) */
.scrolly .hs-zA { overflow: visible; z-index: 0; }
/* remplace le fondu générique .scrolly .hs-headline{animation:hs-fadein} — l'intro WAAPI prend la main */
.scrolly .hs-headline { animation: none; }
/* les deux membres du titre = lignes-blocs animables indépendamment */
.hs-headline .hl-a, .hs-headline .hl-b { display: block; will-change: transform, opacity; }
/* le « é » = un « e » de base + le vrai « é » superposé, rogné pour ne montrer QUE l'accent aigu ; .ea imbriqué
   dans .eb pour que l'accent suive la lettre quand elle encaisse (réaction de masse). */
.hs-headline .ec { position: relative; display: inline-block; }
.hs-headline .eb { display: inline-block; position: relative; vertical-align: baseline; will-change: transform; }
.hs-headline .ea { position: absolute; inset: 0; clip-path: inset(-60% -12% 84% -12%); pointer-events: none; will-change: transform, opacity; }
/* anti-FOUC : état caché AVANT que le JS ne prenne la main (classe `title-intro` posée en <head>, home only) */
html.title-intro #hlA, html.title-intro #hlB, html.title-intro #accE { opacity: 0; }

/* Hovers réactifs — UNIQUEMENT sur des éléments cliquables (affordance honnête) */
.hs-news .card { transition: transform var(--duration-base) var(--easing-ease-out), box-shadow var(--duration-base) var(--easing-ease-out); }
.hs-news .card:hover { transform: translateY(-2px); box-shadow: var(--shadow-xl); }
.hs-news .card .thumb { transition: transform var(--duration-slow) var(--easing-spring); }
.hs-news .card:hover .thumb { transform: translateX(6px) rotate(6deg); }
.hs-icons .ic { transition: transform var(--duration-base) var(--easing-spring); }
.hs-icons .ic:hover { transform: rotate(10deg); } /* clin d'œil décoratif : pas de cursor pointer */
.btn-primary:hover { box-shadow: var(--shadow-lg); }
.ref-card { transition: transform var(--duration-base) var(--easing-ease-out), box-shadow var(--duration-base) var(--easing-ease-out); }
.ref-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); } /* la carte contient un lien source */

/* Rail d'ancres sticky (home, desktop) */
/* L'entrée est SCRUBBÉE par enhance.js (chaque icône monte du bas de l'écran,
   transform/opacity inline) ; .is-visible ne gate que la cliquabilité (posé). */
.anchor-rail { position: fixed; left: var(--spacing-4); top: 50%; transform: translateY(-50%); z-index: var(--z-sticky); display: none; flex-direction: column; gap: var(--spacing-2); pointer-events: none; }
.anchor-rail.is-visible { pointer-events: auto; }
.anchor-rail a { opacity: 0; will-change: transform, opacity; }
/* gate = js-rail (posé INCONDITIONNELLEMENT par enhance.js) : le rail existe aussi en
   reduced-motion — c'est alors enhance.js qui le pose direct à l'état final, sans scrub */
@media (min-width: 1080px) { html.js-rail .anchor-rail { display: flex; } }
.anchor-rail a { width: 44px; height: 44px; display: grid; place-items: center; border: 1px solid var(--color-border-default); background: var(--color-surface-card); border-radius: var(--radius-md); color: var(--color-text-muted); transition: background var(--duration-base), color var(--duration-base), border-color var(--duration-base); }
.anchor-rail a:hover { color: var(--color-text-primary); border-color: var(--color-border-strong); }
.anchor-rail a.is-active { background: var(--color-text-primary); color: var(--color-surface-page); border-color: var(--color-text-primary); }
.anchor-rail svg { width: 18px; height: 18px; display: block; }

/* ── Interactivité des maquettes-produit (enhance.js pose .is-live) ──
   Sans JS : illustrations statiques (rien ne dépend de ces règles). */
/* notif d'impact du calendrier */
/* Région live TOUJOURS rendue (jamais display:none : l'annonce AT exige que la région
   existe AVANT la mutation de texte). Invisible au repos = opacity 0 + pointer-events none. */
.cal-toast {
  position: absolute; top: 46px; right: var(--spacing-3); z-index: 2; max-width: 80%;
  background: var(--color-surface-card); border: 1px solid var(--color-border-default);
  border-left: 3px solid var(--color-intent-primary); border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg); padding: var(--spacing-2) var(--spacing-3);
  font-size: 0.82rem; color: var(--color-text-primary);
  opacity: 0; transform: translateY(-6px); pointer-events: none;
}
.cal-toast:empty { visibility: hidden; box-shadow: none; } /* pas de carcasse fantôme au repos */
.cal-toast.is-in { opacity: 1; transform: none; }
/* impact mis en avant : hausse = liseré succès, baisse = liseré accent + texte appuyé */
.cal-toast.pos { border-left-color: var(--color-intent-success); }
.cal-toast.neg { border-left-color: var(--color-intent-primary); font-weight: 600; }
/* le total du pied FLASHE à chaque changement pour attirer le regard (surtout quand ça baisse) */
.cal-foot em { transition: color var(--duration-base) var(--easing-ease-out); }
.cal-foot em.up { color: var(--color-intent-success); }
.cal-foot em.down { color: var(--color-text-accent); }
@media (prefers-reduced-motion: no-preference) {
  .cal-foot em.flash { animation: total-pop 0.55s var(--easing-ease-out); }
}
@keyframes total-pop { 0% { transform: scale(1); } 35% { transform: scale(1.14); } 100% { transform: scale(1); } }
.cal-grid i.hm { opacity: 0.35; } /* cases hors-mois (juin = 30 j) : mêmes atours que les week-ends, jamais interactives */
.cal-grid.is-live i:not(.we):not(.hm) { cursor: pointer; }
.cal-grid.is-live i:not(.we):not(.hm):hover { border-color: var(--color-intent-primary); }
/* zone tactile étendue des cases (~+6px ; ::before libre — ::after est pris par .on/.cur) */
.cal-grid.is-live i:not(.we):not(.hm)::before { content: ""; position: absolute; inset: -3px; }
.cal-grid i:focus-visible { outline: 2px solid var(--color-text-accent); outline-offset: 1px; }
/* volet filtres cliquable */
.filt-group { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-2); } /* transparent pour la mise en page du volet */
.filt.is-live .chip, .filt.is-live .filt-l { cursor: pointer; position: relative; }
/* cibles tactiles élargies à ≥ ~44px effectifs (chip ~25px + 2×10 ; ligne switch ~19px + 2×13) */
.filt.is-live .chip::after { content: ""; position: absolute; inset: -10px; }
.filt.is-live .filt-l::after { content: ""; position: absolute; inset: -13px 0; }
.filt.is-live .chip:hover { border-color: var(--color-intent-primary); }
.filt.is-live .chip:focus-visible, .filt.is-live .filt-l:focus-visible { outline: 2px solid var(--color-text-accent); outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) {
  .cal-toast { transition: opacity var(--duration-base) var(--easing-ease-out), transform var(--duration-base) var(--easing-ease-out); }
  .cal-grid.is-live i.cur { animation: cal-invite 1.6s var(--easing-ease-in-out) infinite; }
  .ch-bars i { transition: height var(--duration-slow) var(--easing-ease-out); }
  .fv-app .b { transition: height var(--duration-slow) var(--easing-ease-out); }
}
@keyframes cal-invite {
  0%, 100% { box-shadow: 0 0 0 2px rgb(var(--color-intent-primary-rgb) / 0.35); }
  50% { box-shadow: 0 0 0 6px rgb(var(--color-intent-primary-rgb) / 0.12); }
}

/* Nav header : cases séparées par des filets (registre) */
.site-nav { gap: 0; }
.site-nav a:not(.btn) { padding: var(--spacing-2) clamp(var(--spacing-3), 1.6vw, var(--spacing-5)); border-left: 1px solid var(--color-border-subtle); }
.site-nav a:not(.btn):first-child { border-left: none; }
.site-nav .btn { margin-left: clamp(var(--spacing-3), 1.6vw, var(--spacing-5)); }
.site-nav .theme-toggle { margin-left: var(--spacing-3); }

/* En-tête de section : titre + CTA en haut-droite */
.band-head { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-4); flex-wrap: wrap; margin-bottom: var(--spacing-8); }
.band-head h2 { margin: 0; }

/* Bande CTA finale plein accent */
.final-band { background: var(--color-intent-primary); border-block: none; }
.final-band h2 { color: var(--color-text-secondary); }
.final-band .lead { color: rgb(var(--color-text-secondary-rgb) / 0.85); }
.final-band .btn-primary { background: var(--color-surface-card); color: var(--color-text-accent); }

/* ── Simulateur ──────────────────────────────────────────── */
.sim { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: var(--spacing-6); margin: var(--spacing-8) 0; align-items: start; }
.sim-form { display: flex; flex-direction: column; gap: var(--spacing-4); background: var(--color-surface-card); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-lg); padding: var(--spacing-5); }
.sim-form label { display: flex; flex-direction: column; gap: var(--spacing-2); font-size: 0.9rem; color: var(--color-text-muted); }
.sim-form input[type="number"], .sim-form select { font-family: var(--font-family-body); font-size: 1rem; padding: var(--spacing-3); border: 1px solid var(--color-border-default); border-radius: var(--radius-md); background: var(--color-surface-page); color: var(--color-text-primary); min-height: 44px; }
.sim-form .sim-check { flex-direction: row; align-items: center; gap: var(--spacing-2); }
.sim-form .sim-check input { width: 18px; height: 18px; accent-color: var(--color-intent-primary); }
.sim-result { background: var(--color-surface-card); border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); padding: var(--spacing-5); box-shadow: var(--shadow-lg); }
.sim-row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-4); padding: var(--spacing-3) 0; border-bottom: 1px solid var(--color-border-subtle); }
.sim-row[hidden] { display: none; } /* le sélecteur de classe l'emporterait sinon sur [hidden] du UA */
.sim-row b { font-family: var(--font-family-number); font-size: 1.2rem; white-space: nowrap; }
.sim-row.muted, .sim-row.muted b { color: var(--color-text-muted); }
.sim-row.muted b { font-size: 1.05rem; }
.sim-row em { font-style: normal; font-size: 0.85rem; }
.sim-row.subtotal { border-bottom-width: 2px; }
.sim-row.total { border-bottom: none; padding-top: var(--spacing-4); }
.sim-row.total span { font-family: var(--font-family-title); font-size: 1.1rem; }
.sim-row.total b { font-size: 1.9rem; color: var(--color-text-accent); }
.sim-convert { text-align: center; margin-top: var(--spacing-8); }
.sim-convert p { color: var(--color-text-muted); margin-bottom: var(--spacing-4); }

/* ── Showcases produit : 1 titre + 1 ligne + 1 GRANDE illustration (logique bande de la référence) ── */
.showcase .band-head { margin-bottom: var(--spacing-3); }
.showcase .lead { max-width: 52ch; margin: 0 0 var(--spacing-7); }
.showcase-stage {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  min-height: clamp(340px, 52vh, 540px);
  padding: clamp(var(--spacing-6), 6vh, var(--spacing-8)) var(--spacing-4);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-xl);
  background:
    linear-gradient(rgb(var(--color-text-muted-rgb) / 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgb(var(--color-text-muted-rgb) / 0.07) 1px, transparent 1px),
    var(--color-surface-card-elevated);
  background-size: 76px 76px, 76px 76px, auto;
}
/* pixels décoratifs + connecteurs (façon mosaïque du hero) */
.sc-px { position: absolute; width: 14px; height: 14px; background: rgb(var(--color-text-muted-rgb) / 0.4); }
.sc-px.p1 { top: 14%; left: 9%; }
.sc-px.p2 { top: 22%; right: 12%; width: 10px; height: 10px; opacity: 0.7; }
.sc-px.p3 { bottom: 18%; right: 8%; }
.sc-px.p4 { bottom: 16%; left: 14%; width: 10px; height: 10px; opacity: 0.7; }
.sc-line { position: absolute; height: 1px; background: rgb(var(--color-text-muted-rgb) / 0.3); }
.sc-line::after { content: ""; position: absolute; top: -2px; width: 5px; height: 5px; background: rgb(var(--color-text-muted-rgb) / 0.5); }
.sc-line.l1 { top: calc(14% + 6px); left: calc(9% + 14px); width: 16%; } .sc-line.l1::after { right: -2px; }
.sc-line.l2 { bottom: calc(18% + 6px); right: calc(8% + 14px); width: 14%; } .sc-line.l2::after { left: -2px; }
.sc-line.l3 { top: calc(22% + 5px); right: calc(12% + 10px); width: 12%; } .sc-line.l3::after { left: -2px; }
.sc-line.l4 { bottom: calc(16% + 5px); left: calc(14% + 10px); width: 14%; } .sc-line.l4::after { right: -2px; }
/* fenêtre d'app maquettée */
.app-win { position: relative; z-index: 1; width: min(500px, 100%); background: var(--color-surface-page); border: 1px solid var(--color-border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); overflow: hidden; }
.app-win.aw-wide { width: min(760px, 100%); }
.aw-bar { display: flex; align-items: center; gap: var(--spacing-1-5); padding: var(--spacing-2-5) var(--spacing-4); border-bottom: 1px solid var(--color-border-default); }
.aw-bar i { width: 8px; height: 8px; border-radius: var(--radius-full); background: rgb(var(--color-text-muted-rgb) / 0.35); }
.aw-bar span { margin-left: auto; font-family: var(--font-family-mono); font-size: 0.62rem; letter-spacing: 0.08em; color: var(--color-text-muted); }
/* maquette calendrier des jours */
.cal-head { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--spacing-1-5); padding: var(--spacing-3) var(--spacing-4) 0; font-family: var(--font-family-mono); font-size: 0.62rem; color: var(--color-text-muted); text-align: center; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--spacing-1-5); padding: var(--spacing-2) var(--spacing-4) var(--spacing-3); }
.cal-grid i { aspect-ratio: 1; border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm); background: var(--color-surface-card); position: relative; }
.cal-grid i.on { background: rgb(var(--color-intent-primary-rgb) / 0.14); border-color: rgb(var(--color-intent-primary-rgb) / 0.45); }
.cal-grid i.on::after { content: ""; position: absolute; top: 50%; left: 50%; width: 6px; height: 6px; margin: -3px 0 0 -3px; background: var(--color-intent-primary); }
/* demi-journée : moitié basse teintée + demi-point (comme le vrai calendrier) */
.cal-grid i.half { background: linear-gradient(to top, rgb(var(--color-intent-primary-rgb) / 0.14) 50%, transparent 50%); border-color: rgb(var(--color-intent-primary-rgb) / 0.45); }
.cal-grid i.half::after { content: ""; position: absolute; left: 50%; bottom: 22%; width: 6px; height: 3px; margin-left: -3px; background: var(--color-intent-primary); }
.cal-grid i.off { background: repeating-linear-gradient(45deg, transparent 0 3px, rgb(var(--color-text-muted-rgb) / 0.3) 3px 4px); }
.cal-grid i.we { opacity: 0.35; }
.cal-grid i.cur { border-color: var(--color-intent-primary); box-shadow: 0 0 0 2px rgb(var(--color-intent-primary-rgb) / 0.35); }
/* Invite « clique-moi » = surbrillance (anneau + pulse). Case VIDE → glyphe ＋ ; case DÉJÀ travaillée
   (`on cur`, le jour d'aujourd'hui à poser off) → garde le point `.on` (pas de ＋ qui écraserait le point). */
.cal-grid i.cur:not(.on)::after { content: "＋"; position: absolute; inset: 0; display: grid; place-items: center; color: var(--color-intent-primary); font-weight: 700; font-size: 0.8rem; }
.cal-foot { display: flex; align-items: center; gap: var(--spacing-4); padding: var(--spacing-2-5) var(--spacing-4); border-top: 1px dashed var(--color-border-default); font-size: 0.78rem; color: var(--color-text-muted); }
.cal-foot em { margin-left: auto; font-style: normal; font-family: var(--font-family-number); font-weight: 600; color: var(--color-text-primary); }
.cal-foot .dot { display: inline-block; width: 10px; height: 10px; border-radius: var(--radius-sm); margin-right: var(--spacing-1-5); vertical-align: -1px; }
.cal-foot .don { background: rgb(var(--color-intent-primary-rgb) / 0.6); }
.cal-foot .dhalf { background: linear-gradient(to top, rgb(var(--color-intent-primary-rgb) / 0.6) 50%, transparent 50%); border: 1px solid var(--color-border-default); }
.cal-foot .doff { background: repeating-linear-gradient(45deg, transparent 0 2px, rgb(var(--color-text-muted-rgb) / 0.5) 2px 3px); border: 1px solid var(--color-border-default); }

/* ── Calendrier des jours : overlay Impact + Valider → envol → KPI « jours off » (Pile) (handoff Claude
   Design 2026-07-15). Overrides scopés #jours ; classe `ci-on` posée par /assets/calendrier-impact.js.
   Calendrier = édition (impact affiché) ; KPI = validé (n'avance qu'à la validation). Légende harmonisée
   OFF=rouge / TRAVAILLÉ=ambre. 100% tokens (shadows via --shadow-lg → theme-safe). */
#jours .showcase-stage { overflow: visible; }
#jours .jours-duo { display: flex; gap: var(--spacing-5); align-items: stretch; justify-content: center; flex-wrap: wrap; width: 100%; }
#jours .jours-duo .app-win { width: min(430px, 100%); }
/* carte KPI voisine — rectangle compact évoquant une fenêtre de l'app */
.kpi-win { align-self: flex-start; flex: 0 0 auto; width: min(300px, 100%); height: 154px; overflow: hidden; display: flex; flex-direction: column; background: var(--color-surface-page); border: 1px solid var(--color-border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.kpi-win .aw-bar { flex: none; }
.kpi-main { flex: 1; min-height: 0; display: flex; flex-direction: column; justify-content: center; gap: 3px; padding: var(--spacing-2-5) var(--spacing-4); }
.kpi-body { display: flex; align-items: baseline; gap: 6px; }
.kpi-body.kpi-stack { align-items: stretch; justify-content: center; flex-direction: column; gap: 8px; width: 100%; }
.kpi-num { font-family: var(--font-family-number); font-weight: 700; line-height: 0.9; color: var(--color-text-accent); font-size: 2.7rem; display: inline-block; }
.kpi-unit { font-family: var(--font-family-number); font-size: 0.9rem; color: var(--color-text-muted); }
.kpi-calc { font-family: var(--font-family-number); font-weight: 600; font-size: 0.72rem; color: var(--color-text-primary); transition: color var(--duration-base) var(--easing-ease-out); }
.kpi-calc.up { color: var(--color-intent-success); } .kpi-calc.down { color: var(--color-text-accent); }
#jours .cal-foot em { display: none; } /* CA plus affiché sur le calendrier (déplacé au KPI) ; #cal-total reste dans le DOM (recount + observateur) */
.kpi-stack .kpi-line { display: flex; align-items: baseline; gap: 6px; }
.kpi-stack .kpi-num { font-size: 1.9rem; }
.kpi-bricks { display: grid; grid-template-columns: repeat(30, 1fr); gap: 2px; width: 100%; height: 22px; }
.kpi-brick { border-radius: 1px; background: rgb(var(--color-text-muted-rgb) / 0.16); }
.kpi-brick.on { background: var(--jour-off); }
.kpi-brick.half { background: linear-gradient(to top, var(--jour-off) 55%, rgb(var(--color-text-muted-rgb) / 0.16) 55%); }
.kpi-win.is-stack .kpi-main { gap: 8px; }
.kpi-win.is-stack .kpi-calc { font-size: 1.05rem; font-weight: 700; }
/* légende harmonisée : OFF = rouge (comme le KPI), TRAVAILLÉ = ambre (secondaire) */
#jours { --jour-off: var(--color-intent-primary); --jour-off-rgb: var(--color-intent-primary-rgb); --jour-on: var(--color-intent-secondary); --jour-on-rgb: var(--color-intent-secondary-rgb); }
#jours .cal-grid i.on { background: rgb(var(--jour-on-rgb) / 0.2); border-color: rgb(var(--jour-on-rgb) / 0.55); }
#jours .cal-grid i.on::after { background: var(--jour-on); }
#jours .cal-grid i.off { background-color: rgb(var(--jour-off-rgb) / 0.1); background-image: repeating-linear-gradient(45deg, transparent 0 3px, rgb(var(--jour-off-rgb) / 0.55) 3px 4px); border-color: rgb(var(--jour-off-rgb) / 0.5); }
#jours .cal-grid i.half { background: linear-gradient(to top, rgb(var(--jour-off-rgb) / 0.2) 50%, rgb(var(--jour-on-rgb) / 0.16) 50%); border-color: rgb(var(--jour-on-rgb) / 0.55); }
#jours .cal-grid i.half::after { background: var(--jour-off); }
#jours .cal-foot .don { background: rgb(var(--jour-on-rgb) / 0.7); }
#jours .cal-foot .dhalf { background: linear-gradient(to top, var(--jour-off) 50%, var(--jour-on) 50%); }
#jours .cal-foot .doff { background: var(--jour-off); }
#jours .kpi-num { color: var(--jour-off); }

/* couche d'animation au niveau du STAGE (l'envol traverse calendrier → KPI) */
.ci-layer { position: absolute; inset: 0; z-index: 5; pointer-events: none; overflow: visible; }
#jours.ci-on .cal-toast { opacity: 0 !important; transition: none; } /* toast live CONSERVÉ pour le lecteur d'écran, masqué visuellement */

/* barre Impact + Valider, ancrée en BAS du calendrier (les autres jours restent cliquables) */
.ci-bar { position: absolute; transform: translate(0, -100%); z-index: 6; pointer-events: auto; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-3); padding: var(--spacing-2) var(--spacing-3); background: var(--color-surface-card); border: 1px solid var(--color-border-default); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.ci-bar .ci-info { display: flex; align-items: baseline; gap: 8px; min-width: 0; flex-wrap: wrap; }
.ci-bar .ci-k { font-family: var(--font-family-mono); font-size: 0.58rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-text-muted); }
.ci-bar .ci-ca { font-family: var(--font-family-number); font-weight: 700; font-size: 1.2rem; line-height: 1; }
.ci-bar .ci-net { font-style: italic; font-size: 0.76rem; color: var(--color-text-muted); }
.ci-bar.neg { border-left: 3px solid var(--color-text-accent); }
.ci-bar.pos { border-left: 3px solid var(--color-intent-success); }
.ci-valider { flex: none; margin: 0; }

/* jeton qui s'envole vers le KPI */
.ci-chip { position: absolute; z-index: 6; font-family: var(--font-family-number); font-weight: 700; font-size: 0.92rem; white-space: nowrap; padding: 3px 10px; border-radius: var(--radius-full); background: var(--color-surface-card); border: 1px solid var(--color-border-default); box-shadow: var(--shadow-lg); will-change: transform, opacity; }
.ci-chip.neg { color: var(--color-text-accent); }
.ci-chip.pos { color: var(--color-intent-success); }
/* maquette volet filtres → graphe */
.filt-wrap { display: grid; grid-template-columns: 210px 1fr; }
.filt { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-2); padding: var(--spacing-4); border-right: 1px solid var(--color-border-default); }
.filt-t { font-family: var(--font-family-mono); font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-text-muted); font-weight: 400; }
.filt .chip { border: 1px solid var(--color-border-default); border-radius: var(--radius-full); padding: var(--spacing-1) var(--spacing-3); font-size: 0.78rem; color: var(--color-text-muted); }
.filt .chip.on { background: rgb(var(--color-intent-primary-rgb) / 0.12); border-color: var(--color-intent-primary); color: var(--color-text-primary); }
.filt-l { display: flex; align-items: center; gap: var(--spacing-2); font-size: 0.78rem; color: var(--color-text-muted); margin-top: var(--spacing-1); }
.filt .sw { width: 24px; height: 13px; border-radius: var(--radius-full); border: 1px solid var(--color-border-strong); position: relative; flex: none; }
.filt .sw::after { content: ""; position: absolute; top: 1px; left: 1px; width: 9px; height: 9px; border-radius: var(--radius-full); background: var(--color-border-strong); }
.filt .sw.on { border-color: var(--color-intent-primary); background: rgb(var(--color-intent-primary-rgb) / 0.12); }
.filt .sw.on::after { left: auto; right: 1px; background: var(--color-intent-primary); }
.filt-chart { display: grid; grid-template-rows: 1fr auto; padding: var(--spacing-4) var(--spacing-4) var(--spacing-3); min-height: 220px; }
.ch-area { position: relative; border-bottom: 1px solid var(--color-border-default); }
.ch-bars { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: var(--spacing-2); }
.ch-bars[hidden] { display: none; } /* .ch-bars pose display:flex → ne pas battre [hidden] du UA */
/* chaque barre = EMPILEMENT net (bas) + cotisations + TVA (haut) ; les parts se répartissent en flex */
.ch-bars i { flex: 1; height: var(--h); display: flex; flex-direction: column-reverse; border-radius: var(--radius-sm) var(--radius-sm) 0 0; overflow: hidden; }
.ch-bars .sg { width: 100%; min-height: 0; }
.ch-bars .sg[hidden] { display: none; }
.sg.n { background: var(--color-intent-primary); }
.sg.c { background: var(--color-intent-secondary); }
.sg.t { background: rgb(var(--color-text-muted-rgb) / 0.4); }
/* ligne des dépenses par-dessus les barres */
.ch-line { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.ch-line[hidden] { display: none; }
.ch-line polyline { fill: none; stroke: var(--color-text-primary); stroke-width: 1.6; stroke-dasharray: 5 4; }
/* pastilles-légende portées par les interrupteurs eux-mêmes */
.filt .dot { display: inline-block; width: 10px; height: 10px; border-radius: var(--radius-sm); flex: none; }
.dot.d-net { background: var(--color-intent-primary); }
.dot.d-cot { background: var(--color-intent-secondary); }
.dot.d-tva { background: rgb(var(--color-text-muted-rgb) / 0.4); }
.dot.d-dep { background: transparent; height: 0; border-bottom: 2px dashed var(--color-text-primary); border-radius: 0; }
.filt .filt-t:not(:first-of-type) { margin-top: var(--spacing-3); }
.ch-cap { font-style: normal; font-family: var(--font-family-mono); font-size: 0.62rem; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--spacing-2); }

/* ── Showcase C : frise des contrats ── */
.fz-months { display: grid; grid-template-columns: repeat(12, 1fr); padding: var(--spacing-3) var(--spacing-4) 0; font-family: var(--font-family-mono); font-size: 0.62rem; color: var(--color-text-muted); text-align: center; }
.fz-tracks { padding: var(--spacing-2) var(--spacing-4) var(--spacing-3); display: flex; flex-direction: column; gap: var(--spacing-2-5); }
/* pistes 52px → segments 44px : cible tactile réglementaire sans zone étendue */
.fz-tr { position: relative; height: 52px; border-bottom: 1px dashed rgb(var(--color-text-muted-rgb) / 0.25); }
.fz-seg {
  position: absolute; left: var(--l); width: var(--w); top: 4px; bottom: 4px;
  border-radius: var(--radius-full); display: flex; align-items: center; padding-inline: var(--spacing-3);
  font-size: 0.72rem; font-family: var(--font-family-title); overflow: hidden;
}
/* l'ellipsis ne marche que sur un block : le libellé vit dans un span interne */
.fz-seg > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* états : tous en fond TEINTÉ + texte primaire (contraste AA garanti dans les 2 thèmes) */
.fz-seg.done { background: rgb(var(--color-intent-success-rgb) / 0.22); border: 2px solid var(--color-intent-success); color: var(--color-text-primary); }
.fz-seg.run { background: rgb(var(--color-intent-primary-rgb) / 0.18); border: 2px solid var(--color-intent-primary); color: var(--color-text-primary); }
.fz-seg.next { background: rgb(var(--color-intent-secondary-rgb) / 0.35); border: 2px dashed rgb(var(--color-intent-secondary-rgb) / 0.9); color: var(--color-text-primary); }
.fz-seg.is-sel { outline: 3px solid var(--color-text-accent); outline-offset: 2px; }
.fz-tracks.is-live .fz-seg { cursor: pointer; }
.fz-seg:focus-visible { outline: 3px solid var(--color-text-accent); outline-offset: 2px; }

/* ── Reveals au scroll (handoff Claude Design 2026-07-14) — joués UNE fois à l'entrée à l'écran (IO 0.4,
   classes cr- et fr- posées par /assets/reveals.js). Gaté prefers-reduced-motion (rien de caché hors media).
   • GRAPHE #filtres « Pousse » : chaque barre grandit du bas (scaleY 0→1, léger dépassement), cascade G→D via --bd.
   • FRISE #contrats « Tête de lecture » : un curseur .fz-ph balaie le temps ; chaque .fz-seg s'allume à son passage. */
@media (prefers-reduced-motion: no-preference) {
  /* GRAPHE — délais de cascade par barre (12 max) */
  .filt-chart .ch-bars i:nth-child(1) { --bd: 0ms; }    .filt-chart .ch-bars i:nth-child(2) { --bd: 55ms; }
  .filt-chart .ch-bars i:nth-child(3) { --bd: 110ms; }  .filt-chart .ch-bars i:nth-child(4) { --bd: 165ms; }
  .filt-chart .ch-bars i:nth-child(5) { --bd: 220ms; }  .filt-chart .ch-bars i:nth-child(6) { --bd: 275ms; }
  .filt-chart .ch-bars i:nth-child(7) { --bd: 330ms; }  .filt-chart .ch-bars i:nth-child(8) { --bd: 385ms; }
  .filt-chart .ch-bars i:nth-child(9) { --bd: 440ms; }  .filt-chart .ch-bars i:nth-child(10) { --bd: 495ms; }
  .filt-chart .ch-bars i:nth-child(11) { --bd: 550ms; } .filt-chart .ch-bars i:nth-child(12) { --bd: 605ms; }
  @keyframes crGrow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
  .filt-chart.cr-arm .ch-bars i { transform: scaleY(0); transform-origin: bottom; }
  .filt-chart.cr-play .ch-bars i { transform-origin: bottom; animation: crGrow 0.58s cubic-bezier(0.2, 0.85, 0.25, 1.15) var(--bd, 0ms) both; }

  /* FRISE — pop chronologique par contrat (--rvd) + curseur balayeur (--sweepdur), tous deux posés par le JS */
  .fz-tracks { position: relative; }
  @keyframes frPop { 0% { opacity: 0; transform: scale(0.86); } 60% { opacity: 1; transform: scale(1.03); } 100% { opacity: 1; transform: none; } }
  /* le curseur FOND À L'ENTRÉE et À LA SORTIE (opacity dans la keyframe) → il ne reste pas parqué
     visible au bord droit après le one-shot (fr-play jamais retiré + fill:both). [revue adverse] */
  @keyframes frSweep { 0% { left: 0; opacity: 0; } 10% { opacity: 1; } 88% { opacity: 1; } 100% { left: 100%; opacity: 0; } }
  .fz-tracks.fr-arm .fz-seg { opacity: 0; }
  /* a11y : .fz-seg devient focusable (enhance.js pose role=button + tabIndex 0) → un segment focusé au
     clavier reste visible même pendant l'arm, sinon focus sur un élément opacity:0 (WCAG 2.4.7). [revue adverse] */
  .fz-tracks.fr-arm .fz-seg:focus-visible { opacity: 1; animation: none; } /* animation:none INDISPENSABLE : frPop (opacity 0→1) prime sinon sur opacity:1 → focus invisible pendant le reveal [revue] */
  .fz-tracks.fr-play .fz-seg { animation: frPop 0.42s ease-out var(--rvd, 0ms) both; }
  .fz-ph { position: absolute; top: 6px; bottom: 6px; width: 2px; background: var(--color-text-accent); opacity: 0;
    pointer-events: none; z-index: 3; box-shadow: 0 0 6px 1px rgb(var(--color-text-accent-rgb) / 0.5); }
  .fz-tracks.fr-play .fz-ph { animation: frSweep var(--sweepdur, 1.1s) linear both; }
}
.dot.fd-done { background: rgb(var(--color-intent-success-rgb) / 0.22); border: 2px solid var(--color-intent-success); }
.dot.fd-run { background: rgb(var(--color-intent-primary-rgb) / 0.18); border: 2px solid var(--color-intent-primary); }
.dot.fd-next { background: rgb(var(--color-intent-secondary-rgb) / 0.35); border: 2px dashed rgb(var(--color-intent-secondary-rgb) / 0.9); }
#fz-fiche { font-size: 0.8rem; }

/* ── Showcase D : échéancier + jauge de provisions ── */
.ej-gauge-row { display: flex; align-items: center; gap: var(--spacing-3); padding: var(--spacing-3) var(--spacing-4); border-bottom: 1px dashed var(--color-border-default); }
.ej-gauge { flex: 1; height: 12px; border: 1px solid var(--color-border-strong); border-radius: var(--radius-full); overflow: hidden; background: var(--color-surface-card); }
.ej-gauge i { display: block; height: 100%; width: var(--p); background: var(--color-intent-success); }
.ej-cap { flex: none; font-style: normal; font-family: var(--font-family-mono); font-size: 0.68rem; color: var(--color-text-muted); }
.ej-rows { display: flex; flex-direction: column; padding: var(--spacing-2) var(--spacing-4) var(--spacing-3); }
.ej-row { display: flex; align-items: center; gap: var(--spacing-2-5); padding: var(--spacing-2-5) 0; border-bottom: 1px dashed rgb(var(--color-text-muted-rgb) / 0.25); min-height: 44px; }
.ej-row:last-child { border-bottom: none; }
.ej-d { font-family: var(--font-family-mono); font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); width: 4.6em; flex: none; }
.ej-l { font-size: 0.85rem; }
.ej-row em { flex: 1; border-bottom: 1px dashed rgb(var(--color-text-muted-rgb) / 0.3); }
.ej-row b { font-family: var(--font-family-number); font-weight: 600; }
.ej-check { flex: none; width: 20px; height: 20px; border: 2px solid var(--color-border-strong); border-radius: var(--radius-sm); position: relative; }
.ej-row.is-ok .ej-check { background: var(--color-intent-success); border-color: var(--color-intent-success); }
.ej-row.is-ok .ej-check::after { content: "✓"; position: absolute; inset: 0; display: grid; place-items: center; color: var(--color-text-inverted); font-size: 0.75rem; font-weight: 700; }
.ej-row.is-ok .ej-l, .ej-row.is-ok b { color: var(--color-text-muted); }
.ej-rows.is-live .ej-row { cursor: pointer; }
.ej-row:focus-visible { outline: 2px solid var(--color-text-accent); outline-offset: 2px; }

/* ── Showcase E : multi-personnes (une feuille partagée) ── */
.pp-chip { display: flex; align-items: center; gap: var(--spacing-2); border: 1px solid var(--color-border-default); border-radius: var(--radius-full); padding: var(--spacing-1) var(--spacing-3) var(--spacing-1) var(--spacing-1); font-size: 0.85rem; color: var(--color-text-muted); }
.pp-chip.on { background: rgb(var(--color-intent-primary-rgb) / 0.12); border-color: var(--color-intent-primary); color: var(--color-text-primary); }
.pp-av { width: 26px; height: 26px; border-radius: var(--radius-full); display: grid; place-items: center; font-family: var(--font-family-title); font-size: 0.8rem; color: var(--color-text-inverted); font-style: normal; flex: none; }
/* fonds -ink : slots PRÉVUS pour porter du texte inverted (contraste AA dans les 2 thèmes) */
.pp-av.a1 { background: var(--color-intent-primary); }
.pp-av.a2 { background: var(--color-intent-warning-ink); }
.pp-av.a3 { background: var(--color-intent-success-ink); }
.pp-note { margin-top: var(--spacing-2); font-size: 0.72rem; color: var(--color-text-muted); font-family: var(--font-family-mono); }
.pp-bars i { background: var(--color-intent-primary); }
.filt.is-live .pp-chip { cursor: pointer; position: relative; }
.filt.is-live .pp-chip::after { content: ""; position: absolute; inset: -6px; } /* cible tactile ≥ ~44px */
.filt.is-live .pp-chip:focus-visible { outline: 2px solid var(--color-text-accent); outline-offset: 2px; }

/* ── Reveal « trois freelances » (#partage, handoff Claude Design 2026-07-14) — « Rebond » : joué UNE fois
   à l'entrée à l'écran (IO 0.4, classes pp-arm/pp-play posées par /assets/reveals.js). Gaté
   prefers-reduced-motion. Les 3 .pp-chip tombent + rebondissent en cascade (écho de mos-land), puis les 4
   barres montent. Le conteneur .showcase-stage porte déjà .rv (enhance.js révèle le CADRE) : classes
   distinctes → elles composent (cadre révélé, puis contenu animé). */
@media (prefers-reduced-motion: no-preference) {
  /* délais : personnes (gauche→droite) et barres */
  #partage .pp-chip:nth-of-type(1) { --pi: 0; } #partage .pp-chip:nth-of-type(2) { --pi: 1; } #partage .pp-chip:nth-of-type(3) { --pi: 2; }
  #partage .ch-bars i:nth-child(1) { --ppbi: 0; } #partage .ch-bars i:nth-child(2) { --ppbi: 1; }
  #partage .ch-bars i:nth-child(3) { --ppbi: 2; } #partage .ch-bars i:nth-child(4) { --ppbi: 3; }
  /* chute + rebond (écho de mos-land, à l'échelle d'un chip) — les barres réutilisent la keyframe crGrow des reveals */
  @keyframes ppDrop { 0% { opacity: 0; transform: translateY(-22px); } 55% { opacity: 1; transform: translateY(6px); } 75% { transform: translateY(-3px); } 100% { opacity: 1; transform: none; } }
  /* 1 — les personnes tombent et rebondissent, en cascade */
  #partage .pp-arm .pp-chip { opacity: 0; }
  /* a11y : .pp-chip devient focusable (enhance.js role=radio + roving tabIndex) → visible au focus clavier même armé (WCAG 2.4.7) */
  #partage .pp-arm .pp-chip:focus-visible { opacity: 1; animation: none; } /* idem frise : ppDrop primerait sinon sur opacity:1 → focus invisible [revue] */
  #partage .pp-play .pp-chip { animation: ppDrop 0.6s cubic-bezier(0.2, 0.8, 0.3, 1.1) calc(var(--pi, 0) * 170ms) both; }
  /* 2 — puis les barres du mini-graphe montent du bas */
  #partage .pp-arm .ch-bars i { transform: scaleY(0); transform-origin: bottom; }
  #partage .pp-play .ch-bars i { transform-origin: bottom; animation: crGrow 0.5s cubic-bezier(0.2, 0.85, 0.25, 1.1) calc(820ms + var(--ppbi, 0) * 55ms) both; }
}

/* ── Showcase F : deux décors (wrapper de thème IMBRIQUÉ dans la fenêtre) ── */
.th-scope .th-inner { background: var(--color-surface-page); color: var(--color-text-primary); font-family: var(--font-family-body); }
.th-scope .aw-bar { border-bottom-color: var(--color-border-default); }
.th-toggle { margin-left: var(--spacing-3); min-width: 44px; min-height: 34px; border: 1px solid var(--color-border-strong); border-radius: var(--radius-full); background: var(--color-surface-card); color: var(--color-text-primary); font-size: 1rem; position: relative; }
.th-toggle::after { content: ""; position: absolute; inset: -5px 0; } /* 34 + 2×5 = 44px effectifs */
.th-scope.is-live .th-toggle { cursor: pointer; }
.th-toggle:focus-visible { outline: 2px solid var(--color-text-accent); outline-offset: 2px; }
.th-body { padding: var(--spacing-4); }
.th-bars { display: flex; align-items: flex-end; gap: var(--spacing-2); height: 120px; border-bottom: 1px solid var(--color-border-default); }
.th-bars i { flex: 1; height: var(--h); background: var(--color-intent-primary); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.th-total { display: flex; justify-content: space-between; align-items: baseline; padding-top: var(--spacing-3); }
.th-total span { color: var(--color-text-muted); font-size: 0.9rem; }
.th-total b { font-family: var(--font-family-number); font-size: 1.4rem; color: var(--color-text-accent); }
.th-cap { font-style: normal; }

/* ── Souveraineté enrichie : changement de feuille + CSV ── */
.fv-swap { margin-top: var(--spacing-3); }
.fv-sheet i.h { transition: background var(--duration-slow) var(--easing-ease-out); }
.fv-sheet.alt i.h { background: var(--color-intent-secondary); opacity: 0.75; }
.fv-sheet.alt i:nth-child(5) { background: rgb(var(--color-intent-secondary-rgb) / 0.35); }
.fv-note { text-align: center; min-height: 1.4em; margin: 0 0 var(--spacing-2); color: var(--color-intent-success); font-size: 0.9rem; }
.fv-csv { text-align: center; color: var(--color-text-muted); font-size: 0.9rem; margin: 0 0 var(--spacing-6); }

/* ── Mobile ──────────────────────────────────────────────── */
@media (max-width: 820px) {
  .showcase-stage { min-height: 0; padding: var(--spacing-5) var(--spacing-3); }
  .sc-px, .sc-line { display: none; }
  .filt-wrap { grid-template-columns: 1fr; }
  .filt { flex-direction: row; flex-wrap: wrap; align-items: center; border-right: none; border-bottom: 1px solid var(--color-border-default); }
  .filt-t { width: 100%; }
  .filt-chart { min-height: 160px; }
  .cal-foot { flex-wrap: wrap; gap: var(--spacing-2) var(--spacing-4); }
  .flow-visual { gap: var(--spacing-4); }
  .hero { grid-template-columns: 1fr; }
  .charte, .ref-grid, .sim { grid-template-columns: 1fr; }
  html:not(.scrolly) .hs-stage { grid-template-columns: 1fr; }
  .hs-news { display: none; } /* la carte « à la une » n'a pas la place en mobile */
  .hs-headline { font-size: clamp(1.5rem, 7vw, 2rem); } /* au repos le titre tient dans zA (pas de rognage avant scroll) */
}

/* Nav du header : masquer les liens texte dès 960px. Avec 5 liens (Fonctionnalités · Calculateur ·
   Règles de calcul · À propos · Confidentialité) + « Se connecter » + bouton démo + toggle, la barre
   débordait sous ~930px (mesuré : 8px à 920). Séparé du bloc 820 (CONTENU) : seul le header se replie. */
@media (max-width: 960px) {
  .site-nav a:not(.btn):not(.nav-login) { display: none; }
}

/* ── Reduced-motion : ceinture GLOBALE (en fin de feuille : à spécificité égale, gagne) ──
   Coupe les transitions/hovers en transform restés hors gate (btn, cartes actu, piste
   du slider, ref-cards, icônes hero) — l'état final s'applique sans mouvement. */
@media (prefers-reduced-motion: reduce) {
  .btn, .hs-news .card, .hs-news .card .thumb, .hs-icons .ic, .ref-card, .hs-news-track { transition: none; }
  .btn:hover, .hs-news .card:hover, .hs-news .card:hover .thumb, .hs-icons .ic:hover, .ref-card:hover { transform: none; }
}
