/* ═══════════════════════════════════════════════════════════════════════════
   Signal Power, feuille de style.

   Registre sombre assumé, une seule direction artistique. Le crème a été
   abandonné : il ne laissait aucune place à la couleur ni aux fonds animés.
   La palette catégorielle des missions (or, bleu, corail) est validée sur la
   surface sombre : bande de clarté, chroma, séparation daltonienne sur les
   paires adjacentes, plancher en vision normale, contraste.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --ground:    #080D1A;
  --surface:   #0F1729;
  --surface-2: #16203A;
  --ink:       #EDF1F8;   /* 15,9:1 sur --ground */
  --ink-2:     #98A6C2;   /*  7,1:1 */
  --hair:      #1D2941;
  --bord:      #38486A;

  /* accents d'affichage */
  --jalon:     #5F7096;   /* chiffres de la frise : contraste 3,92 sur --ground */
  --or:        #F0B93F;
  --or-2:      #C6912A;
  --bleu:      #5FB0FF;
  --vert:      #35C88E;
  --corail:    #FF8574;

  /* palette catégorielle validée */
  --t1: #BC8926; --t2: #3E88DC; --t3: #D5594A;

  --cta:        #F0B93F;
  --cta-survol: #FFD070;
  --sur-cta:    #10192C;   /* 10,1:1 sur l'or */

  --survol: rgba(237, 241, 248, 0.06);
  --ombre:  0 1px 2px rgba(0,0,0,.5), 0 18px 40px -22px rgba(0,0,0,.9);
  --marge:  clamp(1.25rem, 5vw, 3rem);
  /* Largeur du cadre : c'est elle qui bascule entre la mise en page
     téléphone et la mise en page ordinateur. Tout s'y aligne, y compris
     l'amorce des pistes horizontales. */
  --cadre:  46rem;
  --gouttiere: max(var(--marge), calc((100vw - var(--cadre)) / 2 + var(--marge)));
  --courbe: cubic-bezier(.32,.72,0,1);
}
:root { interpolate-size: allow-keywords; }
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
:target { scroll-margin-top: 1.5rem; }

@keyframes entre { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.hero-contenu > * { animation: entre 900ms var(--courbe) both; }
.hero-contenu > *:nth-child(1) { animation-delay: 60ms; }
.hero-contenu > *:nth-child(2) { animation-delay: 150ms; }
.hero-contenu > *:nth-child(3) { animation-delay: 240ms; }
.hero-contenu > *:nth-child(4) { animation-delay: 330ms; }
.hero-contenu > *:nth-child(5) { animation-delay: 420ms; }

body {
  margin: 0; background: var(--ground); color: var(--ink);
  font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: clamp(1.0625rem, 2.2vw, 1.125rem); line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ── aurore : le fond vit sur toute la page, pas seulement dans le hero ── */
body::before {
  content: ""; position: fixed; inset: -14vh -8vw; z-index: -1; pointer-events: none;
  background:
    radial-gradient(38vw 34vw at 12% 8%,  rgba(62,136,220,.20), transparent 62%),
    radial-gradient(42vw 38vw at 88% 26%, rgba(240,185,63,.16), transparent 64%),
    radial-gradient(36vw 34vw at 26% 72%, rgba(53,200,142,.13), transparent 62%),
    radial-gradient(34vw 30vw at 78% 92%, rgba(213,89,74,.13), transparent 60%);
}


.enveloppe { max-width: var(--cadre); margin: 0 auto; padding-left: var(--marge); padding-right: var(--marge); }
.mono { font-family: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, Menlo, monospace; }
a { color: inherit; text-decoration: none; }
.lien { box-shadow: inset 0 -1px 0 0 currentColor; }

.chapeau {
  margin: 0 0 1.5rem;
  font-family: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, Menlo, monospace;
  font-weight: 500; font-size: 0.6875rem;
  letter-spacing: 0.19em; text-transform: uppercase; color: var(--or);
}

.saut { position: absolute; left: -9999px; top: 0; z-index: 20;
        background: var(--surface); color: var(--ink); padding: 0.7rem 1.15rem;
        border: 1px solid var(--or); border-radius: 3px; }
.saut:focus { left: 1rem; top: 1rem; }

/* ═══ bannière de lancement ═══ */
.banniere {
  position: relative; overflow: hidden; display: flex; align-items: center; gap: 1rem;
  padding: 0.7rem var(--marge);
  background: linear-gradient(100deg, #12203C, #1B2C4E 45%, #2A2340);
  border-bottom: 1px solid var(--hair);
  font-size: 0.875rem; line-height: 1.45;
}
.banniere[hidden], html[data-banniere="fermee"] .banniere { display: none; }
.banniere p { margin: 0 auto; max-width: 60rem; text-wrap: balance; }
.banniere b {
  font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
  font-weight: 500; font-size: 0.6875rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--or); margin-right: 0.6rem; white-space: nowrap;
}
.banniere::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(240,185,63,.22) 50%, transparent 62%);
  transform: translateX(-100%); animation: eclat 5.5s var(--courbe) infinite;
}
@keyframes eclat { 0% { transform: translateX(-100%); } 55%, 100% { transform: translateX(100%); } }
.banniere > * { position: relative; z-index: 1; }
.fermer {
  appearance: none; background: none; border: 0; cursor: pointer; flex: none; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: 3px; color: var(--ink-2);
  transition: color 200ms var(--courbe), background-color 200ms var(--courbe);
}
.fermer:hover { color: var(--ink); background: var(--survol); }

/* ═══ barre ═══ */
.barre { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
         padding-top: clamp(1.25rem, 3.5vw, 2rem); padding-bottom: clamp(1.25rem, 3.5vw, 2rem); }
.barre-droite { display: flex; align-items: center; gap: clamp(0.75rem, 3vw, 1.5rem); }
.logo { display: block; width: auto; height: clamp(48px, 11vw, 96px); }

.langue { display: inline-flex; align-items: center; gap: 0.1rem;
          font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
          font-size: 0.75rem; font-weight: 500; letter-spacing: 0.06em; color: var(--ink-2); }
.langue button { appearance: none; background: none; border: 0; cursor: pointer; font: inherit;
                 letter-spacing: inherit; color: var(--ink-2);
                 display: inline-flex; align-items: center; min-height: 2.5rem; padding: 0 0.5rem;
                 border-radius: 3px; transition: color 200ms var(--courbe), background-color 200ms var(--courbe); }
.langue button:hover { color: var(--ink); background: var(--survol); }
.langue button[aria-pressed="true"] { color: var(--or); }
.langue span { opacity: 0.4; }

.bouton, .bouton-fantome {
  display: inline-block; font-weight: 500; line-height: 1.2; text-decoration: none; border-radius: 4px;
  transition: background-color 200ms var(--courbe), border-color 200ms var(--courbe),
              color 200ms var(--courbe), transform 200ms var(--courbe), box-shadow 200ms var(--courbe);
}
.bouton { background: var(--cta); color: var(--sur-cta); padding: 0.95rem 1.6rem; font-size: 1rem;
          border: 1px solid var(--cta); box-shadow: 0 10px 30px -14px rgba(240,185,63,.8); }
.bouton:hover { background: var(--cta-survol); border-color: var(--cta-survol);
                box-shadow: 0 14px 36px -14px rgba(240,185,63,.9); }
.bouton:active { transform: scale(0.985); }
.bouton-fantome { color: var(--ink); padding: 0.55rem 1rem; font-size: 0.9375rem;
                  border: 1px solid var(--bord); white-space: nowrap; }
.bouton-fantome:hover { border-color: var(--or); color: var(--or); }
.bouton:focus-visible, .bouton-fantome:focus-visible, a:focus-visible, summary:focus-visible,
button:focus-visible, .piste:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; border-radius: 4px; }

/* ═══ premier écran ═══ */
:root { --barre-h: clamp(6.5rem, 15vw, 10.5rem); }
.hero { position: relative; overflow: clip; display: flex; align-items: center;
        min-height: calc(100vh - var(--barre-h)); min-height: calc(100svh - var(--barre-h));
        padding-top: clamp(1.5rem, 4vw, 2.5rem); padding-bottom: clamp(5rem, 9vw, 6.5rem); }
.hero-contenu { position: relative; z-index: 1; width: 100%; }


/* Le nom de la maison en bloc, sur deux lignes assumées : à cette taille il
   ne tient pas sur une ligne, et une coupure au milieu d'« OPTIMISATION »
   passerait pour un accident. */
/* Le nom figure deja dans le logo, 100 px plus haut. Un seul registre ici :
   une ligne mono qui nomme la maison et son metier, sans concurrencer le
   titre ni la seule couleur d'accent de l'ecran, celle du bouton. */
/* Le nom et le qualificatif tenaient sur une seule ligne separes par un point
   median : a l'etroit, la ligne se repliait n'importe ou. Deux span en bloc
   forcent le meme decoupage a toutes les tailles, chacun sur sa propre ligne. */
.marque { margin: 0 0 1.5rem;
  font-family: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, Menlo, monospace;
  font-weight: 500; text-transform: uppercase; color: var(--ink-2); }
.marque-nom, .marque-qual { display: block; white-space: nowrap; }
/* Deux pixels de plus sur les deux lignes. Le qualificatif est en nowrap et
   occupe presque toute la largeur utile d'un telephone : en IBM Plex Mono la
   ligne mesure 30,4 fois la taille de police, soit 425 px a 14 px. Le terme en
   2,85vw plafonne donc la taille a ce que la ligne peut tenir, et rend les deux
   pixels des que la place existe. Il corrige aussi un debordement qui existait
   avant : a 320 px, 10 px demandaient 303 px pour 280 px utiles, et la fin de
   la ligne etait rognee. */
.marque-nom { font-size: clamp(0.875rem, 1.5vw + 2px, 1.0625rem); letter-spacing: 0.22em; line-height: 1.5; }
.marque-qual { margin-top: 0.3rem;
               font-size: min(clamp(0.75rem, 1.15vw + 2px, 0.875rem), 2.85vw);
               letter-spacing: 0.14em; line-height: 1.5; }
