/* HartEdge · monde 1 « Verre de nuit » · la page d'accueil (AG39, p1311) */

@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 200 900; font-display: swap;
  src: url(polices/unbounded-200-900.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url(polices/geist-100-900.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

@property --angle { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@view-transition { navigation: auto; }

:root {
  --nuit: #0a0917; --nuit-2: #141425; --givre: #f3f5fb; --brume: #b2b7c8; --glacier: #85ddf3;
  --sp-1: #fb9989; --sp-2: #eec05b; --sp-3: #68d7a1; --sp-4: #63b9fe; --sp-5: #b48df4;
  --spectre: linear-gradient(90deg, var(--sp-1), var(--sp-2), var(--sp-3), var(--sp-4), var(--sp-5));
  --givre-14: rgba(243, 245, 251, 0.14);
  --marge: clamp(20px, 6vw, 96px);
  --sortie: cubic-bezier(0.33, 1, 0.68, 1);       /* power2.out */
  --sortie-douce: cubic-bezier(0.5, 1, 0.89, 1);  /* power1.out */
  --rebond: cubic-bezier(0.34, 1.56, 0.64, 1);    /* back.out(1.7) */
  --expo: cubic-bezier(0.16, 1, 0.3, 1);          /* expo.out */
  --roule: cubic-bezier(0.76, 0, 0.24, 1);
  --trace: cubic-bezier(0.9, 0.01, 0.19, 1);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--nuit); -webkit-text-size-adjust: 100%; scroll-padding-top: 88px; }
/* R741 (07/11) : le défilement doux au clic sur une ancre ; en mouvement réduit, le saut sec. La cible s'arrête sous l'en-tête fixe (scroll-padding-top, ci-dessus). */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  margin: 0; color: var(--givre); background-color: var(--nuit);
  /* Le grain (§ 3) : un bruit figé, 3,5 %, contre les marches des dégradés sombres. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.035 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  font-family: 'Geist', system-ui, sans-serif; font-size: 17px; line-height: 1.6; font-weight: 400;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
  overflow-x: clip;
}
@media (min-width: 900px) { body { font-size: 18px; } }
a { color: inherit; }
p { margin: 0; }
h1, h2, h3, h4, h5 { margin: 0; font-weight: 300; }
:focus-visible { outline: 2px solid var(--glacier); outline-offset: 4px; border-radius: 6px; }

.evitement { position: fixed; left: 12px; top: -80px; z-index: 50; padding: 12px 18px; border-radius: 10px;
  background: var(--givre); color: var(--nuit); text-decoration: none; font-weight: 500; }
.evitement:focus { top: 12px; }

/* ---------- La scène : fixe, derrière tout ; une carte arrondie qui devient plein écran sur les 50 premiers pixels ---------- */
/* R9 (K6) : la hauteur de la fenêtre barre d'adresse cachée (lvh) ; elle ne suit plus la barre du téléphone quand elle se replie, donc la
   toile n'est ni redimensionnée ni recadrée. Le bas de la carte suit le bas visible par le découpage (--bas : la barre ; 0 au bureau). */
.scene { position: fixed; top: 0; left: 0; right: 0; height: 100vh; height: 100lvh; z-index: 0; background: var(--nuit) center / cover no-repeat;
  --bas: 0px; clip-path: inset(12px 12px calc(12px + var(--bas)) 12px round 20px); transition: opacity 0.45s ease; }
@supports (height: 100dvh) { .scene { --bas: calc(100lvh - 100dvh); } }
@media (max-width: 1024px) { .scene { clip-path: inset(8px 8px calc(8px + var(--bas)) 8px round 20px); } }
.part .scene { opacity: 0; }
.part main, .part .pied, .part .entete { filter: blur(7px); transition: filter 0.45s ease; }

/* Le voile (§ 2, mesuré par agence : 76 % sous le bloc) : de la couleur de la nuit, invisible sur la nuit, il garde la lecture quand la lame passe dessous. */
.voile { position: relative; isolation: isolate; }
.voile::before { content: ''; position: absolute; inset: -14px -18px; z-index: -1; border-radius: 22px;
  background: rgba(10, 9, 23, 0.76); box-shadow: 0 0 48px 28px rgba(10, 9, 23, 0.76); pointer-events: none; }

/* ---------- L'en-tête ---------- */
.entete { position: fixed; top: 0; left: 0; right: 0; z-index: 20; display: flex; align-items: center; gap: 24px;
  padding: 18px var(--marge); padding-top: max(18px, env(safe-area-inset-top));
  background: linear-gradient(var(--nuit) calc(100% - 18px), rgba(10, 9, 23, 0));
  transition: transform 0.7s var(--roule), opacity 0.5s var(--sortie); }
.entete.cache { transform: translateY(-110%); }
/* R659 (06/11) : le nom écrit en texte, dans la police du site, en tête et en pied ; une seule source pour les deux */
.marque, .pied__marque { font-family: 'Unbounded', sans-serif; font-weight: 400; font-size: 17px; letter-spacing: 0.01em; }
.marque { position: relative; z-index: 2; text-decoration: none; margin-right: auto; }
.marque { padding-block: 9px; margin-block: -9px; }
.menu { display: flex; align-items: center; gap: 28px; }
.menu ul { display: flex; gap: 28px; list-style: none; margin: 0; padding: 0; }
.menu ul a { position: relative; text-decoration: none; font-size: 15px; color: var(--brume); transition: color 0.3s ease; padding: 6px 0; }
.menu ul a::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--spectre);
  transform: scaleX(0); transform-origin: left; transition: transform 0.5s var(--trace); }
