:root{--color-bg:#ffffff;--color-surface:#f1f5f8;--color-text:#0f1e2b;--color-accent:#0a96dc;--color-accent-2:#0a96dc;--color-divider:#0f1e2b;
--color-accent-100:#eaf6fd;--color-accent-200:#d3ecfa;--color-accent-300:#a9dbf5;--color-accent-400:#6fc2ec;--color-accent-500:#0a96dc;--color-accent-600:#0779b4;--color-accent-700:#065f8d;--color-accent-800:#074664;--color-accent-900:#082e42;
--cta:#f5c400;--cta-dark:#d9ab00}
body{margin:0;background:var(--color-bg);color:var(--color-text);font-family:var(--font-body);text-wrap:pretty;-webkit-font-smoothing:antialiased}
a{color:var(--color-accent-700)}a:hover{color:var(--color-accent-600)}
button{font-family:inherit}
input,select{font-family:inherit}
.hov-cta:hover{background:var(--cta-dark)!important}
.hov-ink:hover{background:var(--color-accent-100)!important}
.hov-nav:hover{color:var(--color-accent-600)!important}
.hov-card:hover{background:var(--color-accent-100)!important}
.hov-dark:hover{background:rgba(255,255,255,.16)!important}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ══════════════════════════════════════════════════════════════════════════
   TOUT LE RESPONSIVE DU SITE VIT DANS CE FICHIER.
   tools/lib/seo.mjs charge fonts → tokens → page → site : une media query
   placée dans site.css l'emporterait sur celles-ci et casserait l'échelle.
   Le gabarit pose ses grilles en style EN LIGNE, d'où les !important.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Repères globaux ────────────────────────────────────────────────────── */
:root {
  /* Hauteur réelle de l'en-tête fixe : barre + filet de 2 px. Seule source de
     vérité pour la cale de compensation, les ancres et les blocs collants. */
  --hdr-h: 78px;
  /* Le site est dessiné en clair : sans cette ligne, l'assombrissement
     automatique d'Android réinvente les couleurs du schéma du simulateur. */
  color-scheme: light;
}
@media (max-width: 600px) { :root { --hdr-h: 66px } }

/* Toute ancre doit se poser SOUS l'en-tête fixe, jamais dessous. */
html { scroll-padding-top: calc(var(--hdr-h) + 12px); scroll-behavior: smooth }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto } }

/* Filet de sécurité typographique : aucun mot ne doit sortir de sa colonne
   (« ambenergies.com » mesurait 309 px pour 289 px de colonne à 320 px). */
h1, h2, h3, h4, h5, h6, p, li, dt, dd, th, td, summary, figcaption, label, a { overflow-wrap: break-word }

/* Texte réservé aux lecteurs d'écran (annonces du simulateur, des filtres). */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── En-tête ────────────────────────────────────────────────────────────── */
.hdr-bar { height: calc(var(--hdr-h) - 2px) }
.hdr-spacer { height: var(--hdr-h); flex: none }
/* Le burger devient une croix quand le panneau est déployé (.is-open : site.js). */
.hdr-burger .ico-close { display: none }
.hdr-burger.is-open .ico-menu { display: none }
.hdr-burger.is-open .ico-close { display: block }
/* Verrou du défilement de fond pendant que le menu mobile est ouvert. */
body.nav-lock { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden }

/* À 320 px, 288 px utiles ne peuvent pas contenir logo 95 + CTA 161 + burger 44
   séparés de 28 et 18 px de gouttière : on resserre l'ensemble. */
@media (max-width: 600px) {
  .hdr-bar { gap: 12px !important; padding-left: 14px !important; padding-right: 14px !important }
  .hdr-bar img { height: 40px !important }
  .hdr-bar > div:last-child { gap: 10px !important }
  .hdr-bar a[data-page="contact"] { font-size: 13px !important; padding: 11px 12px !important; gap: 6px !important }
  .hdr-bar a[data-page="contact"] svg { width: 14px; height: 14px }
}
@media (max-width: 360px) {
  .hdr-bar a[data-page="contact"] svg { display: none }
}