.fond { position: absolute; inset: -12% 0; z-index: 0; pointer-events: none; contain: paint; }
.ondes { display: block; width: 100%; height: 100%; }
.couche { transform-box: view-box; transform-origin: 0 0; animation: derive var(--duree, 90s) linear infinite; }
.couche path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.c-faible path { stroke: var(--bord); stroke-width: 1.25; opacity: 0.5; }
.c-medium path { stroke: var(--bleu); stroke-width: 1.5; opacity: 0.4; }
.c-or .trait-onde { stroke: var(--or); stroke-width: 1.75; opacity: 0.75; }
.c-or .aire-onde  { fill: var(--or); opacity: 0.07; stroke: none; }
@keyframes derive { from { transform: translateX(0); } to { transform: translateX(-1200px); } }
.voile { position: absolute; inset: 0;
         background: linear-gradient(100deg, var(--ground) 14%, rgba(8,13,26,.62) 50%, transparent 86%); }

/* grille technique qui dérive, très basse en contraste */
.hero::before {
  content: ""; position: absolute; inset: -58px; z-index: 0; pointer-events: none;
  background-image: linear-gradient(rgba(95,176,255,.055) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(95,176,255,.055) 1px, transparent 1px);
  background-size: 58px 58px;
  -webkit-mask-image: radial-gradient(72% 62% at 62% 46%, #000, transparent 78%);
          mask-image: radial-gradient(72% 62% at 62% 46%, #000, transparent 78%);
  will-change: transform;
  animation: derive-grille 24s linear infinite;
}
@keyframes derive-grille { to { transform: translate3d(58px, 58px, 0); } }

/* poussière lumineuse : douze points qui montent lentement */
.poussiere { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.poussiere i {
  position: absolute; top: -6px; width: var(--t, 3px); height: var(--t, 3px);
  border-radius: 50%; background: var(--c, var(--or)); opacity: 0;
  box-shadow: 0 0 10px 1px currentColor; color: var(--c, var(--or));
  animation: monte-poussiere var(--d, 18s) linear infinite var(--r, 0s);
}
/* La poussière tombe : elle part du haut de l'écran et descend. */
@keyframes monte-poussiere {
  0%   { opacity: 0; transform: translateY(0) translateX(0); }
  12%  { opacity: .85; }
  70%  { opacity: .5; }
  100% { opacity: 0; transform: translateY(105vh) translateX(var(--dx, 24px)); }
}

.hero .chapeau {
  font-size: clamp(0.8125rem, 1.9vw, 1.0625rem); letter-spacing: 0.2em; margin-bottom: 1.6rem;
}
h1 { margin: 0 0 1.2rem -0.035em; font-size: clamp(2.3rem, 7.6vw, 4rem); font-weight: 450;
     line-height: 1.03; letter-spacing: -0.034em; text-wrap: balance; max-width: 19ch; }
.lede { margin: 0 0 2.4rem; max-width: 34rem; color: var(--ink-2); text-wrap: pretty; }
.lede strong { color: var(--ink); font-weight: 450; }
.accroche-lecture strong, .apropos-texte strong { color: var(--or); font-weight: 450; }
/* Intitule de famille au-dessus d'une liste de sources. */
.fam { margin: 1.6rem 0 0.7rem; font-size: 0.6875rem; letter-spacing: 0.16em;
       text-transform: uppercase; color: var(--ink-2); }

/* ═══ bandes ═══ */
.bande { padding-top: clamp(2.75rem, 7vw, 4.5rem); padding-bottom: clamp(2.75rem, 7vw, 4.5rem);
         position: relative; contain: layout paint; }
.sur-clair { background: rgba(15,23,41,.82); border-block: 1px solid var(--hair); }
.bande + .bande.sur-clair { border-top: 0; }

/* ═══ pistes horizontales : le suivant s'efface en douceur ═══ */
.piste {
  display: flex; gap: 0.9rem; margin: 0; list-style: none;
  padding: 0.35rem var(--gouttiere) 0.75rem;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scroll-padding-left: var(--gouttiere);
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 calc(var(--gouttiere) * 0.55), #000 calc(100% - 5.5rem), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 calc(var(--gouttiere) * 0.55), #000 calc(100% - 5.5rem), transparent 100%);
}
.piste::-webkit-scrollbar { display: none; }
/* Un élément de grille ou de flex a min-width: auto : il refuse de
   descendre sous la largeur de son contenu. Une piste horizontale imbriquée
   y impose donc la somme de ses cartes, le parent déborde et la piste ne
   défile plus. min-width: 0 sur toute la chaîne rétablit les deux. */
.zone-piste { position: relative; min-width: 0; }
.piste { min-width: 0; }
.apropos-texte, .apropos > *, .duo > *, .duo-volets > * { min-width: 0; }
.zone-piste::after {
  content: ""; position: absolute; z-index: 2; pointer-events: none;
  top: 0; right: 0; bottom: 0; width: 5rem;
  background: linear-gradient(90deg, transparent, rgba(8,13,26,.55) 70%, rgba(8,13,26,.8));
}
.entete { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.entete .chapeau { margin-bottom: 1.1rem; }
.titre { margin: 0 0 1.2rem; font-size: clamp(1.5rem, 3.2vw, 2.2rem); font-weight: 450;
         line-height: 1.12; letter-spacing: -0.022em; text-wrap: balance; }
.fleches { display: flex; gap: 0.4rem; }
.fleche { appearance: none; background: none; cursor: pointer; flex: none;
          display: inline-flex; align-items: center; justify-content: center;
          width: 2.25rem; height: 2.25rem; border: 1px solid var(--bord); border-radius: 4px; color: var(--ink-2);
          transition: color 200ms var(--courbe), border-color 200ms var(--courbe), opacity 200ms var(--courbe); }
.fleche:hover { color: var(--or); border-color: var(--or); }
.fleche[disabled] { opacity: 0.28; cursor: default; }
.fleche[disabled]:hover { color: var(--ink-2); border-color: var(--bord); }
@media (hover: none) { .fleches { display: none; } }

/* ═══ missions ═══ */
.mission[data-teinte="1"] { --teinte: var(--t1); }
.mission[data-teinte="2"] { --teinte: var(--t2); }
.mission[data-teinte="3"] { --teinte: var(--t3); }
.mission {
  flex: 0 0 auto; width: min(18.5rem, 78vw); scroll-snap-align: start;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--hair); border-top: 3px solid var(--teinte); border-radius: 8px;
  padding: 1.1rem 1.25rem 1.35rem; box-shadow: var(--ombre);
  transition: transform 260ms var(--courbe), border-color 260ms var(--courbe);
}
.mission:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--teinte) 55%, var(--hair)); }
.visuel { margin: 0 0 1.1rem; }
/* Releves d'instrument, pas illustrations : traits fins, bouts francs,
   grille de fond a peine lisible, aires tres pales. */
.sig { display: block; width: 100%; height: auto; aspect-ratio: 240 / 64; }
.sig .axe    { stroke: var(--bord); stroke-width: 1; opacity: 0.7; }
.sig .grille { fill: none; stroke: var(--hair); stroke-width: 1; }
.sig .tic    { fill: none; stroke: var(--bord); stroke-width: 1; opacity: 0.55; }
.sig .trait  { fill: none; stroke: var(--ink-2); stroke-width: 1.35; stroke-linecap: butt; stroke-linejoin: miter; }
.sig .accent { fill: none; stroke: var(--teinte); stroke-width: 1.6; stroke-linecap: butt; }
.sig .tirets { stroke-width: 1.35; stroke-dasharray: 4 3.5; }
.sig .aire   { fill: var(--teinte); opacity: 0.11; stroke: none; }
.sig .bande-arret { fill: var(--teinte); opacity: 0.20; }
.sig .repere { fill: none; stroke: var(--teinte); stroke-width: 1; stroke-dasharray: 2.5 3; }
.sig text   { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
              font-size: 7px; fill: var(--ink-2); opacity: 0.65; letter-spacing: 0.06em; }
.mission .ou { margin: 0 0 0.55rem; font-size: 0.75rem; letter-spacing: 0.02em; color: var(--teinte);
               font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace; }
.mission .resultat { margin: 0 0 0.4rem; font-size: 1.0625rem; color: var(--ink-2); text-wrap: pretty; }
.mission .resultat b { font-weight: 450; color: var(--ink); }
.mission .quoi { margin: 0; font-size: 0.9375rem; color: var(--ink-2); text-wrap: pretty; }

/* ═══ engagements ═══ */
.grille-g { display: grid; grid-template-columns: repeat(auto-fit, minmax(12.5rem, 1fr));
            gap: 1.6rem 2rem; list-style: none; max-width: var(--cadre); margin: 0 auto;
            padding-left: var(--marge); padding-right: var(--marge); }
.grille-g li { display: grid; grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 0.6rem; }
.ico { width: 1.6rem; height: 1.6rem; color: var(--or); }
.grille-g b { display: block; font-weight: 450; font-size: 0.9375rem; }
.grille-g span { display: block; font-size: 0.875rem; color: var(--ink-2); text-wrap: pretty; }

/* ═══ secteurs ═══ */
.duo { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.05fr);
       gap: clamp(1.5rem, 4vw, 2.75rem); align-items: start; max-width: var(--cadre); margin: 0 auto;
       padding-left: var(--marge); padding-right: var(--marge); }
.duo-texte h2 { margin: 0 0 0.9rem; max-width: 14ch; font-size: clamp(1.6rem, 3.6vw, 2.3rem);
                font-weight: 450; line-height: 1.12; letter-spacing: -0.022em; text-wrap: balance; }
.duo-texte > p:last-child { margin: 0; color: var(--ink-2); text-wrap: pretty; font-size: 0.9375rem; }
.duo-volets { display: grid; gap: 0.7rem; }
.secteur { border: 1px solid var(--hair); border-radius: 10px; overflow: clip;
           background: linear-gradient(160deg, var(--surface-2), var(--surface)); box-shadow: var(--ombre);
           transition: border-color 220ms var(--courbe); }
.secteur:hover { border-color: var(--bord); }
.secteur > summary { padding: 0.95rem 1.15rem; font-size: 1rem; }
.secteur[open] > summary { border-bottom: 1px solid var(--hair); }
.secteur-corps { padding: 0 0 1.15rem; }
.secteur-corps p { margin: 1rem 1.15rem 0; font-size: 0.9375rem; color: var(--ink-2); text-wrap: pretty; }
/* Seconde offre du volet : c'est une prestation distincte, pas la suite du
   paragraphe. Un filet et un intitule en mono la detachent. */
