/* SIWEL — feuille de style unique (vitrine + espace client).
   Pas de framework : la page doit rester légère, la machine est partagée avec
   le moteur d'interprétation. Tout tient dans un fichier, servi tel quel. */

/* Charte SIWEL : deux couleurs de marque, le bleu nuit #1A2845 et le rouge
   #C52226 du lettrage. Le bleu porte la structure (liens, boutons, surfaces
   sombres), le rouge sert d'accent. Le rouge d'alerte a été aligné sur le rouge
   de marque : deux rouges voisins sur la même page se liraient comme une
   maladresse plutôt que comme une distinction. */
:root {
  --encre:      #141a2b;
  --encre-doux: #4a5168;
  --gris:       #646b83;   /* 5,03:1 sur le crème ; #7b8299 tombait à 3,64:1 */
  --trait:      #e4e2dd;
  --fond:       #fbf9f6;
  --blanc:      #ffffff;
  --nuit:       #111c31;
  --nuit-clair: #1f2e4c;
  --primaire:   #1a2845;
  --primaire-f: #0f1a2e;
  --primaire-p: #e9edf5;
  /* Le bleu de marque est trop sombre pour s'écrire SUR les fonds --nuit (il y
     disparaît). Cette variante éclaircie n'existe que pour ces cas-là. */
  --primaire-c: #8fa8d4;
  --ambre:      #e8833a;
  --ambre-p:    #fdf1e6;
  --vert:       #157f5b;
  --vert-p:     #e6f4ef;
  --rouge:      #c52226;
  --rouge-f:    #a4171b;
  --rouge-p:    #fbecec;
  --r:    14px;
  --r-s:  9px;
  --ombre:   0 1px 2px rgba(17,28,49,.05), 0 8px 24px rgba(17,28,49,.07);
  --ombre-f: 0 2px 6px rgba(17,28,49,.08), 0 18px 44px rgba(17,28,49,.13);
  /* Dérivées de l'accent, surchargées en marque blanche (marque.variables_css).
     --sur-accent : ce qui s'écrit SUR l'accent. --rouge-t : l'accent en TEXTE
     sur le crème. --accent-sombre : l'accent sur les surfaces nuit. */
  --sur-accent: #ffffff;
  --rouge-t:    #c52226;
  --accent-sombre: #ef9092;
  --police: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto,
            "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--police);
  font-size: 17px;
  line-height: 1.6;
  color: var(--encre);
  background: var(--fond);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { line-height: 1.15; letter-spacing: -.02em; margin: 0 0 .5em; font-weight: 680; }
h1 { font-size: clamp(2.1rem, 5vw, 3.4rem); letter-spacing: -.03em; }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.3rem); }
h3 { font-size: 1.2rem; }
p  { margin: 0 0 1em; }
/* Le bleu de marque est à quelques points de la couleur du texte : contrairement
   au violet précédent, un lien posé dans un paragraphe ne se distingue plus par
   la couleur seule. D'où le soulignement permanent, discret au repos et franc au
   survol. Les liens qui portent déjà leur affordance (navigation, boutons, pied,
   menu latéral) le retirent juste en dessous. */
a  { color: var(--primaire); text-decoration: underline;
     text-decoration-thickness: 1px; text-underline-offset: .18em;
     text-decoration-color: rgba(26,40,69,.35); }
a:hover { text-decoration-color: currentColor; }
.nav a, .pied a, .flanc nav a, .flanc .bas a, .logo, .btn { text-decoration: none; }
strong { font-weight: 640; }
small { font-size: .82rem; }

.conteneur { width: min(1140px, 100% - 3rem); margin-inline: auto; }
.etroit    { width: min(760px, 100% - 3rem); margin-inline: auto; }

/* --- en-tête ------------------------------------------------------------- */
.entete {
  position: sticky; top: 0; z-index: 50;
  background: rgba(251,249,246,.88);
  backdrop-filter: blur(10px);
  /* Pas de bordure : l'onde sous la navigation fait la séparation. */
}
.entete-in { display: flex; align-items: center; gap: 1.6rem; height: 68px; }
.logo { display: flex; align-items: center; text-decoration: none; }
.logo:hover { text-decoration: none; }
/* Le lettrage porte sa hauteur en style en ligne (macro `logo`) ; la largeur
   doit suivre, sinon l'attribut width="800" l'emporte et le mot déborde. */
.logo-img { width: auto; display: block; flex: none; }
/* Marque blanche sur surface sombre : le logo d'un revendeur n'a pas de
   variante claire, et sa partie foncée y disparaît. La plaque est la seule
   solution qui n'invente pas une couleur qu'il n'a pas choisie. */
.logo-plaque { background: #fff; padding: .4rem .6rem; border-radius: 8px;
               box-sizing: content-box; }
.nav { display: flex; align-items: center; gap: 1.5rem; margin-left: auto; }
.nav a { color: var(--encre-doux); font-size: .95rem; font-weight: 520; }
.nav a:hover, .nav a.actif { color: var(--encre); text-decoration: none; }
.nav a.actif { font-weight: 640; }
/* Le bouton du menu est un `<a>` : sans cette règle, `.nav a` l'emporte sur
   `.btn-p` (même spécificité de classe, mais un sélecteur de plus) et le libellé
   ressort en gris foncé sur le fond bleu du bouton — illisible. */
