/* ==========================================================================
   VANILLA - socle commun
   --------------------------------------------------------------------------
   REGLES DE FORME posees par le client, tenues partout :
     0 ombre portee   0 flou   0 bordure apparaissant au survol
   Seule exception assumee : le contour de focus clavier.

   UNE SEULE POLICE SUR TOUT LE SITE : COURGETTE.
   ⚠️ C'EST L'OEIL DU CLIENT QUI TRANCHE, PAS LE SCORE. Quatre tours ont eu
   lieu : Courgette (choisie a l'oeil), Grand Hotel puis Aguafina Script
   (toutes deux designees par la MESURE), et retour a Courgette --
   « la première était la plus ressemblante ». C'est sa marque, c'est sa
   decision, et elle est definitive : NE PLUS Y REVENIR.

   Ce que la mesure a quand meme etabli, et qui reste utile :
   - le mot du logo tient dans un rapport largeur/hauteur de 1,6:1 quand
     les 72 scriptes testes sont tous entre 2,3 et 3,5. Son « V » est deux
     fois plus haut que les autres lettres : c'est un LETTRAGE DESSINE, pas
     une police du commerce. Aucune fonte ne sera jamais « identique », et
     c'est pour ca qu'aucun score n'a convaincu.
   - le mot « Vanilla » doit donc rester l'IMAGE du logo partout ou il sert
     de marque, et la police ne porte que le texte autour.
   Banc et scores : `scratchpad/typo2.mjs` et `typo3.mjs`.
   Consigne client du 01/08/2026 : « le nom Vanilla sur le logo, je veux
   exactement la meme typographie sur tout le site ».

   COMMENT ELLE A ETE TROUVEE, et pourquoi ce n'est plus Courgette.
   Un premier tour a l'oeil avait retenu Courgette ; le client a repondu
   que ce n'etait pas identique, et il avait raison. Le second tour est
   MESURE (`scratchpad/typo2.mjs`) : le mot est decoupe dans le logo par
   sa couleur, binarise, debarrasse de son ® par etiquetage des
   composantes connexes, normalise dans une boite fixe ; chaque candidate
   subit le meme traitement et on compare par recouvrement
   (intersection / union). 37 scriptes passes au banc.
   Resultat sur les LETTRES (le mot sans son V) : Grand Hotel 25,7 ·
   Yesteryear 24,6 · Sacramento 24,3 · Pacifico 23,9 · Courgette 15,6.

   ⚠️ AUCUNE POLICE NE SERA « IDENTIQUE », ET C'EST MESURABLE.
   Le mot du logo tient dans un rapport largeur/hauteur de **1,6:1** ;
   toutes les candidates sont entre 2,3 et 3,5. La raison est son « V » :
   il est deux fois plus haut que les autres lettres, ce qu'aucune fonte
   de labeur ne fait. Le logotype est donc un LETTRAGE DESSINE, pas une
   police du commerce. Grand Hotel est ce qui s'en approche le plus sur
   les lettres — monoline, ronde, droite, « a » a un seul etage, hampes du
   « ll » droites — mais le mot « Vanilla » lui-meme doit rester l'IMAGE
   du logo partout ou il apparait comme marque.
   Playfair Display, qui venait des maquettes de reference, est retiree.

   ⚠️ TROIS CONSEQUENCES D'UN SCRIPTE LIE, a ne jamais oublier :
   1. AUCUNE CAPITALE. Un scripte en capitales est illisible : tous les
      `text-transform: uppercase` ont ete supprimes du site.
   2. AUCUN INTERLETTRAGE. `letter-spacing` casse les liaisons entre les
      lettres : tous supprimes egalement.
   3. COURGETTE N'A QU'UNE GRAISSE (400). Tout `font-weight` superieur
      declenche un faux gras synthetique, qui epaissit le trait de facon
      sale sur un scripte. La hierarchie se fait donc a la TAILLE et a la
      COULEUR, jamais a la graisse.
   Et le decoupage des titres reste MOT A MOT : lettre par lettre, chaque
   liaison serait tranchee par son masque.

   PALETTE RELEVEE AU PIXEL SUR LES TROIS MAQUETTES (`reference/`), pas a
   l'oeil. Le fond y occupe 50 % de chaque image et vaut #FFFFFE : c'est
   du BLANC, pas de la creme. Ce seul point expliquait la moitie de l'ecart
   entre le rendu et les maquettes.
   ========================================================================== */

/* -------------------------------------------------------------- JETONS */