.menu ul a:hover { color: var(--givre); }
.menu ul a:hover::after, .menu ul a:focus-visible::after { transform: scaleX(1); }
.menu-bascule { display: none; }

@media (max-width: 899px) {
  .menu-bascule { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
    font: 500 15px/1 'Geist', sans-serif; color: var(--givre); background: rgba(20, 20, 37, 0.9); border: 1px solid var(--givre-14); cursor: pointer; position: relative; z-index: 2; }
  .menu { position: fixed; inset: 0; z-index: 1; flex-direction: column; align-items: flex-start; justify-content: center; gap: 40px;
    padding: 96px var(--marge) 48px; background: var(--nuit-2);
    opacity: 0; visibility: hidden; transition: opacity 0.4s var(--sortie), visibility 0s linear 0.4s; }
  .menu ul { flex-direction: column; gap: 8px; }
  .menu ul a { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: 30px; color: var(--givre); display: inline-block; padding: 6px 0; }
  .menu-ouvert .menu { opacity: 1; visibility: visible; transition: opacity 0.4s var(--sortie); }
  .menu-ouvert { overflow: hidden; }
  .menu-ouvert .entete { transform: none; }
}

/* ---------- Le bouton (§ 4 n° 7) : un aplat givre ; au survol, un anneau spectral fait le tour, une fois ; l'étiquette ne roule plus (R681, 06/11) ---------- */
.bouton { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 26px;
  border-radius: 12px; background: var(--givre); color: var(--nuit); text-decoration: none; font-weight: 500; font-size: 16px; letter-spacing: 0.005em;
  isolation: isolate; white-space: nowrap; }
