/* =====================================================================
   YD Studio · hero
   Mise en page de la scène, composant téléphone, menu, texte, apparitions.
   Toutes les valeurs de réglage sont dans tokens.css.
   ===================================================================== */

/* ---------- Polices hébergées dans le dossier ---------- */
@font-face {
  font-family: "Rethink Sans";
  src: url("../assets/polices/rethink-sans-variable.woff2") format("woff2");
  font-weight: 400 800;
  font-display: swap;
}
@font-face {
  font-family: "Fredoka";
  src: url("../assets/polices/fredoka-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* Le site est clair, et il le dit. Sans cette ligne, un visiteur dont le système est en mode sombre reçoit des
   champs et des ascenseurs sombres — et surtout l'agenda Cal.com, servi dans un cadre, se met en NOIR sur notre
   ciel (vu au banc le 07/10 : le paramètre « theme=light » de leur adresse ne sert à rien, c'est le réglage du
   système qui décide, et un cadre suit celui de la page qui l'accueille). */
html { -webkit-text-size-adjust: 100%; color-scheme: light; }
body {
  margin: 0;
  background: var(--nuage);
  color: var(--encre);
  font-family: var(--police-texte);
  overflow-x: clip;
}
.visuellement-cache {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- La scène ----------
   Chaque élément placé reçoit --x (distance au centre), --y (distance au haut), --l (largeur),
   en unités de maquette ; .place les convertit en pixels. */
.hero {
  position: relative;
  /* 05/10 : la hauteur de la scène (avant : au moins 100svh, ce qui laissait du ciel vide sur tablette en portrait),
     mais jamais moins que le bas du texte et du bouton, qui gardent une taille minimale (3 lignes de 16 px + bouton de 48 px) */
  height: max(calc(var(--hauteur-scene) * var(--u)), calc((var(--texte-y) + 22) * var(--u) + 139px));
  overflow: clip;   /* 05/10 : coupé aussi en bas (le crayon dépassait et faisait défiler la page sur du vide) */
  isolation: isolate;
  /* PLAN 1 · Le ciel : dégradé doux entre deux bleus (exception déclarée) */
  background: linear-gradient(180deg, var(--ciel) var(--ciel-degrade-debut), var(--ciel-clair) var(--ciel-degrade-fin));
}
.place {
  position: absolute;
  left: calc(50% + var(--x, 0) * var(--u));
  top: calc(var(--y, 0) * var(--u));
  width: calc(var(--l) * var(--u));
  transform: translateX(-50%);
}
.plan svg, .titre svg { display: block; width: 100%; height: auto; }

/* ---------- PLAN 1 bis · Grain sur le ciel ---------- */
.grain {
  position: absolute; inset: 0; z-index: 1;
  opacity: var(--grain-opacite);
  mix-blend-mode: soft-light;
  pointer-events: none;
}
.grain svg { width: 100%; height: 100%; }

/* ---------- PLAN 2 · Nuages ---------- */
.montgolfiere svg, .deco-montgolfiere svg { transform-origin: 50% 90%; }
.montgolfiere { --x: var(--montgolfiere-x); --y: var(--montgolfiere-y); --l: var(--montgolfiere-l); z-index: 2; transform: translateX(-50%) rotate(var(--montgolfiere-rotation)); }
.s-encre { stroke: var(--encre); }
.nuages-haut  { --y: var(--nuages-haut-y);  --l: calc(var(--nuages-haut-h) * 16); z-index: 2; }
.nuages-fond  { --y: var(--nuages-fond-y);  --l: calc(var(--nuages-fond-h) * 2400 / 330); z-index: 3; }
.nuages-devant { --y: var(--nuages-devant-y); --l: calc(var(--nuages-devant-h) * 2400 / 440); z-index: 8; pointer-events: none; }
/* Sous les nuages de devant, le blanc continue : la section suivante se pose dessus (BABA) */
.nuages-devant::after {
  content: ""; position: absolute; left: 0; right: 0; top: calc(100% - 2px);
  height: calc(240 * var(--u)); background: var(--nuage);
}

.nuage-corps { fill: var(--nuage); }
.nuage-corps-pale { fill: var(--nuage-ombre); }
.nuage-lumiere { fill: var(--nuage-lumiere); }
.nuage-ombre-portee { fill: var(--nuage-ombre); }
.nuage-texture { fill: var(--nuage-ombre); opacity: 0.22; }
.nuage-loin { fill: var(--nuage); opacity: 0.5; }
.nuage-loin-2 { fill: var(--nuage); opacity: 0.72; }
.nuages-fond .nuage-lumiere { fill: var(--nuage); }
.nuage-haut { fill: var(--nuage); opacity: 0.78; }
.nuages-haut .nuage-lumiere { fill: var(--nuage-lumiere); opacity: 0.9; }

/* ---------- PLAN 3 · Le titre ---------- */
.titre { margin: 0; z-index: 4; position: static; }
.titre-plein { fill: var(--titre-couleur); }
.masque { fill: var(--masque); }
.titre .titre-haut  { --y: var(--haut-y);  --l: var(--haut-l); }
.titre .titre-geant { --y: var(--geant-y); --l: var(--geant-l); }
.titre .titre-haut-1, .titre .titre-haut-2 { display: none; }
.titre svg { position: absolute; z-index: 4; left: calc(50% + var(--x, 0) * var(--u)); top: calc(var(--y) * var(--u)); width: calc(var(--l) * var(--u)); transform: translateX(-50%); }

/* ---------- PLAN 4 · Le ruban de vignettes : RETIRÉ le 06/10 au soir (« ça fait trop »). ----------
   Le dessin et son script restent dans assets/scene/. ---------- */

/* ---------- PLAN 4 · Les outils du métier (assets/scene/outils/dessiner-outils.py) ----------
   Chaque dessin est centré sur la POINTE de l'outil : --x / --y placent la pointe, --l règle la taille
   (600 = la taille dessinée). Le reste de l'outil déborde, coupé par le bord de l'écran ou avalé par les nuages.
   Profondeur, du fond vers l'avant : la plume (au loin, plus petite, devant le petit nuage du coin) ;
   le crayon (devant les téléphones, sa mine passe devant le cadre Figma ; son bout plonge dans les nuages de devant) ;
   le pinceau de droite a été retiré le 05/10 (demande de Yoann). Aucun ne touche le titre, le sous-titre ni le bouton. */
.outil {
  position: absolute; pointer-events: none;
  left: calc(50% + var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
  width: calc(var(--l) * var(--u));
  transform: translate(-50%, -50%);
}
.outil svg { display: block; width: 100%; height: auto; overflow: visible; }
.outil--plume    { --x: var(--plume-x);    --y: var(--plume-y);    --l: var(--plume-l);    z-index: 3; }   /* devant le petit nuage, derrière le titre */
/* le volume : reflet chaud en haut à gauche, ombre en bas à droite (comme les nuages et la montgolfière) */
.outil-reflet { fill: var(--nuage-lumiere); }
.outil-ombre { fill: var(--encre); opacity: 0.2; }
.outil-ombre-douce { fill: var(--encre); opacity: 0.12; }
.outil-ombre-portee { fill: var(--encre); opacity: 0.16; }
.outil-pan-clair { fill: var(--nuage-lumiere); opacity: 0.42; }
.outil-pan-sombre { fill: var(--encre); opacity: 0.16; }
.outil-pan-ombre-nuage { fill: var(--nuage-ombre); }
.outil-arete { fill: var(--encre); opacity: 0.3; }
.outil-poil { fill: var(--encre); opacity: 0.16; }
.outil-laque { fill: var(--nuage); opacity: 0.32; }
.outil-ligne-grise { fill: var(--gris-maquette-fonce); }
.outil-texture { fill: var(--encre); opacity: 0.1; }
.outil-bois { fill: var(--mandarine); opacity: 0.16; }
/* la plume trace une courbe : le point d'ancrage et ses deux poignées (reproduction d'un outil de dessin) */
.outil-courbe { stroke: var(--nuage); fill: none; stroke-linecap: round; }
.outil-poignee { stroke: var(--nuage); fill: none; }
.outil-bouton { fill: var(--nuage); }
.outil-ancre { fill: var(--ciel); stroke: var(--nuage); }
/* La plume : tout est mené par js/plume.js depuis une seule horloge (la pointe tire son carré bleu, la courbe suit).
   06/10 : le balancement CSS a été retiré, il bougeait la plume sans que le trait ni le carré suivent. */
.outil--plume svg { pointer-events: none; }
.outil--plume .plume-corps, .outil--plume .plume-poignee, .outil--plume .outil-ancre { pointer-events: visiblePainted; cursor: pointer; }
.plume-mobile { transform-box: view-box; transform-origin: 50% 50%; will-change: translate; }   /* 50 % de la boîte = la pointe (0, 0) ;
   « will-change » demande au navigateur de garder le dessin filtré en mémoire : il le déplace au lieu de le recalculer */

/* ---------- PLAN 5 · Les téléphones (composant réutilisable) ----------
   <div class="telephone place"> > .telephone__corps > .telephone__tranche + .telephone__cadre > .telephone__ecran
   Largeur réglée par --l ; tout le reste (coins, îlot, bords) suit la largeur. */
.scene-3d {
  position: absolute; inset: 0; z-index: 6;
  perspective: var(--perspective);
  perspective-origin: 50% 32%;
  pointer-events: none;
}
.telephone { --tl: calc(var(--l) * var(--u)); transform-style: preserve-3d; transform: translateX(-50%); }
.telephone__corps { position: relative; transform-style: preserve-3d; }
.telephone__cadre {
  position: relative;
  padding: calc(var(--tl) * 0.031);
  border-radius: calc(var(--tl) * 0.152);   /* exception : coin physique */
  background: var(--demo-telephone);
}
.telephone__tranche {
  position: absolute; inset: 0;
  border-radius: calc(var(--tl) * 0.152);
  background: var(--demo-telephone-tranche);
  transform: translateZ(calc(var(--tl) * -0.03));
}
.telephone__ecran {
  position: relative; overflow: hidden;
  aspect-ratio: 393 / 852;
  border-radius: calc(var(--tl) * 0.124);   /* exception : coin physique */
  background: var(--nuage);
}
.telephone__ecran svg, .telephone__ecran img { display: block; width: 100%; height: 100%; object-fit: cover; }
.telephone__ilot {
  position: absolute; left: 50%; top: calc(var(--tl) * 0.058);
  width: calc(var(--tl) * 0.3); height: calc(var(--tl) * 0.088);
  transform: translateX(-50%);
  border-radius: calc(var(--tl) * 0.044);
  background: var(--demo-ilot);
}
/* reflet très léger sur l'écran (exception déclarée) */
.telephone__reflet {
  position: absolute; inset: calc(var(--tl) * 0.031);
  border-radius: calc(var(--tl) * 0.124);
  background: linear-gradient(118deg, var(--reflet-ecran) 0%, transparent 38%);
  pointer-events: none;
}
.telephone--centre { --x: var(--tel-c-x); --y: var(--tel-c-y); --l: var(--tel-c-l); z-index: 3; }
.telephone--gauche { --x: calc(var(--tel-cote-x) * -1); --y: var(--tel-cote-y); --l: var(--tel-cote-l); z-index: 1; }
.telephone--droite { --x: var(--tel-cote-x); --y: var(--tel-cote-y); --l: var(--tel-cote-l); z-index: 1; }
.telephone--gauche .telephone__corps { transform: rotateY(var(--tel-cote-rotation-y)) rotateZ(calc(var(--tel-cote-rotation-z) * -1)) translateZ(var(--tel-cote-recul)); }
.telephone--droite .telephone__corps { transform: rotateY(calc(var(--tel-cote-rotation-y) * -1)) rotateZ(var(--tel-cote-rotation-z)) translateZ(var(--tel-cote-recul)); }

/* Ombre au sol douce : là où le téléphone entre dans le nuage (exception déclarée) */
.ombre-sol {
  position: absolute; z-index: 9; pointer-events: none;
  left: calc(50% + var(--x) * var(--u)); top: calc(var(--y) * var(--u));
  width: calc(var(--l) * var(--u)); height: calc(var(--l) * 0.16 * var(--u));
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, var(--ombre-sol), transparent);
  mix-blend-mode: multiply;
}
.ombre-sol--centre { --x: var(--tel-c-x); --y: var(--ombre-c-y); --l: calc(var(--tel-c-l) * 1.25); }
.ombre-sol--gauche { --x: calc(var(--ombre-cote-x) * -1); --y: var(--ombre-cote-y); --l: calc(var(--tel-cote-l) * 1.1); }
.ombre-sol--droite { --x: var(--ombre-cote-x); --y: var(--ombre-cote-y); --l: calc(var(--tel-cote-l) * 1.1); }

/* ---------- PLAN 6 · Élément flottant : la carte App Store Connect de BOOXS ---------- */
.carte {
  --x: var(--carte-x); --y: var(--carte-y); --l: var(--carte-l);
  transform: none; left: calc(50% + var(--x) * var(--u));
  z-index: 7;
  display: grid; grid-template-columns: auto 1fr; gap: calc(12 * var(--u)); align-items: center;
  padding: calc(12 * var(--u)) calc(14 * var(--u));
  border-radius: var(--rayon);
  background: var(--nuage);
  font-size: calc(var(--legende-taille) * var(--u));
  line-height: 1.35;
}
.carte svg, .carte img { width: calc(40 * var(--u)); height: calc(40 * var(--u)); display: block; flex: none; }
.carte img { border-radius: calc(40 * 0.2237 * var(--u)); }   /* exception : coins d'une icône d'app iOS */
.carte b { display: block; font-weight: 700; }
.carte__etat { display: flex; align-items: center; gap: 6px; font-weight: 500; }
.carte__etat::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--statut-pret); flex: none; }

/* ---------- Le cadre de sélection Figma autour du téléphone de gauche (reproduction de l'interface Figma, exception 5) ---------- */
.selection-figma {
  position: absolute; inset: calc(var(--tl) * -0.035);
  border: 2px solid var(--selection-figma);
  pointer-events: none;
}
.selection-figma i {
  position: absolute; width: 10px; height: 10px;
  background: var(--nuage); border: 2px solid var(--selection-figma);
}
.selection-figma i:nth-of-type(1) { left: -6px; top: -6px; }
.selection-figma i:nth-of-type(2) { right: -6px; top: -6px; }
.selection-figma i:nth-of-type(3) { left: -6px; bottom: -6px; }
.selection-figma i:nth-of-type(4) { right: -6px; bottom: -6px; }
.selection-figma__nom {
  position: absolute; left: -2px; bottom: calc(100% + 6px);
  font: 600 calc(var(--legende-taille) * var(--u)) / 1 var(--police-texte);
  color: var(--selection-figma);
  white-space: nowrap;
}
.selection-figma__taille {
  position: absolute; left: 50%; top: calc(100% + 8px); transform: translateX(-50%);
  padding: 3px 6px; border-radius: 3px;
  background: var(--selection-figma); color: var(--nuage);
  font: 600 calc(11 * var(--u)) / 1.2 var(--police-texte);
  white-space: nowrap;
}

/* ---------- Le sous-titre et le bouton, posés sur le nuage ---------- */
.accroche {
  --y: var(--texte-y); --l: var(--texte-l);
  z-index: 10; text-align: center;
}
.sous-titre {
  margin: 0 0 calc(22 * var(--u));
  font-size: max(16px, calc(var(--sous-titre-taille) * var(--u)));
  line-height: 1.4; font-weight: 450;
  text-wrap: balance;
}
.bouton {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  height: max(48px, calc(var(--bouton-hauteur) * var(--u)));
  padding: 0 calc(26 * var(--u));
  border-radius: var(--rayon);
  background: var(--encre); color: var(--nuage);
  font: 600 max(15px, calc(var(--bouton-taille) * var(--u))) / 1 var(--police-texte);
  text-decoration: none;
  transition: background-color 260ms var(--douce);
}
/* 07/10 (Yoann) : « enlève la flèche quand il y a marqué "Ouvrir l'agenda", "Réserver un appel" ou tout ça, enlève
   les flèches sur tous les CTA. En plus, ne fais pas monter le bouton : fais-le juste changer de couleur. »
   Le bouton ne bouge donc plus du tout : il s'assombrit au survol, c'est tout. Un bouton qui ne saute pas ne
   décale rien autour de lui, et il reste franc au doigt comme à la souris. */
.bouton__texte { display: block; }
.bouton:hover, .bouton:active { background: var(--encre-survol); }
.bouton:focus-visible { outline: 3px solid var(--mandarine); outline-offset: 3px; }

/* ---------- PLAN 8 · La flèche dessinée ---------- */
/* Le bouton et sa flèche : la flèche est accrochée au bouton. Sa pointe (dessinée en 0,95 × largeur, 0,25 × largeur
   depuis le haut, voir assets/scene/outils/dessiner-fleche.py) arrive au milieu du bord gauche du bouton, à --fleche-air près. */
.accroche__action { position: relative; display: inline-block; }
.fleche {
  --fl: calc(var(--fleche-l) * var(--u));
  position: absolute; z-index: 1; pointer-events: none;
  width: var(--fl);
  left: calc(var(--fl) * -0.95 - var(--fleche-air) * var(--u));
  top: calc(50% - var(--fl) * 0.25);
}
.fleche svg { display: block; width: 100%; height: auto; }

/* ---------- Le menu : deux blocs blancs qui flottent (SKILLFIRE), le logo au début du 1er ---------- */
.menu {
  position: absolute; z-index: 20; left: 0; right: 0;
  top: calc(var(--menu-y) * var(--u));
  display: flex; justify-content: center; gap: 12px;
  padding: 0 16px;
}
.menu__bloc {
  display: flex; align-items: center;
  height: max(44px, calc(var(--menu-hauteur) * var(--u)));
  padding: 0 calc(8 * var(--u));
  border-radius: var(--rayon);
  background: var(--nuage);
}
/* Les onglets, à la suite après le logo : un trait vertical à gauche de chaque onglet, et un après le dernier */
.menu__onglets { display: flex; align-items: center; height: 100%; margin: 0; padding: 0; list-style: none; }
.menu__onglets li { display: flex; align-items: center; height: 100%; }
.menu__onglets li::before {   /* un trait avant chaque onglet (après le logo et entre les onglets), aucun après le dernier */
  content: ""; width: 1px; height: calc(var(--separateur-h) * var(--u)); background: var(--separateur); flex: none;
}
.menu__onglets a {
  display: block; padding: 10px calc(var(--onglet-air) * var(--u));
  color: var(--encre); text-decoration: none;
  font-size: max(14px, calc(var(--menu-taille) * var(--u))); font-weight: 500;
}
.menu__onglets a { position: relative; transition: color 320ms var(--douce); }
/* 06/10 (Yoann, 3e lot) : plus de trait sous l'onglet. Au survol, les lettres s'éteignent puis se rallument
   l'une après l'autre — EXACTEMENT la vague des neuf points du menu (« j'aimerais bien avoir cette même animation
   sur les onglets »), mêmes réglages : 720 ms, même courbe, opacité 1 → 0,18 → 1.
   Les lettres sont enveloppées par js/menu.js ; sans JavaScript, l'onglet reste un texte normal. */
.menu__onglets a .lettre { display: inline-block; white-space: pre; }
@media (prefers-reduced-motion: no-preference) {
  .menu__onglets a:hover :is(.lettre, .fleche-texte),
  .menu__onglets a:focus-visible :is(.lettre, .fleche-texte) { animation: points-vague 720ms var(--douce) both; animation-delay: calc(var(--i) * 45ms); }
}
/* « Avant → après » : une petite flèche dessinée au lieu d'une barre oblique */
.fleche-texte { display: inline-block; width: 0.9em; height: 0.9em; margin: 0 0.18em; vertical-align: -0.1em; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.menu__onglets a:focus-visible { outline: 3px solid var(--mandarine); outline-offset: 2px; border-radius: var(--rayon); }

/* Les trois barres : seulement au téléphone ; elles déplient les liens sous le 1er bloc (balise details, sans JavaScript) */
.menu__deroulant { position: relative; height: 100%; display: none; align-items: center; }
.menu__deroulant summary {
  list-style: none; cursor: pointer;
  display: grid; place-items: center;
  width: max(40px, calc(44 * var(--u))); height: max(36px, calc(var(--menu-hauteur) * var(--u) - 12px));
  border-radius: var(--rayon); color: var(--encre);
}
.menu__deroulant summary::-webkit-details-marker { display: none; }
.menu__deroulant summary:hover { background: var(--nuage-ombre); }
.menu__deroulant summary svg { width: max(20px, calc(22 * var(--u))); height: auto; fill: currentColor; display: block; }
.menu__deroulant summary:focus-visible { outline: 3px solid var(--mandarine); outline-offset: 2px; }
.menu__liens { margin: 0; padding: 8px; list-style: none; }
.menu__deroulant[open] .menu__liens {
  position: absolute; top: calc(100% + 14px); left: calc(-1 * max(8px, calc(8 * var(--u)))); min-width: 220px;
  display: flex; flex-direction: column; border-radius: var(--rayon); background: var(--nuage);
}
.menu__deroulant:not([open]) .menu__liens { display: none; }
.menu__liens a {
  display: block; padding: 10px 14px; border-radius: var(--rayon);
  color: var(--encre); text-decoration: none;
  font-size: max(14px, calc(var(--menu-taille) * var(--u))); font-weight: 500;
}
.menu__liens a:hover { background: var(--nuage-ombre); }
.menu__liens a:focus-visible { outline: 3px solid var(--mandarine); outline-offset: 2px; }
.menu .bouton { height: calc(var(--menu-hauteur) * var(--u) - 12px); min-height: 36px; padding: 0 calc(18 * var(--u)); font-size: max(14px, calc(var(--menu-taille) * var(--u))); }

/* Le logo (YD Studio) : hauteur = 1,5 capitale de « Studio » ; capitale de « Studio » = --logo-echelle × capitale du texte du menu (0,7 em) */
.menu__logo {
  display: block; flex-shrink: 0;
  padding: 0 calc(var(--logo-air) * var(--u)) 0 calc(10 * var(--u));
  line-height: 0;
}
.menu__logo svg { display: block; overflow: visible; width: auto; height: max(18.4px, calc(var(--menu-taille) * 0.7 * 1.5 * var(--logo-echelle) * var(--u))); translate: 0 calc(var(--logo-calage) * var(--u)); }
.menu__logo:focus-visible { outline: 3px solid var(--mandarine); outline-offset: 2px; border-radius: var(--rayon); }

/* ---------- Apparition au chargement (rien d'autre ne bouge) ---------- */
@media (prefers-reduced-motion: no-preference) {
  .titre svg, .accroche { animation: apparait var(--apparition-duree) var(--apparition-courbe) both; }
  .titre .titre-geant { animation-delay: 80ms; }
  .accroche { animation-delay: calc(var(--apparition-decalage) * 3); }
  .telephone__corps { animation: monte calc(var(--apparition-duree) * 1.2) var(--apparition-courbe) both; }
  .telephone--centre .telephone__corps { animation-delay: calc(var(--apparition-decalage) * 1); }
  .telephone--gauche .telephone__corps { animation-delay: calc(var(--apparition-decalage) * 2); }
  .telephone--droite .telephone__corps { animation-delay: calc(var(--apparition-decalage) * 3); }
  .carte, .fleche { animation: apparait var(--apparition-duree) var(--apparition-courbe) calc(var(--apparition-decalage) * 5) both; }
  .outil { animation: apparait var(--apparition-duree) var(--apparition-courbe) calc(var(--apparition-decalage) * 4) both; }
}
@keyframes apparait { from { opacity: 0; translate: 0 8px; } to { opacity: 1; translate: 0 0; } }
/* Les petites touches qui vivent (rien si « réduire les animations ») : la montgolfière dérive.
   06/10 : la montgolfière était menée image par image en JavaScript (brûleur, pendule, inertie) ; Yoann voulait « plus smooth,
   propre et subtil, de droite à gauche et de haut en bas » → une seule boucle CSS, confiée au compositeur.
   06/10 soir (3e retour) : « elle ne bouge pas assez, fais-la un peu plus animée, de gauche à droite » → le voyage
   horizontal est multiplié par presque quatre (16 px partout, 34 px pour celle de la hero, qui est la plus grande),
   et la boucle est raccourcie. Elle part VERS LA GAUCHE : à droite, elle touche déjà le bord de la hero. */
@media (prefers-reduced-motion: no-preference) {
  .montgolfiere svg, .deco-montgolfiere svg { animation: flotte var(--flotte-duree) ease-in-out infinite; }
  .montgolfiere { --flotte-cote: 34px; --flotte-ampleur: 18px; }   /* la grande, en haut à droite de la hero */
  .deco-montgolfiere--appel svg { animation-delay: -7s; }
  .deco-montgolfiere--etapes svg { animation-delay: -13s; }
}
@keyframes flotte {
  0%   { transform: translate(0, 0) rotate(-1.4deg); }
  30%  { transform: translate(calc(var(--flotte-cote) * -0.9), calc(var(--flotte-ampleur) * -1)) rotate(1.2deg); }
  55%  { transform: translate(calc(var(--flotte-cote) * -1.75), calc(var(--flotte-ampleur) * -0.35)) rotate(2deg); }
  80%  { transform: translate(calc(var(--flotte-cote) * -0.75), calc(var(--flotte-ampleur) * -0.9)) rotate(0.4deg); }
  100% { transform: translate(0, 0) rotate(-1.4deg); }
}
@keyframes monte { from { opacity: 0; translate: 0 16px; } to { opacity: 1; translate: 0 0; } }

/* ---------- Téléphone (390 px) ---------- */
@media (max-width: 640px) {
  .titre .titre-haut { display: none; }
  .titre .titre-haut-1 { display: block; --y: var(--haut-y); --l: var(--haut-l); }
  .titre .titre-haut-2 { display: block; --y: var(--haut2-y); --l: var(--haut2-l); }
  .outil { display: none; }   /* au téléphone, la scène est trop serrée : les outils sont masqués */
  .carte, .selection-figma__taille, .montgolfiere { display: none; }
  .menu__logo { padding: 0 6px; }
  .menu__onglets { display: none; }
  .menu__deroulant { display: flex; }
}

/* ---------- Couleurs des dessins SVG (écrans, outils) : uniquement des variables de tokens.css ---------- */
.f-nuage, .f-papier { fill: var(--nuage); }
.f-encre { fill: var(--encre); }
.f-ciel { fill: var(--ciel); }
.f-ciel-clair { fill: var(--ciel-clair); }
.f-mandarine { fill: var(--mandarine); }
.f-nuage-lumiere { fill: var(--nuage-lumiere); }
.f-nuage-ombre { fill: var(--nuage-ombre); }
.f-gris-maquette { fill: var(--gris-maquette); }
.f-gris-maquette-fonce { fill: var(--gris-maquette-fonce); }
.f-demo-telephone { fill: var(--demo-telephone); }
.s-crayon { stroke: var(--gris-crayon); }
.s-gris-fonce { stroke: var(--gris-maquette-fonce); }
.s-gris-fonce-clair { stroke: var(--gris-maquette-fonce); opacity: 0.8; }
.s-gris-maquette { stroke: var(--gris-maquette); }
.s-mandarine { stroke: var(--mandarine); }
.s-ciel { stroke: var(--ciel); }
.s-ciel-clair { stroke: var(--ciel-clair); }
.s-encre { stroke: var(--encre); }
.f-pret { fill: var(--statut-pret); }
.s-nuage { stroke: var(--nuage); }
.trait-batterie { stroke: var(--encre); fill: none; opacity: 0.45; }
.trait-batterie--clair { stroke: var(--nuage); }
.t-titre { font-family: var(--police-titre); font-weight: 600; }
.t-texte { font-family: var(--police-texte); }
.t-encre { fill: var(--encre); }
.t-nuage { fill: var(--nuage); }
.t-ciel { fill: var(--ciel); }

/* =====================================================================
   Commun à toutes les pages (accueil et études de cas), repris d'Off Menu
   ===================================================================== */


/* Les neuf points du menu (au téléphone, et sur les études de cas) : une vague les éteint puis les rallume en diagonale */
.points { display: block; width: 22px; height: 22px; }
.points circle { fill: currentColor; }
@media (prefers-reduced-motion: no-preference) {
  .menu__deroulant summary:hover .points circle,
  .menu__deroulant summary:focus-visible .points circle,
  .menu__deroulant[open] .points circle { animation: points-vague 720ms var(--douce) both; animation-delay: calc(var(--i) * 70ms); }
  @keyframes points-vague { 0% { opacity: 1; } 30% { opacity: 0.18; } 100% { opacity: 1; } }
}

/* =====================================================================
   L'ouverture d'une étude de cas : LA CARTE DEVIENT LA PAGE
   07/10 (Yoann) : « quand j'appuie sur Books parmi les six de la page d'accueil, ça reprend l'élément Books qui est
   en carré en dessous, ça le passe plus grand au milieu, puis boum, d'un coup ça l'affiche en gros. […] L'image de
   Books en carré sur la page d'accueil et celle de la page qui suit sont les mêmes, donc on peut faire un rendu
   super stylé, fluide et propre. »
   C'est exactement ça : des deux côtés c'est la MÊME photo, cadrée autrement. Le navigateur fait donc voyager le
   visuel de la carte jusqu'à la hero de l'étude — il part d'où on a appuyé, grandit, et s'ouvre d'un coup.
   Le nom « ouverture » est posé sur .e-hero par css/etude.css ; sur la carte de départ, au dernier moment, par
   js/ouverture.js (⚠️ à l'arrivée, un script « defer » serait trop tard : voir CLAUDE.md).
   ===================================================================== */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }

/* Le voyage lui-même. La courbe fait tout : il part lentement, grandit à peine, puis s'ouvre d'un coup à la fin.
   C'est le « en deux temps » qu'il demandait, en un seul mouvement — sans à-coup, donc sans rien qui saute. */
::view-transition-group(ouverture) {
  animation-duration: var(--ouverture-duree);
  animation-timing-function: var(--ouverture-courbe);
}
/* Les deux images remplissent la boîte et se recadrent, exactement comme les vraies (object-fit: cover). Sans ça,
   le carré de la carte et le grand cadre de la hero n'ont pas la même forme et l'image se déformerait en route. */
::view-transition-old(ouverture), ::view-transition-new(ouverture) {
  width: 100%; height: 100%; object-fit: cover;
  animation-duration: var(--ouverture-duree); animation-timing-function: linear;
}
::view-transition-old(ouverture) { animation-name: ouverture-sort; }
::view-transition-new(ouverture) { animation-name: ouverture-entre; }
/* On passe de l'une à l'autre au milieu du voyage : on ne voit pas le changement de cadrage, juste un zoom continu */
@keyframes ouverture-sort  { 0%, 28% { opacity: 1; } 68%, 100% { opacity: 0; } }
@keyframes ouverture-entre { 0%, 28% { opacity: 0; } 68%, 100% { opacity: 1; } }

/* Pendant ce temps la page de départ s'efface sur place, sans bouger (les cartes restent en fantôme un instant) */
::view-transition-group(root) { animation-duration: 420ms; }
::view-transition-old(root) { animation-duration: 420ms; animation-timing-function: cubic-bezier(0.4, 0, 1, 1); }
::view-transition-new(root) { animation-duration: 420ms; animation-timing-function: cubic-bezier(0, 0, 0.4, 1); }