:root {
  /* Mesures sur reference/ : part de l'image entre parentheses */
  --blanc:       #FDFCFA;   /* le fond (50 %), a peine rechauffe        */
  --gris:        #EBE2DE;   /* gris rose pale (12 %) : grands aplats    */
  --peche:       #FCE9DB;   /* peche tres pale                          */
  --beige:       #E8C5A7;   /* beige                                    */
  --peche-f:     #F2B38B;   /* peche moyenne                            */
  /* LA COULEUR SECONDAIRE VIENT DU LOGO (client, 01/08/2026 : « sur le
     logo il y a une seconde couleur, je veux l'appliquer comme couleur
     secondaire sur tout le site »). Relevee au pixel sur
     `img/logo-original.jpg` : le mot « Vanilla » est ecrit en #683C22, et
     c'est la seule autre couleur franche de l'image (1,9 % des pixels,
     apres la creme a 57 % et la tache a 33 %). Le terracotta #E28458 des
     maquettes de reference est retire. */
  --secondaire:  #683C22;   /* le scripte du logotype = L'ACCENT         */
  --ocre-logo:   #D5B48A;   /* le trait de la fleur du logo (1 %) :
                               les GRANDS aplats, jamais du texte        */
  /* ⚠️ `--brun` #935A47 (le brun rouge des maquettes) est RETIRE lui aussi.
     Il ne servait plus qu'a du texte -- mot monumental, colonne verticale,
     pied de maquette -- et une fois la couleur secondaire passee au brun du
     logotype, il ne repondait plus a rien : deux bruns voisins mais
     differents dans la meme page se lisent comme une erreur, pas comme une
     nuance. Il pointe donc sur la couleur secondaire. */
  --brun:        var(--secondaire);
  --encre:       #372E2C;   /* presque noir : le texte, 13,6:1          */

  /* Reprises du logo Vanilla, pour que l'identite tienne */
  --nude:        #E7CEB0;   /* la tache du logotype = LE VANILLE CLAIR  */
  --cacao:       #683C22;   /* le scripte du logotype                   */

  /* ⚠️ PLUS AUCUN APLAT CHOCOLAT (client, 01/08/2026) : « mets-la de la
     meme couleur que le logo, le clair vanille ». Toutes les surfaces qui
     etaient en `--brun` ou en `--cacao` -- le pied de page, l'ecran de
     chargement, les boutons, la tache du prix, les taches du decor --
     passent au vanille du logotype, et leur texte passe a l'encre.
     Le vanille choisi est la TACHE du logo (#E7CEB0) et non sa creme
     (#F6F4DD) : sur un fond blanc a #FDFCFA, la creme ne se voit pas.  */
  --vanille:     var(--nude);

  --fond:        var(--blanc);
  --encre-douce: color-mix(in srgb, var(--encre) 74%, transparent);
  --encre-tenue: color-mix(in srgb, var(--encre) 48%, transparent);
  --accent:      var(--secondaire);
  --filet-c:     color-mix(in srgb, var(--encre) 16%, transparent);
  --filet-fort:  color-mix(in srgb, var(--encre) 34%, transparent);

  /* Anciens noms encore references ailleurs, remappes une fois pour
     toutes plutot que disperses dans cinq fichiers.
     ⚠️ LA BASCULE DU TERRACOTTA SE FAIT ICI, en deux lignes et non dans
     quarante regles : `--terra` portait les APLATS, il devient l'ocre
     clair du logo ; `--terra-txt` portait le TEXTE, il devient le brun du
     logotype. Un aplat #683C22 serait un aplat chocolat, precisement ce
     que le client a fait retirer. */
  --terra:       var(--ocre-logo);
  --terra-txt:   var(--secondaire);
  --creme:       var(--blanc);
  --sable:       var(--gris);
  --terre:       var(--terra);
  --ocre:        var(--peche-f);
  --ocre-lisible:var(--terra-txt);
  --cacao-fonce: var(--brun);
  --cacao-clair: color-mix(in srgb, var(--brun) 80%, white);

  /* Formes. Regle unique : surfaces 14 px, boutons en pilule,
     IMAGES A ANGLES VIFS. */
  --r-surface: 14px;
  --r-pilule: 999px;

  --gouttiere: clamp(1.25rem, 4vw, 3.5rem);
  --large: 1360px;
  --section: clamp(2.2rem, 4vw, 3.6rem);   /* 130 px -> 58 px : sept sections
                                              a 260 px de rembourrage faisaient
                                              1 800 px de vide a elles seules  */

  --sortie: cubic-bezier(.16, 1, .3, 1);
  --ressort: cubic-bezier(.34, 1.4, .64, 1);
  --duree: .55s;

  /* La hauteur de l'entete est un jeton : le logotype, le rembourrage et
     le retrait des ancres en derivent tous. Les regler separement, c'est
     les laisser diverger. */
  /* ⚠️ `--entete-h` EST LA HAUTEUR REELLE DE LA BARRE, et elle est posee
     en dur sur `.entete__barre`. Le retrait des ancres, le rail du filet
     et le rembourrage haut du heros en derivent tous : les regler
     separement, c'est les laisser diverger. */
  /* ⚠️ Barre RAMENEE de 107 a 78 px (client, 01/08/2026 : « le header est
     trop grand en hauteur »). C'est le troisieme reglage de cette barre :
     68 -> 107 -> 78. La bonne mesure est celle qui laisse la pilule de
     navigation respirer sans que la barre mange un dixieme de l'ecran. */
  /* ⚠️ Le logotype de l'en-tete est le DETOURE (`img/logo-detoure.png`) :
     sa tache vanille a ete rendue transparente, il ne reste que le scripte
     et la fleur. C'est ce qui permet de l'agrandir sans que la barre
     grandisse avec lui -- la tache imposait une boite presque carree, donc
     une hauteur de barre proportionnelle a la largeur voulue. */
  /* ⚠️ LE LOGOTYPE GARDE SA TACHE (client : « remets le fond, tant pis »).
     Le detourage avait ete tente pour pouvoir l'agrandir sans grandir la
     barre : sa boite etant presque carree, la tache impose une hauteur
     proportionnelle a la largeur voulue. `img/logo-detoure.png` reste dans
     le dossier si la question revient. */
  --marque: clamp(48px, 4.5vw, 62px);   /* la hauteur du logotype */
  --entete-h: clamp(66px, 5.4vw, 80px);

  --rail: 26px;
  --rail-haut: calc(var(--entete-h) + 14px);
  --rail-bas: 64px;
}

/* --------------------------------------------------------- REMISE A ZERO */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--entete-h) + 1.5rem);
}
/* Pendant un glisser sur le filet, le defilement doit suivre le doigt :
   un `smooth` global rendrait la barre molle. */
html.tire { scroll-behavior: auto; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  /* Un scripte a une petite hauteur d'x et des jambages longs : il demande
     un cran de taille en plus et une interligne plus ouverte qu'un romain,
     sinon les boucles des lignes voisines se touchent. */
  font-family: 'Courgette', 'Segoe Script', cursive;
  font-size: clamp(1.06rem, .34vw + .96rem, 1.16rem);
  line-height: 1.8;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

figure, blockquote, dl, dd, h1, h2, h3, h4, p, ul, ol, table { margin: 0; }
ul, ol { padding: 0; list-style: none; }

/* AUCUN ARRONDI SUR LES IMAGES. Consigne client, tenue partout. */
img, svg, video, iframe { display: block; max-width: 100%; border-radius: 0; }
img { height: auto; }

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }

:focus-visible { outline: 2px solid var(--encre); outline-offset: 3px; border-radius: 4px; }
::selection { background: var(--terra); color: var(--encre); }

/* ---------------------------------------------------------- TYPOGRAPHIE
   Le geste bicolore des maquettes est CONSERVE -- une moitie de titre en
   encre, l'autre dans la couleur secondaire -- mais il se joue desormais
   en bas de casse : le scripte du logotype ne supporte pas les capitales.

   ⚠️ `font-weight: 400` est pose explicitement sur tout ce que le
   navigateur met en gras par defaut (h1-h4, strong, b, th). Sans ca il
   fabrique un faux gras, et un faux gras sur un scripte epaissit les
   liaisons jusqu'a les boucher. */
h1, h2, h3, h4, strong, b, th { font-weight: 400; }

.deploy, h1, h2, h3 { line-height: 1.3; }