.offre-2 { padding-top: 0.9rem; border-top: 1px solid var(--hair); }
.offre-2 .etiq { display: block; margin-bottom: 0.3rem;
                 font-size: 0.6875rem; letter-spacing: 0.14em; text-transform: uppercase;
                 color: var(--or); }
.scene { display: block; width: 100%; height: auto; aspect-ratio: 340 / 210; }
.couche, .poussiere i { will-change: transform; }

/* ── éléments des scènes ── */
.scene .mat, .scene .pied { stroke: #C9D4E8; stroke-width: 2.2; stroke-linecap: round; fill: none; }
.scene .pales { fill: #E6EDF9; }
.scene .moyeu { fill: #C9D4E8; }
.scene .soleil { fill: #FFD873; }
.scene .nuage ellipse { fill: #F2F5FA; opacity: 0.11; }
.scene .nuage { animation: passe var(--duree, 44s) linear infinite var(--retard, 0s); }
@keyframes passe { from { transform: translateX(-70px); } to { transform: translateX(370px); } }
.scene .pv-fil { stroke: #0F1729; stroke-width: 1; opacity: 0.45; }
.scene .reflet { fill: #FFFFFF; opacity: 0.16; animation: balaye 4.5s ease-in-out infinite var(--retard, 0s); }
@keyframes balaye { 0%, 12% { transform: translateX(0); opacity: 0; } 30% { opacity: .2; } 60%, 100% { transform: translateX(40px); opacity: 0; } }
.scene .herbe { stroke: #3FD79A; stroke-width: 1.6; fill: none; stroke-linecap: round; opacity: .55;
                transform-box: fill-box; transform-origin: bottom center;
                animation: brise 3.4s ease-in-out infinite alternate var(--retard, 0s); }
@keyframes brise { from { transform: rotate(-7deg); } to { transform: rotate(9deg); } }
.scene .pt { fill: var(--or); animation: flotte-pt 4.2s ease-in-out infinite var(--retard, 0s); }
@keyframes flotte-pt { 0% { opacity: 0; transform: translateY(10px); } 18%,62% { opacity: .9; } 100% { opacity: 0; transform: translateY(-26px); } }
.scene .usine path, .scene .usine rect { fill: #16223C; }
.scene .fumee ellipse { fill: #9FB0CC; opacity: .18; }
.scene .fumee { animation: monte-fumee 6s ease-out infinite var(--retard, 0s); }
@keyframes monte-fumee { 0% { opacity: 0; transform: translate(0,4px) scale(.6); } 25% { opacity: .8; } 100% { opacity: 0; transform: translate(-14px,-46px) scale(1.7); } }
.scene .fenetre { fill: var(--or); animation: veille 5s steps(1) infinite var(--retard, 0s); }
@keyframes veille { 0%, 55% { opacity: .75; } 56%, 100% { opacity: .16; } }
.scene .tapis { fill: #2C3B4A; }
.scene .buisson { fill: #1F5F45; opacity: .85; transform-box: fill-box; transform-origin: bottom center;
                  animation: brise 5s ease-in-out infinite alternate var(--retard, 0s); }
.scene .colis { fill: var(--surface-2); stroke: #C9D4E8; stroke-width: 1.6; animation: avance 1.7s linear infinite var(--retard, 0s); }
@keyframes avance { from { transform: translateX(0); } to { transform: translateX(40px); } }
.scene .eng { fill: none; stroke: #C9D4E8; stroke-width: 2; }
.scene .eng-c { fill: #C9D4E8; }
.scene .dent { stroke: #C9D4E8; stroke-width: 2.4; stroke-linecap: round; }
.scene .onde { fill: none; stroke: var(--corail); stroke-width: 1.6; animation: onde 3s ease-out infinite; }
.scene .onde.o2 { animation-delay: 1.5s; }
@keyframes onde { from { r: 5; opacity: .85; } to { r: 28; opacity: 0; } }
.scene .pastille { fill: var(--corail); }
.scene .pt, .scene .colis, .scene .onde, .scene .nuage, .scene .fumee, .scene .reflet { transform-box: view-box; }

/* ── salle de marche ── */
.scene .ecran { fill: #0A1223; stroke: #2A3A5C; stroke-width: 1; }
.scene .ecran-grille { stroke: #1D2941; stroke-width: 1; }
.scene .bougie .meche { stroke-width: 1; }
.scene .bougie.h .meche, .scene .bougie.h .corps { stroke: var(--vert); fill: var(--vert); }
.scene .bougie.b .meche, .scene .bougie.b .corps { stroke: var(--corail); fill: var(--corail); }
.scene .bougie { animation: pousse-bougie 5.2s ease-in-out infinite var(--retard, 0s);
                 transform-box: fill-box; transform-origin: center; }
@keyframes pousse-bougie { 0%, 72%, 100% { opacity: .78; } 12% { opacity: 1; } }
.scene .pnl { fill: none; stroke: var(--or); stroke-width: 1.8; stroke-linecap: round;
              stroke-dasharray: 220; animation: trace-pnl 7s ease-in-out infinite; }
@keyframes trace-pnl { 0% { stroke-dashoffset: 220; } 45%, 100% { stroke-dashoffset: 0; } }
.scene .pnl-pt { fill: var(--or); animation: bat 2.4s ease-in-out infinite; }
@keyframes bat { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
.scene .carnet.achat { fill: var(--vert); }
.scene .carnet.vente { fill: var(--corail); }
.scene .carnet { opacity: .72; animation: veille 4.4s steps(1) infinite var(--retard, 0s); }
.scene .carnet-prix { fill: #33456B; }
.scene .bureau { fill: #2C3B4A; }
.scene .montant, .scene .pied-bureau { stroke: #C9D4E8; stroke-width: 2; stroke-linecap: round; fill: none; }
.scene .montant { opacity: .55; }
.scene .tick { fill: var(--bleu); opacity: .5;
               animation: veille 3.6s steps(1) infinite var(--retard, 0s); }

/* ═══ volets ═══ */
.volets { max-width: var(--cadre); margin: 0 auto; border-top: 1px solid var(--hair); }
details { border-bottom: 1px solid var(--hair); }
summary { list-style: none; cursor: pointer; display: flex; align-items: center;
          justify-content: space-between; gap: 1.5rem; padding: 1.5rem var(--marge);
          font-size: clamp(1.125rem, 2.6vw, 1.3125rem); font-weight: 450; letter-spacing: -0.012em;
          transition: background-color 200ms var(--courbe); -webkit-tap-highlight-color: transparent; }
summary::-webkit-details-marker { display: none; }
summary:hover { background: var(--survol); }
.chevron { flex: none; color: var(--ink-2); transition: transform 300ms var(--courbe); }
details[open] .chevron { transform: rotate(180deg); color: var(--or); }
details::details-content { block-size: 0; overflow: hidden; opacity: 0;
  transition: block-size 380ms var(--courbe), content-visibility 380ms allow-discrete, opacity 260ms ease; }
details[open]::details-content { block-size: auto; opacity: 1; }
.contenu { padding-top: 0.25rem; padding-bottom: 2.5rem; }
.contenu > p { margin: 0 0 1rem; max-width: 34rem; color: var(--ink-2); text-wrap: pretty; }
.contenu > p:last-child { margin-bottom: 0; }
.contenu strong { color: var(--ink); font-weight: 450; }

/* ═══ étapes : une piste, plus une liste ═══ */
.etape { flex: 0 0 auto; width: min(15.5rem, 74vw); scroll-snap-align: start;
         background: linear-gradient(160deg, var(--surface-2), var(--surface));
         border: 1px solid var(--hair); border-radius: 8px; padding: 1.1rem 1.2rem 1.25rem; }
.etape .num { display: block; font-size: 0.75rem; font-weight: 500; color: var(--or);
              font-variant-numeric: tabular-nums; margin-bottom: 0.75rem; }
.etape b { display: block; font-weight: 450; margin-bottom: 0.25rem; }
.etape span:not(.num) { display: block; font-size: 0.9375rem; color: var(--ink-2); text-wrap: pretty; }

/* ═══ ce qu'on lit : des étiquettes, pas une phrase-liste ═══ */
.puces { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1.25rem; padding: 0; list-style: none; }
.puces li {
  font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
  font-size: 0.8125rem; letter-spacing: 0.02em; color: var(--ink);
  padding: 0.4rem 0.75rem; border: 1px solid var(--hair); border-radius: 999px;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  transition: border-color 200ms var(--courbe), color 200ms var(--courbe), transform 200ms var(--courbe);
}
.puces li:hover { border-color: var(--or); color: var(--or); transform: translateY(-2px); }
.accroche-lecture { margin: 0 0 1rem; color: var(--ink) !important; font-size: 1.0625rem; }
.accroche-lecture strong { color: var(--or); font-weight: 450; }

/* ═══ à propos ═══ */
.apropos { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: clamp(1.25rem, 3vw, 2rem); align-items: start; }
.portrait-carte { margin: 0; width: 9.5rem; }
.portrait-carte img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover;
                      border-radius: 10px; border: 1px solid var(--hair); }
.portrait-carte figcaption { margin-top: 0.7rem; line-height: 1.4; }
.portrait-carte b { display: block; font-weight: 450; font-size: 0.9375rem; }
.portrait-carte figcaption > span { display: block; font-size: 0.8125rem; color: var(--ink-2); margin-bottom: 0.35rem; }
.portrait-carte .lien { font-size: 0.8125rem; color: var(--ink-2); }
.portrait-carte .lien:hover { color: var(--or); }
.apropos-texte > p:first-child { margin-top: 0; }

.domaine { flex: 0 0 auto; width: min(13.5rem, 64vw); scroll-snap-align: start;
           background: linear-gradient(160deg, var(--surface-2), var(--surface));
           border: 1px solid var(--hair); border-radius: 8px; padding: 0.95rem 1.05rem 1.05rem; }
.domaine b { display: block; font-weight: 450; font-size: 0.9375rem; text-wrap: pretty; }
.domaine .val { display: block; margin-top: 0.5rem; font-size: 0.75rem; color: var(--or);
                font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace; }

/* ═══ clôture ═══ */
.rdv { position: relative; overflow: clip; text-align: center; }
.rdv .enveloppe { position: relative; z-index: 1; }
.rdv h2 { margin: 0 auto 1.75rem; max-width: 20ch; font-size: clamp(1.7rem, 4.6vw, 2.6rem);
          font-weight: 450; line-height: 1.13; letter-spacing: -0.024em; text-wrap: balance; }
/* La promesse chiffree, juste sous le titre de cloture. */
.promesse { margin: -0.9rem auto 1.6rem; max-width: 34rem; color: var(--ink-2);
            font-size: 1.0625rem; text-wrap: balance; }
.courriel { display: inline-block; margin: 0 0 1.75rem;
            font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
            font-size: clamp(1.0625rem, 3.2vw, 1.375rem); letter-spacing: -0.01em; color: var(--ink);
            box-shadow: inset 0 -1px 0 0 var(--or);
            transition: color 200ms var(--courbe), box-shadow 200ms var(--courbe); }
.courriel:hover { color: var(--or); box-shadow: inset 0 -2px 0 0 var(--or); }
.filigrane { position: absolute; z-index: 0; right: clamp(1rem, 4vw, 3rem); bottom: clamp(.75rem, 2.5vw, 1.75rem);
             width: min(30rem, 64%); opacity: 0.06; pointer-events: none; }
.filigrane img { display: block; width: 100%; height: auto; }
/* ── formulaire de contact ──
   Un agenda demande de choisir un creneau tout de suite. Beaucoup de visiteurs
   veulent d'abord poser une question, et repartent si le seul chemin ouvert
   engage une demi-heure. Le formulaire vient donc avant l'agenda : il
   n'engage a rien, et il laisse une adresse a qui on peut repondre. */
.mot { max-width: 30rem; margin: 0 auto 1.2rem; text-align: left;
       padding: 1.35rem 1.4rem 1.45rem; border: 1px solid var(--bord); border-radius: 6px;
       background: color-mix(in srgb, var(--surface) 72%, transparent);
       transition: border-color 200ms var(--courbe); }
.mot:focus-within { border-color: color-mix(in srgb, var(--or) 55%, var(--bord)); }
.mot-titre { margin: 0 0 0.9rem; font-size: 1.0625rem; font-weight: 450; color: var(--ink); }
.champ { display: grid; gap: 0.35rem; margin-bottom: 0.95rem; }
.champ label {
  font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-2); }
.champ input, .champ textarea {
  font: inherit; font-size: 1rem; width: 100%; color: var(--ink);
  padding: 0.62rem 0.72rem; border-radius: 4px;
  background: var(--ground); border: 1px solid var(--hair);
  transition: border-color 200ms var(--courbe); }
/* La zone démarre à deux lignes et grandit à mesure qu'on écrit — une grande
   boîte vide demande un long message et fait renoncer. `field-sizing` le fait
   nativement là où il existe ; app.js s'en charge partout ailleurs, et sans
   JavaScript les deux lignes restent redimensionnables à la main. */
.champ textarea { min-height: 3.4rem; max-height: 18rem; line-height: 1.5;
                  resize: vertical; overflow-y: auto; field-sizing: content; }
.champ input:hover, .champ textarea:hover { border-color: var(--bord); }
.champ input:focus-visible, .champ textarea:focus-visible {
  border-color: var(--or); outline: 2px solid var(--or); outline-offset: 1px; }
/* Le rouge natif du navigateur s'allume avant la premiere frappe sur un champ
   requis : on ne signale la faute qu'une fois le champ quitte non vide. */
.champ input:user-invalid, .champ textarea:user-invalid { border-color: var(--corail); }
.mot button.bouton { appearance: none; width: 100%; margin-top: 0.15rem;
                     font: inherit; font-size: 1rem; font-weight: 500; cursor: pointer; }
.mot button.bouton[disabled] { opacity: .6; cursor: progress; }
.mot-note { margin: 0.9rem 0 0; font-size: 0.75rem; color: var(--ink-2); }
/* Piege a robots : hors de l'ecran plutot que display:none, que certains
   scripts d'envoi automatique savent detecter et contourner. */
.champ-piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.mot-ok, .mot-ko { max-width: 30rem; margin: 0 auto 1.2rem; padding: 1rem 1.15rem;
                   border-radius: 6px; text-align: left; font-size: 0.9375rem;
                   color: var(--ink); text-wrap: pretty; }
.mot-ok[hidden], .mot-ko[hidden] { display: none; }
.mot-ok { border: 1px solid color-mix(in srgb, var(--vert) 50%, var(--hair));
          background: color-mix(in srgb, var(--vert) 10%, transparent); }
.mot-ko { border: 1px solid color-mix(in srgb, var(--corail) 50%, var(--hair));
          background: color-mix(in srgb, var(--corail) 10%, transparent); }
.ou-bien { margin: 0 0 1.2rem; font-size: 0.6875rem; font-weight: 500;
           letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-2); }

.creneaux { max-width: 30rem; margin-inline: auto; text-align: left;
            border: 1px solid var(--bord); border-radius: 6px; overflow: hidden;
            transition: border-color 200ms var(--courbe); }
.creneaux > summary { padding: 0.8rem 1.1rem; font-size: 0.9375rem; font-weight: 500; }
.creneaux:hover { border-color: var(--or); }
.creneaux[open] > summary { border-bottom: 1px solid var(--hair); }
.agenda { position: relative; min-height: 3.25rem; }
.agenda iframe { display: block; width: 100%; height: clamp(34rem, 76vh, 47rem); border: 0; }
.agenda-repli { margin: 0; padding: 0.9rem 1.1rem; font-size: 0.9375rem; color: var(--ink-2); }
.agenda.charge .agenda-repli { position: absolute; inset: 0; padding: 0;
  display: flex; align-items: center; justify-content: center; background: var(--surface); }

footer { border-top: 1px solid var(--hair); }
.pied { padding-top: 2rem; padding-bottom: 2.5rem; display: flex; flex-wrap: wrap;
        gap: 0.5rem 1.5rem; justify-content: space-between;
        font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
        font-size: 0.8125rem; letter-spacing: 0.02em; color: var(--ink-2); }
.pied a:hover { color: var(--or); }

/* ═══ apparitions ═══ */
@keyframes monte { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes parallaxe { to { transform: translateY(9%); } }
html[data-js] .revele { opacity: 0; transform: translateY(28px); }
html[data-js] .revele.vu { opacity: 1; transform: none;
  transition: opacity 620ms var(--courbe), transform 620ms var(--courbe); }
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    html[data-js] .revele, html[data-js] .revele.vu { opacity: 1; transform: none;
      animation: monte linear both; animation-timeline: view(); animation-range: entry 8% entry 62%; }
    .grille-g li { animation: monte linear both; animation-timeline: view(); animation-range: entry 4% entry 58%; }
    .fond { animation: parallaxe linear both; animation-timeline: scroll(root); animation-range: 0 100vh; }
  }
}

/* ═══ pages secondaires ═══ */
.doc { padding-top: clamp(2.5rem, 7vw, 4rem); padding-bottom: clamp(3.5rem, 9vw, 5rem); }
.doc h1 { font-size: clamp(1.75rem, 5vw, 2.35rem); max-width: 24ch; margin-bottom: 2.25rem; }
/* Trois niveaux de lecture : le titre accroche l'oeil, la phrase « en clair »
   donne le contenu de la section en une ligne, le corps developpe. Un lecteur
   presse ne lit que les deux premiers et tient tout l'argument. */
.doc h2 { margin: 3.25rem 0 0.6rem; font-size: 1.35rem; font-weight: 450;
          color: var(--ink); letter-spacing: -0.015em; line-height: 1.25;
          scroll-margin-top: 1.75rem; text-wrap: balance; }
.doc h2 .num { font-size: 0.8em; font-weight: 500; letter-spacing: 0.08em;
               color: var(--or); margin-right: 0.55em; }
.clair { margin: 0 0 1.3rem; max-width: 34rem; font-size: 1.0625rem; line-height: 1.55;
         color: var(--ink); text-wrap: pretty; }

/* Sommaire : ce qu'on tient, en combien de temps, et par ou passer. */
.sommaire { margin: 2rem 0 1rem; padding: 1.35rem 1.6rem 1.5rem; max-width: 34rem;
            border: 1px solid var(--hair); border-radius: 6px; background: var(--surface); }
.sommaire-titre { margin: 0 0 0.8rem; font-size: 0.6875rem; letter-spacing: 0.16em;
                  text-transform: uppercase; color: var(--or); }
.sommaire-fil { margin: 0 0 1.1rem; font-size: 0.9375rem; color: var(--ink-2); text-wrap: pretty; }
.sommaire-fil strong { color: var(--ink); font-weight: 450; }
/* Les entrées étaient du texte gris sans repère : rien ne disait qu'on
   pouvait cliquer. Ce sont maintenant des lignes entières, avec le numéro en
   doré, un soulignement discret et un fond au survol. */
.sommaire-liste { margin: 0; padding: 0; list-style: none;
                  display: grid; grid-template-columns: 1fr 1fr; gap: 0.15rem 1.2rem; }
.sommaire-liste a {
  display: flex; align-items: baseline; gap: 0.6rem;
  padding: 0.34rem 0.5rem 0.34rem 0.4rem; border-radius: 4px;
  font-size: 0.9375rem; color: var(--ink-2); text-decoration: none;
  transition: color 160ms var(--courbe), background 160ms var(--courbe);
}
.sommaire-liste .s-num { flex: none; font-size: 0.75rem; color: var(--or); }
.sommaire-liste .s-lib { text-decoration: underline;
                         text-decoration-color: color-mix(in srgb, var(--or) 38%, transparent);
                         text-decoration-thickness: 1px; text-underline-offset: 3px; }
.sommaire-liste a:hover { color: var(--ink); background: color-mix(in srgb, var(--or) 9%, transparent); }
.sommaire-liste a:hover .s-lib { text-decoration-color: var(--or); }
.sommaire-liste a:focus-visible { outline: 2px solid var(--or); outline-offset: 2px; }
@media (max-width: 34rem) { .sommaire-liste { grid-template-columns: 1fr; } }
.sommaire-note { margin: 1.2rem 0 0; padding-top: 1rem; border-top: 1px solid var(--hair);
                 font-size: 0.8125rem; color: var(--ink-2); text-wrap: pretty; }
.doc p { margin: 0 0 0.9rem; max-width: 34rem; color: var(--ink-2); text-wrap: pretty; }
.doc p strong { color: var(--ink); font-weight: 450; }

/* ═══ livrable : schema de chaine et formules ═══ */
.schema { display: block; width: 100%; max-width: 34rem; height: auto; margin: 1.6rem 0 0.6rem; }
.schema .bloc      { fill: var(--surface); stroke: var(--hair); stroke-width: 1; }
.schema .bloc-src  { fill: var(--ground); stroke: var(--hair); stroke-width: 1; }
.schema .bloc-fort { fill: var(--surface-2); stroke: color-mix(in srgb, var(--or) 42%, var(--hair)); stroke-width: 1; }
.schema .bloc-sor  { fill: color-mix(in srgb, var(--or) 9%, var(--surface)); stroke: color-mix(in srgb, var(--or) 55%, var(--hair)); stroke-width: 1; }
.schema text { text-anchor: middle; font-size: 11px; fill: var(--ink-2); }
.schema .src  { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
                font-size: 10px; letter-spacing: 0.06em; }
.schema .lib  { fill: var(--ink); font-size: 12px; }
.schema .sor  { fill: var(--or); font-size: 12px; }
.schema .form { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
                font-size: 10.5px; fill: var(--ink-2); }
.schema .ret  { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
                font-size: 9px; fill: var(--or); opacity: .8; letter-spacing: 0.08em; }
.schema .fl     { fill: none; stroke: #5F7096; stroke-width: 1.2; }
.schema .fl-ret { fill: none; stroke: var(--or); stroke-width: 1.2; stroke-dasharray: 4 3; opacity: .75; }
.legende { margin: 0 0 1.8rem; max-width: 34rem; font-size: 0.8125rem; color: var(--ink-2); }

/* Un livrable d'ingénieur est fait de tableaux. Ils cassent le mur de texte
   sans rien coûter en sérieux, et c'est exactement ce qu'un lecteur technique
   cherche des yeux en premier. */
.tableau-zone { max-width: 40rem; margin: 1.3rem 0 0.8rem; overflow-x: auto;
                border: 1px solid var(--hair); border-radius: 6px; background: var(--surface); }
.tab { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
.tab th, .tab td { padding: 0.62rem 0.9rem; text-align: left; vertical-align: top;
                   border-bottom: 1px solid var(--hair); }
.tab thead th { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
                font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.1em;
                text-transform: uppercase; color: var(--or); white-space: nowrap; }
.tab tbody tr:last-child th, .tab tbody tr:last-child td { border-bottom: 0; }
.tab tbody tr:hover { background: color-mix(in srgb, var(--surface-2) 60%, transparent); }
.tab td { color: var(--ink-2); }
.tab td:first-child { color: var(--ink); }
.tab .num { white-space: nowrap; font-size: 0.8125rem; }
.tab .ok     { color: var(--vert); }
.tab .moyen  { color: var(--or); }
.tab .faible { color: var(--vert); }
.tab .fort   { color: var(--corail); }

/* Les chiffres de cadrage, en bandeau : ils donnent la taille du cas en un
   coup d'oeil avant que le texte ne commence. */
.chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
            gap: 1.1rem 1.6rem; margin: 1.3rem 0 1.4rem; max-width: 34rem;
            padding: 0; list-style: none; }
.chiffres li { display: grid; gap: 0.15rem; padding-left: 0.85rem;
               border-left: 2px solid color-mix(in srgb, var(--or) 40%, var(--hair)); }
.chiffres b { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
              font-size: 1.55rem; font-weight: 500; color: var(--ink); letter-spacing: -0.02em; }
.chiffres span { font-size: 0.8125rem; color: var(--ink-2); text-wrap: pretty; }

.visuellement-cachee { position: absolute; width: 1px; height: 1px; padding: 0;
                       margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Un bloc de mathematiques se lit comme du code : chasse fixe, filet a
   gauche, defilement horizontal plutot que retour a la ligne sauvage. */
/* Plus large que les paragraphes : une equation ne se coupe pas, elle tient
   sur sa ligne ou elle defile. */
.eq { margin: 1.1rem 0; max-width: 46rem; padding: 0.9rem 0 0.9rem 1.1rem;
      border-left: 2px solid var(--bord); overflow-x: auto;
      font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
      font-size: 0.8125rem; line-height: 1.9; color: var(--ink); white-space: pre; }
.eq .cm { color: var(--ink-2); }
.eq .op { color: var(--or); }
.ou-eq { margin: -0.4rem 0 1.4rem; max-width: 34rem; font-size: 0.8125rem; color: var(--ink-2); }

/* Les formules, repliees.
   La page avait trois niveaux de lecture — titre, phrase « en clair », corps —
   et un quatrieme non annonce : les blocs de mathematiques. C'est le seul
   endroit ou un directeur decrochait au milieu d'un document qu'il allait
   transferer. Ils sont maintenant derriere une ligne : la preuve reste a un
   clic pour l'ingenieur a qui il le transfere, elle n'est plus un peage pour
   lui. Le schema de chaine, lui, reste ouvert : c'est le bloc qui se lit le
   plus vite de toute la page, le replier ne ferait gagner aucune lecture. */
.formule { margin: 1.2rem 0 1.6rem; max-width: 46rem;
           border: 1px solid var(--hair); border-radius: 6px; overflow: clip;
           background: color-mix(in srgb, var(--surface) 55%, transparent);
           transition: border-color 200ms var(--courbe); }
.formule:hover { border-color: color-mix(in srgb, var(--or) 38%, var(--hair)); }
.formule > summary { gap: 0.85rem; padding: 0.68rem 0.95rem;
                     font-size: 0.9375rem; font-weight: 400; letter-spacing: 0; }
.formule[open] > summary { border-bottom: 1px solid var(--hair); }
.formule-tag { flex: none; font-size: 0.6875rem; font-weight: 500;
               letter-spacing: 0.14em; text-transform: uppercase; color: var(--or); }
.formule-lib { flex: 1 1 auto; min-width: 0; font-size: 0.875rem;
               color: var(--ink-2); text-wrap: pretty; }
.formule-corps { padding: 0.1rem 0.95rem 0.5rem; }
.formule-corps .eq { margin: 0.8rem 0 0; }
.formule-corps .ou-eq { margin: 0.75rem 0 0.2rem; }
/* Sous 30rem, l'etiquette et la phrase ne tiennent plus cote a cote : la
   phrase passe dessous plutot que de s'etrangler sur trois mots par ligne. */
@media (max-width: 30rem) {
  .formule > summary { flex-wrap: wrap; row-gap: 0.2rem; }
  .formule-tag { order: 1; }
  .formule .chevron { order: 2; margin-left: auto; }
  .formule-lib { order: 3; flex-basis: 100%; }
}
.ou-eq code { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
              font-size: 0.9em; color: var(--ink); }
/* Aucun élément interactif ne portait d'indicateur de focus : au clavier, on
   ne savait pas où on était. Règle unique que les composants peuvent affiner
   mais jamais retirer. */
:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--or); outline-offset: 3px; border-radius: 3px;
}
.piste:focus-visible { outline-offset: -2px; }

.retour { margin-top: 2.75rem; }

/* Flèche de retour : fixe, translucide, hors du flux de lecture. Elle rejoint
   la marge gauche sur les écrans qui en ont une, et se pose en bas à gauche
   sur les autres, où elle ne recouvre aucun texte. */
.retour-flottant {
  position: fixed; z-index: 20; left: 1rem; bottom: 1rem;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  color: var(--ink-2); background: color-mix(in srgb, var(--surface) 72%, transparent);
  border: 1px solid var(--hair); backdrop-filter: blur(6px);
  transition: color 180ms var(--courbe), border-color 180ms var(--courbe),
              transform 180ms var(--courbe);
}
.retour-flottant:hover { color: var(--or); border-color: color-mix(in srgb, var(--or) 45%, var(--hair));
                         transform: translateX(-2px); }
.retour-flottant:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }
/* Au-dessous de 64rem elle n'a plus de marge où se loger et passe donc
   au-dessus du texte : elle devient alors opaque et portée, pour se lire
   comme une commande et non comme une tache sur le paragraphe. */
@media (max-width: 63.99rem) {
  .retour-flottant { background: var(--surface); border-color: var(--bord);
                     box-shadow: 0 6px 22px -6px rgba(0,0,0,.7); backdrop-filter: none; }
}
@media (min-width: 64rem) {
  .retour-flottant { left: max(1.5rem, calc((100vw - var(--cadre)) / 2 - 3.6rem)); top: 8.5rem; bottom: auto; }
}
@media (prefers-reduced-motion: reduce) { .retour-flottant { transition: none; } }
.aremplir { background: rgba(240,185,63,.16); border-left: 2px solid var(--or);
            padding: 0.1rem 0.45rem; border-radius: 2px; color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; }
  html[data-js] .revele { opacity: 1; transform: none; }
  .couche, body::before, .banniere::after, .scene * { animation: none !important; }
}

@media (max-width: 46rem) {
  .duo { grid-template-columns: 1fr; }
  .duo-texte h2 { max-width: 18ch; }
}
@media (max-width: 30rem) {
  .apropos { grid-template-columns: 1fr; }
  /* Sur une seule colonne, la legende passe a cote du portrait plutot que
     de s'etrangler sous une image de 7,5rem. */
  .portrait-carte { width: auto; display: grid; grid-template-columns: 7.5rem minmax(0, 1fr);
                    gap: 0 1rem; align-items: start; }
  .portrait-carte figcaption { margin-top: 0; }
  .banniere { flex-wrap: wrap; padding-block: 0.6rem; }
  .banniere p { margin-inline: 0; }
}

/* Sur les très grands écrans, le tracé des ondes devient le poste le plus
   coûteux. Deux couches secondaires sont retirées : à cette taille la
   différence ne se voit pas, le gain d'images par seconde si. */
@media (min-width: 90rem) {
  .couche.c-faible:nth-of-type(2), .couche.c-faible:nth-of-type(4) { display: none; }
  /* La grille technique est la couche la moins lisible des quatre : sur un
     très grand écran elle disparaît, et le reste retrouve de la fluidité. */
  .hero::before { display: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   MISE EN PAGE ORDINATEUR

   Jusqu'ici le site était une colonne de 46 rem centrée : une maquette
   téléphone étirée sur un grand écran, avec 700 px de vide de chaque côté.
   À partir de 64 rem le cadre s'élargit à 76 rem et les sections passent en
   deux ou trois colonnes. Les blocs de texte gardent leur mesure lisible :
   c'est le cadre qui s'élargit, pas les lignes.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 64rem) {
  :root { --cadre: 76rem; }

  /* le texte ne suit pas le cadre, il garde sa longueur de ligne */
  /* Le cadre s'élargit, pas les lignes : au-delà de ~75 caractères la
     lecture décroche. */
  .lede, .contenu > p, .accroche-lecture, .apropos-texte p, .secteur-corps p { max-width: 38rem; }

  /* ── hero : le texte à gauche, le fond animé occupe la moitié droite ── */
  /* justify-items: start, sinon le bouton s'étire sur toute la colonne. */
  .hero-contenu { display: grid; grid-template-columns: minmax(0, 40rem) minmax(0, 1fr); justify-items: start; }
  .hero-contenu > * { grid-column: 1; }
  h1 { max-width: 18ch; font-size: clamp(2.9rem, 4.2vw, 4.2rem); }

  /* ── missions : titre plus grand, cartes plus larges ── */
  .missions .entete { align-items: flex-end; }
  .mission { width: 22rem; }
  .mission .quoi { font-size: 1rem; }

  /* ── engagements : quatre colonnes franches, alignées à gauche ── */
  .grille-g { grid-template-columns: repeat(4, 1fr); gap: 2rem 2.5rem; }
  .grille-g li { grid-template-columns: 1.6rem 1fr; justify-items: start; text-align: left; gap: 0.9rem; }
  .grille-g .ico { margin-top: 0.15rem; }

  /* ── secteurs : l'énoncé prend le tiers, les volets le reste ── */
  .duo { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); gap: 4rem; }
  .duo-texte h2 { font-size: clamp(1.9rem, 2.6vw, 2.5rem); max-width: 12ch; }
  .duo-volets { grid-template-columns: 1fr; display: grid; gap: 1rem; align-items: start; }

  /* ── volets : le titre à gauche, le contenu à droite ── */
  .volets details { display: grid; grid-template-columns: 18rem minmax(0, 1fr); align-items: start; }
  .volets summary { max-width: none; grid-column: 1; align-self: start;
                    padding-right: 1.5rem; font-size: 1.375rem; }
  .volets details::details-content { grid-column: 2; }
  .volets .contenu { padding-left: 0; padding-top: 1.5rem; }
  .volets .chevron { margin-left: auto; }

  /* ── à propos : portrait, texte, puis la piste sur toute la largeur ── */
  .apropos { grid-template-columns: 15rem minmax(0, 1fr);
             grid-template-areas: "photo texte" "piste piste"; gap: 2rem 2.5rem; }
  .portrait-carte { grid-area: photo; width: 100%; }
  .apropos-texte { grid-area: texte; }
  .apropos .zone-piste { grid-area: piste; margin-top: 0.5rem; }
  /* Une piste imbriquée dans un volet n'est plus pleine largeur : la
     gouttière calculée sur le cadre la décalerait vers la droite et
     couperait la dernière carte. */
  .contenu .piste { padding-left: 0; padding-right: 0;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 4rem), transparent);
            mask-image: linear-gradient(90deg, #000 calc(100% - 4rem), transparent); }
  .domaine { width: 15rem; }

  /* ── missions : une grille, pas un carrousel ──
     Les trois cartes tiennent largement dans le cadre : garder le défilement
     horizontal, ses flèches et son dégradé de bord revient à afficher des
     commandes de téléphone sur un écran qui n'en a pas besoin. */
  .missions .piste { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
                     gap: 1.75rem; overflow: visible; scroll-snap-type: none;
                     -webkit-mask-image: none; mask-image: none; }
  .missions .mission { width: auto; }
  .missions .zone-piste::after { display: none; }
  .missions .fleches { display: none; }

  /* Deux domaines seulement : même raison, la piste n'a rien à faire défiler. */
  .apropos .piste { display: grid; grid-template-columns: repeat(2, minmax(0, 15rem));
                    gap: 1.25rem; overflow: visible;
                    -webkit-mask-image: none; mask-image: none; }
  .apropos .domaine { width: auto; }
  .apropos .zone-piste::after { display: none; }

  /* ── volets : la ligne entière ouvre le volet ──
     Le titre occupait 288 px d'une ligne de 1216 : le reste avait l'air
     cliquable et ne l'était pas. Le pseudo-élément étend la cible au volet
     fermé, sans toucher à la mise en page. Une fois ouvert il disparaît, pour
     qu'un clic dans le contenu ne referme pas ce qu'on est en train de lire. */
  .volets details { position: relative; }
  .volets details:not([open]) > summary::after { content: ""; position: absolute; inset: 0; }
  .volets details:not([open]):has(> summary:hover) { background: var(--survol); }
  .volets details:not([open]) > summary:hover { background: none; }
  /* 18 rem coupaient « Sources de données » en deux lignes. */
  .volets details { grid-template-columns: 22rem minmax(0, 1fr); }

  /* ── secteurs : la scène ne prend pas toute la colonne ──
     À 700 px de large elle écrasait le texte qu'elle illustre, et l'énoncé de
     gauche restait seul devant 700 px de vide. */
  .secteurs .duo-texte { position: sticky; top: clamp(1.5rem, 4vw, 2.5rem); }
  .secteur .scene { max-width: 32rem; margin-inline: auto; }

  /* ── clôture : deux colonnes ──
     Empilée, la section faisait 1 127 px de haut pour une colonne de 30 rem,
     avec 450 px de vide de chaque côté : la page la plus importante du site
     ressemblait à un téléphone étiré. Le discours à gauche, ce qu'on propose de
     faire à droite. */
  .rdv h2 { font-size: clamp(2.2rem, 3.4vw, 3rem); max-width: 18ch; }
  .rdv .enveloppe { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 27rem);
                    gap: clamp(2.5rem, 6vw, 5rem); align-items: start; text-align: left; }
  .rdv .chapeau { margin-bottom: 1.1rem; }
  .rdv h2 { margin: 0 0 1.1rem; max-width: 15ch; }
  .promesse { margin: 0 0 1.5rem; }
  .courriel { margin-bottom: 0; }
  .mot, .mot-ok, .mot-ko, .creneaux { max-width: none; margin-inline: 0; }
  /* Le discours est plus court que le formulaire : centré, il se lit comme le
     pendant du formulaire plutôt que comme une colonne qui s'arrête. */
  .rdv-dire { align-self: center; }
  /* Le filigrane passe à gauche : il occupe le bas de la colonne du discours
     au lieu de se cacher derrière le formulaire. */
  .rdv .filigrane { right: auto; left: var(--gouttiere);
                    bottom: clamp(1rem, 3vw, 2.5rem); width: min(26rem, 34%); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PAGES DOCUMENTAIRES SUR ORDINATEUR

   Le corps d'un document tient dans 34 rem : c'est sa mesure lisible, et elle
   ne bouge pas. Mais dans un cadre de 76 rem, ça donnait 544 px de texte collés
   à gauche et 672 px de vide à droite — la définition même d'une maquette
   téléphone étirée, sur les pages qu'un prospect lit le plus longtemps.

   Deux traitements. L'exemple de livrable a neuf sections : son sommaire passe
   dans une colonne à côté et y reste collé, ce qui remplit la marge par la
   seule chose qui serve à quelque chose pendant une lecture longue. Les pages
   légales n'ont pas de sommaire : leur cadre se resserre, et les éléments
   larges (tableaux, équations) remplissent alors la colonne au lieu de flotter.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 64rem) {
  /* Sans sommaire : ces pages n'ont que des paragraphes, tous à 34 rem. Le
     cadre se cale donc exactement sur la mesure, et la colonne est centrée au
     lieu d'être collée à gauche. */
  .doc:not(:has(.doc-corps)) { max-width: 40rem; }

  /* Avec sommaire : le cadre doit laisser 46 rem au corps, la largeur des blocs
     d'équations, sinon ils défileraient horizontalement dans leur propre boîte. */
  .doc:has(.doc-corps) {
    max-width: 76rem;
    display: grid; grid-template-columns: minmax(0, 1fr) 15rem;
    gap: 0 clamp(2.5rem, 4vw, 3.5rem); align-items: start;
  }
  .doc:has(.doc-corps) > h1    { grid-column: 1 / -1; grid-row: 1; }
  .doc:has(.doc-corps) > .avis { grid-column: 1 / -1; grid-row: 2; }
  .doc-corps { grid-column: 1; grid-row: 3; min-width: 0; }
  /* Même rangée que le corps : la zone collante fait toute la hauteur du
     document, sinon le sommaire décrocherait au bout d'un écran. */
  .doc:has(.doc-corps) > .sommaire {
    grid-column: 2; grid-row: 3; position: sticky; top: 2rem;
    margin: 0; max-width: none; padding: 1.15rem 1.25rem 1.3rem;
  }
  .doc:has(.doc-corps) .sommaire-liste { grid-template-columns: 1fr; }
  .doc:has(.doc-corps) .sommaire-fil,
  .doc:has(.doc-corps) .sommaire-note { font-size: 0.8125rem; }

  /* ── ce qui garde sa mesure, et ce qui prend la place ──
     La prose reste à 34 rem : c'est une mesure de lecture, elle ne s'étire pas.
     Mais tout le reste était plafonné à la même valeur, et c'est ça qui faisait
     lire le livrable comme un document de téléphone posé sur un écran large :
     un schéma de chaîne rendu à 1:1 avec du texte à 11 px, des tableaux de cinq
     colonnes serrés dans 544 px, quatre chiffres de cadrage à l'étroit. Un
     document technique se lit sur ses artefacts — eux prennent la colonne. */
  .doc-corps .tableau-zone,
  .doc-corps .schema,
  .doc-corps .chiffres,
  .doc-corps .resultat { max-width: none; }

  /* Le schéma passe de 544 à ~820 px : son texte est dessiné à 11 px dans un
     viewBox de 534, il était donc rendu à sa taille nominale, illisible de loin
     sur un écran d'ordinateur. */
  .doc-corps .schema { margin-block: 2rem 0.8rem; }
  .doc-corps .tab { font-size: 0.9375rem; }
  .doc-corps .tab th, .doc-corps .tab td { padding: 0.72rem 1.1rem; }
  .doc-corps .chiffres { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 1.2rem 2rem; }
  .doc-corps .resultat { padding: 1.75rem 2rem; }
}

/* Une scène hors champ continue d'animer et de repeindre pour rien. app.js
   pose cette classe dès qu'elle sort de l'écran. */
.scene.dort, .scene.dort * { animation-play-state: paused !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   FRISE : le déroulé et les engagements en une seule section.

   Le rail est un trait fin qu'une lumière parcourt en boucle, et chaque jalon
   s'allume à son tour. Tout est en CSS composé : un translate sur une bande
   de 34 % et une transition de couleur, rien qui repeigne la page.
   ═══════════════════════════════════════════════════════════════════════════ */

/* L'offre de lancement se lit avant la frise, en vert, la seule fois où cette
   teinte sert sur la page. Fond plein et non simple couleur de texte : c'est
   une date qui expire, elle doit se voir. */
.parcours .titre { margin-bottom: 0.9rem; }
.offert[hidden] { display: none; }
.offert {
  display: inline-block; margin: 0 0 2.1rem;
  padding: 0.42rem 0.85rem; border-radius: 4px;
  font-size: 0.75rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--sur-cta); background: var(--vert);
  box-shadow: 0 0 34px -6px color-mix(in srgb, var(--vert) 70%, transparent);
}
.frise-cadre { position: relative; margin: 0 0 3rem; }

.frise { display: grid; grid-template-columns: repeat(3, 1fr);
         gap: 1.5rem 1.75rem; margin: 0; padding: 0; list-style: none; }
.frise li { position: relative; }
.frise b { display: block; font-weight: 450; margin-bottom: 0.3rem; }
.frise li > span:not(.jalon) { display: block; font-size: 0.9375rem; color: var(--ink-2);
                               text-wrap: pretty; max-width: 22rem; }

.jalon {
  position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center;
  width: 3rem; height: 3rem; margin-bottom: 1.1rem; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--bord); color: var(--ink-2);
  animation: allume 5.4s ease-in-out infinite; animation-delay: calc(var(--rang, 0) * 1.5s);
}
.jalon-i { width: 1.35rem; height: 1.35rem; }
@keyframes allume {
  0%, 30%, 100% { border-color: var(--bord); color: var(--ink-2);
                  box-shadow: 0 0 0 0 rgba(240,185,63,0); }
  6%, 20%       { border-color: var(--or); color: var(--or);
                  box-shadow: 0 0 0 5px rgba(240,185,63,.09), 0 0 26px -2px rgba(240,185,63,.6); }
}

/* Le rail relie le centre du premier jalon à celui du dernier. Les jalons
   sont calés à gauche de leur colonne, donc le retrait de droite vaut une
   largeur de colonne moins un demi-jalon. */
.frise-rail { position: absolute; z-index: 0; top: 1.5rem; left: 1.5rem;
              right: calc((100% - 2 * 1.75rem) / 3 - 1.5rem);
              height: 2px; background: var(--hair); border-radius: 2px; overflow: hidden; }
.frise-rail i { position: absolute; inset: 0; width: 34%;
                background: linear-gradient(90deg, transparent, var(--or), transparent);
                animation: parcourt 4.5s cubic-bezier(.45,0,.55,1) infinite; }
@keyframes parcourt { from { transform: translateX(-110%); } to { transform: translateX(400%); } }

.parcours .grille-g { max-width: none; padding-left: 0; padding-right: 0; }

/* ── petits écrans : la frise se redresse à la verticale ── */
@media (max-width: 46rem) {
  .frise { grid-template-columns: 1fr; gap: 1.4rem; }
  .frise li { display: grid; grid-template-columns: 3rem minmax(0, 1fr); gap: 0 1.1rem; align-items: start; }
  .jalon { margin-bottom: 0; grid-row: span 2; }
  .frise b, .frise li > span:not(.jalon) { grid-column: 2; }
    .frise-rail {
    top: 1.5rem; bottom: 1.5rem; left: 1.5rem; right: auto; width: 2px; height: auto;
    transform: translateX(-1px); }
  .frise-rail i { width: 100%; height: 34%; inset: 0 0 auto 0;
                  background: linear-gradient(180deg, transparent, var(--or), transparent);
                  animation-name: parcourt-vertical; }
  @keyframes parcourt-vertical { from { transform: translateY(-110%); } to { transform: translateY(400%); } }
}

/* ═══ finitions : le survol allume la carte de sa propre teinte ═══ */
.mission:hover {
  box-shadow: var(--ombre),
              0 0 0 1px color-mix(in srgb, var(--teinte) 45%, transparent),
              0 22px 60px -30px color-mix(in srgb, var(--teinte) 80%, transparent);
}
.secteur:hover { border-color: color-mix(in srgb, var(--or) 45%, var(--hair));
                 box-shadow: var(--ombre), 0 22px 60px -34px rgba(240,185,63,.55); }
.etape:hover, .domaine:hover { border-color: var(--bord); }
.titre { position: relative; }

/* ── les jalons de la frise restent des chiffres dans la marge ── */
/* Le chiffre était en --bord, soit un rapport de contraste de 2,13 sur le
   fond : sous le seuil AA même pour du grand texte. --jalon vaut 3,92. */
.jalon {
  width: auto; height: auto; border: 0; border-radius: 0; background: none;
  padding: 0; margin: 0 0 0.7rem -0.1rem;
  font-size: 1.7rem; font-weight: 500; letter-spacing: -0.02em;
  color: var(--jalon); animation-name: allume-chiffre; box-shadow: none;
}
@keyframes allume-chiffre {
  0%, 30%, 100% { color: var(--jalon); }
  6%, 20%       { color: var(--or); }
}
.frise-rail { top: 1rem; }

/* ── l'engagement porté par l'étape, plus une liste séparée ── */
/* Spécificité : .frise li > span:not(.jalon) impose display:block, il faut
   viser plus précis pour que la pastille épouse son texte. */
.frise li > span.gage {
  display: inline-block; width: auto; margin: 0 0 0.55rem;
  font-size: 0.6875rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--or); border: 1px solid rgba(240,185,63,.32);
  border-radius: 999px; padding: 0.22rem 0.6rem;
}
.apres-frise { margin: 0; max-width: 44rem; color: var(--ink-2); text-wrap: pretty; }
.apres-frise strong { color: var(--ink); font-weight: 450; }
/* Le lien vers l'exemple sort du paragraphe : c'est la page la plus
   convaincante du site, elle mérite d'être vue comme un objet cliquable et
   non comme un mot souligné dans une phrase. Encadré discret, pas un second
   bouton : il ne doit pas concurrencer la prise de rendez-vous. */
.apres-lien { margin: 1.1rem 0 0; }
.lien-encadre {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.55rem 1rem 0.55rem 1.05rem; border-radius: 5px;
  font-size: 0.9375rem; color: var(--or); text-decoration: none;
  border: 1px solid color-mix(in srgb, var(--or) 38%, var(--hair));
  background: color-mix(in srgb, var(--or) 7%, transparent);
  transition: border-color 200ms var(--courbe), background 200ms var(--courbe);
}
.lien-encadre::after { content: "→"; transition: transform 200ms var(--courbe); }
.lien-encadre:hover { border-color: color-mix(in srgb, var(--or) 70%, var(--hair));
                      background: color-mix(in srgb, var(--or) 12%, transparent); }
.lien-encadre:hover::after { transform: translateX(3px); }
.lien-encadre:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .lien-encadre, .lien-encadre::after { transition: none; } }

@media (max-width: 46rem) {
  .frise li { grid-template-columns: 2.4rem minmax(0, 1fr); }
  .frise-rail { top: 1rem; left: 0.7rem; }
  .jalon { margin-bottom: 0; }
  .gage { grid-column: 2; }
}

/* ── asymétrie du premier écran ── */
@media (min-width: 64rem) {
  .hero-contenu { grid-template-columns: minmax(0, 44rem) minmax(0, 1fr); }
  h1 { max-width: 15ch; }
  .lede { margin-left: 4rem; max-width: 32rem; }
}

.liens-pied { display: inline-flex; gap: 1.25rem; flex-wrap: wrap; }

/* ═══ pages documentaires : avis, date, bloc de résultat ═══ */
.maj { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
       font-size: 0.8125rem; color: var(--ink-2); margin: -1.25rem 0 2.25rem; }
.avis { border-left: 2px solid var(--or); padding: 0.75rem 0 0.75rem 1.1rem;
        background: rgba(240,185,63,.06); border-radius: 0 3px 3px 0; }
.avis strong { color: var(--or); font-weight: 450; }
/* Portee au document : .resultat existe aussi dans les cartes de mission,
   ou il ne doit pas recevoir l'encadre du livrable. */
.doc .resultat { margin: 2rem 0 2.5rem; padding: 1.5rem 1.75rem;
            border: 1px solid var(--hair); border-left: 3px solid var(--or);
            border-radius: 3px; background: var(--surface); max-width: 34rem; }
.doc .resultat-titre { margin: 0 0 0.6rem; font-size: 0.6875rem; letter-spacing: 0.16em;
                  text-transform: uppercase; color: var(--or); }
.doc .resultat-chiffre { margin: 0 0 0.75rem; color: var(--ink);
                    font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
                    font-size: clamp(1.6rem, 4.4vw, 2.2rem); font-weight: 500; letter-spacing: -0.02em; }
.doc .resultat-chiffre span { font-size: 0.5em; color: var(--ink-2); }
.doc .resultat-note { margin: 0; font-size: 0.875rem; color: var(--ink-2); }

/* Les specifications du modele : intitule en mono a gauche, contenu a droite,
   colonne unique au-dessous de 40rem. */
.specs { margin: 0 0 1.4rem; max-width: 34rem; display: grid; gap: 0.85rem; }
.specs > div { display: grid; grid-template-columns: 9rem minmax(0, 1fr); gap: 0 1.1rem;
               padding-top: 0.85rem; border-top: 1px solid var(--hair); }
.specs dt { font-family: "IBM Plex Mono", ui-monospace, Consolas, Menlo, monospace;
            font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase;
            color: var(--ink); padding-top: 0.16rem; }
.specs dd { margin: 0; color: var(--ink-2); text-wrap: pretty; }
@media (max-width: 40rem) {
  .specs > div { grid-template-columns: 1fr; gap: 0.3rem; }
}

/* =========================================================================
   VARIANTES

   La CSP du site interdit les styles en ligne (style-src sans
   'unsafe-inline'). Chaque attribut style= a donc été remplacé par une
   classe, générée ici. Sans cela le navigateur refuse de les appliquer :
   les grains de poussière tombaient tous dans la même colonne, les jalons
   de la frise s’allumaient ensemble, et les scènes perdaient leurs
   décalages. Rien à écrire à la main dans ce bloc.
   ========================================================================= */

.v001 { --duree:118s; }
.v002 { --duree:94s; }
.v003 { --duree:132s; }
.v004 { --duree:76s; }
.v005 { --duree:108s; }
.v006 { --duree:86s; }
.v007 { --duree:40s; --retard:0s; }
.v008 { --duree:54s; --retard:-18s; }
.v009 { --duree:64s; --retard:-32s; }
.v010 { --retard:0.00s; }
.v011 { --retard:-0.18s; }
.v012 { --retard:-0.36s; }
.v013 { --retard:-0.54s; }
.v014 { --retard:-0.72s; }
.v015 { --retard:-0.90s; }
.v016 { --retard:-1.08s; }
.v017 { --retard:-1.26s; }
.v018 { --retard:-1.44s; }
.v019 { --retard:-1.62s; }
.v020 { --retard:-1.80s; }
.v021 { --retard:-1.98s; }
.v022 { --retard:-2.16s; }
.v023 { --retard:-2.34s; }
.v024 { --retard:-2.52s; }
.v025 { --retard:0s; }
.v026 { --retard:-1.6s; }
.v027 { --retard:-2.4s; }
.v028 { --retard:-4s; }
.v029 { left:44%; --t:3px; --d:22s; --r:-20s; --dx:-58px; --c:var(--or); }
.v030 { left:71%; --t:2px; --d:21s; --r:-18s; --dx:-56px; --c:var(--bleu); }
.v031 { left:7%; --t:2px; --d:22s; --r:-13s; --dx:-53px; --c:var(--bleu); }
.v032 { left:14%; --t:4px; --d:16s; --r:-26s; --dx:-39px; --c:var(--bleu); }
.v033 { left:83%; --t:2px; --d:25s; --r:-18s; --dx:31px; --c:var(--or); }
.v034 { left:31%; --t:2px; --d:24s; --r:-4s; --dx:4px; --c:var(--corail); }
.v035 { left:21%; --t:2px; --d:25s; --r:-9s; --dx:-24px; --c:var(--or); }
.v036 { left:77%; --t:3px; --d:21s; --r:-3s; --dx:70px; --c:var(--or); }
.v037 { left:75%; --t:2px; --d:25s; --r:-6s; --dx:57px; --c:var(--corail); }
.v038 { left:43%; --t:4px; --d:25s; --r:-14s; --dx:22px; --c:var(--vert); }
.v039 { left:34%; --t:3px; --d:27s; --r:-24s; --dx:-8px; --c:var(--or); }
.v040 { left:76%; --t:3px; --d:24s; --r:-15s; --dx:17px; --c:var(--corail); }
.v041 { left:39%; --t:2px; --d:17s; --r:-16s; --dx:37px; --c:var(--bleu); }
.v042 { left:46%; --t:3px; --d:30s; --r:-15s; --dx:37px; --c:var(--or); }
.v043 { --rang:0; }
.v044 { --rang:1; }
.v045 { --rang:2; }
.v046 { --retard:-0.3s; }
.v047 { --retard:-0.6s; }
.v048 { --retard:-0.9s; }
.v049 { --retard:-1.2s; }
.v050 { --retard:-1.5s; }
.v051 { --retard:-1.8s; }
.v052 { --retard:-2.1s; }
.v053 { --retard:-2.7s; }
.v054 { --retard:-3s; }
.v055 { --retard:-3.3s; }
.v056 { --retard:-3.6s; }
.v057 { --retard:-3.9s; }
.v058 { --retard:1.3s; }
.v059 { --retard:2.4s; }
.v060 { --retard:0.7s; }
.v061 { --retard:1.8s; }
.v062 { --retard:3s; }
.v063 { --retard:-0.40s; }
.v064 { --retard:-0.80s; }
.v065 { --retard:-1.20s; }
.v066 { --retard:-1.60s; }
.v067 { --retard:-2.00s; }
.v068 { --retard:-2.40s; }
.v069 { --retard:-2.80s; }
.v070 { --retard:-3.20s; }
.v071 { --retard:-3.60s; }
.v072 { --retard:-0.35s; }
.v073 { --retard:-0.70s; }
.v074 { --retard:-1.05s; }
.v075 { --retard:-1.40s; }
.v076 { --retard:-1.75s; }
.v077 { --retard:-2.10s; }
.v078 { --retard:-2.45s; }
.v079 { --retard:-3.15s; }
.v080 { --retard:-3.50s; }
.v081 { --retard:0.4s; }
.v082 { --retard:1.7s; }
.v083 { --retard:2.6s; }
.v084 { --retard:1.1s; }
.v085 { --retard:-0.7s; }
.v086 { --retard:-1.4s; }
.v087 { --retard:-2.8s; }
.v088 { --retard:-0.34s; }
.v089 { --retard:-0.68s; }
.v090 { --retard:-1.02s; }
.v091 { --retard:-1.36s; }
.v092 { --retard:-1.7s; }
.v093 { --retard:-2.04s; }
.v094 { --retard:-2.38s; }
.v095 { --retard:-2.72s; }
.v096 { --retard:-3.06s; }
.v097 { --retard:-3.4s; }
.v098 { --retard:-3.5s; }
.v099 { --retard:-4.2s; }
.v100 { --retard:-4.9s; }
.v101 { --retard:-5.6s; }
.v102 { --retard:-6.3s; }
.v103 { --retard:-7s; }
.v104 { --retard:-7.7s; }
.v105 { --retard:-8.4s; }
.v106 { --retard:-9.1s; }
.v107 { --retard:-9.8s; }
.v108 { --retard:-0.4s; }
.v109 { --retard:-0.8s; }
.v110 { --retard:-2s; }
.v111 { --retard:1.6s; }
.v112 { --retard:2.5s; }

/* Au doigt, une cible de 32 px se rate. Les commandes secondaires gardent leur
   taille visuelle et gagnent une surface de contact par pseudo-élément. */
@media (pointer: coarse) {
  .fermer, .langue button, .fleche { position: relative; }
  .fermer::after, .langue button::after, .fleche::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   IMPRESSION

   L'exemple de livrable est la page qu'un prospect enregistre en PDF pour la
   transférer en interne. Sans cette feuille, elle sortait sur fond sombre :
   soit une cartouche vidée, soit du texte blanc sur blanc une fois le fond
   supprimé par le navigateur. Le document repasse donc en noir sur blanc,
   les volets s'ouvrent, et les liens montrent leur adresse.
   ═══════════════════════════════════════════════════════════════════════════ */

@media print {
  @page { margin: 16mm 14mm; }

  :root {
    --ground: #fff; --surface: #fff; --surface-2: #fff;
    --ink: #111; --ink-2: #333; --hair: #bbb; --bord: #888; --jalon: #555;
    --or: #8a6408; --vert: #14663f; --corail: #9a3225; --bleu: #1b4f8c;
    --ombre: none;
  }
  html, body { background: #fff !important; color: #111 !important; }
  body::before, .fond, .voile, .poussiere, .filigrane { display: none !important; }

  /* Chrome navigateur, commandes et décor : rien de tout cela ne s'imprime. */
  .banniere, .barre-droite, .langue, .saut, .retour-flottant,
  .fleches, .descendre, .scene, .creneaux, .mot, .ou-bien, .mot-ko,
  .sig, .schema .fl-ret { display: none !important; }

  /* Les volets repliés cachent le contenu : ils s'ouvrent tous. La règle sur
     ::details-content est indispensable depuis que les navigateurs animent
     l'ouverture — sans elle, un volet fermé sort du PDF, et la page que le
     prospect enregistre perd ses formules. */
  details > div, details > .contenu, .secteur-corps { display: block !important; }
  details::details-content {
    block-size: auto !important; opacity: 1 !important;
    overflow: visible !important; content-visibility: visible !important; }
  .formule { border-color: #bbb; background: none; }
  summary { list-style: none; }
  summary .chevron { display: none; }

  /* Les mises en page à deux colonnes sont des commodités d'écran. Sur papier,
     le sommaire collant occuperait une colonne sur toutes les pages et
     rétrécirait le corps du document ; la clôture imprimerait une colonne vide,
     son formulaire et son agenda n'étant pas imprimés. */
  .doc, .doc:has(.doc-corps), .rdv .enveloppe { display: block !important; max-width: none !important; }
  .doc > .sommaire { position: static !important; max-width: 34rem; }
  .doc:has(.doc-corps) .sommaire-liste { grid-template-columns: 1fr 1fr; }

  .bande, .doc { padding-block: 0.6rem !important; }
  .sur-clair { background: none !important; border-block: 0 !important; }
  .revele { opacity: 1 !important; transform: none !important; animation: none !important; }
  * { animation: none !important; transition: none !important;
      box-shadow: none !important; text-shadow: none !important;
      backdrop-filter: none !important; }

  .doc h1, .doc h2 { break-after: avoid-page; }
  .tableau-zone, .tab, .eq, .resultat, .chiffres, .schema { break-inside: avoid-page; }
  .tableau-zone { overflow: visible; }
  .avis { background: none; border-left: 2px solid #8a6408; }
  .doc .resultat { background: none; border: 1px solid #888; border-left: 3px solid #8a6408; }
  .schema .bloc, .schema .bloc-src, .schema .bloc-fort, .schema .bloc-sor { fill: #fff; stroke: #888; }
  .schema text { fill: #111; }
  .schema .sor { fill: #8a6408; }
  .sig .aire, .sig .bande-arret { opacity: 0.3; }

  /* L'adresse d'un lien externe ne se déduit pas d'un document papier. */
  .doc a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; color: #555; word-break: break-all; }
  .sommaire { border-color: #bbb; }
  .sommaire-liste a { text-decoration: none; }
}

