:root{
  --bg:#0b1024; --surface:#141b2c; --field:#1a2233;
  --border:#2a3550; --border-soft:#1c2740;
  --ink:#eef2fa; --ink-soft:#dfe6f3; --muted:#9fb0d0;
  --faint:#8a93a8; --fainter:#66718a;
  --accent:#e0a500; --accent-tint:#e0a50022; --on-accent:#14100a;
  --max:1080px;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  font-size:17px; line-height:1.65; -webkit-font-smoothing:antialiased;
}
a{color:var(--accent); text-decoration:none}
a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--accent); outline-offset:3px; border-radius:4px}
img,svg{max-width:100%; height:auto}

/* Les changements au survol — couleur d'un lien, bordure d'un bouton,
   éclaircissement d'un bouton doré — étaient instantanés : passer la souris
   sur la page la faisait clignoter. Un fondu de 0,18 s suffit à l'adoucir.
   ⚠️ La règle est enfermée dans « prefers-reduced-motion:no-preference » : un
   visiteur qui a réglé son téléphone ou son ordinateur sur « limiter les
   animations » retrouve le comportement instantané.

   ⚠️ CE COMMENTAIRE A AFFIRMÉ, DU 2 AU 4 AOÛT 2026, QUE C'ÉTAIT LA SEULE
   ANIMATION DU SITE ET QUE « rien ne bouge tout seul ». C'ÉTAIT FAUX : la page
   d'accueil lance une vidéo de 23 secondes en boucle automatique, et elle,
   n'est pas coupée quand le visiteur demande à limiter les animations — le
   site n'exécutant aucun script, on ne peut pas la mettre en pause. Le fichier
   le concédait déjà 700 lignes plus bas, ce qui faisait deux commentaires
   contradictoires dans le même fichier. Ne pas réécrire cette phrase à
   l'envers : la vidéo bouge toute seule, c'est un choix assumé (voir l'encadré
   du démarrage automatique dans la fonction apercu()). */
@media(prefers-reduced-motion:no-preference){
  a,.btn,.store,.badge,.pages img{
    transition:
      color .18s cubic-bezier(.22,1,.36,1),
      border-color .18s cubic-bezier(.22,1,.36,1),
      filter .18s cubic-bezier(.22,1,.36,1),
      transform .18s cubic-bezier(.22,1,.36,1);
  }
}

/* ── Animations (27 août 2026) ───────────────────────────────────────
   Trois familles, et pas une de plus — demande d'Eric : « un peu plus
   moderne, sans en avoir trop » :
     1. l'entrée du haut de page : titre, sous-titre, boutons puis capture
        apparaissent en fondu décalé, au chargement ;
     2. l'apparition au défilement : cartes, formules, captures, pages du
        rapport et sections légales se révèlent en entrant dans l'écran,
        et les barres d'ensoleillement se remplissent ;
     3. les survols : les objets cliquables se soulèvent d'un pixel (la
        transition « transform » est déclarée juste au-dessus).

   ⚠️ TOUT est enfermé dans « prefers-reduced-motion:no-preference » : un
   visiteur qui limite les animations retrouve le site parfaitement figé.
   Et RIEN ne boucle : chaque animation se joue une fois puis s'arrête —
   le seul mouvement perpétuel reste la vidéo, choix déjà assumé.

   ⚠️ L'apparition au défilement se fait SANS AUCUN SCRIPT : c'est la
   propriété CSS « animation-timeline: view() » (Chrome et Android depuis
   2023, Safari 26), enfermée dans un @supports. Un navigateur qui ne la
   connaît pas affiche la page comme avant, tout visible. C'est aussi
   pourquoi AUCUN état caché ne doit être posé dans les styles de base :
   l'invisibilité ne vit QUE dans les @keyframes — un élément dont
   l'animation ne tourne pas (vieux navigateur, impression) reste donc
   toujours visible. Ne jamais écrire « opacity:0 » hors d'une @keyframes.

   ⚠️ LE MODE DE REMPLISSAGE EST « backwards », PAS « both ». Une fois
   l'animation finie, « both » ne lâche jamais l'élément : le navigateur
   le garde indéfiniment en état d'animation, composé à part, pour un
   état final identique au style de base. « backwards » cache l'élément
   pendant le délai, joue le fondu, puis rend la main au style de base —
   à l'écran les deux sont indiscernables, backwards est simplement le
   mode qui ne laisse aucune trace. (La capture noire du volet d'aperçu
   local a un temps été imputée à « both » : faux, mesurée AUSSI avec la
   feuille d'origine sans aucune animation — c'est le volet masqué qui
   diffère la peinture, voir la note près de .hero-tel.) */