/* Le titre de section. */
.titre-section {
  font-size: clamp(1.9rem, 4.4vw, 3.5rem);
  font-weight: 400;
  line-height: 1.3;
  text-wrap: balance;
}
/* La seconde moitie du titre passe en terracotta, comme dans les
   maquettes. Le ton est assombri pour rester lisible : le terracotta
   d'aplat ne passe que 2,5:1 sur du blanc. */
.titre-section em { font-style: normal; color: var(--terra-txt); }

.titre-caps {
  font-size: clamp(1.4rem, 2.8vw, 2.1rem);
  font-weight: 400;
  line-height: 1.3;
}

/* L'etiquette : petites capitales tres espacees, terracotta. */
.etiquette {
  font-size: .92rem;
  font-weight: 400;
  color: var(--terra-txt);
  line-height: 1.5;
}

.chapeau {
  font-size: clamp(.98rem, .4vw + .9rem, 1.06rem);
  line-height: 1.75;
  color: var(--encre-douce);
  max-width: 46ch;
  text-wrap: pretty;
}

.prix, .horaires td:last-child, .montage__total { font-variant-numeric: tabular-nums; }
.prix { font-size: 1.2rem; font-weight: 400; color: var(--terra-txt); white-space: nowrap; }

/* ------------------------------------------------------------- STRUCTURE */

.enveloppe { width: min(100% - var(--gouttiere) * 2, var(--large)); margin-inline: auto; }
.section { padding-block: var(--section); }

/* `clip` et non `hidden` : `hidden` fait de l'element un conteneur de
   defilement, ce qui fige les animations liees au defilement posees dedans
   et casse `position: sticky`. */
.coupe { overflow-x: clip; }

.bande--creme { background: var(--blanc); }
.bande--sable { background: var(--gris); }
.bande--nude { background: var(--peche); }
/* La bande autrefois chocolat est desormais VANILLE : son texte passe donc
   a l'encre, sans quoi il disparait. */
.bande--cacao { background: var(--vanille); color: var(--encre); }
.bande--cacao .etiquette { color: var(--terra-txt); }
.bande--cacao .chapeau { color: var(--encre-douce); }
.bande--cacao .prix { color: var(--terra-txt); }

/* ------------------------------------------------------------- BOUTONS */

.bouton {
  --bg: var(--vanille);
  --fg: var(--encre);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  padding: .85em 1.8em;
  border-radius: var(--r-pilule);
  background: var(--bg);
  color: var(--fg);
  font-size: .92rem;
  font-weight: 400;
  line-height: 1.3;
  white-space: nowrap;              /* un libelle ne passe jamais a la ligne */
  overflow: clip;
  isolation: isolate;
  transition: color var(--duree) var(--sortie), scale .35s var(--sortie);
}
/* Le bouton se remplit depuis le bas ; il ne bascule pas de couleur d'un
   bloc. `isolation: isolate` garde le voile en `z-index: -1` DANS le
   bouton au lieu de le laisser passer derriere la section. */
.bouton::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: var(--terra);
  transform-origin: bottom;
  scale: 1 0;
  transition: scale .5s var(--sortie);
}
.bouton:hover::before { scale: 1 1; }
.bouton:active { scale: .975; }

/* Le contour existe des le depart et ne fait que changer de couleur :
   une bordure qui APPARAIT au survol decalerait tout ce qui suit. */
.bouton--clair {
  --bg: transparent; --fg: var(--encre);
  border: 1px solid var(--filet-fort);
  padding: calc(.85em - 1px) calc(1.8em - 1px);
}
.bouton--clair::before { background: var(--peche); }
.bouton--terre { --bg: var(--terra); --fg: var(--encre); }
.bouton--terre::before { background: var(--peche-f); }
.index .bouton::before, .bande--cacao .bouton::before { background: var(--terra); }
.bande--cacao .bouton { --bg: var(--blanc); --fg: var(--encre); }
.bande--cacao .bouton--clair { --bg: transparent; --fg: var(--encre); }

.bouton .ico { transition: translate .45s var(--sortie); }
.bouton:hover .ico { translate: 3px 0; }

/* Le trait d'un lien se retrace depuis la gauche au lieu de s'allumer. */
.lien-souligne {
  position: relative;
  display: inline-block;
  padding-bottom: 2px;
  transition: color var(--duree) var(--sortie);
}
.lien-souligne::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: color-mix(in srgb, currentColor 32%, transparent);
}
.lien-souligne::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: currentColor;
  transform-origin: right; scale: 0 1;
  transition: scale .45s var(--sortie);
}
.lien-souligne:hover::after { transform-origin: left; scale: 1 1; }

/* ---------------------------------------------------------------- ICONES */

/* Un <svg> qui instancie un <use> n'a AUCUN ratio intrinseque : le viewBox
   vit sur le <symbol>. Sans `aspect-ratio` il retombe sur la hauteur par
   defaut d'un remplace, 150 px, et deforme tout ce qui l'entoure. */
.ico {
  width: 1em; height: 1em; aspect-ratio: 1;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  flex: none;
}

/* ==========================================================================
   L'ENTETE
   --------------------------------------------------------------------------
   Reprise de la disposition des references : les liens a gauche, le
   logotype AU CENTRE dans sa tache, les contacts a droite, et un filet
   horizontal qui traverse toute la barre en s'interrompant sur le logo.
   ========================================================================== */

.entete {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
}

/* La coiffe ne se leve qu'une fois la page defilee : sans elle le contenu
   passe AU TRAVERS de la barre et les titres se font couper.
   `z-index: -1` la place derriere les enfants tout en la gardant au-dessus
   de la page ; sans cela un pseudo-element positionne se peint APRES les
   enfants non positionnes et masquerait le logo. */
.entete::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: var(--fond);
  border-bottom: 1px solid var(--filet-c);
}
.filet-ok .entete::before {
  opacity: 0;
  animation: coiffe linear both;
  animation-timeline: scroll(root block);
  animation-range: 0px 90px;
}
@keyframes coiffe { to { opacity: 1; } }

/* ⚠️ TROIS COLONNES SYMETRIQUES `1fr auto 1fr`, jamais `auto 1fr auto`.
   Le logo est plus large que les outils : avec des colonnes laterales de
   largeurs differentes, la pilule de navigation se centre sur l'espace
   RESTANT et non sur la page. Ici les deux cotes pesent pareil, elle tombe
   pile au milieu. (Regle reprise de Dolce Coffee, ou elle avait coute
   39 px de decalage.) */