.bouton__roule { display: grid; overflow: hidden; height: 1.4em; line-height: 1.4em; }
.bouton__roule > span { grid-area: 1 / 1; transition: transform 0.3s var(--roule); }
.bouton__roule > span + span { transform: translateY(100%); }
.bouton::before { content: ''; position: absolute; inset: -3px; border-radius: 15px; padding: 2px; z-index: -1; pointer-events: none;
  background: conic-gradient(from var(--angle), transparent 0deg, var(--sp-1) 20deg, var(--sp-2) 45deg, var(--sp-3) 70deg, var(--sp-4) 95deg, var(--sp-5) 120deg, transparent 140deg, transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0; }
.bouton:hover::before { animation: anneau 0.9s 0.15s var(--sortie-douce) 1 both; }
@keyframes anneau { 0% { --angle: -140deg; opacity: 1; } 85% { opacity: 1; } 100% { --angle: 360deg; opacity: 0; } }
.bouton--verre { background: rgba(243, 245, 251, 0.06); color: var(--givre); box-shadow: inset 0 0 0 1px rgba(243, 245, 251, 0.32); }

.lien { color: var(--glacier); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; text-decoration-color: rgba(133, 221, 243, 0.45);
  transition: text-decoration-color 0.3s ease; }
.lien:hover { text-decoration-color: var(--glacier); }

/* ---------- Le filet qui se trace (§ 4 n° 3) ---------- */
.filet { display: block; position: relative; height: 1px; width: 100%; max-width: 640px; margin-bottom: 32px; background: var(--givre-14);
  transform: scaleX(0); transform-origin: left; transition: transform 1.2s var(--trace); }
/* R11 (6), le 05/11 : le spectre reste une fois tracé (« qu'elles apparaissent et qu'elles restent ») ; le fondu à 0 après 1,2 s retiré. Le tracé
   est posé une fois (page.js, l'observateur se retire) : la remontée le garde. */
.filet::after { content: ''; position: absolute; inset: 0; background: var(--spectre); }
.filet.trace { transform: scaleX(1); }

/* ---------- Les titres ---------- */
.titre-ouverture { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: clamp(31px, 8.2vw, 46px); line-height: 1.12; letter-spacing: -0.015em; }
@media (min-width: 900px) {
  .titre-ouverture { font-size: clamp(50px, 5vw, 80px); }
  .titre-ouverture .ligne { display: block; }
}
.titre-section { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: clamp(24px, 3vw, 40px); line-height: 1.18; letter-spacing: -0.01em; max-width: 18em; }
.nom-domaine { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: clamp(38px, 5.4vw, 84px); line-height: 1.04; letter-spacing: -0.02em; }
.titre-fin { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: clamp(30px, 4.6vw, 70px); line-height: 1.1; letter-spacing: -0.015em; max-width: 13em; }
.petit-titre { font-family: 'Geist', sans-serif; font-weight: 500; font-size: 17px; letter-spacing: 0.01em; color: var(--givre); }
.titre-panneau { font-family: 'Unbounded', sans-serif; font-weight: 400; font-size: clamp(19px, 1.6vw, 23px); line-height: 1.3; letter-spacing: -0.005em; }
.phrase, .accroche { color: var(--brume); max-width: 34em; }
.accroche { font-size: clamp(18px, 1.5vw, 21px); margin-top: 18px; }

/* La mise au point des titres (§ 4 n° 2) : lettre par lettre, flou → net, une fois ; la hauteur est celle du texte final (rien ne saute). */
.js .mise-au-point .lettre { display: inline-block; filter: blur(10px); opacity: 0; transform: translateY(15%);
  transition: filter 0.6s var(--sortie-douce), opacity 0.6s var(--sortie-douce), transform 0.6s var(--sortie-douce);
  transition-delay: calc(var(--i) * 0.04s); }
.mise-au-point .mot { display: inline-block; white-space: nowrap; }
.js .mise-au-point.net .lettre { filter: none; opacity: 1; transform: none; }

/* ---------- 1. L'ouverture ---------- */
main { position: relative; z-index: 1; }
.ouverture { position: relative; min-height: 100vh; min-height: 100svh; display: flex; align-items: flex-end; padding: 0 var(--marge) clamp(56px, 12vh, 128px); }
.ouverture__bloc { max-width: 100%; }
.ouverture__phrase { margin-top: 22px; color: var(--brume); max-width: 30em; font-size: clamp(17px, 1.35vw, 20px); }
.ouverture__bouton { margin-top: 32px; }
/* A15 d : la phrase qui lève le risque, sous le bouton du haut */
.ouverture__note { margin-top: 14px; font-size: 15px; color: var(--brume); }
.seul-tel { display: none; }
@media (max-width: 899px) { .seul-bureau { display: none; } .seul-tel { display: inline; } }

/* L'arrivée (§ 4 a-d) : dès les polices, sans attendre la lumière (R9 bis, 7) : le titre (par lignes masquées), la phrase à la fin de la montée des mots
   (+0,95 s), l'en-tête (+1,55 s) ; la lumière entre en même temps, sur 1,6 s. Le bouton n'attend plus (A15 h, plus bas). */
.titre-ouverture .masque { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.titre-ouverture .masque > span { display: inline-block; }
.js .titre-ouverture .masque > span { transform: translateY(110%); transition: transform 0.8s var(--sortie); transition-delay: calc(var(--l, 0) * 0.05s); }
/* R9 bis, 7 bis : le titre caché tant que page.js n'a pas posé ses masques (le premier rendu le peignait en entier, puis il disparaissait) ; le filet de 4 s le rend. */
.js .titre-ouverture { visibility: hidden; }
.js .titre-ouverture .masque, .js.arrive .titre-ouverture { visibility: visible; }
.js .ouverture__phrase { opacity: 0; transform: translateY(14px); transition: opacity 0.8s var(--sortie) 0.95s, transform 0.8s var(--sortie) 0.95s; }
/* A15 h (06/11) : le bouton du haut et sa phrase n'attendent plus les polices ni le titre (visible à 2,48 s servi, A15) : ils paraissent au
   premier rendu. Sans fondu depuis le relais 153 (opaques dès la première image ; avec le fondu de 0,3 s : 974 ms au téléphone, en local) :
   une montée de 6 px en 0,2 s. Le titre et la phrase sous le titre gardent leur entrée. */
.js .ouverture__bouton, .js .ouverture__note { animation: vient 0.2s var(--sortie) both; }
@keyframes vient { from { transform: translateY(6px); } to { transform: none; } }
.js .entete { opacity: 0; transform: translateY(-40px); }
.js.arrive .titre-ouverture .masque > span { transform: none; }
.js.arrive .ouverture__phrase { opacity: 1; transform: none; }
.js.arrive .entete { opacity: 1; transform: none; transition: transform 0.5s var(--sortie) 1.55s, opacity 0.5s var(--sortie) 1.55s; }
.js.arrive.defile .entete { transition: transform 0.7s var(--roule), opacity 0.5s var(--sortie); }
.js.arrive .entete.cache { transform: translateY(-110%); }

/* ---------- 3. La méthode : le moment produit ---------- */
.methode { position: relative; }
.methode__piste { height: 210vh; }
.methode__colle { position: sticky; top: 0; height: 100vh; height: 100svh; display: flex; align-items: flex-end; padding: 0 var(--marge) clamp(56px, 12vh, 120px); }
.methode__texte { max-width: min(100%, 980px); }
.methode__texte .petit-titre { margin-top: clamp(28px, 6vh, 64px); }
.phrase-allumee { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: clamp(30px, 4.6vw, 70px); line-height: 1.12; letter-spacing: -0.015em;
  margin: 14px 0 22px; max-width: 13.5em; color: var(--givre); }
@media (max-width: 374px) { .phrase-allumee { font-size: 26px; } }
.js .phrase-allumee .m { color: var(--brume); opacity: 0.55; transition: color 0.35s ease, opacity 0.35s ease; }
.js .phrase-allumee .m.on { color: var(--givre); opacity: 1; }

.methode__suite { position: relative; display: grid; gap: 48px; align-items: center; padding: 18vh var(--marge) 22vh; }
@media (min-width: 900px) { .methode__suite { grid-template-columns: repeat(12, 1fr); } .schema { grid-column: 1 / span 6; } .methode__valider { grid-column: 8 / span 5; } }
.methode__valider .phrase { margin-top: 12px; }
/* N° 15 : les quatre temps (A15 e). Les temps 1 et 2 au-dessus du temps 3 dans la scène collante (deux colonnes au bureau), le temps 4 et
   son bouton après la maquette. Avec le script, les temps 1 et 2 s'allument au défilement, puis la phrase du temps 3, mot à mot. */
.temps-debut { display: grid; gap: 18px; margin-top: clamp(22px, 4.5vh, 48px); }
@media (min-width: 900px) { .temps-debut { grid-template-columns: 1fr 1fr; gap: 40px; max-width: 860px; } }
.methode__texte .temps .petit-titre { margin-top: 0; }
.temps .phrase { margin-top: 6px; }
.methode__texte .temps-trois { margin-top: clamp(22px, 4.5vh, 48px); }
.js .temps { opacity: 0.55; transition: opacity 0.45s ease; }
.js .temps.on { opacity: 1; }
.methode__bouton { margin-top: 28px; }

/* Le schéma : la maquette sort du verre, nette, se compose bloc par bloc, puis se retourne en écran de téléphone. */
.schema { position: relative; container-type: inline-size; margin: 0; display: flex; justify-content: center; align-items: center; min-height: clamp(380px, 52vw, 560px); perspective: 1400px; }
/* R9 bis (point 3, le CLS) : la figure a dès le départ la hauteur du téléphone retourné, et le cadre, hors du flux, se centre par une
   transformation : le retournement ne déplace plus rien dans la page. La ligne en vw sert le navigateur sans cqw (elle réserve un peu plus). */
.schema::before { content: ''; width: 0; height: calc(min(56vw, 250px) * 18.5 / 9); height: calc(min(56cqw, 250px) * 18.5 / 9); }
.schema__cadre { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) rotateY(0deg); width: min(100%, 560px); aspect-ratio: 16 / 10.5; border-radius: 14px;
  background: linear-gradient(rgba(243, 245, 251, 0.06), rgba(243, 245, 251, 0.06)), rgba(10, 9, 23, 0.75);
  border: 1px solid var(--givre-14); box-shadow: inset 0 1px 0 rgba(243, 245, 251, 0.3);
  backdrop-filter: blur(24px) saturate(140%); -webkit-backdrop-filter: blur(24px) saturate(140%);
  transition: width 0.9s var(--roule), aspect-ratio 0.9s var(--roule), border-radius 0.9s var(--roule), transform 0.9s var(--roule); }
.schema__cadre::after { content: ''; position: absolute; left: 10%; right: 10%; top: -1px; height: 1px; background: var(--spectre); opacity: 0; transition: opacity 0.6s ease; }
.schema.compose .schema__cadre::after { opacity: 0.9; }
.schema .b { position: absolute; border-radius: 4px; background: rgba(243, 245, 251, 0.07); border: 1px solid rgba(243, 245, 251, 0.1);
  transition: background-color 0.5s ease, border-color 0.5s ease, left 0.9s var(--roule), top 0.9s var(--roule), width 0.9s var(--roule), height 0.9s var(--roule), border-radius 0.9s var(--roule), opacity 0.9s var(--roule);
  transition-delay: calc(var(--k) * 0.12s), calc(var(--k) * 0.12s), 0s, 0s, 0s, 0s, 0s, 0s; }
.schema.compose .b { background: rgba(243, 245, 251, var(--plein, 0.5)); border-color: rgba(243, 245, 251, 0.5); }
/* La page de bureau */
.b-haut   { --k: 0; --plein: 0.85; left: 6%;  top: 6%;  width: 18%; height: 3.5%; }
.b-image  { --k: 1; --plein: 0.22; left: 6%;  top: 15%; width: 88%; height: 34%; }
.b-ligne1 { --k: 2; --plein: 0.9;  left: 6%;  top: 55%; width: 56%; height: 4%; }
.b-ligne2 { --k: 3; --plein: 0.6;  left: 6%;  top: 62%; width: 40%; height: 4%; }
.b-carte1 { --k: 4; --plein: 0.18; left: 6%;  top: 71%; width: 27%; height: 18%; }
.b-carte2 { --k: 5; --plein: 0.18; left: 36.5%; top: 71%; width: 27%; height: 18%; }
.b-carte3 { --k: 6; --plein: 0.18; left: 67%; top: 71%; width: 27%; height: 18%; }
.b-bouton { --k: 7; --plein: 1;    left: 72%; top: 5%;  width: 22%; height: 5%; border-radius: 6px; }
/* Retournée : l'écran de téléphone (les mêmes blocs, en une colonne) */
.schema.retourne .schema__cadre { width: min(56%, 250px); aspect-ratio: 9 / 18.5; border-radius: 28px; transform: translate(-50%, -50%) rotateY(360deg); }
.schema.retourne .b-haut   { left: 9%; top: 5%; width: 34%; height: 2.4%; }
.schema.retourne .b-bouton { left: 9%; top: 86%; width: 82%; height: 5.5%; border-radius: 10px; }
.schema.retourne .b-image  { left: 9%; top: 11%; width: 82%; height: 30%; }
.schema.retourne .b-ligne1 { left: 9%; top: 45%; width: 76%; height: 3.2%; }
.schema.retourne .b-ligne2 { left: 9%; top: 50.5%; width: 54%; height: 3.2%; }
.schema.retourne .b-carte1 { left: 9%; top: 58%; width: 82%; height: 7.5%; }
.schema.retourne .b-carte2 { left: 9%; top: 67%; width: 82%; height: 7.5%; }
.schema.retourne .b-carte3 { left: 9%; top: 76%; width: 82%; height: 7.5%; opacity: 0.6; }
/* R9 bis (point 3 v2, le CLS des blocs) : les blocs se placent par translate, plus par left/top : leur coin de mise en page reste
   au coin du cadre, qui change de taille, et un déplacement par transformation ne compte pas dans le CLS. La position est en
   unités du cadre (cqw/cqh, le cadre en container-type: size) ; la transition porte sur deux nombres enregistrés (--bx, --by), pas
   sur translate : en cqw, la valeur d'arrivée change avec la taille du cadre pendant le retournement, et la transition repartirait
   à chaque image. Le chemin est celui de left/top : x = (--bx du moment) % de la largeur du moment. Sans cqw : left/top, au-dessus. */
@property --bx { syntax: '<number>'; inherits: false; initial-value: 0; }
@property --by { syntax: '<number>'; inherits: false; initial-value: 0; }
@supports (width: 1cqw) {
  .schema__cadre { container-type: size; }
  .schema .b, .schema.retourne .b { left: 0; top: 0; translate: calc(var(--bx) * 1cqw) calc(var(--by) * 1cqh); }
  .schema .b { transition: background-color 0.5s ease, border-color 0.5s ease, --bx 0.9s var(--roule), --by 0.9s var(--roule), width 0.9s var(--roule), height 0.9s var(--roule), border-radius 0.9s var(--roule), opacity 0.9s var(--roule);
    transition-delay: calc(var(--k) * 0.12s), calc(var(--k) * 0.12s), 0s, 0s, 0s, 0s, 0s, 0s; }
  .b-haut { --bx: 6; --by: 6; }
  .b-image { --bx: 6; --by: 15; }
  .b-ligne1 { --bx: 6; --by: 55; }
  .b-ligne2 { --bx: 6; --by: 62; }
  .b-carte1 { --bx: 6; --by: 71; }
  .b-carte2 { --bx: 36.5; --by: 71; }
  .b-carte3 { --bx: 67; --by: 71; }
  .b-bouton { --bx: 72; --by: 5; }
  .schema.retourne .b-haut { --bx: 9; --by: 5; }
  .schema.retourne .b-image { --bx: 9; --by: 11; }
  .schema.retourne .b-ligne1 { --bx: 9; --by: 45; }
  .schema.retourne .b-ligne2 { --bx: 9; --by: 50.5; }
  .schema.retourne .b-carte1 { --bx: 9; --by: 58; }
  .schema.retourne .b-carte2 { --bx: 9; --by: 67; }
  .schema.retourne .b-carte3 { --bx: 9; --by: 76; }
  .schema.retourne .b-bouton { --bx: 9; --by: 86; }
}

/* ---------- 2. Les domaines ---------- */
.domaines { position: relative; padding: 8vh var(--marge) 6vh; }
.domaines__tete { max-width: 760px; margin-bottom: clamp(72px, 14vh, 160px); }
.domaines__tete .phrase { margin-top: 18px; }
.domaine { display: grid; gap: 32px; margin-bottom: clamp(96px, 18vh, 200px); }
.domaine__nom { align-self: start; }
.domaine__panneaux { display: grid; gap: 24px; }
@media (min-width: 900px) {
  .domaine { grid-template-columns: repeat(12, 1fr); column-gap: 24px; }
  .domaine__nom { grid-column: 1 / span 5; position: sticky; top: 18vh; }
  .domaine__panneaux { grid-column: 6 / span 7; padding-top: 22vh; gap: 32px; }
  .domaine--duo .domaine__panneaux { grid-template-columns: 1fr 1fr; align-items: start; }
}

/* Le verre (§ 3) : dépoli, un bord de 1 px à 14 %, un reflet de 1 px plus clair en haut ; sur la scène, le voile de 75 %. */
.verre { position: relative; border-radius: 16px; padding: clamp(24px, 3vw, 40px); display: grid; gap: 18px; justify-items: start;
  --flou: 24px;
  overflow: hidden; }
/* La matière du verre, une seule source : les panneaux */
.verre {
  background: linear-gradient(rgba(243, 245, 251, 0.06), rgba(243, 245, 251, 0.06)), rgba(10, 9, 23, 0.75);
  border: 1px solid var(--givre-14); box-shadow: inset 0 1px 0 rgba(243, 245, 251, 0.30);
  backdrop-filter: blur(var(--flou, 24px)) saturate(140%); -webkit-backdrop-filter: blur(var(--flou, 24px)) saturate(140%); }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .verre, .schema__cadre { background: rgba(20, 20, 37, 0.92); } }