.nav a.btn-p, .nav a.btn-p:hover { color: #fff; }
.menu-btn { display: none; background: none; border: 0; font-size: 1.5rem;
            color: var(--encre); cursor: pointer; margin-left: auto; padding: .2rem .4rem; }

/* --- boutons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .72rem 1.35rem; border-radius: 999px; border: 1px solid transparent;
  font: inherit; font-size: .96rem; font-weight: 600; cursor: pointer;
  transition: transform .16s cubic-bezier(.22,.9,.3,1),
              box-shadow .18s cubic-bezier(.22,.9,.3,1),
              background .18s cubic-bezier(.22,.9,.3,1);
  text-decoration: none; white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: translateY(-1px); }
}
.btn:hover { text-decoration: none; }
/* L'appui doit se sentir même sans survol possible : `translateY(0)` seul
   n'annulait que le soulèvement, donc ne faisait rien au doigt. */
.btn:active { transform: scale(.97); transition-duration: .07s; }
/* ⚠️ Aucun anneau de focus n'existait sur .btn : au clavier, rien n'indiquait
   où l'on était — y compris sur le bouton qui déplie le calculateur. */
.btn:focus-visible { outline: 3px solid var(--ambre); outline-offset: 3px; }
.btn-p { background: var(--primaire); color: #fff; box-shadow: 0 6px 18px rgba(26,40,69,.26); }
.btn-p:hover { background: var(--primaire-f); color: #fff; }
.btn-s { background: var(--blanc); color: var(--encre); border-color: var(--trait); box-shadow: var(--ombre); }
.btn-s:hover { border-color: #cfccc6; color: var(--encre); }
.btn-f { background: transparent; color: var(--encre-doux); border-color: transparent; padding-inline: .4rem; }
.btn-f:hover { color: var(--encre); }
.btn-d { background: var(--rouge); color: var(--sur-accent); }
.btn-d:hover { background: var(--rouge-f); color: var(--sur-accent); }
.btn-sm { padding: .46rem .9rem; font-size: .87rem; }
.btn-bloc { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }

/* --- héros --------------------------------------------------------------- */
.heros { padding: clamp(3.5rem, 8vw, 6.5rem) 0 clamp(3rem, 6vw, 5rem); }
.heros p.chapo { font-size: clamp(1.05rem, 2vw, 1.28rem); color: var(--encre-doux);
                 max-width: 42ch; margin-bottom: 2rem; }
.heros-grille { display: grid; grid-template-columns: 1.05fr .95fr; gap: 3.5rem; align-items: center; }
.pastille {
  display: inline-flex; align-items: center; gap: .5rem; margin-bottom: 1.3rem;
  padding: .34rem .85rem .34rem .5rem; border-radius: 999px;
  background: var(--primaire-p); color: var(--primaire-f);
  font-size: .84rem; font-weight: 600;
}
.pastille b { background: var(--rouge); color: var(--sur-accent); border-radius: 999px;
              padding: .08rem .5rem; font-size: .76rem; font-weight: 700; }
.actions { display: flex; flex-wrap: wrap; gap: .8rem; align-items: center; }
.sous-actions { margin-top: 1.1rem; color: #5b6480; font-size: .88rem; }

/* --- démonstration visuelle du flux ------------------------------------- */
.demo {
  background: var(--nuit); color: #e7ecf4; border-radius: 20px; padding: 1.5rem;
  box-shadow: var(--ombre-f); font-size: .93rem;
}
.demo-tete { display: flex; align-items: center; gap: .5rem; padding-bottom: .9rem;
             border-bottom: 1px solid rgba(255,255,255,.1); margin-bottom: 1rem; }
.point { width: 9px; height: 9px; border-radius: 50%; background: #ff5f57; }
.point:nth-child(2) { background: #febc2e; }
.point:nth-child(3) { background: #28c840; }
.demo-tete span { margin-left: auto; color: #8593ae; font-size: .78rem; letter-spacing: .06em; }
.bulle { margin-bottom: .7rem; padding: .7rem .95rem; border-radius: 12px;
         background: var(--nuit-clair); position: relative; }
.bulle .qui { display: block; font-size: .72rem; letter-spacing: .09em;
              text-transform: uppercase; color: #93a2bd; margin-bottom: .25rem; }
.bulle.cible { background: rgba(50,82,140,.30); border: 1px solid rgba(143,168,212,.40); }
.bulle.cible .qui { color: var(--primaire-c); }
.bulle[dir="rtl"] { text-align: right; }
.demo-pied span { display: inline-flex; align-items: center; gap: .34rem; }
.demo-pied span svg { width: 14px; height: 14px; flex: 0 0 auto; opacity: .85; }
.demo-pied { display: flex; gap: 1.2rem; color: #8593ae; font-size: .78rem;
             padding-top: .9rem; border-top: 1px solid rgba(255,255,255,.1); }

/* --- sections ------------------------------------------------------------ */
section { padding: clamp(3rem, 6vw, 5rem) 0; }
.section-sombre { background: var(--nuit); color: #e7ecf4; }
.section-sombre h2 { color: #fff; }
.section-sombre p { color: #b4c1d8; }
.tete-section { max-width: 58ch; margin-bottom: 2.6rem; }
.tete-section.centre { margin-inline: auto; text-align: center; }
.tete-section p { color: var(--encre-doux); font-size: 1.06rem; margin-bottom: 0; }
.surtitre { display: block; font-size: .78rem; font-weight: 700; letter-spacing: .13em;
            text-transform: uppercase; color: var(--rouge-t); margin-bottom: .7rem; }
.section-sombre .surtitre { color: var(--accent-sombre, #ef9092); }

/* ⚠️ Cartes DANS la bande sombre. `.section-sombre` impose un texte clair à
   toute la section, et `.carte` un fond BLANC : combinées sans règle dédiée,
   les quatre cartes de cette bande affichaient du texte clair sur blanc —
   mesuré à 1,19:1 pour les titres et 1,82:1 pour le corps, contre 4,5:1
   exigé. Autrement dit : la section qui explique ce qui distingue SIWEL était
   illisible. On rend la carte sombre plutôt que d'assombrir son texte : la
   bande garde son unité, et le contraste redevient franc. */
.section-sombre .carte {
  background: var(--nuit-clair);
  border-color: rgba(255, 255, 255, .10);
  box-shadow: none;
}
.section-sombre .carte h3 { color: #fff; }
.section-sombre .carte p { color: #cfd9ea; }
/* Le chapô de section a sa propre couleur, choisie pour un fond CLAIR : sur la
   bande sombre elle tombait à 2,16:1. Même cause que les cartes — une règle plus
   spécifique qui ignore le fond sur lequel elle atterrit. */
.section-sombre .tete-section p { color: #b4c1d8; }

.grille { display: grid; gap: 1.4rem; }
.g2 { grid-template-columns: repeat(2, 1fr); }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g4 { grid-template-columns: repeat(4, 1fr); }

.carte {
  background: var(--blanc); border: 1px solid var(--trait); border-radius: var(--r);
  padding: 1.6rem; box-shadow: var(--ombre);
}
.carte h3 { margin-bottom: .4rem; }
.carte p:last-child { margin-bottom: 0; }
.carte .ico { width: 42px; height: 42px; border-radius: 11px; background: var(--primaire-p);
              color: var(--primaire-f); display: grid; place-items: center;
              margin-bottom: 1rem; font-size: 1.2rem; }
.carte.ambre .ico { background: var(--ambre-p); color: #b45f18; }

.liste-check { list-style: none; padding: 0; margin: 0; }
.liste-check li { position: relative; padding-left: 1.8rem; margin-bottom: .6rem; }
.liste-check li::before {
  content: ""; position: absolute; left: 0; top: .42em;
  width: 8px; height: 8px; border-radius: 50%; background: var(--primaire);
}

/* --- tarifs -------------------------------------------------------------- */
.tarifs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; align-items: start; }
.tarif { background: var(--blanc); border: 1px solid var(--trait); border-radius: var(--r);
         padding: 1.9rem 1.6rem; box-shadow: var(--ombre); display: flex; flex-direction: column; }
.tarif.vedette { border-color: var(--primaire); box-shadow: var(--ombre-f); position: relative; }
.tarif .etiquette { position: absolute; top: -13px; left: 1.6rem; background: var(--rouge);
                    color: var(--sur-accent); font-size: .74rem; font-weight: 700; letter-spacing: .08em;
                    text-transform: uppercase; padding: .25rem .75rem; border-radius: 999px; }
.tarif .nom { font-size: 1.15rem; font-weight: 680; margin-bottom: .2rem; }
.tarif .resume { color: var(--gris); font-size: .9rem; min-height: 3em; }
.prix { display: flex; align-items: baseline; gap: .35rem; margin: 1rem 0 .15rem; }
.prix .montant { font-size: 2.5rem; font-weight: 700; letter-spacing: -.04em; }
.prix .unite { color: var(--gris); font-size: .93rem; }
.tarif .ttc { color: var(--gris); font-size: .82rem; margin-bottom: 1.2rem; }
.tarif .quota { background: var(--primaire-p); color: var(--primaire-f); border-radius: var(--r-s);
                padding: .7rem .9rem; font-weight: 620; font-size: .95rem; margin-bottom: 1.3rem; }
.tarif ul { flex: 1; margin-bottom: 1.5rem; }

/* --- tableaux ------------------------------------------------------------ */
.tableau-enveloppe { overflow-x: auto; border: 1px solid var(--trait); border-radius: var(--r);
                     background: var(--blanc); box-shadow: var(--ombre); }
table { width: 100%; border-collapse: collapse; font-size: .93rem; }
th, td { padding: .8rem 1rem; text-align: left; border-bottom: 1px solid var(--trait); }
th { font-size: .76rem; letter-spacing: .07em; text-transform: uppercase;
     color: var(--gris); font-weight: 700; background: #faf9f7; }
tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Sélecteur volontairement restreint à `td` : la classe `.vide` sert aussi aux
   colonnes sans consommation de l'histogramme, qui héritaient sinon de ces
   40 px de marge intérieure et se retrouvaient 80 px plus hautes que les
   autres — les barres ne partaient plus de la même ligne de base. */
td.vide { padding: 2.5rem 1rem; text-align: center; color: var(--gris); }

/* --- formulaires --------------------------------------------------------- */
.champ { margin-bottom: 1.05rem; }
.champ label { display: block; font-size: .88rem; font-weight: 620; margin-bottom: .35rem; }
.champ .aide { display: block; color: var(--gris); font-size: .82rem; margin-top: .3rem; }
input[type=text], input[type=email], input[type=password], input[type=tel],
input[type=number], select, textarea {
  width: 100%; padding: .72rem .9rem; font: inherit; font-size: .96rem;
  color: var(--encre); background: var(--blanc);
  border: 1px solid #d8d5ce; border-radius: var(--r-s);
  transition: border-color .15s cubic-bezier(.22,.9,.3,1),
              box-shadow .15s cubic-bezier(.22,.9,.3,1);
}
input:focus, select:focus, textarea:focus {
  outline: 0; border-color: var(--primaire); box-shadow: 0 0 0 3px rgba(26,40,69,.18);
}
textarea { min-height: 130px; resize: vertical; }
.champ-case { display: flex; align-items: flex-start; gap: .6rem; font-size: .9rem; }
.champ-case input { margin-top: .25rem; flex: none; }
.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.pot-de-miel { position: absolute; left: -9999px; opacity: 0; height: 0; }

/* --- messages ------------------------------------------------------------ */
.avis { border-radius: var(--r-s); padding: .85rem 1.1rem; margin-bottom: 1.4rem;
        font-size: .93rem; border: 1px solid; }
.avis-ok  { background: var(--vert-p);  border-color: #bfe0d3; color: #0f5c42; }
.avis-err { background: #fbecec; border-color: #f2cbcc; color: #8e1417; }
.avis-info{ background: var(--primaire-p); border-color: #ccd7e8; color: var(--primaire-f); }
.avis ul { margin: .4rem 0 0; padding-left: 1.1rem; }

/* --- espace client ------------------------------------------------------- */
.app { display: grid; grid-template-columns: 244px 1fr; min-height: 100vh; }
.flanc { background: var(--nuit); color: #c0cade; padding: 1.5rem 1.1rem;
         display: flex; flex-direction: column; gap: 1.6rem; }
.flanc .logo { color: #fff; padding-inline: .4rem; }
.flanc nav { display: flex; flex-direction: column; gap: .15rem; }
.flanc nav a { color: #a4b2cb; padding: .6rem .8rem; border-radius: var(--r-s);
               font-size: .95rem; font-weight: 540; display: flex; gap: .6rem; align-items: center; }
@media (hover: hover) and (pointer: fine) {
  .flanc nav a:hover { background: rgba(255,255,255,.07); color: #fff; text-decoration: none; }
}
/* Le bleu de marque EST le fond du menu latéral : l'élément actif se marque
   donc au rouge d'accent, seule couleur qui ressorte sur cette surface. */
.flanc nav a.actif { background: var(--rouge); color: var(--sur-accent); }
.flanc .bas { margin-top: auto; font-size: .84rem; color: #7e8da8; }
.flanc .bas a { color: #a4b2cb; }
.contenu { padding: 2.2rem clamp(1.2rem, 3vw, 2.8rem) 4rem; min-width: 0; }
.contenu-tete { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap;
                margin-bottom: 1.8rem; }
.contenu-tete h1 { font-size: 1.85rem; margin-bottom: .2rem; }
.contenu-tete p { color: var(--gris); margin: 0; font-size: .95rem; }
.contenu-tete .actions { margin-left: auto; }

.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-bottom: 1.8rem; }
.stat { background: var(--blanc); border: 1px solid var(--trait); border-radius: var(--r);
        padding: 1.2rem 1.3rem; box-shadow: var(--ombre); }
.stat .cle { font-size: .78rem; letter-spacing: .06em; text-transform: uppercase;
             color: var(--gris); font-weight: 700; margin-bottom: .4rem; }
.stat .val { font-size: 1.8rem; font-weight: 700; letter-spacing: -.03em; line-height: 1.1; }
.stat .sous { color: var(--gris); font-size: .84rem; margin-top: .2rem; }

.jauge { height: 10px; border-radius: 999px; background: #e7ebf2; overflow: hidden; margin: .7rem 0 .5rem; }
.jauge span { display: block; height: 100%; border-radius: 999px; background: var(--primaire);
              transform-origin: left center;
              transition: transform .26s cubic-bezier(.22,.9,.3,1); }
.jauge.chaud span { background: var(--ambre); }
.jauge.plein span { background: var(--rouge); }

.badge { display: inline-block; padding: .16rem .6rem; border-radius: 999px;
         font-size: .76rem; font-weight: 660; letter-spacing: .02em; }
.badge-ok    { background: var(--vert-p); color: var(--vert); }
.badge-attn  { background: var(--ambre-p); color: #a95c14; }
.badge-err   { background: #fbecec; color: #a4171b; }
.badge-neutre{ background: #eeedea; color: var(--encre-doux); }

/* Histogramme de consommation, en CSS pur : pas de bibliothèque de graphiques
   pour quatorze barres. */
/* `overflow: hidden` : sur 90 jours, les dates (non coupables) dépassent leur
   colonne de 12 px et faisaient apparaître une barre de défilement horizontale
   sur toute la page. */
.histo { display: flex; align-items: flex-end; gap: 3px;
         padding: 1rem 1.2rem .8rem; background: var(--blanc); border: 1px solid var(--trait);
         border-radius: var(--r); box-shadow: var(--ombre); overflow: hidden; }
/* `min-width: 0` est indispensable : sans lui, l'étiquette de date (non
   coupable, `nowrap`) impose une largeur minimale à chaque colonne et une série
   de 30 ou 90 jours débordait de la carte au lieu de se comprimer. */
.histo .barre { flex: 1; min-width: 0; display: flex; flex-direction: column;
                align-items: center; gap: .4rem; }
/* La piste porte une hauteur DÉFINIE et sert de repère aux pourcentages des
   barres. Une piste en `flex: 1` semblait plus élégante mais ne donnait pas la
   même hauteur selon que la barre était vide ou non (mesuré : 39 px contre
   119 px) — un pourcentage résolu contre une hauteur elle-même issue du contenu
   est un piège. Ici tout est déterministe et toutes les colonnes partagent la
   même ligne de base. */
.histo .piste { width: 100%; height: 118px; display: flex; align-items: flex-end; }
.histo .barre i { display: block; width: 100%; min-height: 2px; border-radius: 4px 4px 0 0;
                  background: var(--primaire); opacity: .92; }
@media (hover: hover) and (pointer: fine) { .histo .barre:hover i { opacity: 1; } }
/* `min-height` réserve la place de l'étiquette même quand elle est vide (séries
   longues où l'on n'affiche qu'une date sur trois) : sans elle, ces colonnes
   n'ont pas la même hauteur de texte et leurs barres ne partent pas de la même
   ligne de base. */
.histo .barre em { font-style: normal; font-size: .66rem; color: var(--gris);
                   white-space: nowrap; min-height: 1.1em; line-height: 1.1; }
.histo .barre.vide i { background: #e3e8f0; }

/* --- pied de page -------------------------------------------------------- */
.pied { background: var(--nuit); color: #95a3bd; padding: 3.5rem 0 2rem; font-size: .92rem; }
.pied-grille { display: grid; grid-template-columns: 1.6fr repeat(3, 1fr); gap: 2.4rem; }
.pied h4 { color: #fff; font-size: .84rem; letter-spacing: .09em; text-transform: uppercase;
           margin-bottom: .9rem; }
.pied a { color: #95a3bd; display: block; margin-bottom: .45rem; }
.pied a:hover { color: #fff; text-decoration: none; }
.pied .logo { color: #fff; margin-bottom: .8rem; }
.pied-bas { margin-top: 2.6rem; padding-top: 1.4rem; border-top: 1px solid rgba(255,255,255,.1);
            display: flex; gap: 1.2rem; flex-wrap: wrap; color: #78869f; font-size: .85rem; }
.pied-bas a { display: inline; margin: 0; }

/* --- page légale --------------------------------------------------------- */
.legal { background: var(--blanc); border: 1px solid var(--trait); border-radius: var(--r);
         padding: clamp(1.5rem, 4vw, 3rem); box-shadow: var(--ombre); }
.legal h2 { font-size: 1.3rem; margin-top: 2.2rem; }
.legal h2:first-of-type { margin-top: 0; }
.legal h3 { font-size: 1.02rem; margin-top: 1.4rem; }
.legal ul { padding-left: 1.2rem; }
.legal li { margin-bottom: .4rem; }
.legal .maj { color: var(--gris); font-size: .88rem; }

/* --- responsive ---------------------------------------------------------- */
@media (max-width: 940px) {
  .heros-grille, .g4, .tarifs, .stats, .pied-grille { grid-template-columns: 1fr 1fr; }
  .g3 { grid-template-columns: 1fr 1fr; }
  .app { grid-template-columns: 1fr; }
  .flanc { flex-direction: row; align-items: center; gap: 1rem; padding: .8rem 1rem;
           overflow-x: auto; }
  .flanc nav { flex-direction: row; }
  .flanc .bas { display: none; }
}
@media (max-width: 720px) {
  body { font-size: 16px; }
  .conteneur, .etroit { width: calc(100% - 2rem); }
  .nav { display: none; }
  .nav.ouvert { display: flex; position: absolute; top: 68px; left: 0; right: 0;
                flex-direction: column; align-items: stretch; gap: 0;
                background: var(--blanc); border-bottom: 1px solid var(--trait);
                padding: .5rem 1rem 1rem; box-shadow: var(--ombre); }
  .nav.ouvert a { padding: .7rem .2rem; border-bottom: 1px solid var(--trait); }
  .nav.ouvert .btn { margin-top: .8rem; }
  .menu-btn { display: block; }
  .heros-grille, .g2, .g3, .g4, .tarifs, .stats, .duo, .pied-grille { grid-template-columns: 1fr; }
  .contenu-tete .actions { margin-left: 0; width: 100%; }
}

@media print {
  .entete, .pied, .flanc, .actions { display: none; }
  body { background: #fff; }
}


/* =========================================================================
   ADMINISTRATION — droits d'un compte et solde d'heures d'IA (31-08-2026)
   L'IA et la transcription s'ouvrent compte par compte, à la main, après accord
   commercial : ces cases sont la seule commande de cette décision.
   ========================================================================= */
.bandeau-ok, .bandeau-err {
  border-radius: 12px; padding: .8rem 1.1rem; margin-bottom: 1.4rem;
  font-size: .95rem; border: 1px solid;
}
.bandeau-ok  { background: #eaf7ef; border-color: #bfe3cd; color: #1d6b3c; }
.bandeau-err { background: #fdeeee; border-color: #f2c7c8; color: #a3282c; }

.panneau {
  background: var(--blanc); border: 1px solid var(--trait); border-radius: var(--r);
  padding: 1.5rem; margin-bottom: 1.6rem;
}
.panneau h2 { font-size: 1.12rem; margin-bottom: 1.1rem; }

.droits { display: grid; gap: .7rem; margin-bottom: 1.6rem; }
.droit { display: flex; gap: .7rem; align-items: flex-start; cursor: pointer;
         padding: .7rem .9rem; border: 1px solid var(--trait); border-radius: 12px; }
@media (hover: hover) and (pointer: fine) { .droit:hover { background: #fafbfd; } }
.droit input { margin-top: .25rem; width: 17px; height: 17px; accent-color: var(--primaire); }
.droit strong { display: block; font-size: .96rem; }
/* La justification vit à côté de la case, pas dans une note de bas de page :
   c'est au moment de cocher qu'on a besoin de savoir ce qu'on ouvre. */
.droit em { display: block; font-style: normal; font-size: .85rem; color: var(--gris);
            margin-top: .15rem; }

.heures-ia { border-top: 1px solid var(--trait); padding-top: 1.2rem; }
.heures-ia strong { display: block; font-size: .96rem; }
.heures-ia em { font-style: normal; font-size: .85rem; color: var(--gris); }
.heures-ia .ligne { display: flex; gap: .6rem; margin: .7rem 0 .3rem; }
.heures-ia input { font: inherit; padding: .5rem .7rem; border-radius: 10px;
                   border: 1px solid var(--trait); width: 8rem; }
.heures-ia .aide { font-size: .8rem; }


/* ===== Onde sonore sous la navigation (reprise du tracé du logo) ===== */
.entete { position: relative; }
/* Réservé sous l'en-tête pour que l'onde ne recouvre pas le contenu. */
.entete-in { margin-bottom: 6px; }
.onde-nav {
  position: absolute; left: 0; right: 0; bottom: -1px;
  width: 100%; height: 22px; overflow: visible; pointer-events: none;
}
.onde-trait {
  fill: none; stroke: url(#g-onde); stroke-width: 2; stroke-linecap: round;
  /* ⚠️ Pas de `transition: d` : le tracé est déjà interpolé image par image en
     requestAnimationFrame, une transition CSS relancerait un tween sur 180
     points à chaque image. */
  transition: opacity .18s cubic-bezier(.22,.9,.3,1);
  opacity: .85;
}
@media (hover: hover) and (pointer: fine) {
  .entete:hover .onde-trait { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .onde-trait { transition: none; }
}

/* Le dégradé du logo : bleu de marque à gauche, rouge à droite. */
.onde-degrade { position: absolute; width: 0; height: 0; }


/* ===== Cartes « option » (classe `ambre`) : facturé en plus de l'abonnement ===== */
.carte.ambre {
  background: #fffaf4;
  border-color: #f0dcc6;
}
.carte .badge { margin-bottom: .55rem; }


/* ===== Surfaces dessinées par le navigateur ===== */
::selection { background: rgba(197, 34, 38, .16); color: var(--encre); }  /* rouge de marque */
:root { caret-color: var(--primaire); accent-color: var(--primaire); }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--primaire);
  outline-offset: 3px;
  border-radius: 6px;
}
:where(a, button, input, select, textarea, [tabindex]):focus:not(:focus-visible) {
  outline: none;
}

* { scrollbar-width: thin; scrollbar-color: #cdc7bd transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: #cdc7bd; border-radius: 999px;
  border: 3px solid var(--fond);
}
::-webkit-scrollbar-thumb:hover { background: #b6afa3; }

/* Chiffres alignés en colonne dans les tableaux de consommation. */
table td, .rp-v, .stat .val { font-variant-numeric: tabular-nums; }

/* === Scène d'accueil : le mot, l'onde, les porteurs de lettres ============
   Le héros passe en bande sombre : l'onde et les silhouettes ne se lisent pas
   sur le crème, et le texte gagne en contraste plutôt que d'en perdre.
   Rien n'est animé d'autre que `transform` et `opacity`.                     */
.heros-scene { position: relative; overflow: hidden; background: var(--nuit);
               padding-bottom: clamp(11rem, 24vw, 17rem); }
.heros-scene h1, .heros-scene .pastille b { color: #fff; }
/* ⚠️ `.heros p.chapo` (deux classes + un élément) l'emporte sur `.heros-scene
   .chapo` : le chapô restait en --encre-doux, soit 1,5:1 sur le bleu nuit.
   Il faut au moins la même spécificité. */
.heros-scene p.chapo { color: #b8c5dc; }
.heros-scene .sous-actions { color: #8593ae; }
.heros-scene .pastille { background: rgba(143,168,212,.16); color: #dbe4f3; }
.heros-scene .btn-s { background: transparent; color: #dbe4f3;
                      border-color: rgba(219,228,243,.45); }
@media (hover: hover) and (pointer: fine) {
  .heros-scene .btn-s:hover { background: rgba(219,228,243,.10); }
}
/* ⚠️ `.demo` est DÉJÀ sombre : sur un héros sombre elle disparaît. On la
   détache par une surface plus claire et un liseré, pas par une ombre — une
   ombre ne se voit pas sur du bleu nuit. */
.heros-scene .demo { background: var(--nuit-clair);
                     border: 1px solid rgba(143,168,212,.22); box-shadow: none; }
.heros-scene .bulle { background: rgba(9,16,30,.55); }

/* ⚠️ La scène occupait tout le héros : l'onde traversait le paragraphe et les
   porteurs marchaient sur le texte, qui devenait illisible. Elle est confinée à
   une bande basse — ce qui sert aussi l'intention, une frise qui tire l'œil vers
   le bas de page. */
.scene { position: absolute; left: 0; right: 0; bottom: 0;
         height: clamp(160px, 20vw, 240px); pointer-events: none; z-index: 0; }
.scene svg { width: 100%; height: 100%; display: block; }
.heros-scene .heros-grille { position: relative; z-index: 1; }

/* Le mot de marque, en creux. Tracé seul : rempli, il concurrencerait le titre. */
.nappe path { fill: url(#deg-nappe); }

/* Traits en dégradé : ils naissent et meurent dans le bord du cadre au lieu
   d'être coupés net. Lueur uniquement sur la crête portante. */
.onde { fill: none; stroke-linecap: round; }
.onde-1 { stroke: url(#deg-onde);   stroke-width: 3.4; filter: url(#lueur-onde); }
.onde-2 { stroke: url(#deg-onde-2); stroke-width: 2.4; }
.onde-3 { stroke: url(#deg-onde-3); stroke-width: 1.8; }

/* Les silhouettes marchent sur l'onde, chacune portant une lettre. */
.porteur { transform-box: fill-box; }
/* (Ancienne règle du héros, conservée pour la pile de polices.)
   ⚠️ Chaque écriture a besoin d'une police qui la couvre. La pile du site
   (-apple-system, Segoe UI, Inter…) ne porte ni l'arabe, ni l'hébreu, ni le CJK :
   sans ces noms explicites, le visiteur voit un carré à la place de la lettre —
   ce qui, pour une société de traduction, est le pire rendu possible.
   Les noms couvrent Windows, macOS/iOS, Android et Linux. */
.porteur .lettre {
  fill: #fff; font-size: 22px; font-weight: 700; text-anchor: middle;
  font-family: var(--police),
    "Segoe UI Historic", "Noto Sans Arabic", "Geeza Pro", "Arabic Typesetting",
    "Noto Sans Hebrew", "Arial Hebrew", "Noto Sans Devanagari", "Nirmala UI",
    "Devanagari Sangam MN", "Noto Sans CJK SC", "PingFang SC", "Microsoft YaHei",
    "Noto Sans", "DejaVu Sans", sans-serif;
}

@media (prefers-reduced-motion: no-preference) {
  /* Une seule période de translation : la trame de l'onde mesure exactement
     400 unités, le raccord est donc invisible. */
  @keyframes onde-file { to { transform: translateX(-400px); } }
  /* ⚠️ La transform CSS REMPLACE l'attribut `transform` du SVG : les abscisses
     du balisage ne décalent rien ici. L'ancienne course -1240 → +60 laissait
     donc les sept porteurs hors cadre (0-1200) tout le cycle sauf la fin — la
     bande paraissait vide au chargement. Il faut traverser tout le cadre. */
  @keyframes marche    { from { transform: translate(-140px, var(--y, 0)); }
                         to   { transform: translate(1340px, var(--y, 0)); } }
  @keyframes pas       { 0%,100% { transform: translateY(0); }
                         50%     { transform: translateY(-5px); } }

  .onde-1 { animation: onde-file 9s linear infinite; }
  .onde-2 { animation: onde-file 14s linear infinite reverse; }
  .onde-3 { animation: onde-file 21s linear infinite; }
  .porteur { animation: marche linear infinite; }
  .porteur > g { animation: pas .9s ease-in-out infinite; }

  /* Départs et allures échelonnés : sans décalage, sept silhouettes
     avancent au même pas et l'ensemble ressemble à une frise, pas à une foule. */
  .porteur { animation-duration: 42s; }
  .p1 { animation-delay:   0s; }    .p2 { animation-delay:  -6s; }
  .p3 { animation-delay: -12s; }    .p4 { animation-delay: -18s; }
  .p5 { animation-delay: -24s; }    .p6 { animation-delay: -30s; }
  .p7 { animation-delay: -36s; }
  .p1 { --y: 9px; }  .p2 { --y: 5px; }  .p3 { --y: 13px; } .p4 { --y: 7px; }
  .p5 { --y: 15px; } .p6 { --y: 4px; }  .p7 { --y: 11px; }
  .p2 > g { animation-duration: 1.05s; }
  .p3 > g { animation-duration: .82s; }
  .p4 > g { animation-duration: 1.15s; }
  .p5 > g { animation-duration: .95s; }
  .p6 > g { animation-duration: .78s; }
  .p7 > g { animation-duration: 1.1s; }
}
/* ⚠️ Sans animation, seul l'attribut `transform` du SVG s'applique. Ils y ont
   donc des abscisses ÉTALÉES : avec la même valeur pour tous, la scène en
   mouvement réduit était vide — les sept superposés hors cadre. */

@media (max-width: 900px) {
  .scene-mot { font-size: 96px; }
  /* Au-delà de trois silhouettes sur un écran étroit, la scène devient un
     grouillement. ⚠️ On garde celles du CENTRE (x 430-800) : `xMidYMax slice`
     recadre sur le milieu du viewBox, donc les porteurs des extrémités tombent
     hors champ — garder p1-p3 laissait la bande vide sur mobile. */
  .p1, .p2, .p6, .p7 { display: none; }
}

/* === Le toboggan : le logo dévalé au défilement ===========================
   Le logo SIWEL est déjà une ligne continue en forme d'onde : il sert de piste
   tel quel. La trajectoire des lutins suit sa ligne médiane, extraite de
   l'image (moyenne verticale des pixels opaques colonne par colonne, puis
   lissage) — pas une courbe devinée à l'œil.

   Piloté par `animation-timeline` : aucun JavaScript, donc aucun calcul sur
   l'événement `scroll`, qui saccade par construction.

   ⚠️ Amélioration progressive. Sans `animation-timeline`, la scène reste une
   composition fixe et lisible : lutins posés le long de la piste, quatre textes
   visibles. Personne ne voit une page vide.                                   */
.toboggan { position: relative; height: 460vh; padding: 0; background: var(--nuit); }
.tob-sticky { position: sticky; top: 0; height: 100vh; overflow: hidden;
              display: grid; place-items: center; }

/* Le volume vient de la perspective ET d'une ombre portée : sur une image
   plate, la seule rotation ne suffit pas à faire lire une rampe. */
.tob-scene { width: min(1150px, 92vw);
             transform: perspective(1200px) rotateX(30deg) translateZ(0);
             transform-origin: 50% 85%;
             filter: drop-shadow(0 34px 30px rgba(0,0,0,.55)); }
.tob-scene svg { width: 100%; height: auto; display: block; overflow: visible; }

/* Marque blanche : la piste tracée telle quelle, à la place du lettrage SIWEL.
   ⚠️ MÊMES coordonnées que l'`offset-path` juste dessous — si l'une bouge,
   l'autre aussi, sinon les lutins glissent à côté de la piste. */
.piste-neutre { fill: none; stroke: var(--rouge); stroke-width: 3;
                stroke-linecap: round; stroke-linejoin: round; opacity: .9; }
.lutin { offset-path: path("M 0 141 L 24 138 L 48 135 L 72 129 L 96 129 L 120 113 L 144 110 L 168 110 L 192 116 L 216 129 L 256 136 L 280 160 L 304 170 L 328 151 L 352 164 L 376 156 L 400 146 L 424 157 L 448 149 L 472 128 L 496 144 L 520 149 L 544 154 L 568 151 L 592 159 L 616 157 L 640 133 L 664 101 L 688 120 L 712 142 L 736 142 L 760 141 L 784 141"); offset-rotate: auto; offset-distance: 0%; }
/* ⚠️ Le lutin est dessiné couché sur la pente par `offset-rotate: auto`. On le
   redresse dans un groupe interne, sinon il glisse la tête en bas dans les
   descentes. */
.lutin-corps { transform: translate(-8px, -22px) scale(1.15); }
.pancarte { fill: #fbf9f6; stroke: #1a2845; stroke-width: 1.5; }
.pancarte-manche { stroke: #8b6a45; stroke-width: 2.2; stroke-linecap: round; }
.lutin-lettre { fill: #1a2845; font-size: 15px; font-weight: 700; text-anchor: middle;
                font-family: var(--police), "Noto Sans Arabic", "Geeza Pro",
                  "Noto Sans Hebrew", "Arial Hebrew", "Noto Sans", "DejaVu Sans", sans-serif; }

/* Le texte occupe une moitié d'écran, du côté opposé au lutin : ainsi on voit
   la scène ET on lit, sans que l'un cache l'autre. */
.tob-textes { position: absolute; inset: 0; pointer-events: none; }
.tob-texte { position: absolute; top: 50%; translate: 0 -50%;
             width: min(42vw, 480px); color: #e7ecf4;
             padding: 2rem 2.2rem; border-radius: 20px; }
/* ⚠️ Le logo occupe toute la largeur : posé dessus, le paragraphe devenait
   illisible. Un voile dégradé depuis le bord rend le texte net sans masquer la
   scène — l'assombrir entièrement aurait tué l'effet. */
.tob-texte.gauche { left: 3vw; text-align: left;
  background: linear-gradient(90deg, rgba(17,28,49,.94) 0%, rgba(17,28,49,.88) 62%,
                              rgba(17,28,49,0) 100%); }
.tob-texte.droite { right: 3vw; text-align: right;
  background: linear-gradient(270deg, rgba(17,28,49,.94) 0%, rgba(17,28,49,.88) 62%,
                              rgba(17,28,49,0) 100%); }
.tob-texte h3 { color: #fff; font-size: clamp(1.5rem, 3.4vw, 2.4rem);
                line-height: 1.12; margin-bottom: .6rem; }
.tob-texte p { color: #b8c5dc; margin: 0; font-size: clamp(1rem, 1.5vw, 1.12rem); }
.tob-jalon { display: inline-block; margin-bottom: .8rem; font-size: .78rem;
             letter-spacing: .14em; text-transform: uppercase; color: var(--primaire-c); }
.tob-suite { position: absolute; bottom: 3vh; left: 50%; translate: -50% 0;
             font-size: .78rem; letter-spacing: .12em; text-transform: uppercase;
             color: #6c7b9c; }

@supports (animation-timeline: view()) {
  .toboggan { view-timeline-name: --tob; view-timeline-axis: block; }

  @keyframes glisse { to { offset-distance: 100%; } }
  @keyframes parait {
    0%       { opacity: 0; translate: var(--dx, 26px) -50%; }
    12%, 86% { opacity: 1; translate: 0 -50%; }
    100%     { opacity: 0; translate: calc(var(--dx, 26px) * -1) -50%; }
  }
  @keyframes parait-fin {
    0%        { opacity: 0; translate: var(--dx, 26px) -50%; }
    45%, 100% { opacity: 1; translate: 0 -50%; }
  }
  /* Le zoom demandé : la rampe se redresse et se rapproche pendant la descente. */
  @keyframes zoome { to { transform: perspective(1200px) rotateX(9deg) scale(1.22); } }

  .lutin { animation: glisse linear both; animation-timeline: --tob; }
  /* ⚠️ Départs décalés mais arrivée commune : les lutins se rattrapaient et
     finissaient en grappe. Ils partent ensemble et vont à des ALLURES
     différentes — l'écart se creuse au lieu de se refermer. */
  .toboggan:not(.vertical) .lutin {
    animation-name: glisse-etale; animation-range: contain 0% contain 100%; }
  @keyframes glisse-etale { from { offset-distance: var(--d0); }
                            to   { offset-distance: var(--d1); } }
  .lutin.g1 { --d0:  0%; --d1: 52%; }
  .lutin.g2 { --d0:  9%; --d1: 61%; }
  .lutin.g3 { --d0: 19%; --d1: 71%; }
  .lutin.g4 { --d0: 29%; --d1: 81%; }
  .lutin.g5 { --d0: 38%; --d1: 90%; }
  .lutin.g6 { --d0: 48%; --d1: 100%; }
  /* ⚠️ Les lutins de la seconde descente ont leurs PROPRES plages. Sans elles
     ils héritaient de la règle générale et se superposaient tous au même point. */
  .toboggan.vertical .lutin { animation-name: descend-vertical;
                              animation-range: contain 0% contain 100%; }
  @keyframes descend-vertical { from { offset-distance: var(--d0); }
                                to   { offset-distance: var(--d1); } }
  .lutin.v1 { --d0:  0%; --d1: 58%; }
  .lutin.v2 { --d0: 10%; --d1: 68%; }
  .lutin.v3 { --d0: 21%; --d1: 79%; }
  .lutin.v4 { --d0: 31%; --d1: 89%; }
  .lutin.v5 { --d0: 42%; --d1: 100%; }

  .tob-scene { animation: zoome linear both; animation-timeline: --tob;
               animation-range: contain 0% contain 100%; }

  .tob-texte { opacity: 0; animation: parait linear both; animation-timeline: --tob; }
  .tob-texte.gauche { --dx: -26px; }
  /* ⚠️ Plages qui SE CHEVAUCHENT : bord à bord, un texte finit son fondu avant
     que le suivant ne commence, et l'écran reste vide un instant. */
  .tob-texte.t1 { animation-range: contain  0% contain 25%; }
  .tob-texte.t2 { animation-range: contain 25% contain 50%; }
  .tob-texte.t3 { animation-range: contain 50% contain 75%; }
  .toboggan:not(.vertical) .tob-texte.t4 { animation-name: parait-fin;
                  animation-range: contain 75% contain 100%; }
  .tob-suite { animation: parait linear both; animation-timeline: --tob;
               animation-range: contain 0% contain 14%; --dx: 0px; }
}

/* ⚠️ Une descente de 460vh pilotée au défilement est exactement ce que
   `prefers-reduced-motion` vise. Elle se réduit à une vue unique, sans sticky. */
@media (prefers-reduced-motion: reduce) {
  .toboggan { height: auto; padding: clamp(3rem, 6vw, 5rem) 0; }
  .tob-sticky { position: static; height: auto; }
  .tob-scene { transform: perspective(1200px) rotateX(16deg); }
  .tob-textes { position: static; inset: auto; display: grid; gap: 2rem;
                margin-top: 3rem; }
  .tob-texte { position: static; translate: none; opacity: 1; animation: none;
               width: auto; text-align: left; }
  .tob-suite { display: none; }
  .lutin { animation: none; }
  .lutin.g1 { offset-distance:  8%; } .lutin.g2 { offset-distance: 25%; }
  .lutin.g3 { offset-distance: 42%; } .lutin.g4 { offset-distance: 59%; }
  .lutin.g5 { offset-distance: 76%; } .lutin.g6 { offset-distance: 93%; }
  .lutin.v1 { offset-distance: 10%; } .lutin.v2 { offset-distance: 30%; }
  .lutin.v3 { offset-distance: 50%; } .lutin.v4 { offset-distance: 70%; }
  .lutin.v5 { offset-distance: 90%; }
}

@media (max-width: 900px) {
  .toboggan { height: 380vh; }
  .tob-scene { transform: perspective(900px) rotateX(22deg); }
  /* Sur un écran étroit, une demi-largeur ne tient pas : le texte reprend
     toute la place, sous la scène. */
  .tob-texte { width: 88vw; left: 6vw; right: auto; text-align: left;
               top: auto; bottom: 8vh; translate: none; }
  .tob-texte.droite { right: auto; left: 6vw; text-align: left; }
}

/* --- Deuxième descente : le logo dressé, lettre par lettre --------------- */
/* ⚠️ Le mot est cursif : on ne peut pas simplement le pivoter, les lettres
   se retrouvent couchées. Elles sont donc DÉCOUPÉES du logo aux vallées d'encre
   (48 / 241 / 286 / 507 / 610 / 700 sur l'original de 800px), recalées chacune
   sur son barycentre d'encre — pas sur son centre de boîte, qui décentre toute
   lettre à queue fine — et empilées droites. Les vagues d'entrée et de sortie
   sont retirées : dans une colonne elles dépassent latéralement.
   C'est ce format portrait (1 pour 2,3) qui rend enfin possible la mise en deux
   colonnes que le mot pivoté (1 pour 3,5) ne pouvait pas remplir. */
.toboggan.vertical { height: 380vh; }
.toboggan.vertical .tob-sticky {
  display: grid; grid-template-columns: 50vw 50vw; align-items: center;
  padding: 0; gap: 0;
}
.toboggan.vertical .tob-scene {
  grid-column: 1; grid-row: 1; justify-self: center; width: auto; height: 82vh;
  transform: none; transform-origin: 50% 50%;
}
.toboggan.vertical .tob-lettres { width: auto; height: 100%; overflow: visible; }
.toboggan.vertical .lutin { offset-path: path("M 120 -14 Q 74 34 90 60 Q 166 148 150 174 Q 74 256 90 282 Q 166 364 150 390 Q 74 478 90 504 Q 120 546 120 576"); offset-rotate: 0deg; }

.toboggan.vertical .tob-textes {
  position: relative; inset: auto; grid-column: 2; grid-row: 1;
  width: 50vw; height: 82vh; display: block; align-self: center;
}
.toboggan.vertical .tob-texte {
  position: absolute; top: 50%; translate: 0 -50%;
  left: 3.5vw; right: 4vw; width: auto; max-width: 40rem;
  text-align: left; padding: 2rem 2.2rem; border-radius: 20px;
}
.toboggan.vertical .tob-texte.gauche,
.toboggan.vertical .tob-texte.droite { left: 3.5vw; right: 4vw; text-align: left; }
.toboggan.vertical .tob-texte h3 { font-size: clamp(1.6rem, 2.7vw, 2.5rem); }
.toboggan.vertical .tob-texte p  { font-size: clamp(1rem, 1.25vw, 1.15rem); }

@supports (animation-timeline: view()) {
  /* Le zoom part d'un peu plus loin et se rapproche : la colonne grandit sans
     jamais dépasser la hauteur utile. */
  @keyframes zoome-vertical { from { scale: .88; } to { scale: 1.06; } }
  .toboggan.vertical .tob-scene { animation-name: zoome-vertical; }
}
@media (prefers-reduced-motion: reduce) {
  .toboggan.vertical .tob-sticky { grid-template-columns: 1fr; }
  .toboggan.vertical .tob-scene { grid-column: 1; height: 60vh; margin: 2rem auto; }
  .toboggan.vertical .tob-textes { grid-column: 1; height: auto;
                                   display: grid; gap: 1.6rem; }
  .toboggan.vertical .tob-texte { position: static; translate: none;
                                  left: auto; right: auto; }
}

/* --- Pictogrammes dessinés ---------------------------------------------- */
.carte .ico .picto { width: 22px; height: 22px; display: block; }
.carte .ico:has(.picto) { display: grid; place-items: center; }

/* --- Palier entre les deux descentes ------------------------------------- */
.palier { background: var(--nuit); color: #e7ecf4; text-align: center;
          padding: clamp(4rem, 9vw, 8rem) 0; position: relative; }
.palier .conteneur { display: grid; justify-items: center; gap: 1rem; }
.palier-fil { display: block; width: 1px; height: clamp(48px, 7vw, 88px);
              background: linear-gradient(to bottom, transparent,
                          rgba(143,168,212,.55)); }
.palier-sur { color: #8593ae; font-size: .95rem; margin: 0; }
.palier h2 { margin: 0; max-width: 30ch; font-size: clamp(1.7rem, 3.4vw, 2.9rem);
             line-height: 1.15; }
.palier-sous { color: #b6c2d8; max-width: 54ch; margin: 0; }
.palier-fleche svg { width: 22px; height: 30px; fill: none;
                     stroke: rgba(143,168,212,.7); stroke-width: 2;
                     stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: no-preference) {
  @keyframes palier-appel { 0%,100% { translate: 0 0; opacity: .55; }
                            50%     { translate: 0 7px; opacity: 1; } }
  .palier-fleche { animation: palier-appel 2.2s ease-in-out infinite; }
}

/* --- L'acronyme : la lettre s'allume quand on lit son mot ---------------- */
/* La lettre en cours passe au premier plan, les autres restent en réserve :
   c'est ce qui relie le texte de droite à la position du lutin à gauche. */
.toboggan.vertical .lt { opacity: .26; }
.toboggan.vertical .tob-jalon {
  font-size: clamp(2.4rem, 4.6vw, 4rem); font-weight: 800; letter-spacing: 0;
  color: var(--primaire-c); line-height: 1; text-transform: none;
  display: block; margin-bottom: .2rem;
}
.toboggan.vertical .tob-texte h3 { margin: 0 0 .7rem; }

@supports (animation-timeline: view()) {
  @keyframes lettre-allumee {
    0%, 10%   { opacity: .26; }
    22%, 90%  { opacity: 1; }
    99%, 100% { opacity: .26; }
  }
  .toboggan.vertical .lt {
    animation: lettre-allumee linear both;
    animation-timeline: --tob;
  }
  .toboggan.vertical .lt-s { animation-range: contain 0% contain 26%; }
  .toboggan.vertical .lt-i { animation-range: contain 18% contain 44%; }
  .toboggan.vertical .lt-w { animation-range: contain 36% contain 62%; }
  .toboggan.vertical .lt-e { animation-range: contain 54% contain 80%; }
  @keyframes lettre-allumee-fin {
    0%, 12%  { opacity: .26; }
    30%, 100% { opacity: 1; }
  }
  .toboggan.vertical .lt-l { animation-name: lettre-allumee-fin;
                             animation-range: contain 72% contain 100%; }

  /* Cinq textes : les plages de l'ancienne version en comptaient quatre. */
  .toboggan.vertical .tob-texte.t1 { animation-range: contain  0% contain  20%; }
  .toboggan.vertical .tob-texte.t2 { animation-range: contain 20% contain  40%; }
  .toboggan.vertical .tob-texte.t3 { animation-range: contain 40% contain  60%; }
  .toboggan.vertical .tob-texte.t4 { animation-range: contain 60% contain  80%; }
  .toboggan.vertical .tob-texte.t5 { animation-name: parait-fin;
                                     animation-range: contain 80% contain 100%; }
  .toboggan.vertical .lt-s { animation-range: contain  0% contain  20%; }
  .toboggan.vertical .lt-i { animation-range: contain 20% contain  40%; }
  .toboggan.vertical .lt-w { animation-range: contain 40% contain  60%; }
  .toboggan.vertical .lt-e { animation-range: contain 60% contain  80%; }
  .toboggan.vertical .lt-l { animation-range: contain 80% contain 100%; }
}
@media (prefers-reduced-motion: reduce) {
  /* ⚠️ `.toboggan { height: auto }` ne suffit pas : `.toboggan.vertical` est
     plus spécifique et laissait 3 420 px de vide sous la vue statique. */
  .toboggan.vertical { height: auto; }
  .toboggan.vertical .lt { animation: none; opacity: 1; }
}

/* --- La descente verticale sur mobile ----------------------------------- */
/* ⚠️ Placé en fin de feuille à dessein : la colonne desktop `width: 50vw` a la
   même spécificité, seul l'ordre la départage. L'ancien bloc mobile ne
   redéfinissait pas `width` — le texte gardait 195 px de large, se pliait à un
   mot par ligne et débordait de 375 px au-dessus de l'écran. */
@media (max-width: 900px) {
  .toboggan.vertical { height: 340vh; }
  .toboggan.vertical .tob-sticky {
    grid-template-columns: 1fr; grid-template-rows: 1fr auto;
    align-content: center; padding: 3vh 0 4vh;
  }
  .toboggan.vertical .tob-scene {
    grid-column: 1; grid-row: 1; height: 42vh; justify-self: center;
  }
  .toboggan.vertical .tob-textes {
    grid-column: 1; grid-row: 2; position: relative; inset: auto;
    width: 100%; height: 38vh; align-self: end;
  }
  .toboggan.vertical .tob-texte {
    position: absolute; top: 0; bottom: auto; translate: none;
    left: 5vw; right: 5vw; width: auto; max-width: none;
    padding: 0; text-align: left;
  }
  /* ⚠️ `parait` translate de -50% en Y pour compenser `top: 50%`. Ici le texte
     est ancré en haut de sa zone : la même keyframe le remonterait de la moitié
     de sa hauteur. D'où une paire dédiée au mobile. */
  @keyframes parait-mob {
    0%       { opacity: 0; translate: var(--dx, 18px) 0; }
    12%, 86% { opacity: 1; translate: 0 0; }
    100%     { opacity: 0; translate: calc(var(--dx, 18px) * -1) 0; }
  }
  @keyframes parait-mob-fin {
    0%        { opacity: 0; translate: var(--dx, 18px) 0; }
    45%, 100% { opacity: 1; translate: 0 0; }
  }
  .toboggan.vertical .tob-texte.t1,
  .toboggan.vertical .tob-texte.t2,
  .toboggan.vertical .tob-texte.t3,
  .toboggan.vertical .tob-texte.t4 { animation-name: parait-mob; }
  .toboggan.vertical .tob-texte.t5 { animation-name: parait-mob-fin; }

  /* ⚠️ Les plages desktop se recouvrent de 5 points pour un fondu croisé. Sur
     390 px de large, les deux textes occupent la MÊME zone : le croisement
     devient une bouillie de deux paragraphes. Plages jointives, sans
     recouvrement, et fondu resserré. */
  @keyframes parait-mob {
    0%, 4%    { opacity: 0; translate: var(--dx, 18px) 0; }
    14%, 88%  { opacity: 1; translate: 0 0; }
    97%, 100% { opacity: 0; translate: calc(var(--dx, 18px) * -1) 0; }
  }
  .toboggan.vertical .tob-texte.t1 { animation-range: contain  0% contain  20%; }
  .toboggan.vertical .tob-texte.t2 { animation-range: contain 20% contain  40%; }
  .toboggan.vertical .tob-texte.t3 { animation-range: contain 40% contain  60%; }
  .toboggan.vertical .tob-texte.t4 { animation-range: contain 60% contain  80%; }
  .toboggan.vertical .tob-texte.t5 { animation-range: contain 80% contain 100%; }
  .toboggan.vertical .lt-s { animation-range: contain  0% contain  20%; }
  .toboggan.vertical .lt-i { animation-range: contain 20% contain  40%; }
  .toboggan.vertical .lt-w { animation-range: contain 40% contain  60%; }
  .toboggan.vertical .lt-e { animation-range: contain 60% contain  80%; }
  .toboggan.vertical .lt-l { animation-range: contain 80% contain 100%; }
  @keyframes lettre-allumee {
    0%, 8%    { opacity: .32; }
    18%, 86%  { opacity: 1; }
    96%, 100% { opacity: .32; }
  }
  .toboggan.vertical .lt { opacity: .32; }

  .toboggan.vertical .tob-jalon { font-size: 2.4rem; margin-bottom: .1rem; }
  .toboggan.vertical .tob-texte h3 { font-size: 1.45rem; margin-bottom: .5rem; }
  .toboggan.vertical .tob-texte p  { font-size: .97rem; line-height: 1.55; }
}

/* Bascule de langue : discrète, mais elle doit se distinguer des rubriques. */
.bascule-langue { position: relative; padding-left: .9rem; }
.bascule-langue::before {
  content: ""; position: absolute; left: 0; top: 50%; translate: 0 -50%;
  width: 1px; height: 1em; background: currentColor; opacity: .28;
}

/* ⚠️ Le burger était le caractère `☰` : dessin variable selon la police, et
   carré là où elle manque — le défaut corrigé partout ailleurs. */
.menu-btn svg { width: 24px; height: 24px; fill: none; stroke: currentColor;
                stroke-width: 2; stroke-linecap: round; display: block; }
/* Hors du menu repliable : sur téléphone, une bascule enfermée dans le burger
   rend l'autre langue introuvable. */
.bascule-langue.hors-menu { display: none; }
@media (max-width: 720px) {
  .bascule-langue.hors-menu {
    display: inline-flex; align-items: center; margin-left: auto;
    padding: .3rem .6rem; border: 1px solid var(--trait); border-radius: 999px;
    font-size: .82rem; font-weight: 650; color: var(--encre); letter-spacing: .04em;
    text-decoration: none;
  }
  .bascule-langue.hors-menu::before { display: none; }
  .menu-btn { margin-left: .6rem; }
  .nav .bascule-langue { order: 99; }
}

/* Toboggans d'une page intérieure : plus courts que ceux de l'accueil. Sur une
   page de détail, 460 vh par section fait quatre écrans de molette avant le
   contenu suivant — l'effet devient un péage. */
.toboggan.court { height: 300vh; }
.toboggan.vertical.court { height: 280vh; }
/* Sur l'accueil le jalon est une seule lettre, ailleurs c'est un mot : la même
   taille donnerait « Il en manque une » en 4 rem. */
.toboggan.vertical.court .tob-jalon {
  font-size: clamp(1.1rem, 1.7vw, 1.5rem); font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
}

/* Fiche compte : un service = une case + son quota, groupés visuellement. */
.service { padding: .7rem 0; border-bottom: 1px solid var(--trait); }
.service:last-of-type { border-bottom: 0; }
.service-quota { margin: .5rem 0 0 2rem; gap: .6rem; align-items: center; flex-wrap: wrap; }
.service-quota .aide { flex: 1 1 14rem; }
.service-quota input[type=text] { max-width: 12rem; }
.mini { display: inline-flex; align-items: center; gap: .35rem;
        font-size: .84rem; color: var(--gris); white-space: nowrap; }
/* Les champs de saisie de l'admin coupaient leur propre libellé indicatif. */
.panneau .ligne { flex-wrap: wrap; gap: .6rem; }
.panneau .ligne input[type=text] { min-width: 13rem; flex: 0 1 16rem; }
.panneau .ligne select { flex: 0 1 15rem; min-width: 11rem; }

/* Grille tarifaire par nombre de canaux : trois cartes de même hauteur, celle
   du milieu ne doit pas paraître plus courte parce que son texte l'est. */
.grille-tarifs .tarif-evt { display: flex; flex-direction: column;
                            text-align: center; position: relative; }
.grille-tarifs .tarif-evt .resume { flex: 1; color: var(--gris);
                                    font-size: .92rem; margin: .6rem 0 1.2rem; }
.grille-tarifs .tarif-evt .nom { font-weight: 700; font-size: 1.05rem; }
.grille-tarifs .tarif-evt.vedette { border-color: var(--primaire);
                                    box-shadow: 0 10px 30px rgba(26,40,69,.14); }

/* --- Toboggan sur fond clair -------------------------------------------- */
/* ⚠️ Ce n'est pas la même image teintée : le logo « clair » est fait pour un
   fond sombre, sur blanc il serait délavé. La macro sert `siwel-mot.png` et les
   lettres `siwel-sombre-*`, la version bleu nuit et rouge. */
.toboggan.clair { background: var(--blanc); color: var(--encre); }
.toboggan.clair .tob-texte { color: var(--encre); }
.toboggan.clair .tob-texte h3 { color: var(--encre); }
.toboggan.clair .tob-texte p  { color: var(--encre-doux); }
.toboggan.clair .tob-jalon    { color: var(--primaire); }
.toboggan.clair .tob-suite    { color: var(--gris); }
/* ⚠️ Le voile est un `background` sur `.gauche`/`.droite`, pas un pseudo-élément.
   Laissé tel quel, il posait un rectangle bleu nuit sur une page blanche. */
.toboggan.clair .tob-texte.gauche {
  background: linear-gradient(90deg, rgba(253,252,249,.96) 0%,
              rgba(253,252,249,.90) 62%, rgba(253,252,249,0) 100%); }
.toboggan.clair .tob-texte.droite {
  background: linear-gradient(270deg, rgba(253,252,249,.96) 0%,
              rgba(253,252,249,.90) 62%, rgba(253,252,249,0) 100%); }
/* Sur blanc, la pancarte a besoin de son cercle : sans lui la lettre flotte. */
.toboggan.clair .pancarte { fill: #fff; stroke: var(--primaire); stroke-width: 1.3; }
.toboggan.clair .lutin-lettre { fill: var(--primaire); }
.toboggan.clair .pancarte-manche { stroke: #8a6a3a; }
/* La lettre en réserve : .26 convenait sur du bleu nuit, sur du blanc c'est un
   fantôme illisible. */
.toboggan.clair .lt { opacity: .34; }
@supports (animation-timeline: view()) {
  @keyframes lettre-allumee-clair {
    0%, 10%   { opacity: .34; }
    22%, 90%  { opacity: 1; }
    99%, 100% { opacity: .34; }
  }
  @keyframes lettre-allumee-fin-clair {
    0%, 12%   { opacity: .34; }
    30%, 100% { opacity: 1; }
  }
  .toboggan.clair .lt   { animation-name: lettre-allumee-clair; }
  .toboggan.clair .lt-l { animation-name: lettre-allumee-fin-clair; }
}
@media (prefers-reduced-motion: reduce) {
  .toboggan.clair .lt { opacity: 1; }
}
/* Le palier suit les deux descentes qu'il sépare : entre deux sections claires,
   une bande bleu nuit ferait un trou au milieu de la page. */
.palier.clair { background: var(--blanc); color: var(--encre); }
.palier.clair h2 { color: var(--encre); }
.palier.clair .palier-sur { color: var(--gris); }
.palier.clair .palier-sous { color: var(--encre-doux); }
.palier.clair .palier-fil { background: linear-gradient(to bottom, transparent,
                            rgba(26,40,69,.45)); }
.palier.clair .palier-fleche svg { stroke: rgba(26,40,69,.6); }
/* ⚠️ L'ombre portée de la scène est noire à 55 % : conçue pour détacher le logo
   d'un fond bleu nuit, elle pose une tache grise sur une page blanche. Sur clair
   il faut une ombre bleutée, très douce — juste assez pour le volume. */
.toboggan.clair .tob-scene { filter: drop-shadow(0 26px 26px rgba(26,40,69,.16)); }

/* --- Calculateur d'économies -------------------------------------------- */
.duo-calc { display: grid; grid-template-columns: minmax(0,22rem) minmax(0,1fr);
            gap: 1.6rem; align-items: start; }
.calc-form .champ { margin-bottom: 1rem; }
.calc-form .champ:last-child { margin-bottom: 0; }
.calc-res .cle { font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
                 color: var(--gris); }
.calc-res .val { font-size: 1.5rem; font-weight: 700; margin-top: .2rem; }
.calc-res .sous { color: var(--gris); font-size: .84rem; margin-top: .25rem; }
.carte-verdict { margin-top: 1rem; text-align: center;
                 padding: clamp(1.4rem, 3vw, 2.2rem); border-width: 2px; }
.montant-verdict { font-size: clamp(1.9rem, 4.4vw, 2.9rem); font-weight: 800;
                   letter-spacing: -.02em; line-height: 1.05; margin: .3rem 0; }
/* Le vocabulaire ET la couleur suivent le signe : on ne présente jamais un
   surcoût dans l'habillage d'un gain. */
.verdict-gain     { border-color: var(--primaire); background: rgba(26,40,69,.04); }
.verdict-surcout  { border-color: var(--rouge); background: rgba(197,34,38,.05); }
.verdict-surcout .montant-verdict { color: var(--rouge-t); }
.verdict-egal,
.verdict-inconnu  { border-color: var(--trait); }
.verdict-inconnu .montant-verdict { color: var(--gris); }
.calc-detail { margin-top: 1.2rem; }
.calc-detail summary { cursor: pointer; font-weight: 650; padding: .5rem 0; }
@media (max-width: 900px) {
  .duo-calc { grid-template-columns: 1fr; }
}
/* Accès au calculateur, juste après le héros : c'est la promesse chiffrée. */
.teaser-calc { padding: clamp(2.4rem, 5vw, 3.6rem) 0; background: var(--blanc); }

/* --- Bandeau RGPD : volontairement grand ---------------------------------- */
/* C'est l'argument que les concurrents ne peuvent pas tenir. Il doit se voir
   au défilement rapide, donc bande pleine largeur et chiffres énormes. */
.bandeau-rgpd { background: var(--nuit); color: #e7ecf4; text-align: center;
                padding: clamp(3.4rem, 7vw, 6rem) 0; }
.rgpd-oeil { display: inline-block; font-size: .8rem; font-weight: 800;
             letter-spacing: .28em; color: var(--primaire-c);
             border: 1px solid rgba(143,168,212,.45); border-radius: 999px;
             padding: .35rem 1rem .3rem 1.15rem; margin-bottom: 1.4rem; }
.bandeau-rgpd h2 { font-size: clamp(1.8rem, 4.4vw, 3.2rem); line-height: 1.1;
                   margin: 0 auto; max-width: 22ch; color: #fff; }
.rgpd-chapo { max-width: 56ch; margin: 1.4rem auto 0; color: #b8c5dc;
              font-size: clamp(1rem, 1.4vw, 1.15rem); }
.rgpd-faits { margin-top: clamp(2rem, 4vw, 3rem); text-align: left; }
.rgpd-faits p { color: #b8c5dc; font-size: .95rem; margin: .3rem 0 0; }
.rgpd-faits strong { color: #fff; }
.rgpd-chiffre { font-size: clamp(2.2rem, 5vw, 3.4rem); font-weight: 800;
                line-height: 1; color: var(--primaire-c); letter-spacing: -.02em; }
.rgpd-pied { max-width: 62ch; margin: clamp(1.8rem, 3vw, 2.4rem) auto 0;
             color: #8593ae; font-size: .92rem; }
.bandeau-rgpd .btn-s { color: #e7ecf4; border-color: rgba(219,228,243,.4);
                       background: transparent; }
@media (hover: hover) and (pointer: fine) {
  .bandeau-rgpd .btn-s:hover { background: rgba(219,228,243,.10); }
}

/* --- Visuel du héros : le matériel remplacé par le téléphone -------------- */
.heros-visuel { display: block; }
.heros-visuel svg { width: 100%; height: auto; max-width: 420px;
                    margin-inline: auto; display: block; overflow: visible; }
/* Le matériel qu'on ne loue plus : présent mais en retrait, et barré. */
.hv-remplace { fill: none; stroke: rgba(184,197,220,.30); stroke-width: 1.6;
               stroke-linecap: round; stroke-linejoin: round; }
.hv-barre { stroke: var(--rouge); stroke-width: 2.2; opacity: .85; }
.hv-nom { fill: rgba(184,197,220,.55); font-size: 9.5px; text-anchor: middle;
          letter-spacing: .06em; text-transform: uppercase; stroke: none; }
.hv-chassis { fill: #0c1425; stroke: rgba(219,228,243,.22); stroke-width: 1.5; }
.hv-encoche { fill: rgba(219,228,243,.18); }
.hv-live { fill: var(--rouge); }
.hv-etat { fill: #ffb4b0; font-size: 9px; letter-spacing: .16em; font-weight: 700; }
.hv-titre { fill: #fff; font-size: 15px; font-weight: 700; }
.hv-sous { fill: #8593ae; font-size: 10.5px; }
.hv-opt { fill: rgba(219,228,243,.06); stroke: rgba(219,228,243,.16); stroke-width: 1; }
.hv-opt-on { fill: rgba(143,168,212,.18); stroke: var(--primaire-c); stroke-width: 1.4; }
.hv-lang { fill: #dbe4f3; font-size: 11.5px; font-weight: 600; }
.hv-check { fill: none; stroke: var(--primaire-c); stroke-width: 2.2;
            stroke-linecap: round; stroke-linejoin: round; }
.hv-onde path { fill: none; stroke: var(--primaire-c); stroke-width: 2;
                stroke-linecap: round; opacity: .8; }
@media (prefers-reduced-motion: no-preference) {
  /* L'onde avance : elle dit « ça arrive en direct ». Une seule période,
     donc pas de raccord visible. */
  @keyframes hv-file { to { transform: translateX(-48px); } }
  .hv-onde path { animation: hv-file 3.2s linear infinite; }
  .hv-live { animation: hv-battement 1.8s ease-in-out infinite; }
  @keyframes hv-battement { 0%,100% { opacity: 1 } 50% { opacity: .35 } }
}

/* ─── Calculateur de diffusion audio (/tarification) ───────────────────── */
.perimetre {
  display: inline-block; margin-top: 1rem; padding: .55rem 1rem;
  background: var(--primaire-p); color: var(--primaire-f);
  border-radius: var(--r-s); font-size: .9rem; font-weight: 600;
}

.calc { display: grid; grid-template-columns: minmax(0,1.55fr) minmax(0,1fr);
        gap: 2rem; align-items: start; }
.calc-reglages { display: grid; gap: 1.25rem; border: 0; padding: 0; margin: 0; }

.calc-jauge { border: 1px solid var(--trait); border-radius: var(--r);
         background: var(--blanc); padding: 1.35rem 1.5rem 1.6rem; margin: 0;
         box-shadow: var(--ombre); }
.calc-jauge legend { font-weight: 700; font-size: 1.02rem; color: var(--encre);
                padding: 0 .4rem; }
.calc-jauge-aide { margin: .15rem 0 .5rem; font-size: .88rem; color: var(--gris); }
.calc-jauge-valeur { display: block; margin-top: .65rem; font-weight: 700;
                font-size: 1.05rem; color: var(--primaire); }

.lutins svg { width: 100%; height: auto; display: block; }
/* ⚠️ L'animation porte sur le groupe INTERNE. La propriété CSS `transform`
   REMPLACE l'attribut `transform` du SVG : appliquée au <g> extérieur, elle
   effaçait sa position et empilait tous les lutins en x=0. */
.lutin-chiffre { opacity: .3; transition: opacity .18s ease; }
.lutin-chiffre .lutin-anim { transition: transform .18s ease; }
.lutin-chiffre.passe { opacity: .62; }
.lutin-chiffre.actif { opacity: 1; }
.lutin-chiffre.actif .lutin-anim { transform: translateY(-4px); }
@media (prefers-reduced-motion: reduce) {
  .lutin-chiffre, .lutin-chiffre .lutin-anim { transition: none; }
  .lutin-chiffre.actif .lutin-anim { transform: none; }
}
.lutin-chiffre .pancarte { fill: var(--blanc); stroke: var(--encre); stroke-width: 1.6; }
.lutin-chiffre.actif .pancarte { fill: var(--ambre-p); stroke: var(--ambre); }
.lutin-chiffre .pancarte-num { text-anchor: middle; font-weight: 800;
  font-size: 15px; fill: var(--encre); font-family: var(--police); }
.lutin-chiffre.actif .pancarte-num { fill: var(--primaire-f); }
.lutin-chiffre .manche { stroke: var(--encre); stroke-width: 1.6; }
.lutin-chiffre .chapeau { fill: var(--rouge); }
.lutin-chiffre .tete { fill: #f6e3cf; }
.lutin-chiffre .corps-1 { fill: var(--primaire); }
.lutin-chiffre .corps-2 { fill: var(--rouge); }
.lutin-chiffre .corps-3 { fill: var(--nuit); }

/* Le curseur est le seul élément réellement pilotable : il reste visible et
   focusable même si les lutins ne s'affichent pas. */
.calc-jauge input[type=range] { width: 100%; accent-color: var(--primaire);
                           height: 1.9rem; cursor: pointer; }
.calc-jauge input[type=range]:focus-visible { outline: 3px solid var(--ambre);
                                         outline-offset: 3px; border-radius: 4px; }

.compteur { display: flex; align-items: center; gap: .85rem; }
.compteur input[type=range] { flex: 1 1 auto; }
.pas { flex: 0 0 auto; width: 2.6rem; height: 2.6rem; border-radius: 50%;
       border: 1px solid var(--trait); background: var(--blanc);
       font-size: 1.35rem; line-height: 1; color: var(--encre);
       cursor: pointer; box-shadow: var(--ombre); }
.pas:hover:not(:disabled) { border-color: var(--primaire); color: var(--primaire); }
.pas:disabled { opacity: .35; cursor: not-allowed; }
.pas:focus-visible { outline: 3px solid var(--ambre); outline-offset: 2px; }

.recap { position: sticky; top: 1.5rem; border: 1px solid var(--trait);
         border-radius: var(--r); background: var(--blanc); padding: 1.5rem;
         box-shadow: var(--ombre-f); }
.recap-lignes { margin: 0 0 1rem; font-size: .93rem; }
.recap-lignes > div { display: flex; justify-content: space-between; gap: 1rem;
                      padding: .34rem 0; }
.recap-lignes > div.sep { border-top: 1px solid var(--trait); margin-top: .4rem;
                          padding-top: .6rem; font-weight: 700; }
.recap-lignes dt { color: var(--encre-doux); margin: 0; }
.recap-lignes dd { margin: 0; font-variant-numeric: tabular-nums; color: var(--encre); }
.recap-total { margin: .9rem 0 .1rem; font-size: 2.35rem; font-weight: 800;
               line-height: 1.1; color: var(--primaire-f);
               font-variant-numeric: tabular-nums; }
.recap-total .ht { font-size: .95rem; font-weight: 700; color: var(--gris); }
.recap-sous { margin: 0 0 .55rem; color: var(--encre-doux); font-size: .93rem; }
.recap-eco { margin: 0 0 .8rem; padding: .6rem .8rem; border-radius: var(--r-s);
             background: var(--vert-p); color: #106b4d; font-weight: 600;
             font-size: .9rem; }
/* ⚠️ Pas `var(--vert)` (#157f5b) : sur ce fond pâle il tombe à 4,40:1, sous le
   seuil de 4,5. Même teinte, deux crans plus sombre → 5,74:1. */
.recap-validite { margin: 0 0 1rem; font-size: .85rem; color: var(--gris); }
.recap-mention { margin: .8rem 0 0; font-size: .8rem; color: var(--gris);
                 line-height: 1.45; }
.devis-titre { margin: 0 0 .4rem; font-size: 1.3rem; font-weight: 800; }
.devis-txt { margin: 0 0 1.2rem; color: var(--encre-doux); font-size: .93rem; }

.bande-sur-mesure { background: var(--primaire-p); padding: 3rem 0; }
.bande-sur-mesure h2 { margin-top: 0; }

/* Barre fine du total : masquée sur grand écran, où le récapitulatif est déjà
   collé à droite en permanence. */
.barre-total { display: none; }

@media (max-width: 880px) {
  .calc { grid-template-columns: 1fr; }
  /* ⚠️ Le récapitulatif NE COLLE PAS sur mobile : il fait 472 px de haut pour
     un écran de 844, il masquait plus de la moitié des curseurs. Il reprend sa
     place dans le flux, et c'est la barre fine ci-dessous qui suit le doigt. */
  .recap { position: static; }
  .recap-total { font-size: 2rem; }
  .lutins svg { max-height: 120px; }

  .barre-total {
    display: flex; align-items: center; justify-content: space-between;
    gap: .8rem; position: sticky; bottom: 0; z-index: 20;
    margin: 0; padding: .7rem 1rem; border-radius: var(--r-s) var(--r-s) 0 0;
    background: var(--nuit); color: #fff;
    box-shadow: 0 -6px 20px rgba(17,28,49,.22);
  }
  .barre-total .bt-lbl { font-size: .78rem; color: #b9c4d8; }
  .barre-total .bt-val { font-size: 1.4rem; font-weight: 800;
                         font-variant-numeric: tabular-nums; line-height: 1.1; }
  .barre-total .btn { padding: .5rem 1rem; font-size: .87rem; }
}

/* ─── Dépliage du calculateur dans la page Tarifs ─────────────────────────
   Moment authored : les lutins arrivent par la gauche le long de la piste et
   plantent leur panneau à leur palier. C'est le geste du monde existant (des
   porteurs qui longent une ligne) et il explique la rangée qu'on va choisir. */

.ouvre-calc { display: inline-flex; align-items: center; gap: .55rem; }
.ouvre-calc-fleche { transition: transform .28s cubic-bezier(.16,1,.3,1); }
.ouvre-calc[aria-expanded="true"] .ouvre-calc-fleche { transform: rotate(180deg); }

/* ⚠️ Pas de `clip-path` ni d'`overflow:hidden` sur le panneau : les deux créent
   un bloc conteneur et casseraient le `position:sticky` du récapitulatif. Le
   dépliage passe par une grille 0fr → 1fr, et l'`overflow` vit sur l'enveloppe
   INTERNE, qui n'a pas d'enfant collant. */
.calc-panneau {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .42s cubic-bezier(.16,1,.3,1);
}
.calc-panneau > * { min-height: 0; }
.calc-panneau.ouvert { grid-template-rows: 1fr; }

/* Fermé : rien n'est atteignable ni annoncé. `visibility` bascule à la FIN de
   la fermeture et au DÉBUT de l'ouverture — d'où les deux durées de délai
   asymétriques, sinon le contenu disparaîtrait avant d'avoir fini de se
   replier. */
.calc-panneau-corps {
  visibility: hidden;
  transition: visibility 0s linear .42s;
}
.calc-panneau.ouvert .calc-panneau-corps {
  visibility: visible;
  transition-delay: 0s;
}
/* Dans le panneau le récapitulatif ne colle pas : il n'a pas de hauteur de
   défilement propre, et coller dans un bloc qui vient de s'ouvrir accroche. */
.calc-panneau .recap { position: static; }

/* Entrée des porteurs. ⚠️ On anime la propriété `translate`, PAS `transform` :
   `transform` est déjà pris par l'état actif du lutin (le soulèvement), et sur
   un <g> SVG il écraserait en plus l'attribut `transform` qui porte la
   position. Les deux propriétés se composent, elles ne se remplacent pas. */
.calc-panneau .lutin-anim { translate: -46px 0; opacity: 0; }
.calc-panneau.ouvert .lutin-anim {
  translate: 0 0; opacity: 1;
  transition: translate .46s cubic-bezier(.16,1,.3,1) var(--pas, 0s),
              opacity .3s ease-out var(--pas, 0s);
}
/* Décalage par rang, plafonné : 6 porteurs × 50 ms = 250 ms de retard au plus,
   soit une arrivée bouclée en ~710 ms. Mesuré : à 70 ms de pas et 520 ms de
   course, le dernier porteur bougeait encore à 1,2 s — ce n'est plus une
   arrivée, c'est une attente.

   ⚠️ Le retard passe par une PROPRIÉTÉ PERSONNALISÉE, pas par
   `transition-delay` posé sur ces sélecteurs. `…:nth-child(n) .lutin-anim` est
   plus spécifique que `…ouvert .lutin-anim` : un `transition-delay: 0s` écrit
   dans la requête de mouvement réduit ne l'emportait PAS (une requête média
   n'ajoute aucune spécificité), et l'arrivée restait décalée de 250 ms là où
   l'on demande justement qu'elle ne le soit pas. Une variable, elle, s'hérite
   du panneau et une seule ligne suffit à l'annuler. */
.calc-panneau.ouvert .lutin-chiffre:nth-child(1) .lutin-anim { --pas: 0s }
.calc-panneau.ouvert .lutin-chiffre:nth-child(2) .lutin-anim { --pas: .05s }
.calc-panneau.ouvert .lutin-chiffre:nth-child(3) .lutin-anim { --pas: .10s }
.calc-panneau.ouvert .lutin-chiffre:nth-child(4) .lutin-anim { --pas: .15s }
.calc-panneau.ouvert .lutin-chiffre:nth-child(5) .lutin-anim { --pas: .20s }
.calc-panneau.ouvert .lutin-chiffre:nth-child(6) .lutin-anim { --pas: .25s }

/* Le récapitulatif suit l'arrivée, une fois les porteurs en place. */
.calc-panneau .recap { translate: 0 -10px; opacity: 0; }
.calc-panneau.ouvert .recap {
  translate: 0 0; opacity: 1;
  transition: translate .42s cubic-bezier(.16,1,.3,1) .14s,
              opacity .3s ease-out .14s;
}

@media (prefers-reduced-motion: reduce) {
  /* Le déplacement disparaît, l'apparition reste : sans elle on ne verrait pas
     que quelque chose vient de s'ouvrir. */
  .calc-panneau, .ouvre-calc-fleche { transition-duration: .01ms; }
  /* Une seule ligne annule les six retards, par héritage de la variable. */
  .calc-panneau { --pas: 0s; }
  .calc-panneau .lutin-anim, .calc-panneau .recap { translate: 0 0; }
  .calc-panneau.ouvert .lutin-anim,
  .calc-panneau.ouvert .recap { transition: opacity .2s ease-out; }
}

/* Fiche du tarif dégressif (/tarifs). Elle porte seule le message de prix
   depuis le retrait de la grille 245/295/330 : elle a droit à plus d'air que
   les cartes voisines. */
.carte-degressif { padding: 2rem 2.2rem; }
.carte-degressif h2 { margin: 0 0 .9rem; font-size: 1.6rem; }
.carte-degressif p { margin: 0 0 1rem; color: var(--encre-doux); }
.carte-degressif p:last-of-type { margin-bottom: 1.5rem; }
@media (max-width: 640px) { .carte-degressif { padding: 1.5rem 1.4rem; } }

/* ── Ajouts du 17-09-2026 : soucis du jour J, bandeau langues, sceau RGPD ── */

/* Les contrariétés d'organisateur. La barre rouge se barre au survol : le
   geste dit « supprimé » mieux qu'un mot. */
.grille-soucis { gap: 1.1rem; }
.souci { position: relative; background: var(--blanc); border: 1px solid var(--trait);
         border-radius: var(--r); padding: 1.3rem 1.3rem 1.3rem 1.6rem; }
.souci h3 { font-size: 1.02rem; margin: 0 0 .35rem; }
.souci p  { color: var(--encre-doux); font-size: .94rem; margin: 0; }
.souci-barre { position: absolute; left: 0; top: 1.3rem; bottom: 1.3rem; width: 3px;
               border-radius: 3px; background: var(--rouge); opacity: .55;
               transition: opacity .18s ease, transform .18s ease; }
.souci:hover .souci-barre { opacity: 1; transform: scaleY(1.06); }

/* Bandeau des langues : clair, juste avant le bandeau RGPD sombre. */
.bandeau-langues { background: var(--primaire-p); padding: clamp(2.6rem, 5.5vw, 4.2rem) 0; }
.pastille-ia b { background: var(--primaire); }
.langues-chiffres { display: grid; grid-template-columns: repeat(3, 1fr);
                    gap: 1.2rem; margin-top: clamp(1.6rem, 3vw, 2.4rem); }
.lg-bloc { background: var(--blanc); border: 1px solid var(--trait);
           border-radius: var(--r); padding: 1.4rem; }
/* Le bloc « mesurées » est le seul argument que la concurrence ne tient pas :
   il est mis en avant, les deux autres restent sobres. */
.lg-bloc-fort { border-color: var(--primaire-c); box-shadow: var(--ombre); }
.lg-bloc p { color: var(--encre-doux); font-size: .94rem; margin: .3rem 0 0; }
.lg-bloc strong { color: var(--encre); }
.lg-nombre { font-size: clamp(2rem, 4.6vw, 3rem); font-weight: 800; line-height: 1;
             color: var(--primaire); letter-spacing: -.02em; }
.langues-puces { display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center;
                 list-style: none; padding: 0; margin: clamp(1.6rem, 3vw, 2.2rem) 0 0; }
.langues-puces li { background: var(--blanc); border: 1px solid var(--trait);
                    border-radius: 999px; padding: .28rem .7rem;
                    font-size: .82rem; color: var(--encre-doux); }
.langues-pied { text-align: center; margin: 1.4rem 0 0; color: var(--encre-doux);
                font-size: .95rem; }

/* Sceau RGPD du pied de page.
   ⚠️ Préfixé `.pied` À DESSEIN : `.pied a { display:block }` vaut (0,1,1) et
   bat un simple `.sceau-rgpd` (0,1,0), quel que soit l'ordre dans le fichier.
   Sans ce préfixe le sceau s'étire sur toute la colonne. */
.pied .sceau-rgpd { display: inline-flex; align-items: center; gap: .55rem;
              width: fit-content; margin: 1rem 0 0;
              padding: .45rem .8rem .45rem .6rem; border-radius: 999px;
              border: 1px solid rgba(219,228,243,.28); text-decoration: none;
              transition: border-color .18s ease, background .18s ease; }
.pied .sceau-rgpd:hover { border-color: rgba(219,228,243,.6); background: rgba(219,228,243,.07); }
.sceau-rgpd svg { width: 21px; height: 25px; flex: none; }
.sc-bouclier { fill: none; stroke: var(--primaire-c); stroke-width: 1.6; }
.sc-coche { fill: none; stroke: #7fd4a8; stroke-width: 2.2;
            stroke-linecap: round; stroke-linejoin: round; }
.sceau-rgpd span { display: flex; flex-direction: column; line-height: 1.15;
                   font-size: .74rem; color: #b8c5dc; }
.sceau-rgpd b { font-size: .82rem; letter-spacing: .07em; color: #fff; }

@media (max-width: 760px) {
  .langues-chiffres { grid-template-columns: 1fr; }
}

/* Titre d'accueil long (17-09-2026) : « Traduisez et diffusez vos évènements en
   simultané, avec ou sans interprète » fait 74 caractères contre 45 au titre
   précédent. À 3,4 rem il occupait 313 px de haut et repoussait le chapeau et
   les boutons sous la ligne de flottaison. Mesuré, pas supposé. */
.h1-long { font-size: clamp(1.85rem, 3.9vw, 2.7rem); }

/* Captcha auto-hébergé du formulaire de contact (29-09-2026). La case se coche
   seule quand la preuve de travail est trouvée ; le bouton d'envoi reste
   désactivé avant. Rendre la vérification VISIBLE la rend rassurante : une
   attente muette se lit comme une page qui rame. */
.antibot { display: flex; align-items: center; gap: .7rem; margin: .2rem 0 1rem;
           padding: .7rem .9rem; border: 1px solid var(--trait);
           border-radius: var(--r-s); background: var(--fond);
           font-size: .9rem; color: var(--encre-doux); }
.antibot .ab-case { width: 20px; height: 20px; flex: none; border-radius: 5px;
                    border: 2px solid var(--gris); background: var(--blanc);
                    position: relative; transition: border-color .2s, background .2s; }
.antibot.ok { border-color: #bfe0d3; background: var(--vert-p); color: #0f5c42; }
.antibot.ok .ab-case { border-color: var(--vert); background: var(--vert); }
.antibot.ok .ab-case::after { content: ""; position: absolute; left: 5px; top: 1px;
                              width: 5px; height: 10px; border: solid #fff;
                              border-width: 0 2px 2px 0; transform: rotate(45deg); }