.entete__barre {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(.6rem, 1.6vw, 1.4rem);
  height: var(--entete-h);
}

/* Le logotype, A GAUCHE et sans habillage : l'image porte deja sa tache. */
/* `z-index` : il deborde de la barre, il doit passer AU-DESSUS de la coiffe
   qui se leve au defilement, pas dessous. */
.marque { position: relative; z-index: 1; display: inline-flex; align-items: center; justify-self: start; transition: scale .5s var(--ressort); }
.marque img { height: var(--marque); width: auto; }
.marque:hover { scale: 1.05; }

/* LA PILULE DE NAVIGATION
   Les liens sont poses sur un aplat CLAIR (demande client du 01/08/2026 :
   la barre etait en brun fonce, elle passe au vanille du logotype), en
   pilule comme tous les elements interactifs du site. */
.entete__nav {
  display: flex; justify-content: center; align-items: center;
  gap: clamp(1px, .3vw, 4px);
  padding: 5px;
  background: var(--vanille);
  border-radius: var(--r-pilule);
}
/* L'aplat etant clair, les liens sont a l'encre. A l'interieur d'une boite
   un souligne se lit mal : le survol prend un voile sombre, la section en
   cours l'aplat plein de la couleur secondaire. */
/* ⚠️ TOUT L'EN-TETE EST EN `--secondaire`, JAMAIS EN ENCRE (client,
   01/08/2026 : « dans le header le texte est noir, je le veux brun fonce
   comme le texte Vanilla sur le logo »). Le brun passe 6,2:1 sur le
   vanille de la pilule et 9,1:1 sur le blanc : les deux sont largement
   au-dessus du minimum. */
.entete__nav a {
  padding: .26em clamp(.6rem, .95vw, 1rem);
  font-size: .96rem;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--secondaire);
  border-radius: var(--r-pilule);
  transition: color .22s var(--sortie), background-color .25s var(--sortie);
}
/* Le survol se joue DANS la meme couleur : un voile brun qui se pose, puis
   l'aplat plein pour la section en cours. Aucune bordure n'apparait, aucun
   ton etranger n'entre dans la barre. */
.entete__nav a:hover { background: color-mix(in srgb, var(--secondaire) 16%, transparent); }
.entete__nav a[aria-current] { color: var(--vanille); background: var(--secondaire); }

/* LES OUTILS, a droite : le telephone garde son numero lisible -- c'est le
   premier geste d'un client de creperie -- puis TROIS BULLES CLAIRES pour
   les reseaux, tout a droite (demande client du 01/08/2026). */
.entete__outils { display: flex; align-items: center; justify-self: end; gap: .4rem; }
/* ⚠️ LE MEME SURVOL QUE LES BOUTONS (client : « le hover du bouton
   "composer la vôtre", je veux pareil pour le bouton téléphone, facebook,
   insta et tiktok »). Ce n'est donc plus un changement de fond : c'est un
   VOILE QUI MONTE DEPUIS LE BAS, exactement comme `.bouton::before`.
   `isolation: isolate` garde ce voile en `z-index: -1` DANS la pastille,
   au lieu de le laisser passer derriere la barre. */
.outil {
  position: relative;
  display: grid; place-items: center;
  width: 42px; height: 42px;
  border-radius: var(--r-pilule);
  background: var(--vanille);
  color: var(--secondaire);
  overflow: clip;
  isolation: isolate;
  transition: color var(--duree) var(--sortie), scale .35s var(--sortie);
}
.outil::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: var(--terra);
  transform-origin: bottom;
  scale: 1 0;
  transition: scale .5s var(--sortie);
}
.outil:hover::before { scale: 1 1; }
.outil:active { scale: .975; }
.outil .ico { font-size: 1.2rem; }
.outil--tel {
  width: auto; grid-auto-flow: column; gap: .5rem;
  padding-inline: 1rem;
  font-size: .96rem; white-space: nowrap;
}
/* Les trois bulles de reseaux forment un groupe, colle a droite. */
.entete__reseaux { display: flex; align-items: center; gap: .4rem; margin-left: .3rem; }

.burger { display: none; }

@media (max-width: 1080px) {
  .entete__nav { display: none; }
  .entete__barre { grid-template-columns: auto 1fr; }
  .entete .burger { display: grid; }
  .outil--tel span { display: none; }
  .outil--tel { width: 46px; padding-inline: 0; }
}
@media (max-width: 720px) {
  /* Trois bulles de reseaux + le telephone + le burger ne tiennent pas :
     les reseaux sont deja dans le voile de navigation. */
  .entete__reseaux { display: none; }
}

/* Le voile de navigation, ouvert depuis la barre */
.voile__pied a, .voile__pied span { text-transform: none; }
.voile {
  position: fixed;
  inset: 0;
  z-index: 39;
  background: var(--creme);
  display: grid;
  align-content: center;
  justify-items: start;
  gap: .6rem;
  padding: 5rem var(--gouttiere) 3rem;
  font-size: clamp(2rem, 9vw, 3.4rem);
  line-height: 1.3;
  translate: 0 -101%;
  visibility: hidden;
  transition: translate .6s var(--sortie), visibility .6s;
}
.voile[data-ouvert='oui'] { translate: 0 0; visibility: visible; }
.voile a { transition: color var(--duree) var(--sortie), translate var(--duree) var(--sortie); }
.voile a:hover { color: var(--ocre-lisible); translate: .5rem 0; }
.voile__pied {
  margin-top: 1.4rem; display: grid; gap: .4rem;
  font-size: 1.05rem; color: var(--encre-douce);
}

/* ==========================================================================
   ECRAN DE CHARGEMENT
   DEUX TEMPS, aucune barre de progression :
   1. le logotype se pose, ECRIT EN BLANC, et le CHOCOLAT le remplit de bas
      en haut au niveau exact du liquide ;
   2. le rideau balaye vers le haut en laissant couler ses gouttes.

   ⚠️ LE SENS DU REMPLISSAGE A ETE INVERSE (client, 01/08/2026 : « il faut
   que par défaut le texte soit blanc, puis rempli de chocolat brun sombre,
   pas l'inverse »). C'est donc le logotype CREME qui est en fond et le
   logotype CHOCOLAT qui est decoupe par `inset(var(--n) 0 0 0)` : la coupe
   descend, donc le chocolat monte dans les lettres.
   Une premiere version, encore avant, faisait monter du chocolat sur un
   scripte deja chocolat : invisible. Le piege reste vrai -- verifier le
   CONTRASTE de l'effet, pas seulement sa mecanique.

   ⚠️ IL N'Y A PLUS QU'UN SEUL COULISSAGE. La tache de couleur qui
   s'etendait jusqu'a couvrir la fenetre est supprimee, ainsi que le
   rectangle qui comblait ses echancrures.
   ========================================================================== */