@media(prefers-reduced-motion:no-preference){
  html{scroll-behavior:smooth}

  /* 1. L'entrée du haut de page. Une seule cascade, courte : tout est en
     place en à peine plus d'une seconde, personne n'attend. */
  @keyframes lever{
    from{opacity:0; transform:translateY(14px)}
  }
  .hero h1{animation:lever .6s cubic-bezier(.22,1,.36,1) backwards}
  .hero p{animation:lever .6s cubic-bezier(.22,1,.36,1) .1s backwards}
  .hero .stores{animation:lever .6s cubic-bezier(.22,1,.36,1) .2s backwards}
  .hero .actions{animation:lever .6s cubic-bezier(.22,1,.36,1) .3s backwards}
  /* Le conteneur, PAS la balise .tel : elle porte déjà une rotation, et
     une animation qui pose « transform » l'écraserait. Le halo doré
     (::before du conteneur) monte avec l'ensemble.
     ℹ️ Si la capture paraît NOIRE dans le volet d'aperçu local juste
     après un chargement : ce n'est pas cette animation — mesuré le
     27/08/2026 avec la feuille de style d'origine, sans aucune
     animation, même noir. Le volet masqué retarde la peinture des
     images en chargement différé ; un défilement la déclenche. */
  .hero-tel{animation:lever .8s cubic-bezier(.22,1,.36,1) .25s backwards}

  /* 2. L'apparition au défilement. */
  @supports (animation-timeline: view()){
    @keyframes reveler{
      from{opacity:0; transform:translateY(16px)}
    }
    /* Chaque bloc suit SA propre position dans la page : les décalages
       entre cartes viennent tout seuls de la mise en page, sans rien
       régler. Deux règles pour compléter cette liste un jour :
       ne pas y mettre un bloc contenu dans un autre de la liste (les
       deux fondus se cumuleraient), et ne pas y mettre la vidéo (.film)
       — sur téléphone elle est dans l'écran d'arrivée, un fondu piloté
       par le défilement la laisserait à moitié transparente tant qu'on
       n'a pas bougé, or on doit voir l'application dès qu'on arrive. */
    section h2,.card,.public,.plan,.row,.ecrans,.pages,.sec,
    .bloc-final .stores,.bloc-final .actions{
      animation:reveler linear backwards;
      animation-timeline:view();
      /* La montée se joue pendant que le bloc grimpe le premier tiers de
         l'écran : arrivé à hauteur de lecture, il est en place. Un bloc
         déjà à l'écran au chargement est au-delà de cette plage, donc
         affiché plein — aucun éclair au premier rendu. */
      animation-range:entry 0% cover 30%;
    }
    /* Les barres d'ensoleillement se remplissent — l'ombre recule devant
       le soleil, c'est le geste même de l'application. La largeur
       d'arrivée n'est PAS écrite ici : une @keyframes sans état final
       rend la main à la largeur calculée plus bas (la part de soleil),
       la barre ne peut donc toujours pas contredire son chiffre. */
    @keyframes pousser{
      from{width:0}
    }
    .duree-soleil{
      /* Tant que la barre est plus courte que son chiffre, le chiffre ne
         doit pas déborder sur l'ombre. Sans effet sur les halos : une
         ombre portée n'est pas rognée par l'overflow de son propre
         élément. */
      overflow:hidden;
      animation:pousser linear backwards;
      animation-timeline:view();
      animation-range:entry 0% cover 35%;
    }
    /* Le chiffre ne paraît qu'une fois sa barre presque pleine : un
       nombre rogné par un bord en mouvement ne se lit pas. */
    @keyframes paraitre{
      from{opacity:0}
    }
    .duree-num{
      animation:paraitre linear backwards;
      animation-timeline:view();
      animation-range:cover 28% cover 42%;
    }
  }

  /* 3. Les survols. Le fondu de 0,18 s est déclaré plus haut ; l'élément
     revient tout seul à sa place quand la souris part. */
  .btn:hover,.store:hover,.badge:hover{transform:translateY(-1px)}
  .pages a:hover img{transform:translateY(-3px)}
}
/* text-wrap:balance répartit un titre sur des lignes de longueur égale au lieu
   de laisser un mot seul en dernière ligne ; text-wrap:pretty fait la même
   chose, en plus discret, sur les paragraphes. Deux propriétés du navigateur,
   sans effet sur les navigateurs qui ne les connaissent pas. */
h1,h2,h3{line-height:1.2; letter-spacing:-.02em; margin:0; text-wrap:balance}
h1{font-size:clamp(2.1rem,6vw,3.4rem); font-weight:700}
h2{font-size:clamp(1.5rem,3.6vw,2.1rem); font-weight:650}
h3{font-size:1.08rem; font-weight:600}
p{margin:0 0 1em; text-wrap:pretty}
p:last-child{margin-bottom:0}

.wrap{max-width:var(--max); margin:0 auto; padding:0 22px}
section{padding:clamp(52px,8vw,92px) 0; border-top:1px solid var(--border-soft)}
section:first-of-type{border-top:0}
.lede{color:var(--ink-soft); font-size:1.12rem; max-width:62ch}

/* ⚠️ IL N'Y A PLUS DE PETITE ÉTIQUETTE DORÉE AU-DESSUS DES TITRES, et c'est
   volontaire (2 août 2026). Chaque section en portait une — « La différence »,
   « Pour qui », « Portée »… : sept en tout, une par section. C'est le tic
   d'écran le plus reconnaissable des pages fabriquées automatiquement, et il
   ne servait à rien ici, les titres se suffisant à eux-mêmes (« Une course du
   soleil, ce n'est pas un ensoleillement » n'a pas besoin qu'on annonce
   « La différence » au-dessus). Le filet gris entre deux sections marque déjà
   la séparation. Ne pas les remettre. */

/* ── En-tête ─────────────────────────────────────────────────────── */
/* ⚠️ Les deux premières propriétés sont indispensables : sur la page d'accueil, le
   bandeau qui suit remonte DERRIÈRE cette en-tête (marge négative) et, sans
   eux, il passait par-dessus — le logo et les liens disparaissaient purement
   et simplement sous l'image. */
.top{
  position:relative; z-index:2;
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; padding:18px 0;
}
.brand{
  display:inline-flex; align-items:center; gap:10px;
  color:var(--ink); font-weight:650; letter-spacing:-.01em; font-size:1.05rem;
}
.brand:hover{text-decoration:none}
.top nav{display:flex; gap:20px; font-size:.94rem}
.top nav a{color:var(--muted)}
.top nav a:hover{color:var(--ink)}