.verre > p { color: var(--brume); max-width: 36em; }
.verre > .texte-fort { color: var(--givre); font-size: clamp(18px, 1.45vw, 21px); line-height: 1.5; }
.verre .pour-qui, .volet .pour-qui { color: var(--givre); font-size: 15px; padding-left: 14px; border-left: 1px solid var(--givre-14); }
.verre .bouton { margin-top: 8px; }
/* Le reflet qui suit le curseur (§ 4 n° 6) et le bord le plus proche qui s'allume en spectre */
.verre .reflet, .verre .bord { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity 0.5s ease; }
.verre .reflet { background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(243, 245, 251, 0.08), rgba(243, 245, 251, 0.072) var(--r1, 30px), rgba(243, 245, 251, 0) var(--r2, 60px)); mix-blend-mode: screen; }
.verre .bord { -webkit-mask: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), #000 0, transparent 34%); mask: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), #000 0, transparent 34%); }
.verre .bord::before { content: ''; position: absolute; inset: -1px; border-radius: 16px; padding: 1px;
  background: linear-gradient(115deg, var(--sp-1), var(--sp-2), var(--sp-3), var(--sp-4), var(--sp-5));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
.verre.survol .reflet, .verre.survol .bord { opacity: 1; }

/* Le prix : un seul panneau --nuit-2, un seul chiffre allumé */
.prix { width: 100%; display: grid; grid-template-columns: auto 1fr; align-items: baseline; column-gap: 18px; row-gap: 4px;
  padding: 20px 22px; border-radius: 12px; background: var(--nuit-2); border: 1px solid rgba(243, 245, 251, 0.08); }
.prix__chiffre { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: clamp(36px, 3.4vw, 48px); line-height: 1; color: var(--glacier);
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em; grid-row: 1 / span 2; }
.prix__precision { color: var(--brume); font-size: 16px; }
.prix__lien { font-size: 16px; justify-self: start; }
/* A15 i : « Voir le prix » (26 px) et « Mentions légales » (24 px) : une zone de 44 px au moins au doigt ; la marge négative rend la place, le regard ne bouge pas */
.prix__lien, .pied__bas .lien { padding-block: 11px; margin-block: -11px; }

.volets { display: grid; gap: 28px; width: 100%; }
@media (min-width: 1100px) { .volets { grid-template-columns: 1fr 1fr; gap: 32px; } }
.volet { display: grid; gap: 10px; align-content: start; }
.volet h5 { font-family: 'Geist', sans-serif; font-weight: 500; font-size: 17px; color: var(--givre); }
.volet p { color: var(--brume); }

/* ---------- 6. L'appel de la fin ---------- */
.fin { position: relative; min-height: 100vh; min-height: 100svh; display: flex; align-items: flex-end; padding: 0 var(--marge) clamp(64px, 14vh, 140px); }
.fin__bloc { max-width: 900px; }
.fin__bloc .phrase { margin-top: 22px; max-width: 32em; }
.actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }

/* ---------- 8. Le pied : la seconde scène ---------- */
.pied { position: relative; z-index: 2; background: var(--nuit); overflow: hidden; }
.pied__scene { position: relative; height: 92vh; height: 92svh; min-height: 460px; will-change: transform, opacity; }
.pied__nom { position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); text-align: center; margin: 0;
  font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: 14.5vw; line-height: 1; letter-spacing: -0.03em; color: var(--givre); white-space: nowrap; }
.scene-pied { position: absolute; inset: 0; }
/* N° 15 (A9) : le pied en trois rangs, dans l'ordre de P1311-TEXTES.md § 2 : le nom et le dernier bouton ; l'appel, le courriel, le lieu ;
   la TVA et les deux pages. Au téléphone, l'un sous l'autre ; au bureau, chaque rang sur une ligne. */
.pied__bas { position: relative; display: grid; gap: 30px;
  padding: 36px var(--marge) max(32px, env(safe-area-inset-bottom)); border-top: 1px solid var(--givre-14); background: var(--nuit-2);
  font-size: 15px; color: var(--brume); }
.pied__marque { color: var(--givre); }
.pied__tete { display: flex; flex-wrap: wrap; gap: 24px 32px; justify-content: space-between; align-items: center; }
.pied__contact { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 10px 56px; align-items: flex-end; }
.contact { display: inline-flex; flex-direction: column; gap: 2px; padding-block: 6px; text-decoration: none; }
.contact__nom { font-size: 15px; letter-spacing: 0.02em; color: var(--brume); }
.contact__valeur { font-size: 18px; color: var(--givre); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px;
  text-decoration-color: var(--givre-14); transition: text-decoration-color 0.3s ease; }