@property --n { syntax: '<percentage>'; inherits: true; initial-value: 92%; }

.prechargement { display: none; }
.js-charge, .js-charge body { overflow: hidden; }

.js-charge .prechargement {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-content: center;
  justify-items: center;
  background: var(--creme);
  overflow: clip;
  transition: translate 1s cubic-bezier(.76, 0, .24, 1);
}

/* ⚠️ LE RECTANGLE ET LA TACHE SONT SUPPRIMES (client, 01/08/2026).
   Ils formaient le deuxieme temps de l'ecran : une tache de couleur qui
   s'etendait jusqu'a couvrir la fenetre, doublee d'un rectangle plein pour
   en combler les echancrures. Le client n'en veut qu'un seul, le rideau
   qui balaye vers le haut. Il reste donc : le logotype qui se remplit, puis
   le rideau. La regle `.prechargement.plein` n'a plus rien a piloter, mais
   la classe est toujours posee par le script -- elle ne fait plus rien. */


.prechargement__scene {
  position: relative;
  z-index: 1;
  width: clamp(200px, 34vw, 340px);
  aspect-ratio: 640 / 605;
  --n: 92%;
  animation: pre-pose .9s var(--ressort) both,
             pre-monte 1.5s cubic-bezier(.55, .05, .35, 1) .75s both;
}
.prechargement__scene > * { position: absolute; inset: 0; }
.prechargement__scene img { width: 100%; height: 100%; object-fit: contain; }

/* ⚠️ `.prechargement__creme` PORTE MAINTENANT LE LOGOTYPE CHOCOLAT (le nom
   de la classe est reste, pour ne pas casser le script). C'est lui qui est
   decoupe : sous le trait il est visible, au-dessus c'est le logotype creme
   du fond qui reste. La coupe descend, donc le chocolat monte. */
.prechargement__creme { clip-path: inset(var(--n) 0 0 0); }

/* La course est calee sur la bande qu'occupe REELLEMENT le scripte dans
   l'image (92 % a 33 % de la hauteur). De 100 % a 0 %, la moitie du temps
   se joue au-dessus et en dessous des lettres. */
@keyframes pre-monte { from { --n: 92%; } to { --n: 33%; } }
@keyframes pre-pose {
  from { opacity: 0; scale: .84; rotate: -6deg; }
  to   { opacity: 1; scale: 1; rotate: 0deg; }
}

/* Les gouttes sont posees JUSTE SOUS le bord bas du rideau, donc hors de
   l'ecran. Elles n'apparaissent qu'en trainant derriere lui pendant qu'il
   se leve : rien ne surgit au milieu de rien. */
.prechargement__gouttes {
  position: absolute;
  top: 100%; left: 0; right: 0;
  height: clamp(44px, 6vw, 88px);
  width: 100%;
}
.prechargement__gouttes path { fill: var(--creme); }

.js-charge .prechargement.parti { translate: 0 -101%; }

/* ==========================================================================
   ENTREE EN SCENE
   Rien n'est masque hors de `.js` : sans JavaScript, tout s'affiche.
   ========================================================================== */

/* CINQ GESTES DIFFERENTS, PAS CINQ FOIS LE MEME FONDU (client, 01/08/2026 :
   « après le loading, créer des animations d'entrées différentes pour le
   logo, le header, l'image 1, le titre, le sous-titre »).
   Chacun a son mouvement propre, et ils s'enchainent sans jamais laisser
   la composition a moitie vide plus d'une demi-seconde :

     1. LE LOGOTYPE se pose comme un TAMPON      -- il tombe en tournant ;
     2. LA PILULE de navigation S'OUVRE          -- elle s'ecarte du centre ;
     3. LES OUTILS arrivent DE LA DROITE         -- un par un, decales ;
     4. LA PHOTO se DECADRE                      -- elle monte en se
        desagrandissant, le mouvement inverse des autres ;
     5. LE TITRE se leve MOT A MOT sous son masque (voir `.mot`) ;
     6. LE SOUS-TITRE et les boutons SUIVENT en montant.                */
.js-charge .marque,
.js-charge .entete__nav,
.js-charge .entete__outils { opacity: 0; }

/* ⚠️ MINUTAGE RALENTI (client, 01/08/2026 : « les animations d'entrée
   s'affichent trop vite, pas le temps de les voir »). Les durees sont
   multipliees par ~1,6 et les decalages par ~2. La regle « jamais plus
   d'une demi-seconde avec la moitie de la composition invisible » tient
   quand meme : les pieces arrivent EN CONTINU, il n'y a aucun trou dans
   la sequence -- le logotype a 0,2 s, la pilule a 0,75 s, les outils de
   1,0 a 1,5 s, et le heros compose par-dessus a partir de 0,7 s. */
.entre .marque       { animation: e-tampon 1.3s var(--ressort) .2s both; }
.entre .entete__nav  { animation: e-ouvre 1.15s var(--sortie) .75s both; }
.entre .entete__outils > *,
.entre .entete__reseaux > * { animation: e-droite .9s var(--sortie) both; }
.entre .entete__outils { opacity: 1; }
/* Les outils tombent l'un apres l'autre, de la droite vers la gauche. */
.entre .entete__outils > :nth-child(1) { animation-delay: 1.02s; }
.entre .entete__outils > :nth-child(2) { animation-delay: 1.14s; }
.entre .entete__reseaux > :nth-child(1) { animation-delay: 1.14s; }
.entre .entete__reseaux > :nth-child(2) { animation-delay: 1.28s; }
.entre .entete__reseaux > :nth-child(3) { animation-delay: 1.42s; }

@keyframes e-tampon {
  from { opacity: 0; scale: .5; rotate: -22deg; translate: 0 -14px; }
  to   { opacity: 1; scale: 1; rotate: 0deg; translate: 0 0; }
}
/* La pilule s'ouvre : elle part d'un point au centre et s'ecarte. Le
   contre-etirement du contenu evite que les libelles soient ecrases
   pendant la course. */