/* ══ ÉCHELLE DE PALIERS ═══════════════════════════════════════════════════
   1240 largeur de la maquette · 1080 portable 13 pouces · 960 bascule
   bureau → tactile (la navigation change de forme) · 720 tablette portrait
   basse · 560 téléphone en paysage · 400 petit téléphone.
   Avant, un palier unique à 960 px faisait passer l'accueil de 10 600 px à
   17 421 px de haut pour un seul pixel de largeur en moins.
   ══════════════════════════════════════════════════════════════════════ */

@media (max-width: 1240px) {
  /* Colonne de liens du pied de page : 213 px ne suffisent pas à
     « Chauffe-eau thermodynamique ». */
  .rsp-foot { grid-template-columns: 1.3fr 1fr 1fr 1fr !important }
}

@media (max-width: 1180px) {
  /* 5 colonnes ne laissent que 137 px de texte : 9 libellés de service sur 12
     passaient sur deux lignes. */
  .mega { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: 22px 0 !important }
  .mega > div { padding-right: 14px !important }
}
/* À pleine largeur, cinq colonnes égales de 232 px laissent 194 px de texte,
   et « Chauffe-eau thermodynamique » en réclame 214. Les colonnes se dimensionnent
   donc sur leur contenu et se répartissent l'espace restant : plus aucun libellé
   ne se casse en deux. minmax(0,…) garde le repli si un libellé s'allonge. */
@media (min-width: 1181px) {
  .mega { grid-template-columns: repeat(5, minmax(0, max-content)) !important; justify-content: space-between }
  .mega > div { padding-right: 12px !important }
}

@media (max-width: 1080px) {
  .rsp-foot { grid-template-columns: repeat(2, minmax(0, 1fr)) !important }
  /* Grilles de 3 imbriquées dans une colonne latérale (thèmes d'avis) : 170 px
     de colonne à 961 px, illisible. */
  .rsp-aside .rsp-3 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important }
  .rsp-aside .rsp-3 > *:last-child:nth-child(odd) { grid-column: 1 / -1 }
  /* Lignes d'aide : le libellé reprend toute la largeur plutôt que d'être rogné. */
  .aide-row { grid-template-columns: minmax(0, 1fr) !important; gap: 4px !important }
}

@media (max-width: 960px) {
  /* Bascule de la navigation */
  .hide-m { display: none !important }
  .show-m { display: inline-flex !important }
  .side { position: static !important }
  .stack-m { flex-direction: column !important; align-items: flex-start !important }
  /* En axe colonne, un margin-left:auto hérité de la ligne pousse l'élément
     sur l'axe transversal : le lien du bandeau partait se coller à droite. */
  .stack-m > * { margin-left: 0 !important }
  .stack-m { gap: 8px !important }

  /* Mises en page « colonne latérale + contenu » : elles n'ont plus de sens. */
  .rsp-hero, .rsp-aside { grid-template-columns: minmax(0, 1fr) !important }
  /* Les grilles de 3 et 4 gardent 2 colonnes : sur iPad portrait, une colonne
     unique donnait des lignes de 91 à 114 caractères. */
  .rsp-3, .rsp-4 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important }
  .rsp-3:not(.rsp-cards) > *:last-child:nth-child(odd) { grid-column: 1 / -1 }
  /* Les cartes de service portent une photo : trois colonnes tiennent encore. */
  .rsp-cards { grid-template-columns: repeat(3, minmax(0, 1fr)) !important }
  .rsp-steps { row-gap: 32px !important }
}

@media (max-width: 720px) {
  .rsp-2, .prose-grid, .rsp-cards { grid-template-columns: minmax(0, 1fr) !important }
}

@media (max-width: 560px) {
  .rsp-3, .rsp-4 { grid-template-columns: minmax(0, 1fr) !important }
}

@media (max-width: 400px) {
  /* Un enfant de grille garde min-width:auto : il ne peut pas rétrécir sous son
     contenu, et débordait alors de son cadre (298 px pour 284 px). */
  .cfg-grid > *, .rsp-2 > *, .rsp-3 > *, .rsp-4 > *, .rsp-hero > * { min-width: 0 !important }
}

/* Paires de champs : c'est la largeur du CONTENEUR qui décide, pas celle de la
   fenêtre — la barre latérale ne fait que 232 px sur un écran de 320 px. */
.rsp-fields { display: grid !important; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)) !important; gap: 10px !important }