.contact:hover .contact__valeur { text-decoration-color: var(--glacier); }
.pied__lieu { padding-block: 6px; color: var(--brume); }
.pied__legal { display: flex; flex-wrap: wrap; gap: 12px 28px; align-items: center; padding-top: 24px; border-top: 1px solid var(--givre-14); }
@media (min-width: 900px) { .pied__legal p { margin-right: auto; } }
/* Au téléphone, comme les boutons de la fin (relais 153) : les rangs du bas hors de la colonne de la pause (44 px + 16 px), en largeur maximale */
@media (max-width: 899px) { .pied__contact, .pied__legal { max-width: calc(100% - 60px); } }

/* ---------- La pause (pour tout le monde) ---------- */
.pause { position: fixed; right: 16px; bottom: 16px; z-index: 15; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center;
  background: rgba(20, 20, 37, 0.92); border: 1px solid var(--givre-14); color: var(--brume); cursor: pointer; transition: color 0.3s ease; }
.pause:hover { color: var(--givre); }
.pause svg { fill: currentColor; }
.pause .pause__lecture { display: none; }
.pause.fige .pause__barre { display: none; }
.pause.fige .pause__lecture { display: inline; }
.pause[hidden] { display: none; }

@media (max-width: 899px) {
  .pause { transition: color 0.3s ease, transform 0.45s var(--roule); }
  /* Relais 153 (vu sur tel-09) : avec « Nous appeler », « Nous en parler » passait à droite et la pause, fixe en bas à droite, le couvrait.
     Les boutons de la fin restent hors de sa colonne (44 px + 16 px) : ils vont à la ligne plutôt que de passer dessous. */
  /* Une largeur maximale en pourcentage, pas une marge : elle ne compte pas dans la largeur minimale du bloc (avec 60 px de marge, la page
     faisait 337 px à 320 px d'écran, mesuré cap3). */
  .fin .actions { max-width: calc(100% - 60px); }
}