@keyframes e-ouvre {
  from { opacity: 0; scale: .04 .6; }
  to   { opacity: 1; scale: 1 1; }
}
@keyframes e-droite { from { opacity: 0; translate: 22px 0; scale: .8; } to { opacity: 1; translate: 0 0; scale: 1; } }

/* Le heros est pilote par `data-vu` et non par `.entre` : une TRANSITION
   survit au retrait de la classe, une `animation` non, et le titre
   resterait coince sous son masque.

   Les retards sont SERRES. La premiere version etalait l'entree sur deux
   secondes : le titre restait seul au-dessus d'un grand vide pendant
   presque une seconde, et cet etat intermediaire se lit comme un defaut
   de mise en page, pas comme une animation. Toute la composition tient
   maintenant en 0,8 s. */
.js .hero__chapeau,
.js .hero__actions,
.js .hero__etat {
  opacity: 0;
  translate: 0 34px;
  transition: opacity 1s var(--sortie) var(--d, 0ms),
              translate 1.15s var(--sortie) var(--d, 0ms);
}
.js .hero__chapeau { --d: 620ms; }
.js .hero__actions { --d: 820ms; }
.js .hero__etat    { --d: 940ms; }
/* L'etiquette au-dessus du titre glisse depuis la GAUCHE : encore un geste
   different, et c'est la premiere chose qui se pose. */
.js .hero__corps .etiquette {
  opacity: 0; translate: -26px 0;
  transition: opacity .85s var(--sortie) 250ms, translate 1s var(--sortie) 250ms;
}
.js [data-vu='oui'] .hero__corps .etiquette { opacity: 1; translate: 0 0; }
.js [data-vu='oui'] .hero__chapeau,
.js [data-vu='oui'] .hero__actions,
.js [data-vu='oui'] .hero__etat { opacity: 1; translate: 0 0; }

/* ==========================================================================
   LE FILET COULANT (la barre de defilement)
   Pilote entierement par `animation-timeline: scroll()` : aucune ecoute de
   l'evenement `scroll`. La barre native n'est masquee QUE si le navigateur
   sait animer sur le defilement, sinon une barre invisible et immobile
   serait un piege.

   ⚠️ COULEUR ET FORME REGLEES PAR LE CLIENT (01/08/2026) : « mets-la de
   couleur brune claire, et PAS DE DEGRADE de couleur, et pour la boule,
   légèrement plus sombre, et supprime à la fin de la scrollbar l'élément
   et l'animation. » Le filet est donc un APLAT uni d'ocre du logotype, la
   goutte est du meme ocre assombri d'un tiers de brun, et la crepe qui
   gonflait en fin de course -- ainsi que ses trois eclats -- sont partis.

   ⚠️ CE QUE CA COUTE, ET C'EST ASSUME : l'ocre #D5B48A sur le fond blanc
   #FDFCFA ne fait que 1,9:1. Le filet est donc discret au point d'etre
   difficile a reperer avant qu'on le cherche. C'est la demande, mais si
   quelqu'un signale un jour « je ne trouve plus la barre », c'est ici.
   ========================================================================== */

.filet { display: none; }
.filet-ok { scrollbar-width: none; }
.filet-ok::-webkit-scrollbar { width: 0; height: 0; }

@media (pointer: fine) {
  /* La zone de prise fait 26 px pour qu'on puisse l'attraper ; le filet
     lui-meme n'en fait que 7 et vit en son milieu. */
  .filet-ok .filet {
    display: block;
    position: fixed;
    top: var(--rail-haut);
    bottom: var(--rail-bas);
    right: 0;
    width: var(--rail);
    z-index: 45;
    cursor: grab;
    --course: calc(100vh - var(--rail-haut) - var(--rail-bas));
  }
  .filet-ok .filet:active { cursor: grabbing; }

  .filet::before {
    content: '';
    position: absolute;
    top: 0; bottom: 0; left: 50%;
    width: 3px; margin-left: -1.5px;
    border-radius: var(--r-pilule);
    background: color-mix(in srgb, var(--encre) 9%, transparent);
  }

  /* ⚠️ MEME EPAISSEUR QUE LE RAIL (client : « la barre verticale fill est
     trop épaisse, garde-la fine comme la barre empty »). Elle faisait 7 px
     contre 3 pour le rail : la partie parcourue paraissait deux fois plus
     grosse que la partie restante, ce qui se lit comme deux barres et non
     comme une seule qui se remplit. Et UN APLAT, jamais un degrade. */
  .filet__coulee {
    position: absolute;
    top: 0; bottom: 0; left: 50%;
    width: 3px; margin-left: -1.5px;
    border-radius: var(--r-pilule);
    background: var(--ocre-logo);
    transform-origin: top;
    scale: 1 0;
    animation: coule linear both;
    animation-timeline: scroll(root block);
  }

  .filet__goutte {
    position: absolute;
    top: 0; left: 50%;
    width: 19px; height: 24px;
    margin-left: -9.5px;
    animation: descend linear both;
    animation-timeline: scroll(root block);
  }
  /* La boule, « légèrement plus sombre » que le filet : le meme ocre,
     assombri d'un tiers de brun. Assez pour la distinguer du trait,
     assez peu pour rester la meme matiere. */
  /* ⚠️ LA BOULE NE SE DEFORME PLUS (client : « le cercle de la scrollbar
     s'aplatit au fur et a mesure du scroll, a garder fixe »). Elle etait
     etiree par `etire` (0,78 x 1,85) au fil du defilement : la goutte
     s'allongeait jusqu'a devenir un trait. Elle garde desormais sa forme
     du debut a la fin, elle ne fait que descendre. */
  .filet__goutte span {
    display: block; width: 100%; height: 100%;
    border-radius: 50%;
    background: color-mix(in srgb, var(--secondaire) 32%, var(--ocre-logo));
  }

  /* ⚠️ LA CREPE DE FIN DE COURSE ET SES TROIS ECLATS SONT SUPPRIMES
     (client, 01/08/2026). Ils gonflaient et eclaboussaient dans les
     derniers 12 % du defilement. Leurs balises restent dans le HTML mais
     n'ont plus aucune regle : rien ne s'affiche, et les remettre ne
     demande que de reecrire ce bloc. */
}

@keyframes coule   { to { scale: 1 1; } }
@keyframes descend { to { translate: 0 calc(var(--course) - 22px); } }

/* ------------------------------------------- LE CREDIT DU PIED DE PAGE
   « Fait avec ♥ par Core Agency ». Le coeur est un SVG inline, jamais un
   emoji : consigne de marque tenue sur tous les sites. */