/* ── Filets des grilles bordées, une fois le nombre de colonnes changé ───── */
@media (max-width: 960px) {
  /* Chiffres clés en 2 colonnes : filet vertical entre les colonnes seulement. */
  .rsp-stats > * { padding: 28px 24px !important; border-right: 2px solid var(--color-divider) }
  .rsp-stats > *:nth-child(odd) { padding-left: 0 !important }
  .rsp-stats > *:nth-child(even) { padding-right: 0 !important; border-right: 0 !important }
  .rsp-stats > *:nth-child(-n+2) { border-bottom: 2px solid var(--color-divider) }
  /* Certifications : même logique, et une séparation horizontale entre elles. */
  .rsp-certs > * { padding: 32px 24px !important }
  .rsp-certs > *:nth-child(odd) { padding-left: 0 !important }
  .rsp-certs > *:nth-child(even) { padding-right: 0 !important; border-right: 0 !important }
  .rsp-certs > *:not(:last-child) { border-bottom: 2px solid var(--color-divider) }
}
@media (max-width: 560px) {
  .rsp-stats > * { padding: 24px 0 !important; border-right: 0 !important; border-bottom: 2px solid var(--color-divider) }
  .rsp-stats > *:last-child { border-bottom: 0 !important }
  .rsp-certs > * { padding: 28px 0 !important; border-right: 0 !important }
}

/* ── Blocs à colonne fixe ───────────────────────────────────────────────── */
@media (max-width: 480px) {
  /* Page contact : 110 px de libellé + 16 px de gouttière écrasaient la valeur. */
  .kv-row { grid-template-columns: minmax(0, 1fr) !important; gap: 2px !important }
  .kv-row > span:first-child { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-accent-700) }
}
@media (max-width: 960px) {
  /* Photo portrait 4/5 : 883 px de haut en tablette, plus qu'un écran entier. */
  .photo-portrait { aspect-ratio: 16 / 10 !important; max-height: 60vh }
}

/* ══ TITRES SUR PETIT ÉCRAN ═══════════════════════════════════════════════
   Les tailles sont posées en style en ligne : clamp(42px,6.2vw,88px) pour le
   héros, clamp(36px,4.6vw,62px) pour les services. Sous ~680 px le clamp reste
   collé à son plancher, d'où 6 à 7 lignes de titre et 43 à 46 % de la hauteur
   d'écran à 320 px — l'appel à l'action du héros passait sous le pli. */
@media (max-width: 600px) {
  h1 {
    font-size: clamp(27px, 7.6vw, 38px) !important;
    line-height: 1.08 !important;
    letter-spacing: -.02em !important;
    margin-left: 0 !important;   /* le débord optique n'a de sens qu'aux grandes tailles */
    text-wrap: balance;
  }
  h2 { font-size: clamp(22px, 5.6vw, 30px) !important; line-height: 1.12 !important; margin-left: 0 !important }
  /* Les sur-titres en capitales espacées ne descendent pas sous 12 px. */
  .kicker-h2 { font-size: 12px !important }
}

/* ══ CIBLES TACTILES ══════════════════════════════════════════════════════
   Au doigt, 44 px minimum (WCAG 2.5.8, Apple, Material). Le critère n'est pas
   la largeur mais le pointeur : une tablette de 1024 px en paysage affiche la
   navigation large ET se pilote au doigt. D'où « écran étroit OU pointeur sans
   survol ». Sur un bureau à la souris, rien de tout cela ne s'applique : le
   dessin d'origine est intact.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 1100px), (hover: none) {
  /* iOS Safari zoome la page dès qu'un champ actif est sous 16 px. */
  .input { font-size: 16px !important }
  input.input, select.input { min-height: 46px !important }
  textarea.input { min-height: 88px !important }

  nav[aria-label="Navigation mobile"] a { display: flex; align-items: center; min-height: 48px }
  nav[aria-label="Navigation mobile"] > div { gap: 8px !important }

  nav[aria-label="Thèmes"] { gap: 0 !important }
  nav[aria-label="Thèmes"] a { display: flex; align-items: center; min-height: 44px }

  footer nav[aria-label] { gap: 0 !important }
  footer nav[aria-label] a { display: flex; align-items: center; min-height: 44px; border-bottom: 1px solid rgba(15, 30, 43, .12) }
  footer nav[aria-label] a:last-child { border-bottom: 0 }
  .foot-legal { gap: 4px 24px !important }
  .foot-legal a { display: inline-flex; align-items: center; min-height: 44px }

  .stack-m a[data-action="go-contact"] { display: inline-flex; align-items: center; min-height: 44px }
  .link-cta { display: inline-flex !important; align-items: center; min-height: 44px }
  [data-action="filter"] { padding-block: 12px !important; min-height: 44px }

  /* Un lien en ligne ne peut pas faire 44 px sans décaler le texte : 4 px de
     padding suffisent à passer les 24 px de WCAG 2.5.8 sans chevauchement
     (25,6 px d'interligne − 17 px de contenu = 8,6 px à partager). */
  .prose a, main p a, main li a { padding-block: 4px }

  .hdr-tel { min-height: 44px }
  .crumbs a, .crumbs span[aria-current] { display: inline-flex; align-items: center; min-height: 32px }
}