/* ---------- Sans WebGL : l'affiche, et rien d'autre ne change ---------- */
.sans-webgl .scene { clip-path: none; }

/* ---------- Le mouvement réduit : tout à son état final ---------- */
@media (prefers-reduced-motion: reduce) {
  .js .titre-ouverture .masque > span, .js .ouverture__phrase, .js .ouverture__bouton, .js .ouverture__note, .js .entete { opacity: 1 !important; transform: none !important; transition: none !important; animation: none !important; }
  .js .mise-au-point .lettre { filter: none; opacity: 1; transform: none; transition: none; }
  .filet { transform: none; transition: none; }
  .filet::after { transition: none; }
  .js .phrase-allumee .m { color: var(--givre); opacity: 1; }
  .js .temps { opacity: 1; transition: none; }
  .bouton__roule > span { transition: none; }
  .bouton::before { opacity: 1; animation: none !important; --angle: 0deg;
    background: linear-gradient(90deg, var(--sp-1), var(--sp-2), var(--sp-3), var(--sp-4), var(--sp-5)); }
  .bouton:hover .bouton__roule > span:first-child { transform: none; }
  .bouton:hover .bouton__roule > span + span { transform: translateY(100%); }
  .verre .reflet, .verre .bord { display: none; }
  .schema__cadre, .schema .b { transition: none !important; }
  .scene, .entete { transition: none; }
  .pause { transition: none !important; }
}