/* ── Accueil ─────────────────────────────────────────────────────── */
/* Le haut de page est posé sur un rendu 3D de l'application.
   ⚠️ Le voile n'est pas une coquetterie : sans lui, le texte blanc traverse
   des toits clairs et devient illisible par endroits. Il est fait de DEUX
   dégradés, et les deux servent :
     • le vertical raccorde l'image au fond du site en haut et en bas — sans
       lui, deux lignes de coupure nettes barreraient la page ;
     • l'horizontal assombrit le côté du texte en laissant respirer le
       paysage à droite, là où il n'y a rien à lire.
   Ne pas les remplacer par un aplat uniforme : on perdrait l'image sans rien
   gagner en lisibilité. Les alphas sont écrits en hexadécimal à la suite de
   la couleur du thème (#0b1024), comme ailleurs dans ce fichier. */
/* Le bandeau remonte DERRIÈRE l'en-tête, pour que l'image parte du tout haut
   de la page : sans ça, une bande de fond uni la coiffait et l'effet tombait.
   L'en-tête n'a pas de fond, elle se pose donc simplement dessus — et le
   dégradé vertical la garde sur du sombre, donc lisible.
   ⚠️ La variable --entete est la hauteur de cette en-tête (18 px de marge en
   haut et en bas + 26 px de logo). Si l'en-tête change de taille, corriger
   ici. Une valeur trop petite ne casse rien : il resterait juste un liseré de
   fond uni au-dessus de l'image. */