/* Cibles hors media query : elles ne coûtent rien au bureau. */
.skip-link { min-height: 44px; display: inline-flex; align-items: center }
/* Un padding vertical sur un élément en ligne agrandit la zone de clic sans
   toucher à la hauteur de ligne. */
footer address a { padding-block: 5px }
@media (max-width: 1100px), (hover: none) {
  footer address a { display: inline-block; padding-block: 12px }
}

/* ══ SIMULATEUR ═══════════════════════════════════════════════════════════
   Grand écran : le schéma (l'effet) suit le défilement à gauche pendant qu'on
   règle les équipements (la commande) à droite — sans quoi il flottait au
   milieu de 364 px de vide et sortait de l'écran dès qu'on descendait.
   Sous 1100 px : tout s'empile et le schéma reste COLLÉ sous l'en-tête, ce qui
   rend chaque appui immédiatement visible.
   ══════════════════════════════════════════════════════════════════════ */
.cfg-grid > * { min-width: 0 }
[data-cfg] [hidden] { display: none !important }

.cfg-lbl { font-weight: 700; fill: #0f1e2b; paint-order: stroke; stroke: #fff; stroke-width: 2.5; stroke-linejoin: round }
.cfg-flow { animation: cfgFlow 1s linear infinite }
.cfg-spin { transform-origin: 152px 353px; animation: cfgSpin 1.8s linear infinite }
@keyframes cfgFlow { to { stroke-dashoffset: -32 } }
@keyframes cfgSpin { to { transform: rotate(360deg) } }
@keyframes cfgPulse { 0% { opacity: 1 } 35% { opacity: .3 } 100% { opacity: 1 } }
.cfg-pulse { animation: cfgPulse .6s ease-out }
@media (prefers-reduced-motion: reduce) {
  .cfg-flow, .cfg-spin, .cfg-pulse { animation: none !important }
}

.cfg-legend { font-size: 13.5px; font-weight: 600; line-height: 1.45; color: var(--color-text) }
.cfg-mini { display: none }

/* Boutons d'équipement (construits par shared/js/configurateur.js) */
.cfg-tg {
  width: 100%; min-height: 58px; display: flex; align-items: center; gap: 14px;
  padding: 11px 14px; text-align: left; cursor: pointer; font: inherit; color: inherit;
  background: #fff; border: 2px solid var(--color-divider); transition: background .2s, color .2s;
}
.cfg-tg[aria-pressed="true"] { background: var(--color-text); color: #fff }
.cfg-tg:hover { background: var(--color-accent-100) }
.cfg-tg[aria-pressed="true"]:hover { background: var(--color-accent-900) }
.cfg-box { width: 24px; height: 24px; flex: none; border: 2px solid currentColor; display: inline-flex; align-items: center; justify-content: center; font-size: 15px; font-weight: 800 }
.cfg-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0 }
.cfg-t { font-size: 15px; font-weight: 800; font-family: var(--font-heading); line-height: 1.15 }
.cfg-d { font-size: 12.5px; color: rgba(15, 30, 43, .68) }
.cfg-tg[aria-pressed="true"] .cfg-d { color: rgba(255, 255, 255, .75) }
.cfg-aide { border: 2px solid var(--color-divider); padding: 4px 9px; font-size: 12.5px; font-weight: 600 }
/* Les deux chiffres suivent la largeur de leur demi-colonne : à 36 px figés,
   « 4 800 € / an » remplissait la cellule au pixel près. */
.cfg-num { font-size: clamp(28px, 2.6vw, 36px) }
.cfg-cta:hover { background: var(--cta-dark, #d9ab00) !important }

/* Grand écran : le schéma suit le défilement au lieu de flotter dans le vide. */
@media (min-width: 1101px) {
  .cfg-left { justify-content: flex-start !important }
  .cfg-inner { position: sticky; top: calc(var(--hdr-h) + 16px) }
}

/* Deux colonnes seulement au-delà de 1100 px : en dessous, le panneau de
   commande tombait à 319 px et le schéma rendait ses libellés à 7 px. */
@media (max-width: 1100px) {
  /* display:block et non grid : dans une grille, la zone d'un élément fait sa
     propre hauteur — un position:sticky n'y a aucune course à parcourir. */
  .cfg-grid { display: block !important }
  .cfg-left {
    position: sticky; top: var(--hdr-h); z-index: 3;
    background: #fff;
    border-right: 0 !important; border-bottom: 2px solid var(--color-divider);
    padding: 12px clamp(12px, 3vw, 24px) 10px !important;
    box-shadow: 0 8px 16px -10px rgba(15, 30, 43, .45);
  }
  .cfg-svg {
    height: clamp(130px, 26vh, 240px) !important; width: 100% !important;
    overflow: hidden !important;
  }
  /* À cette échelle les libellés du dessin tomberaient à 5 px : c'est la
     légende en clair, juste dessous, qui les remplace. */
  .cfg-lbl { display: none }
  .cfg-note { display: none }
  .cfg-mini { display: block; flex: 1 1 100% }
  .cfg-legend { margin-top: 8px !important }
  .cfg-foot { margin-top: 10px !important; padding-top: 8px !important }
}

/* Écran de 568 px de haut : la bande collante doit laisser de la place aux
   équipements qu'on vient y cocher. Placé après le palier 1100, qui fixe
   sinon la hauteur du schéma. */
@media (max-width: 400px) {
  .cfg-svg { height: clamp(112px, 21vh, 190px) !important }
  .cfg-legend { font-size: 12.5px }
  .cfg-foot { font-size: 12.5px }
}

/* Poignée du curseur de facture : 16 px en natif, quatre fois moins que le
   minimum tactile. Le bureau à la souris garde le curseur natif et sa accent-color. */
@media (max-width: 1100px), (hover: none) {
  .cfg-range { -webkit-appearance: none; appearance: none; height: 44px !important; background: transparent; margin: 4px 0 0 !important; touch-action: pan-y }
  .cfg-range::-webkit-slider-runnable-track { height: 8px; background: rgba(15, 30, 43, .18) }
  .cfg-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 30px; height: 30px; margin-top: -11px; background: var(--color-accent); border: 2px solid #0f1e2b; border-radius: 0 }
  .cfg-range::-moz-range-track { height: 8px; background: rgba(15, 30, 43, .18); border: 0 }
  .cfg-range::-moz-range-thumb { width: 30px; height: 30px; background: var(--color-accent); border: 2px solid #0f1e2b; border-radius: 0 }
}

/* ── Téléphone en paysage ────────────────────────────────────────────────
   Sur 390 px de haut, un héros de 100 vh repoussait le titre ET l'appel à
   l'action sous le pli. On enlève la hauteur plancher, on réduit le titre et
   on retire la bande de réassurance, reprise telle quelle plus bas. */
@media (max-height: 560px) and (orientation: landscape) {
  .hero { min-height: 0 !important }
  .hero-inner { padding-top: 96px !important; padding-bottom: 26px !important }
  .hero-inner h1 { font-size: clamp(26px, 4.2vw, 34px) !important; margin-bottom: 14px !important }
  .hero-inner > div > p { font-size: 15px !important; margin-bottom: 20px !important }
  .hero-trust { display: none !important }
  .cfg-svg { height: clamp(110px, 34vh, 170px) !important }
  .cfg-left { padding-top: 8px !important; padding-bottom: 8px !important }
}

/* ── Longueur de ligne ────────────────────────────────────────────────────
   En colonne unique entre 700 et 960 px, les paragraphes atteignaient 91 à
   114 caractères — plus long que sur le bureau, là où c'est le moins
   confortable. 68 caractères est la limite haute admise pour du corps de texte. */
.prose p, .prose li { max-width: 68ch }

/* ── Bandeau « Aides 2026 » ───────────────────────────────────────────────
   Empilé, il consommait 210 px du premier écran d'un iPhone SE avant même le
   titre de la page. On resserre sans rien retirer du texte. */
@media (max-width: 600px) {
  .stack-m { gap: 6px !important }
  .aides-bar { font-size: 13px !important; padding-top: 8px !important; padding-bottom: 8px !important; line-height: 1.45 }
}

/* Deux cibles de l'en-tête restaient à 40 et 42 px sur téléphone. */
@media (max-width: 600px) {
  .hdr-bar > a:first-child { min-height: 44px }
  .hdr-bar a[data-page="contact"] { min-height: 44px }
}

/* ══ PAGE DE CHARGEMENT ═══════════════════════════════════════════════════
   Les 13 pétales du logo sortent un par un depuis le bas, en spirale : chacun
   part réduit et pivoté AUTOUR DU CŒUR de la fleur (transform-box:view-box),
   pas autour de lui-même — c'est ce qui donne le déploiement. Ils sont triés
   par angle dans le gabarit, --n porte le rang.
   Puis la typographie monte, puis le voile s'efface.
   Le repli sans JavaScript est assuré par la dernière animation : même si rien
   ne tourne, le voile disparaît au bout de 2,4 s.
   ═══════════════════════════════════════════════════════════════════════ */
#chargement {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background: #fff;
  animation: ldRepli 0s linear 2.2s forwards;   /* filet : jamais bloquant */
}
/* Deuxième page vue de la session : le voile n'existe même pas. */
.sans-splash #chargement { display: none }
.ld-pile { display: flex; flex-direction: column; align-items: center; gap: clamp(18px, 4vh, 34px) }
.ld-fleur { width: clamp(112px, 26vmin, 190px); height: auto; display: block; overflow: visible }
.ld-fleur path {
  transform-box: view-box; transform-origin: 50% 50%;
  animation: ldPetale .45s cubic-bezier(.2, .9, .3, 1) both;
  animation-delay: calc(var(--n) * 40ms);
}
/* La typographie reste une image. Sans JavaScript, elle apparaît au bout d'une
   seconde ; avec, site.js attend qu'elle soit vraiment chargée (en réseau bridé
   elle arrivait après le début de son propre fondu). */
.ld-mot {
  width: clamp(150px, 40vmin, 260px); height: auto; display: block;
  opacity: 0; animation: ldMot .5s cubic-bezier(.2, .8, .3, 1) .95s forwards;
}
.ld-mot.ld-attente { animation: none }
.ld-mot.ld-visible { animation: ldMot .5s cubic-bezier(.2, .8, .3, 1) 0s forwards }
@keyframes ldPetale {
  from { opacity: 0; transform: rotate(-40deg) scale(.32) }
  to   { opacity: 1; transform: none }
}
@keyframes ldMot {
  from { opacity: 0; transform: translateY(12px) }
  to   { opacity: 1; transform: none }
}
@keyframes ldRepli { to { opacity: 0; visibility: hidden } }

/* Sortie pilotée par site.js dès que la page a fini de charger. */
#chargement.ld-parti {
  opacity: 0; visibility: hidden;
  transition: opacity .4s ease, visibility 0s linear .4s;
  animation: none;
}

/* « Moins d'animations » : le logo se pose, sans spirale ni rotation. */
@media (prefers-reduced-motion: reduce) {
  .ld-fleur path { animation: ldPose .3s ease-out both; animation-delay: 0s }
  .ld-mot { animation: ldPose .3s ease-out .15s forwards }
  #chargement { animation-delay: 1.2s }
  @keyframes ldPose { from { opacity: 0 } to { opacity: 1 } }
}

/* ── Logo de l'en-tête ────────────────────────────────────────────────────
   Sur l'accueil, l'en-tête est transparent au-dessus d'un héros sombre : le
   bleu de la typographie y descend sous le seuil de lisibilité. On bascule
   alors sur la version inversée (fleur intacte, typographie blanche). Dès que
   l'en-tête devient plein — au défilement ou menu ouvert — le logo couleur
   revient. Les deux fichiers ont exactement les mêmes dimensions : la bascule
   ne décale rien. */
.logo-inverse { display: none }
body.home header:not(.solid):not(.menu-open) .logo-couleur { display: none }
body.home header:not(.solid):not(.menu-open) .logo-inverse { display: block }

/* ══ TRANSITION ENTRE LES PAGES ═══════════════════════════════════════════
   Fondu enchaîné de 250 ms au changement de page, joué PENDANT le chargement :
   il ne coûte aucune attente. C'est la continuité qu'apporterait un voile à
   chaque page, sans son prix — mesuré, une navigation interne prend 51 ms en
   réseau normal et 703 ms à 1,6 Mb/s, un voile complet la ferait passer à ~2 s.
   Les navigateurs qui ne gèrent pas encore l'API naviguent comme avant : la
   règle est simplement ignorée.
   ═══════════════════════════════════════════════════════════════════════ */
@view-transition { navigation: auto }

/* 200 ms : mesuré, le fondu est gratuit sur mobile (+4 ms à 1,6 Mb/s, il se
   joue pendant le chargement) et ne coûte son temps que sur une connexion très
   rapide, où la page était déjà affichée en 87 ms. */
::view-transition-old(root),
::view-transition-new(root) { animation-duration: .2s; animation-timing-function: ease }

/* L'en-tête est le même d'une page à l'autre : on le nomme pour qu'il reste en
   place au lieu de disparaître puis réapparaître dans le fondu. */
header { view-transition-name: ambe-entete }

/* « Moins d'animations » : la page se remplace d'un coup, sans fondu. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none }
  header { view-transition-name: none }
}

/* ═══════════════ Bandeau de consentement ═══════════════════════════════════
   Ancré en bas, jamais en plein écran : le contenu reste lisible pendant que
   le visiteur choisit, ce qui exclut le « mur de cookies ».
   Les deux boutons ont le même poids visuel — même taille, même graisse, même
   surface. Un « refuser » plus discret que « accepter » vicierait le
   consentement : la CNIL le sanctionne comme une interface trompeuse. */
.consentement {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 60;
  background: #0f1e2b;
  color: #fff;
  border-top: 4px solid var(--color-accent);
  animation: consentement-monte .28s ease-out both;
}
@keyframes consentement-monte { from { transform: translateY(100%) } to { transform: none } }
@media (prefers-reduced-motion: reduce) { .consentement { animation: none } }

.consentement-corps {
  max-width: 1240px;
  margin: 0 auto;
  padding: 18px clamp(16px, 4vw, 40px);
  display: flex;
  align-items: center;
  gap: 20px clamp(24px, 4vw, 56px);
}
.consentement-texte { flex: 1 1 auto; min-width: 0 }
.consentement-titre {
  margin: 0 0 4px;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 15px;
  letter-spacing: .02em;
}
.consentement-detail {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(255, 255, 255, .82);
  max-width: 74ch;
}
.consentement-detail a { color: #fff; text-underline-offset: 3px }

.consentement-boutons { flex: none; display: flex; gap: 10px }
.consentement-boutons button {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 14px;
  padding: 12px 22px;
  border: 2px solid #fff;
  cursor: pointer;
  white-space: nowrap;
  min-width: 148px;
  transition: background .15s ease, color .15s ease;
}
/* Fond, texte, bordure, taille : rigoureusement identiques pour les deux.
   Un « accepter » en blanc plein face à un « refuser » en contour se lit comme
   une incitation, et c'est le motif de sanction le plus fréquent de la CNIL sur
   les bandeaux. Ici, seul le libellé distingue les deux boutons. */
.consentement-boutons button { background: #fff; color: #0f1e2b }
.consentement-boutons button:hover { background: var(--color-accent-100, #eef6fb) }
.consentement-boutons button:focus-visible { outline: 3px solid var(--color-accent-400); outline-offset: 3px }

/* Sous 720 px la ligne unique casserait les libellés : on empile, en gardant
   les deux boutons côte à côte et de largeur égale. */
@media (max-width: 720px) {
  .consentement-corps { flex-direction: column; align-items: stretch; gap: 14px; padding: 16px }
  .consentement-boutons button { flex: 1 1 0; min-width: 0; padding: 13px 12px }
}