/* Le prix au téléphone : le chiffre, puis sa précision et le lien, l'un sous l'autre */
@media (max-width: 520px) {
  .prix { grid-template-columns: 1fr; }
  .prix__chiffre { grid-row: auto; margin-bottom: 6px; }
}

/* R9 bis, règle 1 bis (session 106) : La répétition (page.js, repeter()) : les entrées une fois jouées une fois, au repos après le LCP,
   au-dessus de tout pour être dessinées (dessous, un fond opaque les cacherait au compositeur), presque transparentes (0 ne serait pas dessiné ; à 0,01, les lettres levaient le fond de 3 niveaux sur 255 : visibles). */
.repetition { position: fixed; inset: 0; z-index: 90; overflow: hidden; pointer-events: none; padding: 24px 16px; }
.js .repetition .mise-au-point.net .lettre, .repetition .filet { opacity: 0.001; }
/* Le cadre du schéma à 0,002 (session 107) : à 0,001, son flou de fond (backdrop-filter) n'était ni dessiné ni compilé ; à 1 et à 0,002, la salve de 2 010 tombe (s6a-chaine.sh qo, qp). La cause (un alpha sur 8 bits arrondi à 0) : non vérifiée. */
.repetition .schema__cadre { opacity: 0.002; }

/* La modale (R734, chef-hartedge, 07/11) : la confirmation d'un envoi (formulaire.js) et « Nous appeler » (appel.js). Un <dialog> ouvert par
   showModal() : le focus y reste, Échap la ferme, et elle ne dépend ni du défilement ni du moteur. La matière est celle du verre (§ 3). */
.modale { width: min(460px, calc(100vw - 32px)); max-width: none; max-height: calc(100dvh - 32px); margin: auto; padding: 0; overflow: auto;
  color: var(--givre); border-radius: 16px; border: 1px solid var(--givre-14);
  background: linear-gradient(rgba(243, 245, 251, 0.06), rgba(243, 245, 251, 0.06)), rgba(10, 9, 23, 0.96);
  box-shadow: inset 0 1px 0 rgba(243, 245, 251, 0.30), 0 30px 90px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(24px) saturate(140%); -webkit-backdrop-filter: blur(24px) saturate(140%); }
.modale::backdrop { background: rgba(10, 9, 23, 0.62); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.modale[open] { animation: modale-entre 0.4s var(--sortie) both; }
.modale::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--spectre); opacity: 0.8; }
.modale__boite { display: grid; gap: 16px; justify-items: start; padding: clamp(26px, 4vw, 38px); }
.modale .titre-section { font-size: clamp(22px, 2.4vw, 28px); max-width: none; }
.modale p { margin: 0; color: var(--brume); font-size: 17px; line-height: 1.55; }
.modale .modale__numero { font-family: 'Unbounded', sans-serif; font-weight: 300; font-size: clamp(26px, 3vw, 32px); line-height: 1.2;
  letter-spacing: 0.01em; color: var(--givre); white-space: nowrap; user-select: all; }
.modale__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.modale button.bouton { border: 0; font-family: inherit; cursor: pointer; }
@keyframes modale-entre { from { opacity: 0; transform: translateY(14px) scale(0.98); } }
@media (prefers-reduced-motion: reduce) { .modale[open] { animation: none; } }