.pied__bas svg.credit__coeur {
  display: inline-block;
  width: .95em; height: .95em;
  vertical-align: -.14em;
  fill: var(--ocre-logo);
  stroke: none;
}
.credit__agence { font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.credit__agence:hover { color: var(--secondaire); }
@media (prefers-reduced-motion: no-preference) {
  /* Deux battements rapproches puis une pause : c'est le rythme d'un vrai
     coeur. Une pulsation reguliere se lit comme un clignotement. */
  .credit__coeur { animation: battement 2.4s ease-in-out infinite; }
  @keyframes battement {
    0%, 100% { scale: 1; }
    12% { scale: 1.22; }
    24% { scale: 1; }
    36% { scale: 1.14; }
    48% { scale: 1; }
  }
}

/* Sur un ecran tactile ou en mouvement reduit, la barre native reprend sa
   place : une barre invisible qui ne bouge pas serait un piege. */
@media (pointer: coarse) {
  .filet-ok { scrollbar-width: auto; }
  .filet-ok::-webkit-scrollbar { width: initial; }
}

/* ------------------------------------------------------------ MOUVEMENT */

/* Amplitude : une passe a 20 px avait ete jugee « visuellement, aucun
   changement ». Il faut 40 a 100 px de course pour que le geste se lise. */
[data-reveler] { --d: 0ms; }

/* Le geste bicolore survit au decoupage mot a mot : voir `data-em` dans
   js/commun.js. Hors requete de media, sinon le titre perd sa couleur
   pour qui a demande moins de mouvement. */
.mot--em { color: var(--terra-txt); }

/* ==========================================================================
   LES APPARITIONS AU DEFILEMENT
   --------------------------------------------------------------------------
   Chaque enfant d'un `[data-reveler]` recoit un `data-anim` selon son ROLE
   (voir `VU.apparitions` dans js/commun.js) : une image ne doit pas arriver
   comme un titre, sinon toute la section se lit comme un seul bloc qui
   monte. Cinq gestes, tous en `translate` / `scale` / `opacity` -- les
   trois seules proprietes qui tournent sur le compositeur, donc sans mise
   en page ni redessin.

   ⚠️ ELLES REJOUENT. `data-vu` est POSE a l'entree et RETIRE a la sortie
   complete (js/commun.js) : en remontant, le visiteur revoit les memes
   gestes. C'est aussi pour ca que ce sont des TRANSITIONS et non des
   `animation` -- une animation ne se rejoue pas au simple retrait d'une
   classe, il faudrait la relancer a la main.

   ⚠️ La duree est volontairement LONGUE (.8 a 1 s) et l'amorti tres doux :
   une apparition rapide se lit comme un clignotement, pas comme un geste.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  [data-reveler] > * {
    opacity: 0;
    transition: opacity .85s var(--sortie) var(--d),
                translate .95s var(--sortie) var(--d),
                scale .95s var(--sortie) var(--d);
  }
  [data-reveler] > [data-anim='bas']     { translate: 0 44px; }
  [data-reveler] > [data-anim='gauche']  { translate: -46px 0; }
  [data-reveler] > [data-anim='droite']  { translate: 46px 0; }
  [data-reveler] > [data-anim='zoom']    { scale: 1.06; translate: 0 26px; }
  [data-reveler] > [data-anim='echelle'] { scale: .88; }

  [data-reveler][data-vu='oui'] > * { opacity: 1; translate: 0 0; scale: 1; }

  .mot {
    display: inline-block;
    overflow: clip;
    /* pose plus bas : `.mot--em` doit vivre hors de la requete de media */
    vertical-align: bottom;
    padding-bottom: .22em;      /* reserve pour les jambages du scripte */
    margin-bottom: -.22em;
  }
  .mot > span {
    display: inline-block;
    translate: 0 108%;
    transition: translate 1.15s var(--sortie) var(--d);
  }
  [data-vu='oui'] .mot > span { translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .filet { display: none !important; }
  .filet-ok { scrollbar-width: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --------------------------------------------------------------- L'APPEL */

.appel { position: relative; overflow: clip; background: var(--creme); padding-block: var(--section); text-align: center; }
.appel > .enveloppe { position: relative; z-index: 1; }
.appel__phrase {
  font-size: clamp(1.7rem, 4.6vw, 3.4rem);
  max-width: 24ch;
  font-weight: 400;
  line-height: 1.3;
  max-width: 18ch;
  margin: 0 auto 1.6rem;
}
.appel__phrase em { font-style: normal; color: var(--terra-txt); }
.appel__actions { display: flex; flex-wrap: wrap; gap: .8rem; justify-content: center; }

/* --------------------------------------------------------------- LE PIED */

/* Le pied etait la plus grande surface chocolat du site. Il est desormais
   en vanille, donc tout ce qu'il contenait en creme passe a l'encre. */
/* ⚠️ FONDS INVERSES AVEC « NOUS JOINDRE » (client, 02/08/2026). Le pied
   passe au brun du logotype, le formulaire au vanille. Tout ce que le pied
   portait en encre bascule donc au clair : sur #683C22, l'encre #372E2C ne
   fait que 1,5:1. */
.pied {
  background: var(--secondaire);
  color: var(--vanille);
  /* ⚠️ COMPACTE AU MAXIMUM (client, 01/08/2026 : « le footer, compacte-le
     le plus possible, la il est trop grand »). Il faisait 537 px pour
     quatre listes de liens courts. Rembourrage, gouttieres, taille du
     logo et retrait du bandeau legal sont tous divises. */
  padding-block: clamp(1.6rem, 2.6vw, 2.4rem) 1.1rem;
  /* L'interligne de 1,8 du corps de texte, sur quatre listes de liens,
     coutait a lui seul une centaine de pixels. */
  line-height: 1.45;
}
.pied a { color: inherit; }
/* ⚠️ MESURE, pas estimation : `--terra-txt` ne passe que 3,3:1 sur le
   vanille -- il est calibre pour le BLANC. L'accent du pied est donc le
   cacao du logotype (6,2:1), qui n'est pas un aplat chocolat mais la
   couleur du scripte, posee sur la couleur de sa tache : exactement le
   couple du logo. */
.pied .etiquette { color: var(--ocre-logo); }

.pied__grille {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: .7rem clamp(1.2rem, 2.6vw, 2.4rem);
  align-items: start;
}
.pied__colonne { display: grid; gap: .35rem; align-content: start; }
.pied__colonne ul { display: grid; gap: .1rem; font-size: .98rem; }
.pied__colonne a { color: color-mix(in srgb, var(--vanille) 88%, transparent); transition: color var(--duree) var(--sortie); }
.pied__colonne a:hover { color: var(--blanc); }
.pied__logo img { height: 58px; width: auto; }
.pied__phrase { max-width: 34ch; }

.pied__bas {
  margin-top: 1.1rem;
  padding-top: .8rem;
  border-top: 1px solid color-mix(in srgb, var(--vanille) 24%, transparent);
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: .8rem 2rem;
  font-size: .95rem;
  color: color-mix(in srgb, var(--vanille) 74%, transparent);
}

@media (max-width: 880px) {
  .pied__grille { grid-template-columns: 1fr 1fr; }
  .pied__colonne--marque { grid-column: 1 / -1; }
}
/* En une seule colonne le pied faisait 1 200 px sur telephone, soit un
   cinquieme du defilement pour trois listes de liens courts. Il reste sur
   deux colonnes ; seule l'adresse e-mail a besoin de pouvoir se couper. */
@media (max-width: 520px) {
  .pied__grille { gap: 1.6rem 1.2rem; }
  .pied__colonne ul { font-size: .95rem; }
  .pied__colonne a { overflow-wrap: anywhere; }
}

/* --------------------------------------------------------------- DIVERS */

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

/* ⚠️ LE LIEN « ALLER AU CONTENU » EST SUPPRIME (client, 01/08/2026).
   C'etait un lien d'evitement d'accessibilite : hors de l'ecran, il
   n'apparaissait qu'au premier appui sur Tab, pour permettre a une
   navigation au clavier de sauter l'en-tete. Il est retire des trois
   pages a la demande du client. La cible `#contenu` reste en place, donc
   le remettre est une ligne par page si la question revient. */

/* ==========================================================================
   PERFORMANCE
   --------------------------------------------------------------------------
   Client : « optimise à mort le site, il ne doit pas ramer. » Quatre leviers,
   tous mesurables, aucun qui change le rendu.
   ========================================================================== */

/* 1. LES SECTIONS HORS DE L'ECRAN NE SONT PAS MISES EN PAGE.
   `content-visibility: auto` dit au navigateur de sauter la mise en page et
   le dessin de ce qui n'est pas visible. Sur une page de 8 000 px avec dix
   sections, des taches en `clip-path`, des vagues SVG et des animations
   liees au defilement, c'est le seul levier qui compte vraiment.
   ⚠️ `contain-intrinsic-size` EST OBLIGATOIRE : sans lui, une section non
   rendue vaut 0 px de haut, la barre de defilement saute a chaque section
   qui entre a l'ecran, et la page devient impossible a parcourir. La valeur
   est une ESTIMATION -- elle n'a pas besoin d'etre juste, seulement d'etre
   du bon ordre de grandeur.
   ⚠️ Le HEROS en est EXCLU : il est visible au chargement, l'exclure evite
   un calcul inutile et garantit qu'il ne clignote jamais. */
main > section:not(.scene-hero) {
  content-visibility: auto;
  contain-intrinsic-size: auto 620px;
}

/* 2. LES ANIMATIONS TOURNENT SUR LE COMPOSITEUR.
   `translate`, `scale` et `opacity` ne declenchent ni mise en page ni
   redessin. Les taches du decor et les ondes n'animent QUE ca -- c'est deja
   le cas partout, cette regle ne fait que le garantir aux elements qui
   respirent en boucle. */
.tache, .vague svg, .marque { will-change: transform; }

/* 3. LES IMAGES NE FONT PLUS SAUTER LA PAGE.
   Chaque `<img>` du site porte `width`/`height` ou un `aspect-ratio` : le
   navigateur reserve la place avant que l'image arrive. Cette regle est le
   filet pour celles qui seraient ajoutees plus tard sans y penser. */
img { background-color: color-mix(in srgb, var(--gris) 60%, transparent); }
img[src] { background-color: transparent; }

/* 4. AUCUNE ANIMATION POUR QUI N'EN VEUT PAS.
   Deja tenu partout par `prefers-reduced-motion`. Rappel ici pour que la
   regle se lise au meme endroit que le reste des choix de performance. */
/* ==========================================================================
   PASSE DU 02/08/2026 (nuit) — corrections mesurees
   ========================================================================== */

/* 1. LE RIDEAU DU CHARGEMENT PART EN BRUN.
   ⚠️ Il reste CREME pendant que le logotype se remplit -- sinon le
   chocolat qui monte dans les lettres serait invisible sur du chocolat.
   Il ne bascule au brun QU'AU MOMENT DE PARTIR : c'est un panneau brun qui
   balaye vers le haut, pas un fond qui change sous nos yeux. La bascule
   dure 0,25 s et la course 1 s, donc on ne voit jamais l'entre-deux. */
.js-charge .prechargement.parti { background: var(--secondaire); }
.js-charge .prechargement { transition: translate 1s cubic-bezier(.76, 0, .24, 1), background-color .25s linear; }
.prechargement.parti .prechargement__scene { opacity: 0; transition: opacity .3s linear; }

/* 2. La vitesse des ondes se regle dans `decor.css` : une regle de meme
   specificite ecrite ici serait ecrasee par celle de decor.css, chargee
   apres. Piege paye le 02/08/2026. */

/* 3. LES PIECES DU HEROS QUI N'AVAIENT AUCUNE ENTREE.
   La box, les deux paves et la colonne verticale apparaissaient d'un coup
   pendant que tout le reste se composait. Chacun a maintenant son geste et
   son rang dans la sequence. */
.js .hero__socle,
.js .hero__pave,
.js .hero__cote {
  opacity: 0;
  transition: opacity .9s var(--sortie) var(--d, 0ms),
              translate 1s var(--sortie) var(--d, 0ms),
              scale 1s var(--sortie) var(--d, 0ms);
}
.js .hero__socle { --d: 520ms; scale: .94; }
.js .hero__pave--hg { --d: 900ms; translate: -20px -14px; }
.js .hero__pave--bd { --d: 1020ms; translate: 20px 14px; }
.js .hero__cote { --d: 1140ms; translate: 26px 0; }
.js [data-vu='oui'] .hero__socle,
.js [data-vu='oui'] .hero__pave,
.js [data-vu='oui'] .hero__cote { opacity: 1; translate: 0 0; scale: 1; }