.hero-fond{
  --entete:62px;
  position:relative;
  /* Le halo doré derrière la capture (.hero-tel::before) déborde volontairement
     de 8 % sur les côtés. Sur un grand écran il tombe dans la marge du site et
     ne gêne personne ; sur une tablette, où la colonne touche presque le bord,
     il poussait la page de 6 px et créait une barre de défilement horizontale.
     « clip » le coupe au bord sans créer de zone défilante — contrairement à
     « hidden », qui en créerait une. Le halo étant déjà transparent à cet
     endroit, la coupe ne se voit pas. */
  overflow-x:clip;
  margin-top:calc(-1 * var(--entete));
  padding-top:var(--entete);
  background-color:var(--bg);
  /* Cadrage choisi en comparant trois prises à l'écran : c'est celui qui
     montre à la fois l'étendue de la ville et la crête qui la domine — ce que
     l'application sait faire, en une image. */
  background-position:50% 56%;
  background-size:cover;
  background-repeat:no-repeat;
}
.hero-fond::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(180deg,#0b1024 0,#0b102433 14%,#0b102433 62%,#0b1024 100%),
    linear-gradient(90deg,#0b1024f2 0,#0b1024e0 28%,#0b102496 52%,#0b10240f 100%);
}
.hero-fond > .wrap{position:relative; z-index:1}
/* Sur un téléphone, le texte occupe TOUTE la largeur : le dégradé horizontal
   ne peut plus le protéger, c'est donc le voile général qui se renforce. Le
   cadrage se décale aussi, une image en 2:1 étant très rognée sur un écran
   étroit — sans quoi on ne verrait qu'une bande de montagne sans la ville. */
@media(max-width:759px){
  .hero-fond{background-position:64% 38%}
  .hero-fond::after{
    background:
      linear-gradient(180deg,#0b1024 0,#0b10247a 16%,#0b10247a 62%,#0b1024 100%),
      linear-gradient(90deg,#0b10249e 0,#0b10247a 100%);
  }
}
.hero-fond{background-image:url("/medias/fond-hero.f4264d0d6f.jpg")}
.hero{
  display:grid; gap:clamp(30px,5vw,56px); align-items:center;
  grid-template-columns:1fr; padding:clamp(30px,5vw,56px) 0 clamp(52px,8vw,92px);
}
/* Sur une tablette, la place est comptée : à parts presque égales, la colonne
   de texte tombait à 42 caractères par ligne, en dessous du confort de lecture.
   On donne donc plus de largeur au texte tant que l'écran n'est pas vraiment
   large (mesuré : 52 caractères sur un iPad vertical), et on revient à
   l'équilibre au-delà. La capture, elle, ne perd rien : elle est de toute façon
   plafonnée à 268 px. */
@media(min-width:760px){.hero{grid-template-columns:1.3fr .7fr}}
@media(min-width:980px){.hero{grid-template-columns:1.05fr .95fr}}
.hero p{color:var(--ink-soft); font-size:1.14rem; max-width:54ch}
/* Sur un téléphone, la capture du haut de page est masquée : elle occuperait
   tout l'écran d'arrivée et repousserait la vidéo sous le pli — or un
   navigateur ne démarre une vidéo muette QUE lorsqu'elle devient visible. Le
   visiteur d'un téléphone voit donc la promesse, les boutons, puis la vidéo :
   c'est mieux qu'une image fixe. */
@media(max-width:759px){.hero > div:last-child{display:none}}
/* Le cadre de téléphone du haut de page est un peu incliné et éclairé par une
   lueur dorée : c'est la seule fantaisie graphique du site, et elle sert à ce
   que la première chose vue soit l'application elle-même, pas un dessin. */
.hero-tel{position:relative; display:flex; justify-content:center}
/* La lueur est écrite avec l'opacité en clair (le « 30 » final) plutôt qu'avec
   --accent-tint : cette variable vaut 13 % d'opacité, réglée pour un fond de
   badge de quelques pixels, et étalée sur un halo de cette taille elle ne se
   voyait tout simplement pas. */
.hero-tel::before{
  content:""; position:absolute; inset:-16% -8% -12%;
  background:radial-gradient(closest-side,#e0a50030,#e0a50010 52%,transparent 74%);
  pointer-events:none;
}
.hero-tel .tel{max-width:268px; transform:rotate(-2.2deg)}
/* Toujours sur téléphone : la vidéo remonte AVANT la phrase d'introduction,
   pour être dans l'écran d'arrivée. C'est aussi ce qui la met en marche, un
   navigateur ne démarrant une vidéo muette que quand elle devient visible. */
@media(max-width:759px){
  #images{padding-top:0}
  #images .wrap{display:flex; flex-direction:column}
  #images h2{order:1}
  #images .film{order:2; margin-top:22px}
  #images .lede{order:3; margin-top:22px}
  #images .ecrans{order:4}
}
.actions{display:flex; flex-wrap:wrap; gap:12px; margin-top:30px}
.btn{
  display:inline-flex; align-items:center; gap:9px;
  padding:13px 22px; border-radius:12px; font-weight:600; font-size:.98rem;
  background:var(--accent); color:var(--on-accent); border:1px solid var(--accent);
}
.btn:hover{text-decoration:none; filter:brightness(1.08)}
.btn-ghost{background:transparent; color:var(--ink); border-color:var(--border)}
.btn-ghost:hover{border-color:var(--accent); filter:none}
.btn[aria-disabled="true"]{
  background:var(--field); color:var(--muted); border-color:var(--border);
  cursor:default; pointer-events:none;
}

/* ── Boutons de téléchargement ───────────────────────────────────── */
/* ⚠️ RIEN N'EST REDESSINÉ ICI — ni le triangle du Play Store, ni la pomme.
   Les badges sont les fichiers OFFICIELS de Google et d'Apple, téléchargés et
   rangés par « preparer-medias.py badges ». Les deux maisons imposent de les
   employer tels quels : un logo refait à peu près serait hors de leurs règles.
   Tant qu'un store n'a pas l'application, son badge ne s'affiche pas (c'est
   aussi leur règle) et on garde le bouton « Bientôt sur … » en texte, qui ne
   reprend aucun logo. */
.stores{display:flex; flex-wrap:wrap; align-items:center; gap:12px; margin-top:30px}
/* Les badges gardent leur propre apparence : ni fond, ni bordure, ni arrondi
   de notre part — on ne fait que leur donner une taille.
   ⚠️ Les deux fichiers ne se cadrent PAS de la même façon : celui d'Apple est
   plein bord, celui de Google arrive avec sa zone de sécurité incluse (58 px
   transparents sur 250 de haut). Pour que les deux logos paraissent de la même
   taille, il faut donc donner au fichier Google une hauteur plus grande :
   40 × 250 / 192 ≈ 52. Ne pas « corriger » ces deux valeurs en les égalisant. */
.badge{display:inline-flex}
.badge:hover{text-decoration:none; filter:brightness(1.12)}
.badge img{display:block; width:auto}
.badge-apple img{height:40px}
.badge-google img{height:52px}
.store{
  display:inline-flex; align-items:center; gap:13px; line-height:1.2;
  padding:11px 22px; border-radius:13px;
  border:1px solid var(--border); background:var(--surface); color:var(--ink);
}
.store:hover{text-decoration:none; border-color:var(--accent)}
.store .sm{display:block; font-size:.73rem; color:var(--muted)}
.store .lg{display:block; font-size:1.04rem; font-weight:650; letter-spacing:-.01em}
.store svg{flex:0 0 auto}
/* Le store où l'application est réellement disponible est le bouton plein :
   entre deux boutons de même poids, on ne sait pas lequel mène quelque part. */
.store.dispo{background:var(--accent); border-color:var(--accent); color:var(--on-accent)}
/* Le « Télécharger sur » de ce bouton fait 12,4 px : c'est du petit texte, il
   lui faut donc 4,5:1 comme n'importe quel autre. Un noir à 58 % d'opacité ne
   donnait que 4,09:1. On reprend « onAccentSoft », la couleur que l'application
   utilise déjà pour un sous-texte posé sur du doré — 4,90:1, et une valeur de
   moins à inventer. Ce bouton ne s'affiche que le jour où un store a
   l'application ET où son badge officiel manque : le défaut était donc invisible
   aujourd'hui, et serait apparu le jour du lancement. */
.store.dispo .sm{color:#4a3c14}
.store.dispo:hover{filter:brightness(1.08)}
.store[aria-disabled="true"]{cursor:default; pointer-events:none; opacity:.72}

/* ── Cartes ──────────────────────────────────────────────────────── */
.grid{display:grid; gap:16px; grid-template-columns:1fr; margin-top:38px}
@media(min-width:640px){.grid{grid-template-columns:1fr 1fr}}
.card{
  background:var(--surface); border:1px solid var(--border-soft);
  border-radius:16px; padding:24px;
}
.card h3{margin-bottom:9px}
.card p{color:var(--muted); font-size:.98rem}
.ico{color:var(--accent); margin-bottom:14px; display:block}

/* ── « Pour qui » : trois colonnes de texte, SANS cadre ───────────── */
/* ⚠️ Volontairement pas des cartes (2 août 2026). La page enchaînait quatre
   sections de boîtes de suite — les quatre outils, les trois publics, les deux
   formules, les trois limites — et cette répétition était le passage le plus
   terne de la page : quatre fois la même forme, on ne regarde plus rien.
   Ces trois textes sont courts, ils n'ont pas besoin d'être contenus dans un
   cadre : un simple filet au-dessus sépare aussi bien et laisse respirer.
   Ne pas les repasser en « card ». */
.publics{display:grid; gap:0; margin-top:30px}
.public{padding:22px 0; border-top:1px solid var(--border-soft)}
.public h3{margin-bottom:7px}
.public p{color:var(--muted); font-size:.98rem}
@media(min-width:760px){
  .publics{grid-template-columns:repeat(3,1fr); gap:32px; margin-top:38px}
  /* Sur grand écran les trois filets se rangent côte à côte et forment une
     ligne unique en haut du bloc : d'où la bordure un peu plus marquée. */
  .public{padding:20px 0 0; border-top:1px solid var(--border)}
}

/* ── Le chiffre d'illustration, DESSINÉ ──────────────────────────── */
/* 🔴 CE BLOC A LONGTEMPS ÉTÉ DEUX NOMBRES DORÉS DE MÊME TAILLE SÉPARÉS
   D'UNE FLÈCHE GRISE, et c'était le passage le plus faible de la page :
   le fait le plus convaincant du site y était ÉNONCÉ, jamais MONTRÉ. Deux
   nombres écrits dans le même corps se ressemblent ; il fallait les lire,
   puis faire la division de tête pour comprendre que le premier étage
   reçoit deux fois et demie le soleil du rez-de-chaussée.

   Il est maintenant dessiné, avec les deux seules matières dont parle
   l'application : la lumière et l'ombre. Chaque étage reçoit son rail
   sombre, et un segment doré y occupe exactement sa part de soleil. Les
   deux rails ont la même longueur et les deux segments partent du même
   bord : l'écart se voit sans rien lire, et les chiffres exacts restent là
   pour qui veut les vérifier.

   ⚠️ AUCUNE LONGUEUR N'EST ÉCRITE À LA MAIN ICI. Les deux largeurs sont
   calculées depuis les minutes de content.mjs (voir PART_COURTE plus haut),
   et le chiffre inscrit sur la barre vient de la même source. Une barre ne
   peut donc pas contredire son propre chiffre — c'est le seul vrai danger
   de ce genre de dessin, et il est fermé par construction. Ne jamais poser
   un pourcentage en dur dans ces règles.

   ℹ️ DEPUIS LE 27/08/2026, LES BARRES SE REMPLISSENT quand elles entrent
   dans l'écran (bloc « Animations » en tête de feuille). Ce fichier a
   longtemps interdit toute animation ici, pour deux raisons : une
   animation CSS serait partie au chargement (donc finie avant qu'on
   arrive aux barres) et aurait touché ceux qui limitent les animations.
   Les deux objections sont levées SANS script : le déclenchement est
   piloté par le défilement (animation-timeline: view()) et le tout est
   enfermé dans « prefers-reduced-motion:no-preference ». La largeur
   d'arrivée reste celle calculée ci-dessous — l'animation n'écrit aucune
   longueur, et le chiffre (le span .duree-num de la page) ne paraît
   qu'une fois sa barre presque pleine. */
.compare{
  background:var(--surface); border:1px solid var(--border-soft);
  border-radius:16px; padding:clamp(20px,3.2vw,28px); margin:32px 0 0;
  /* L'écart entre les deux étages est nettement plus grand que celui qui
     sépare un étage de sa propre barre (9 px) : chaque couple « nom +
     barre » se tient, et les deux couples se distinguent. */
  display:grid; gap:clamp(22px,3vw,28px);
}
/* La liste est une vraie liste de définitions : « Au rez-de-chaussée » est
   le terme, la durée sa valeur. Un lecteur d'écran annonce donc le couple,
   dans le bon ordre, sans qu'on ait à lui décrire les barres. */
.compare dd{margin:0}
.duree-lieu{color:var(--muted); font-size:.95rem; margin-bottom:9px}
/* LE RAIL, C'EST L'OMBRE. Il s'assombrit vers la droite : plus on s'éloigne
   du soleil, plus la journée est noire.

   ⚠️ CE QUI LE REND VISIBLE, C'EST LA LUMIÈRE D'À CÔTÉ, PAS SA PROPRE
   COULEUR — et ce n'est pas une image, c'est une contrainte mesurée. La
   palette du site est déjà très sombre : contre la carte qui le porte, AUCUN
   fond, même le noir pur, ne dépasse 1,23:1 (mesuré). Assombrir davantage ne
   ferait donc rien apparaître. Ce qui donne à l'ombre son étendue, c'est le
   halo doré qui déborde de la barre et éclaire les premiers centimètres du
   rail — exactement comme on ne voit une ombre que parce qu'il y a de la
   lumière à côté. Ne pas essayer de « corriger » ce rail en le noircissant.

   ℹ️ Le filet reste volontairement discret (--border, 1,41:1). Il donne un
   bord sans transformer le rail en cadre — un filet plus clair (--fainter,
   3,51:1) a été essayé : le bloc se met alors à ressembler à une jauge de
   batterie, ce qui est exactement ce qu'on ne veut pas. L'information, elle,
   ne dépend pas de ce filet : elle est portée par le rapport entre les deux
   longueurs dorées, lisible à 8,8:1 sur le fond du rail, et la barre pleine
   du premier étage marque à elle seule où le rail s'arrête. */
.duree-rail{
  height:clamp(34px,5.6vw,44px);
  background:linear-gradient(90deg,#0a1122,#05070f);
  border:1px solid var(--border);
  border-radius:5px; overflow:hidden;
}
/* LA BARRE, C'EST LE SOLEIL. Elle s'éclaircit vers son bord droit — le
   point où le soleil disparaît — et deux halos en débordent : un serré et
   vif contre l'arête, un large et doux qui va mourir dans l'ombre.

   ⚠️ LE DÉGRADÉ EST HORIZONTAL, PAS VERTICAL. Un dégradé de haut en bas
   (essayé le 4 août) donne un liseré plus sombre en bas de barre : l'objet
   prend aussitôt l'aspect d'un bouton en plastique, et tout le bloc redevient
   une jauge. De haut en bas, la barre reste une matière plate et lumineuse.

   ⚠️ PAS DE COINS ARRONDIS SUR LA BARRE ELLE-MÊME : c'est le rail qui
   découpe (overflow:hidden). Elle garde donc un bord franc là où le soleil
   s'arrête — c'est une mesure, pas une pastille — et épouse l'arrondi du
   rail quand elle va jusqu'au bout.

   ⚠️ Conséquence du même découpage : les halos ne débordent QUE vers
   l'ombre, et la barre pleine du premier étage n'en montre aucun. C'est
   voulu — la lumière ne déborde que là où il reste de l'ombre à éclairer. */
.duree-soleil{
  display:flex; height:100%; align-items:center; justify-content:flex-end;
  padding:0 clamp(11px,1.7vw,15px);
  background:linear-gradient(90deg,#d59c00,var(--accent) 62%,#f7c62f);
  box-shadow:
    7px 0 14px -4px rgb(255 199 62 / .78),
    22px 0 46px -12px rgb(255 184 40 / .55);
  color:var(--on-accent); font-weight:650; letter-spacing:-.01em;
  font-size:clamp(.92rem,1.7vw,1.02rem);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.duree-basse .duree-soleil{width:41.9%}
.duree-haute .duree-soleil{width:100%}
/* Alignée à gauche et sur une largeur lisible, comme le texte qu'elle
   commente. Elle a été centrée tant que le bloc au-dessus l'était ; il ne
   l'est plus. Sert aussi à la mention d'abonnement, plus bas dans la page. */
.compare-note{color:var(--faint); font-size:.92rem; margin-top:14px; max-width:62ch}

/* ── Listes à puces dorées ───────────────────────────────────────── */
.ticks{list-style:none; margin:22px 0 0; padding:0; display:grid; gap:11px}
.ticks li{position:relative; padding-left:26px; color:var(--ink-soft)}
.ticks li::before{
  content:""; position:absolute; left:0; top:.62em;
  width:8px; height:8px; border-radius:50%; background:var(--accent);
}

/* ── Tarifs ──────────────────────────────────────────────────────── */
.plan{background:var(--surface); border:1px solid var(--border-soft); border-radius:16px; padding:26px}
.plan.featured{border-color:var(--accent); background:linear-gradient(180deg,var(--accent-tint),transparent 40%),var(--surface)}
/* La ligne dorée sous le titre d'une formule. Elle porte « Gratuit » dans la
   colonne de gauche et RIEN dans celle de droite (voir l'encadré du bloc
   Premium, plus bas) — mais elle reste présente dans les deux, vide d'un côté :
   sans elle, la liste d'avantages de Premium remontait de 67 px et les deux
   colonnes, pourtant côte à côte et de même hauteur, démarraient leur liste à
   deux niveaux différents. Ça se lisait comme une erreur de mise en page.
   ⚠️ La hauteur minimale est donc là pour réserver la place, pas pour
   décorer : c'est la hauteur mesurée du mot « Gratuit » à 2 rem (53 px).
   ⚠️ Rappel pour qui édite ce bloc : on est à l'intérieur d'une chaîne
   JavaScript délimitée par des accents graves — un accent grave dans un
   commentaire la referme et casse la fabrication. Utiliser « » . */
.price{
  display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
  margin:14px 0 4px; min-height:53px;
}
.price .amount{font-size:2rem; font-weight:700; color:var(--accent)}
/* Les règles « per » (le / mois après un montant) et « price-alt » (le prix
   barré) ont été retirées le 2 août 2026 : elles n'étaient plus employées
   nulle part depuis que le site n'affiche plus aucun prix. */
.plan .ticks li{font-size:.98rem}

/* ── Blocs d'information ─────────────────────────────────────────── */
.rows{display:grid; gap:2px; margin-top:34px}
.row{background:var(--surface); border:1px solid var(--border-soft); padding:22px 24px}
.row:first-child{border-radius:16px 16px 0 0}
.row:last-child{border-radius:0 0 16px 16px}
.row h3{color:var(--accent); font-size:1rem; margin-bottom:6px}
.row p{color:var(--muted); font-size:.98rem}

/* ── Captures d'écran et vidéos ──────────────────────────────────── */
/* Le cadre de téléphone est dessiné en CSS : aucune image de coque à
   charger, et il s'adapte à la hauteur réelle de la capture. */
/* La bande de captures défile horizontalement, comme celle d'une fiche de
   store. Cinq captures de téléphone ne tiennent pas côte à côte sur un écran,
   et les réduire jusqu'à ce qu'elles y tiennent les rendrait illisibles.
   La propriété scroll-snap fait que chacune s'arrête bien cadrée — c'est le
   navigateur qui s'en charge, le site n'exécutant aucun script.

   La dernière capture est volontairement coupée par le bord droit : c'est ce
   qui fait comprendre, sans flèche ni texte, que la bande continue. */
/* ⚠️ Cette bande porte tabindex="0" dans la page, et ce n'est pas décoratif :
   elle cache 592 px de contenu sur ordinateur et 1 265 px sur téléphone,
   et elle ne contient AUCUN élément sur lequel on puisse s'arrêter au clavier
   (ce sont des images, pas des liens). Chrome et Firefox rendent d'eux-mêmes
   une zone défilante atteignable au clavier ; Safari non — sans cet attribut,
   un visiteur qui n'utilise pas de souris n'y voyait que les deux premières
   captures. Le contour de focus doré est fourni par la règle :focus-visible
   générale, qui ne se déclenche qu'au clavier : un clic à la souris ne dessine
   donc pas de cadre. */
.ecrans{
  display:flex; gap:clamp(14px,2.4vw,22px); margin-top:40px;
  padding:6px 0 20px; overflow-x:auto;
  scroll-snap-type:x proximity; scrollbar-width:thin;
}
.ecran{
  flex:0 0 auto; width:min(228px,62vw); scroll-snap-align:start;
  display:flex; flex-direction:column; align-items:center; text-align:center;
}
.tel{
  width:100%; max-width:290px; padding:9px;
  background:#05080f; border:1px solid var(--border);
  border-radius:30px; box-shadow:0 18px 44px rgb(0 0 0 / .45);
}
.tel img{display:block; width:100%; border-radius:22px}
.ecran h3{margin:18px 0 5px; font-size:1rem}
.ecran p{color:var(--muted); font-size:.9rem}

/* Une vidéo pèse plus qu'une image : elle n'est chargée que si le
   visiteur la lance (attribut preload="none" dans la page), et l'image
   d'attente suffit à comprendre de quoi il s'agit. */
.film{margin-top:40px; display:flex; flex-direction:column; align-items:center; text-align:center}
.film .tel{max-width:360px}   /* la vidéo est la pièce principale de la page */
/* height:auto est indispensable : contrairement à une image, une balise
   <video> ne recalcule PAS sa hauteur quand on lui donne width:100%. Elle
   garderait la hauteur de son attribut (1386 px), et l'image d'attente
   flotterait au milieu de bandes noires dans le cadre du téléphone.
   Les attributs width/height restent utiles : ils réservent la place. */
.film video{display:block; width:100%; height:auto; border-radius:22px; background:#05080f}
.film h3{margin:22px 0 7px}
.film p{color:var(--muted); font-size:.95rem; max-width:56ch}

/* ── Le rapport, page par page ───────────────────────────────────── */
/* Bande défilante horizontalement sur téléphone : quatre pages A4 côte à
   côte ne tiennent pas sur un écran étroit, et les réduire les rendrait
   illisibles. */
.pages{
  display:flex; gap:16px; margin-top:36px; padding:4px 0 18px;
  overflow-x:auto; scroll-snap-type:x proximity;
  scrollbar-width:thin;
}
.pages > *{
  flex:0 0 auto; width:min(232px,64vw); scroll-snap-align:start;
  color:var(--muted); font-size:.84rem; text-align:center;
}
.pages a:hover{text-decoration:none; color:var(--ink)}
.pages img{
  display:block; width:100%; border-radius:8px;
  border:1px solid var(--border-soft); background:#fff;
  box-shadow:0 10px 26px rgb(0 0 0 / .38);
}
.pages span{display:block; margin-top:10px}
/* --faint et non --fainter : à cette taille, le gris le plus clair
   descend sous le contraste lisible (mesuré 3,86:1 pour 4,5 requis). */
.pages .num{margin-top:3px; color:var(--faint); font-size:.78rem}
.pages a:hover img{border-color:var(--accent)}

/* ── Pages légales ───────────────────────────────────────────────── */
/* 🔴 PIÈGE DE L'UNITÉ « ch » — NE PAS REMONTER CETTE VALEUR.
   Au-delà d'environ 75 caractères par ligne, l'œil perd le début de la ligne
   suivante ; ce sont les pages les plus longues du site, la règle compte.

   Mais « ch » ne mesure PAS un caractère : il mesure la largeur du chiffre
   zéro, qui est l'un des plus larges de la police. Les vraies lettres d'un
   texte français sont bien plus étroites, donc il en rentre beaucoup plus que
   le chiffre annoncé. Mesuré en ligne le 4 août 2026 sur la politique de
   confidentialité : « 72ch » donnait 771 px, soit **93 caractères réels en
   moyenne et jusqu'à 97** — très au-delà de la limite que la valeur prétendait
   poser. La correction du 2 août (76 → 72) reposait donc sur un chiffre qui ne
   voulait pas dire ce qu'on croyait.

   56ch ≈ 600 px ≈ **72 caractères réels**, mesuré de la même façon (nombre de
   lignes réellement occupées par les plus longs paragraphes, divisé par leur
   nombre de caractères). Pour revérifier un jour : compter les lignes avec un
   Range dans le navigateur, jamais se fier au chiffre écrit ici. */
.doc{max-width:56ch; margin:0 auto; padding:clamp(30px,5vw,54px) 0 clamp(52px,8vw,86px)}
.doc .updated{color:var(--faint); font-size:.92rem; margin-top:16px}
.doc .intro{color:var(--ink-soft); margin-top:22px; font-size:1.05rem}
.sec{margin-top:44px; padding-top:28px; border-top:1px solid var(--border-soft)}
.sec-head{display:flex; gap:14px; align-items:baseline; margin-bottom:14px}
.sec-num{color:var(--accent); font-variant-numeric:tabular-nums; font-weight:650; font-size:.92rem}
.sec h2{font-size:1.28rem}
.sec p{color:var(--ink-soft)}
/* ⚠️ PAS DE GROS TRAIT DORÉ SUR LE CÔTÉ GAUCHE — retiré le 2 août 2026, ne pas
   le remettre. Le bloc portait une languette dorée de 3 px collée sur son bord
   gauche : c'est la signature visuelle la plus reconnaissable des interfaces
   fabriquées automatiquement, et elle apparaissait six fois sur le site (sur
   l'accueil, quatre dans la politique de confidentialité, une dans les
   conditions). Le fond doré très transparent suffit à détacher le bloc ; le
   cadre complet lui donne un contour franc au lieu d'une languette collée sur
   le bord. */
.note{
  background:var(--accent-tint); border:1px solid #e0a5004d;
  border-radius:12px; padding:16px 18px; margin:18px 0; color:var(--ink-soft);
}
.items{list-style:none; margin:18px 0; padding:0; display:grid; gap:14px}
.items li{background:var(--surface); border:1px solid var(--border-soft); border-radius:12px; padding:16px 18px}
.items .lab{font-weight:600; color:var(--ink); display:block; margin-bottom:3px}
.items .txt{color:var(--muted); font-size:.97rem}
.items .meta{color:var(--faint); font-size:.87rem; margin-top:6px; display:block}
.items .lnk{font-size:.87rem; margin-top:6px; display:inline-block}
.back{display:inline-block; margin-top:44px; color:var(--muted); font-size:.95rem}

/* ── Pied de page ────────────────────────────────────────────────── */
footer{border-top:1px solid var(--border-soft); padding:44px 0 56px; color:var(--faint); font-size:.92rem}
footer nav{display:flex; flex-wrap:wrap; gap:10px 22px; margin-bottom:20px}
footer nav a{color:var(--muted)}
/* --faint et non --fainter, pour la MÊME raison que les numéros de page du
   rapport plus haut : à cette taille le gris le plus clair tombe à 3,86:1 pour
   4,5 requis. C'est la mention de licence des données IGN — la ligne du site
   qu'il serait le plus gênant de ne pas pouvoir lire. Mesuré : 6,12:1. */
.attrib{color:var(--faint); font-size:.85rem; margin-top:14px; max-width:58ch}

/* ── Espacements et alignements ponctuels ────────────────────────── */
/* 🔴 CES RÈGLES REMPLACENT DES STYLES QUI ÉTAIENT ÉCRITS DANS LES BALISES
   (style="…") ET QUI NE S'APPLIQUAIENT JAMAIS. Trouvé le 4 août 2026, présent
   depuis l'origine du site.

   Pourquoi : la politique de sécurité du site (.htaccess) dit « style-src
   'self' » — les styles venant de ce fichier sont autorisés, ceux écrits dans
   la page sont interdits. C'est le MÊME verrou qui interdit les scripts, et
   c'est lui qui dispense le site de bandeau cookies. Le navigateur jetait donc
   les 16 réglages en silence : le bloc final s'affichait aligné à gauche au
   lieu d'être centré, le logo avait les coins carrés sur les cinq pages, et six
   marges retombaient sur de mauvaises valeurs.

   ⚠️ L'APERÇU LOCAL NE PEUT PAS VOIR CE DÉFAUT : le serveur d'aperçu ne sert
   pas les en-têtes du .htaccess (c'est écrit en tête de .claude/site-server.mjs).
   Tout marchait sur localhost et rien en ligne. Un contrôle par curl ne le voit
   pas davantage : le style EST dans le HTML, c'est le navigateur qui le refuse.
   Cela ne se constate qu'avec un vrai navigateur sur le vrai site.

   ⚠️ NE JAMAIS REMETTRE d'attribut style= : la fabrication échoue désormais si
   elle en trouve un (contrôle à la fin de ce fichier). */

/* Le paragraphe d'introduction qui suit un titre. Exprimé par la parenté
   plutôt que par une classe posée à la main : impossible d'oublier de la
   mettre, impossible de la mettre au mauvais endroit. */
h2 + .lede{margin-top:18px}
h3 + .lede{margin-top:10px}
.ticks + .note{margin-top:26px}
.note + h3{margin-top:44px}

/* Le second bouton, qui suit un premier groupe de boutons : il lui appartient,
   donc il se colle davantage que les 30 px par défaut de .actions. */
.actions.suite{margin-top:14px}
.centre{justify-content:center}

/* Le bloc de clôture de la page d'accueil, et la page 404 : tout est centré. */
.bloc-final{text-align:center}
.bloc-final .lede{margin:16px auto 0}

/* ℹ️ La règle .compare-note.mention a été retirée le 4 août 2026. Elle
   remettait à gauche, sur 62ch, la mention d'abonnement — parce que
   .compare-note était centrée pour le chiffre d'illustration. Ce bloc-là
   n'est plus centré (il est devenu deux barres alignées à gauche), donc la
   règle de base porte désormais ces deux réglages et l'exception n'a plus
   d'objet. Le rendu de la mention est inchangé. */

.brand img{display:block; border-radius:7px}
.illustration{
  width:100%; border-radius:18px; border:1px solid #1c2740;
  background:linear-gradient(180deg,#111a33,#0b1024);
}

/* ── Page 404 ────────────────────────────────────────────────────── */
.center{text-align:center; padding:clamp(60px,12vw,130px) 0}
.center p{color:var(--muted); margin-top:14px}