/* =========================================================================
   ESDI : page d'accueil, en-tête et pied de page.

   Dérivée d'un prototype unique, pour que toutes les sections partagent la
   même échelle, les mêmes couleurs et le même rythme.
   Charte : turquoise #3fbecc, bleu #1b5aa8, Inter. Logo et favicon officiels.

   Partis pris : aucune carte, aucun surtitre, aucun texte en dégradé, aucun
   numéro de section. Un seul aplat de couleur (ESDI Manager). Une seule
   animation d'entrée (le hero), qui part d'un état visible. Les vraies
   captures des sites livrés remplacent le faux terminal de l'ancien site.

   Mouvement : menu mobile en transitions (220 ms ouverture, 160 ms fermeture,
   liens décalés de 30 ms), ombre d'en-tête pilotée par le défilement en CSS
   pur, fondu croisé de la bascule de thème. Rien d'autre ne bouge.

   Cette feuille est chargée APRÈS esdi.css : ses règles l'emportent.
   ========================================================================= */

/* =========================================================================
   ESDI - page d'accueil
   Charte : turquoise #3fbecc, bleu #1b5aa8, Inter. Logo et favicon officiels.
   Un seul aplat de couleur (ESDI Manager), une seule animation d'entrée (hero).
   Aucune carte, aucun surtitre, aucun texte en dégradé.
   ========================================================================= */

:root {
  --bleu:        #1b5aa8;
  --bleu-fonce:  #164d8f;
  --bleu-nuit:   #0f3a6e;
  --turquoise:   #3fbecc;

  /* Neutres tirés vers le bleu : air froid, montagne, pas un gris d'imprimante. */
  --fond:        #ffffff;
  --surface:     #f4f7fa;
  --encre:       #0b1526;
  --encre-2:     #4a6079;
  --encre-3:     #5b7290;
  --filet:       rgb(11 21 38 / .10);
  --filet-fort:  rgb(11 21 38 / .18);

  --ombre-1: 0 1px 2px rgb(11 21 38 / .06), 0 6px 20px -10px rgb(11 21 38 / .18);
  --ombre-2: 0 2px 6px rgb(11 21 38 / .08), 0 28px 60px -24px rgb(11 21 38 / .35);

  --sortie: cubic-bezier(.23, 1, .32, 1);
  --mesure: 1200px;
  --marge:  clamp(1.25rem, 4.5vw, 3rem);
}
html.esdi-sombre {
  --fond:        #0e141d;
  --surface:     #151d29;
  --encre:       #eaf0f7;
  --encre-2:     #9fb1c6;
  --encre-3:     #7a8ca3;
  --filet:       rgb(255 255 255 / .10);
  --filet-fort:  rgb(255 255 255 / .18);
  --ombre-1: 0 1px 2px rgb(0 0 0 / .3), 0 6px 20px -10px rgb(0 0 0 / .5);
  --ombre-2: 0 2px 6px rgb(0 0 0 / .35), 0 28px 60px -24px rgb(0 0 0 / .7);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
/* WordPress peint le fond du corps depuis sa propre palette (theme.json), avec
   une regle « body{background-color:var(--wp--preset--color--base)} » chargee
   apres celle-ci. On aligne donc SA variable sur notre jeton, plutot que de
   lutter a coups de !important : le fond suit alors le theme clair ou sombre. */
:root { --wp--preset--color--base: var(--fond); }
body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  font: 400 1rem/1.6 Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-feature-settings: "cv11";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Surfaces du navigateur : sélection, focus, barre de défilement.
   Ce sont les pièces qu'on n'a pas dessinées et qui trahissent une page assemblée. */
::selection { background: rgb(63 190 204 / .28); color: var(--encre); }
:focus-visible { outline: 2px solid var(--turquoise); outline-offset: 3px; border-radius: 4px; }
html { scrollbar-color: var(--encre-3) transparent; scrollbar-width: thin; }

h1, h2, h3 {
  margin: 0;
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.05;
  text-wrap: balance;
}
h1 { font-size: clamp(2.5rem, 6.4vw, 4.75rem); letter-spacing: -.04em; }
h2 { font-size: clamp(1.875rem, 3.8vw, 2.75rem); }
h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); letter-spacing: -.02em; line-height: 1.2; }
p  { margin: 0; }
a  { color: inherit; }
img { display: block; max-width: 100%; height: auto; }
ul { margin: 0; padding: 0; list-style: none; }

.lisible { max-width: var(--mesure); margin-inline: auto; padding-inline: var(--marge); }
.prose   { max-width: 36rem; color: var(--encre-2); font-size: 1.0625rem; line-height: 1.65; }
.prose strong { color: var(--encre); font-weight: 600; }

/* Icônes Lucide : la balise <i> est remplacée par un <svg> qui hérite des classes. */
.ic { width: 20px; height: 20px; flex: none; stroke-width: 1.75; }
.ic-t { color: var(--turquoise); }

/* ------------------------------------------------------------ Boutons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  height: 3rem; padding: 0 1.5rem;
  border-radius: 999px; border: 1px solid transparent;
  font: 600 .9375rem/1 Inter, sans-serif;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color .18s var(--sortie), border-color .18s var(--sortie),
              color .18s var(--sortie), transform .16s var(--sortie), box-shadow .18s var(--sortie);
}
.btn:active { transform: scale(.97); }
/* Plein : bleu de marque, blanc dessus (7,4:1). Jamais de blanc sur turquoise (2,2:1). */
.btn-plein { background: var(--bleu); color: #fff; box-shadow: 0 1px 2px rgb(27 90 168 / .3); }
.btn-plein .ic { color: rgb(255 255 255 / .85); }
/* Trait : filet fort, encre. */
.btn-trait { border-color: var(--filet-fort); color: var(--encre); background: transparent; }
/* Sur fond bleu profond. */
.btn-blanc { background: #fff; color: var(--bleu); }
.btn-clair { border-color: rgb(255 255 255 / .5); color: #fff; background: transparent; }
@media (hover: hover) and (pointer: fine) {
  .btn-plein:hover { background: var(--bleu-fonce); transform: translateY(-1px); box-shadow: 0 6px 16px -6px rgb(27 90 168 / .5); }
  .btn-trait:hover { border-color: var(--encre); }
  .btn-blanc:hover { transform: translateY(-1px); box-shadow: 0 6px 16px -6px rgb(0 0 0 / .3); }
  .btn-clair:hover { border-color: #fff; background: rgb(255 255 255 / .1); }
  .btn:hover .ic-fleche { transform: translateX(2px); }
}
.ic-fleche { transition: transform .18s var(--sortie); }

/* La feuille générale du thème colore TOUS les liens en cyan en mode sombre
   (html.esdi-sombre a). Ici chaque lien porte sa propre couleur : on rend la
   main, puis on refixe celle des boutons, que cette règle rendait illisibles
   (cyan sur blanc dans « Découvrir ESDI Manager »). */
html.esdi-sombre a { color: inherit; }
html.esdi-sombre .btn-plein { color: #fff; }
html.esdi-sombre .btn-blanc { color: var(--bleu); }
html.esdi-sombre .btn-trait { color: var(--encre); }
html.esdi-sombre .btn-clair { color: #fff; }

/* ------------------------------------------------------------ En-tête */
/* WordPress enveloppe chaque partie de gabarit dans un <header> ou un <footer>
   de la classe wp-block-template-part, haut comme son contenu : un en-tête
   collant ne pourrait jamais en sortir et ne collerait pas. L'enveloppe est
   retirée de la mise en page ; nos propres balises <header> et <footer>
   restent les repères de la page. Sans effet sur le prototype. */
header.wp-block-template-part, footer.wp-block-template-part { display: contents; }

.entete {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--fond) 94%, transparent);
  border-bottom: 1px solid var(--filet);
}
@media (min-width: 1024px) { .entete { backdrop-filter: saturate(160%) blur(10px); } }
.entete .lisible { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; height: 76px; }

/* Ombre au défilement : indication d'état, imperceptible, pilotée par la
   position de défilement en CSS pur. Aucun écouteur de défilement, ils
   tournent à chaque image et saccadent. Sans prise en charge, pas d'ombre. */
.entete::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: 0 8px 24px -16px rgb(11 21 38 / .25);
  opacity: 0;
}
@supports (animation-timeline: scroll()) {
  .entete::after { animation: ombre-entete linear both; animation-timeline: scroll(); animation-range: 0 80px; }
  @keyframes ombre-entete { to { opacity: 1; } }
}
html.esdi-sombre .entete::after { box-shadow: 0 8px 24px -16px rgb(0 0 0 / .6); }

/* Le logo occupe un peu moins de la moitié de la hauteur de la barre :
   au-delà, il écrase le menu au lieu de le porter. */
.logo { display: block; height: 44px; flex: none; }
@media (max-width: 640px) { .logo { height: 38px; } }
.logo img { height: 100%; width: auto; }
/* Le logo garde ses couleurs d'origine dans les deux modes, à la demande du
   client : aucun filtre. Sur fond sombre, le bleu de marque est dense (2,7:1) ;
   c'est un graphique, pas du texte, et c'est le logo tel qu'il existe. */

/* Mode sombre : le menu et ses boutons passent en blanc pur, pas en gris-bleu. */
html.esdi-sombre .nav a { color: #fff; }
html.esdi-sombre .rond { color: #fff; border-color: rgb(255 255 255 / .22); }
html.esdi-sombre .menu-panneau li a { color: #fff; }
html.esdi-sombre .menu-panneau li a .ic { color: rgb(255 255 255 / .55); }
html.esdi-sombre .menu-tel { color: #fff; }

.nav { display: none; align-items: center; gap: .125rem; }
@media (min-width: 1024px) { .nav { display: flex; } }
.nav a {
  padding: .55rem .75rem; border-radius: 8px;
  font-size: .9375rem; font-weight: 500; color: var(--encre-2); text-decoration: none;
  transition: color .15s var(--sortie), background-color .15s var(--sortie);
}
@media (hover: hover) and (pointer: fine) { .nav a:hover { color: var(--encre); background: var(--surface); } }
.entete-actions { display: flex; align-items: center; gap: .5rem; }
.btn-entete { height: 2.625rem; padding: 0 1.2rem; font-size: .9rem; }
@media (max-width: 1279px) { .btn-entete { display: none; } }

/* Boutons ronds de l'en-tête : bascule de thème, menu. */
.rond {
  width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--filet);
  background: transparent; color: var(--encre-2); display: grid; place-items: center; cursor: pointer;
  position: relative;
  transition: border-color .15s var(--sortie), color .15s var(--sortie), transform .16s var(--sortie);
}
.rond:active { transform: scale(.94); }
@media (hover: hover) and (pointer: fine) { .rond:hover { border-color: var(--filet-fort); color: var(--encre); } }
.rond .ic { width: 18px; height: 18px; }

/* Bascule : les deux icônes se superposent, celle qui part tourne d'un quart
   de tour en s'effaçant, celle qui arrive fait l'inverse. Une transition, pas
   une image-clé : re-cliquer à mi-course repart de l'état courant. */
.bascule .ic { position: absolute; transition: opacity .2s var(--sortie), transform .2s var(--sortie); }
.bascule .lune   { opacity: 1; transform: rotate(0); }
.bascule .soleil { opacity: 0; transform: rotate(-90deg) scale(.9); }
html.esdi-sombre .bascule .lune   { opacity: 0; transform: rotate(90deg) scale(.9); }
html.esdi-sombre .bascule .soleil { opacity: 1; transform: rotate(0); }

/* Menu : bouton visible sous 1024 px, panneau qui descend de l'en-tête.
   Cinq entrées, un logo de 150 px et deux boutons ronds : en dessous, le
   menu de bureau déborderait. Le bouton « devis » attend 1280 px. */
.menu-bouton { display: grid; }
@media (min-width: 1024px) { .menu-bouton { display: none; } }
.menu-bouton .ic { position: absolute; transition: opacity .18s var(--sortie), transform .18s var(--sortie); }
.menu-bouton .ferme { opacity: 0; transform: rotate(-90deg) scale(.9); }
.entete[data-ouvert] .menu-bouton .ouvre { opacity: 0; transform: rotate(90deg) scale(.9); }
.entete[data-ouvert] .menu-bouton .ferme { opacity: 1; transform: rotate(0); }

/* Le panneau vient d'en haut, comme un tiroir attaché à l'en-tête : il glisse
   de 8 px et s'éclaircit. Ouverture 220 ms ; fermeture 160 ms, plus nette,
   parce que c'est la réponse du système, pas la décision de l'utilisateur. */
.menu-panneau {
  position: fixed; top: 76px; left: 0; right: 0; z-index: 39;
  max-height: calc(100dvh - 76px); overflow-y: auto;
  background: var(--fond); border-bottom: 1px solid var(--filet);
  box-shadow: 0 24px 48px -24px rgb(11 21 38 / .3);
  padding: .5rem var(--marge) 1.5rem;
  opacity: 0; transform: translateY(-8px); visibility: hidden;
  transition: opacity .16s var(--sortie), transform .16s var(--sortie), visibility 0s .16s;
}
.entete[data-ouvert] .menu-panneau {
  opacity: 1; transform: translateY(0); visibility: visible;
  transition: opacity .22s var(--sortie), transform .22s var(--sortie), visibility 0s;
}
@media (min-width: 1024px) { .menu-panneau { display: none; } }
.menu-panneau ul { display: grid; }
.menu-panneau li a {
  display: flex; align-items: center; justify-content: space-between;
  padding: .95rem 0; border-bottom: 1px solid var(--filet);
  font-size: 1.125rem; font-weight: 600; color: var(--encre); text-decoration: none;
}
.menu-panneau li a .ic { color: var(--encre-3); width: 18px; height: 18px; }
.menu-panneau li a:active { color: var(--bleu); }
/* Les liens arrivent décalés de 30 ms à l'ouverture seulement. À la fermeture,
   tout part ensemble : on ne fait pas attendre une décision déjà prise. */
.menu-panneau li { opacity: 0; transform: translateY(6px); transition: opacity .2s var(--sortie), transform .2s var(--sortie); }
.entete[data-ouvert] .menu-panneau li { opacity: 1; transform: none; }
.entete[data-ouvert] .menu-panneau li:nth-child(2) { transition-delay: 30ms; }
.entete[data-ouvert] .menu-panneau li:nth-child(3) { transition-delay: 60ms; }
.entete[data-ouvert] .menu-panneau li:nth-child(4) { transition-delay: 90ms; }
.entete[data-ouvert] .menu-panneau li:nth-child(5) { transition-delay: 120ms; }
.entete[data-ouvert] .menu-panneau li:nth-child(6) { transition-delay: 150ms; }
.entete[data-ouvert] .menu-panneau li:nth-child(7) { transition-delay: 180ms; }
.menu-actions { display: grid; gap: .75rem; margin-top: 1.25rem; }
.menu-actions .btn { width: 100%; }
.menu-tel { display: flex; align-items: center; justify-content: center; gap: .5rem; padding: .5rem; font-weight: 600; color: var(--encre-2); text-decoration: none; font-variant-numeric: tabular-nums; }
.menu-tel .ic { color: var(--turquoise); width: 18px; height: 18px; }

/* Voile derrière le panneau : ferme au toucher. */
.voile {
  position: fixed; inset: 76px 0 0 0; z-index: 38;
  background: rgb(11 21 38 / .35);
  opacity: 0; visibility: hidden;
  transition: opacity .2s var(--sortie), visibility 0s .2s;
}
body:has(.entete[data-ouvert]) .voile { opacity: 1; visibility: visible; transition: opacity .22s var(--sortie), visibility 0s; }
@media (min-width: 1024px) { .voile { display: none; } }
html:has(.entete[data-ouvert]) { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .menu-panneau, .menu-panneau li { transform: none !important; }
  .bascule .ic, .menu-bouton .ic { transform: none !important; }
}

/* ------------------------------------------------------------ Hero */
.hero { padding-block: clamp(3.5rem, 8vw, 7rem) clamp(2.5rem, 5vw, 4rem); overflow: hidden; }
.hero-grille { display: grid; gap: clamp(2.5rem, 5vw, 4rem); align-items: center; }
@media (min-width: 1024px) { .hero-grille { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); } }
.hero h1 { margin-bottom: 1.5rem; }
.hero h1 em { font-style: normal; color: var(--bleu); }
html.esdi-sombre .hero h1 em { color: #6fcfdc; }
.hero .prose { margin-bottom: 2.25rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .75rem; }

/* La pile de captures : trois vrais sites, légèrement en éventail.
   Tout est en transform, rien n'est absolu hors du conteneur : sur téléphone,
   seule la première capture reste, à plat. */
.pile { position: relative; aspect-ratio: 16 / 11; }
.pile img {
  position: absolute; inset: 0; margin: auto;
  width: 82%; aspect-ratio: 16 / 10; object-fit: cover;
  border-radius: 12px; border: 1px solid var(--filet);
  box-shadow: var(--ombre-2);
  background: var(--surface);
}
.pile img:nth-child(1) { transform: translate(-13%, -9%) rotate(-5deg); z-index: 1; opacity: .92; }
.pile img:nth-child(2) { transform: translate(13%, 9%) rotate(4deg);   z-index: 2; opacity: .96; }
.pile img:nth-child(3) { transform: translate(0, 0) rotate(-1deg) scale(1.04); z-index: 3; }
@media (max-width: 1023px) {
  .pile { aspect-ratio: 16 / 10; max-width: 34rem; }
  .pile img { width: 100%; position: static; transform: none !important; opacity: 1; }
  .pile img:not(:nth-child(1)) { display: none; }
}

/* Une phrase, pas quatre tuiles. Les chiffres vivent dans le texte. */
.hero-preuve {
  margin-top: clamp(2.5rem, 5vw, 3.5rem); padding-top: 1.5rem;
  border-top: 1px solid var(--filet);
  display: flex; flex-wrap: wrap; gap: .75rem 2.5rem; align-items: baseline;
  color: var(--encre-2); font-size: .9375rem;
}
.hero-preuve b { color: var(--encre); font-weight: 700; font-variant-numeric: tabular-nums; }
.hero-preuve span { display: inline-flex; align-items: center; gap: .5rem; }

/* La seule animation d'entrée du site. Chaque élément part visible ; l'animation
   ne joue que si le mouvement est autorisé, et se lit du bas vers le haut. */
@media (prefers-reduced-motion: no-preference) {
  .hero [data-m] { animation: monte .7s var(--sortie) both; animation-delay: calc(var(--i, 0) * 70ms); }
  @keyframes monte { from { opacity: 0; transform: translateY(14px); } }
  .pile img { animation: pose .9s var(--sortie) both; }
  .pile img:nth-child(1) { animation-delay: .25s; }
  .pile img:nth-child(2) { animation-delay: .35s; }
  .pile img:nth-child(3) { animation-delay: .45s; }
  @keyframes pose { from { opacity: 0; translate: 0 20px; } }
}

/* ------------------------------------------------------------ Sections */
.section { padding-block: clamp(3.5rem, 7vw, 5.75rem); }
.section-tete { max-width: 40rem; margin-bottom: clamp(2rem, 4vw, 3rem); }
.section-tete .prose { margin-top: 1rem; }
/* Deux blocs de même fond qui se suivent : le second se rapproche, le changement de fond faisant déjà frontière ailleurs. */
.section:not(.surface):not(.manager):not(.locski):not(.apropos) + :is(.section, .contact):not(.surface):not(.manager):not(.locski):not(.apropos),
.section.surface + .section.surface { padding-top: clamp(2.25rem, 4.5vw, 3.5rem); }

/* ------------------------------------------------------------ Vignettes */
/* De petites scènes dessinées en CSS pour les blocs qui n'avaient que du
   texte : un téléphone, un planning, une boîte de réception, une conversation.
   Elles ne montrent pas de la technique mais ce que le client verra sur son
   écran. Chacune joue une courte séquence quand elle arrive sous les yeux
   (classe .jouee posée par le script), puis reste posée : l'état final est
   l'état par défaut, la page se lit donc aussi figée, sans script ou avec les
   animations réduites. Un survol ou un appui la rejoue. Décoratives, elles
   sont cachées des lecteurs d'écran. Les noms de clients y sont inventés,
   sauf la vraie réponse Google.
   Tout est en flux (flex), jamais en position absolue : la scène se replie
   d'elle-même sur un petit écran, et les pièces de trop s'effacent par
   paliers de largeur (@container). */
.vignette {
  position: relative; display: flex; flex-direction: column; justify-content: center; gap: 10px;
  min-height: var(--vg-h, 10rem); padding: 14px 6%; overflow: hidden;
  border-radius: 12px; border: 1px solid var(--filet); background: var(--surface);
  font-size: .6875rem; line-height: 1.3; color: var(--encre-2);
  user-select: none; -webkit-user-select: none; cursor: default; container-type: inline-size;
  transition: opacity .3s var(--sortie);
}
.esdi-vignettes .vignette:not(.jouee) { opacity: 0; }
.vignette .ic { width: 12px; height: 12px; stroke-width: 2.25; flex: none; }
.vignette b { font-weight: 600; color: var(--encre); }
/* Rejouer : au survol, une petite flèche dans l'angle dit qu'on peut cliquer. */
.vignette::after {
  content: ""; position: absolute; right: 8px; bottom: 8px; width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--filet); background: var(--fond) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a6079' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8'/%3E%3Cpath d='M3 3v5h5'/%3E%3C/svg%3E") center / 12px no-repeat;
  opacity: 0; transition: opacity .2s var(--sortie);
}
html.esdi-sombre .vignette::after { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239fb1c6' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8'/%3E%3Cpath d='M3 3v5h5'/%3E%3C/svg%3E"); }
@media (hover: hover) and (pointer: fine) { .vignette:hover::after { opacity: 1; } }

/* Pièces communes. */
.vg-carte { position: relative; min-width: 0; background: var(--fond); border: 1px solid var(--filet); border-radius: 8px; box-shadow: var(--ombre-1); }
.vg-ligne { display: block; height: 5px; border-radius: 3px; background: var(--filet-fort); }
.vg-ligne + .vg-ligne { margin-top: 5px; }
.vg-titre { height: 7px; background: var(--encre-2); opacity: .7; }
.vg-puce { display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border-radius: 999px; line-height: 1.35; font-weight: 600; font-size: .625rem; white-space: nowrap; background: rgb(63 190 204 / .2); color: var(--bleu-fonce); }
html.esdi-sombre .vg-puce { color: #9fe3ec; }
.vg-puce.bleue { background: var(--bleu); color: #fff; }
.vg-puce.grise { background: var(--filet); color: var(--encre-2); }
.vg-puce .ic { width: 11px; height: 11px; }
/* La pastille tient sur une ligne : sans hauteur de ligne propre, elle
   hérite du 1,6 du corps de page et double de hauteur. */
.vg-flot { padding: 4px 9px; max-width: 100%; line-height: 1.35; background: var(--fond); color: var(--encre); border: 1px solid var(--filet); box-shadow: var(--ombre-1); }
.vg-flot .ic { color: var(--turquoise); }
.vg-bouton { display: inline-block; padding: 3px 9px; border-radius: 999px; background: var(--bleu); color: #fff; font-weight: 600; font-size: .625rem; }
.vg-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--filet); }
.vg-tete b, .vg-tete span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vg-tete span { color: var(--encre-3); font-size: .625rem; }
.vg-rang { display: flex; align-items: center; gap: 8px; padding: 5px 10px; }
.vg-rang + .vg-rang { border-top: 1px solid var(--filet); }
.vg-rang > div { flex: 1; min-width: 0; }
.vg-rang b, .vg-rang > div > span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vg-rang > div > span { color: var(--encre-3); font-size: .625rem; }
.vg-rang > .ic { color: var(--encre-3); }
.vg-jours { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: .5625rem; font-weight: 600; color: var(--encre-3); margin-bottom: 4px; }
.vg-jours i { font-style: normal; }

/* Le téléphone : un cadre, une photo de montagne, trois lignes, un bouton. */
.vg-tel { flex: none; width: 88px; border-radius: 14px; border: 2px solid var(--encre); background: var(--fond); padding: 7px 7px 10px; box-shadow: var(--ombre-2); }
.vg-tel::before { content: ""; display: block; width: 24px; height: 3px; border-radius: 2px; background: var(--filet-fort); margin: 0 auto 7px; }
.vg-photo { position: relative; height: 40px; border-radius: 6px; overflow: hidden; margin-bottom: 7px; background: linear-gradient(165deg, #cfe9ee 0%, #5aa0d8 55%, var(--bleu) 100%); }
.vg-photo::after { content: ""; position: absolute; left: -6%; right: -6%; bottom: -2px; height: 62%; background: #fff; opacity: .92; clip-path: polygon(0 100%, 14% 58%, 28% 78%, 47% 22%, 62% 60%, 78% 40%, 100% 100%); }
.vg-tel .vg-bouton { margin-top: 8px; }

/* Site : le téléphone, puis ce qu'on y trouve, en pastilles décalées. */
.vg-site { flex-direction: row; align-items: center; gap: 14px; }
.vg-pastilles { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; min-width: 0; }
.vg-pastilles .vg-flot:nth-child(2) { margin-left: 14%; }
.vg-pastilles .vg-flot:nth-child(3) { margin-left: 6%; }
@container (max-width: 270px) { .vg-site { gap: 10px; } .vg-site .vg-tel { width: 74px; } .vg-pastilles .vg-flot { margin-left: 0 !important; font-size: .5625rem; padding: 3px 7px; } }

/* Boutique : trois produits, une commande payée, un stock qui baisse. */
.vg-boutique { flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; }
.vg-produits { display: flex; gap: 10px; flex: none; }
.vg-produit { position: relative; width: 70px; padding: 6px; border-radius: 8px; background: var(--fond); border: 1px solid var(--filet); }
.vg-produit i { display: block; height: 44px; border-radius: 5px; margin-bottom: 6px; background: linear-gradient(150deg, #dff1f4, #a9dde6); }
.vg-produit:nth-child(2) i { background: linear-gradient(150deg, #dbe7f7, #8db4e2); }
.vg-produit:nth-child(3) i { background: linear-gradient(150deg, #e7ebf1, #b9c3d1); }
.vg-produit .vg-puce { position: absolute; top: 4px; right: 4px; padding: 1px 5px; font-size: .5625rem; }
.vg-recu { display: flex; align-items: center; gap: 9px; padding: 8px 11px; margin-top: 30px; flex: 1 1 auto; }
.vg-recu > div { min-width: 0; }
.vg-recu b, .vg-recu span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vg-recu .ic { width: 18px; height: 18px; padding: 3px; border-radius: 50%; background: var(--turquoise); color: #0b1526; }
.vg-recu span { color: var(--encre-3); font-size: .625rem; }
@container (max-width: 400px) { .vg-produit:nth-child(3) { display: none; } }
@container (max-width: 330px) { .vg-produit:nth-child(2) { display: none; } }
@container (max-width: 270px) { .vg-recu { gap: 7px; padding: 7px 9px; } .vg-recu b { font-size: .625rem; } }
@container (max-width: 270px) { .vg-recu { gap: 7px; padding: 7px 9px; } .vg-recu b { font-size: .625rem; } }

/* Calendrier : le mois se remplit, deux réservations arrivent. */
.vg-calendrier { flex-direction: row; align-items: center; gap: 12px; }
.vg-mois { flex: none; width: 150px; padding-bottom: 8px; }
.vg-mois .vg-jours { padding: 0 10px; margin-top: 6px; }
.vg-cases { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; padding: 0 10px; }
.vg-cases span { aspect-ratio: 1; border-radius: 3px; background: var(--surface); }
.vg-cases .prise { background: var(--turquoise); }
.vg-cases .forte { background: var(--bleu); }
.vg-cote { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.vg-resa { display: flex; align-items: center; gap: 8px; padding: 6px 10px; width: 100%; }
.vg-resa > .ic { color: var(--turquoise); }
.vg-resa > div { min-width: 0; }
.vg-resa b, .vg-resa span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vg-resa span { color: var(--encre-3); font-size: .625rem; }
@container (max-width: 420px) { .vg-resa:nth-child(2) { display: none; } .vg-cote .vg-flot { white-space: normal; text-align: left; line-height: 1.25; border-radius: 10px; } }
@container (max-width: 340px) { .vg-resa { display: none; } }
@container (max-width: 290px) { .vg-cote .vg-flot { font-size: .5625rem; } }

/* Google : la question se tape, la bonne réponse sort en premier. */
.vg-recherche { display: flex; align-items: center; gap: 9px; padding: 7px 13px; border-radius: 999px; color: var(--encre); font-size: .75rem; }
.vg-recherche > .ic { width: 14px; height: 14px; color: var(--encre-3); }
.vg-saisie { min-width: 0; overflow: hidden; }
.vg-saisie > span { display: inline-block; max-width: 24ch; overflow: hidden; white-space: nowrap; vertical-align: bottom; }
.vg-curseur { width: 2px; height: 14px; margin-left: -6px; background: var(--bleu); opacity: 0; flex: none; }
.vg-resultat { width: 84%; padding: 8px 13px; }
/* Visible au repos : seule la séquence (.jouee) le fait arriver après la
   frappe. Une vignette qui n'a pas joué reste donc complète. */
.vg-google .vg-resultat { opacity: 1; }
.vg-url { display: block; color: var(--encre-3); font-size: .625rem; }
.vg-resultat b { display: block; color: var(--bleu); font-size: .75rem; margin: 2px 0 7px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@container (max-width: 420px) { .vg-resultat b { white-space: normal; } }
html.esdi-sombre .vg-resultat b { color: #6fcfdc; }

/* Planning : la semaine, les locations posées comme sur un vrai planning. */
.vg-semaine { padding-bottom: 8px; }
.vg-semaine .vg-jours { padding: 0 10px; margin-top: 6px; }
.vg-locs { display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: 16px; gap: 4px 3px; padding: 0 10px; }
.vg-loc { grid-column: var(--c) / span var(--l); border-radius: 4px; background: var(--bleu); color: #fff; font-size: .5625rem; font-weight: 600; line-height: 16px; padding: 0 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vg-loc.t { background: var(--turquoise); color: #0b1526; }

/* Clients et réglages : une liste de trois. */
.vg-liste .vg-rang { padding: 7px 11px; }
.vg-avatar { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: var(--surface); color: var(--encre); font-style: normal; font-weight: 700; font-size: .625rem; flex: none; }
.vg-interrupteur { position: relative; flex: none; width: 26px; height: 15px; border-radius: 999px; background: var(--filet-fort); }
.vg-interrupteur::after { content: ""; position: absolute; top: 2px; left: 2px; width: 11px; height: 11px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgb(0 0 0 / .25); }
.vg-interrupteur.on { background: var(--turquoise); }
.vg-interrupteur.on::after { translate: 11px 0; }
@container (max-width: 290px) { .vg-liste .vg-puce { display: none; } }

/* Liaison : la caisse, l'outil, la comptabilité, et ce qui circule entre eux. */
.vg-noeuds { display: flex; align-items: center; }
.vg-noeud { flex: none; display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 8px 11px; border-radius: 8px; background: var(--fond); border: 1px solid var(--filet); box-shadow: var(--ombre-1); color: var(--encre); font-weight: 600; font-size: .625rem; white-space: nowrap; }
.vg-noeud .ic { width: 16px; height: 16px; color: var(--turquoise); }
.vg-noeud.centre { border-color: var(--bleu); }
.vg-fil { position: relative; flex: 1; min-width: 18px; height: 0; border-top: 2px dashed var(--filet-fort); }
.vg-fil::after { content: ""; position: absolute; top: -5px; left: calc(100% - 8px); width: 8px; height: 8px; border-radius: 50%; background: var(--turquoise); }
.vg-fil.retour::after { left: 0; }
.vg-bas { display: flex; justify-content: center; }
@container (max-width: 270px) { .vg-noeud { padding: 7px 8px; font-size: .5625rem; } }

/* Croissance : quatre saisons, une colonne plus haute à chaque fois. */
.vg-colonnes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; height: 104px; padding: 8px 12px 6px; }
.vg-colonnes > div { display: flex; flex-direction: column; justify-content: flex-end; gap: 4px; text-align: center; font-size: .5625rem; color: var(--encre-3); min-width: 0; }
.vg-colonnes > div > b { font-size: .5625rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vg-colonnes i { display: block; height: var(--h); border-radius: 4px 4px 2px 2px; background: var(--bleu); transform-origin: bottom; }
.vg-colonnes > div:last-child i { background: var(--turquoise); }
@container (max-width: 340px) { .vg-colonnes { gap: 8px; height: 114px; } .vg-colonnes > div > b { white-space: normal; line-height: 1.2; } }
@container (max-width: 270px) { .vg-colonnes { gap: 6px; } .vg-colonnes > div > b { font-size: .5rem; hyphens: auto; overflow-wrap: anywhere; } }

/* Mails : trois mails du matin, chacun déjà traité. */
.vg-ecarte { opacity: .45; }
@container (max-width: 290px) { .vg-boite .vg-puce { display: none; } }

/* Conversation : la question d'un client à 21 h 42, la réponse dans la seconde. */
.vg-chat { gap: 8px; }
.vg-bulle { position: relative; max-width: 74%; padding: 7px 10px; border-radius: 12px; background: var(--fond); border: 1px solid var(--filet); color: var(--encre); }
.vg-bulle time { display: block; margin-top: 3px; font-size: .5625rem; color: var(--encre-3); }
.vg-bulle.assistant { align-self: flex-end; background: var(--bleu); border-color: var(--bleu); color: #fff; }
.vg-bulle.assistant time { color: rgb(255 255 255 / .72); }
.vg-points { position: absolute; right: 6%; top: 50%; translate: 0 -50%; display: flex; gap: 3px; padding: 7px 9px; border-radius: 10px; background: var(--fond); border: 1px solid var(--filet); opacity: 0; }
.vg-points i { width: 5px; height: 5px; border-radius: 50%; background: var(--encre-3); }

/* Sur l'accueil, un appareil sous le titre des métiers : trois écrans se
   relaient au rythme des trois blocs qu'on fait défiler à droite, et trois
   onglets permettent d'y aller directement (le script pose .active et --n).
   Sur petit écran, le script place chaque écran en tête de son métier. */
.scene { margin-top: 1.75rem; }
.scene-ecran { position: relative; --vg-h: 15rem; height: var(--vg-h); padding: 8px; border-radius: 14px; border: 1px solid var(--filet-fort); background: var(--fond); box-shadow: var(--ombre-2); }
.scene-ecran .vignette { position: absolute; inset: 8px; min-height: 0; border-radius: 8px; opacity: 0; transition: opacity .24s var(--sortie); }
.scene-ecran .vignette.active { opacity: 1; }
.scene-ecran .vignette::after { display: none; }
.scene-onglets { position: relative; display: grid; grid-template-columns: repeat(3, 1fr); margin-top: .75rem; padding: 4px; border-radius: 999px; background: var(--surface); border: 1px solid var(--filet); }
.scene-onglets .curseur { position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc((100% - 8px) / 3); border-radius: 999px; background: var(--fond); box-shadow: var(--ombre-1); transform: translateX(calc(var(--n, 0) * 100%)); transition: transform .3s var(--sortie); }
.scene-onglets button { position: relative; z-index: 1; appearance: none; -webkit-appearance: none; border: 0; background: none; margin: 0; padding: .55rem .25rem; border-radius: 999px; font: 600 .8125rem/1.2 Inter, ui-sans-serif, system-ui, sans-serif; color: var(--encre-2); cursor: pointer; transition: color .2s var(--sortie); }
.scene-onglets button[aria-pressed="true"] { color: var(--encre); }
@media (hover: hover) and (pointer: fine) { .scene-onglets button:hover { color: var(--encre); } }
@media (max-width: 899px) { .scene { display: none; } .service .vignette { margin-bottom: 1.25rem; } }

/* Relief au pointeur : sur grand écran, la pile de captures et les vitrines
   des bandeaux s'inclinent doucement vers la souris (le script pose --px et
   --py entre -1 et 1), les captures du dessus un peu plus que celles du
   dessous. Un demi-seconde de décélération pour que ça suive sans coller. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .hero-grille, .bandeau-grille { perspective: 1400px; }
  .relief { transform-style: preserve-3d; transform: rotateX(calc(var(--py, 0) * -4deg)) rotateY(calc(var(--px, 0) * 6deg)); transition: transform .5s var(--sortie); }
  .pile.relief img:nth-child(1) { translate: 0 0 -30px; }
  .pile.relief img:nth-child(2) { translate: 0 0 10px; }
  .pile.relief img:nth-child(3) { translate: 0 0 40px; }
  .vitrine.relief img:nth-child(2), .duo.relief img:nth-child(2) { translate: 0 0 30px; }
}

/* Les séquences. Chaque pièce porte son rang (--d) ; tout part de l'état final,
   avec la même décélération que le reste du site. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes vg-monte { from { opacity: 0; translate: 0 8px; } }
  @keyframes vg-pop { from { opacity: 0; scale: .5; } }
  @keyframes vg-etire { from { clip-path: inset(0 100% 0 0); } }
  @keyframes vg-pousse { from { transform: scaleY(0); } }
  @keyframes vg-taper { from { max-width: 0; } }
  @keyframes vg-curseur { 0%, 44% { opacity: 1; } 52% { opacity: 0; } 60%, 74% { opacity: 1; } 82%, 100% { opacity: 0; } }
  @keyframes vg-ecarter { from { opacity: 1; } }
  @keyframes vg-allume { from { background: var(--filet-fort); } }
  @keyframes vg-glisse { from { translate: 0 0; } }
  @keyframes vg-circule { from { left: 0; } to { left: calc(100% - 8px); } }
  @keyframes vg-circule-retour { from { left: calc(100% - 8px); } to { left: 0; } }
  @keyframes vg-points { 0% { opacity: 0; } 30%, 88% { opacity: 1; } 100% { opacity: 0; } }
  @keyframes vg-pulse { 50% { translate: 0 -3px; } }

  .jouee .vg-tel, .jouee .vg-flot, .jouee .vg-produit, .jouee .vg-recu, .jouee .vg-resa,
  .jouee .vg-rang, .jouee .vg-noeud, .jouee .vg-bulle, .jouee .vg-colonnes > div > b {
    animation: vg-monte .45s var(--sortie) both; animation-delay: calc(var(--d, 0) * 110ms);
  }
  .jouee .vg-flot, .jouee .vg-recu, .jouee .vg-resa { animation-delay: calc(.35s + var(--d, 0) * 140ms); }
  .jouee .vg-produit .vg-puce { animation: vg-pop .3s var(--sortie) both; animation-delay: calc(.9s + var(--d, 0) * 100ms); }
  .jouee .vg-cases .prise { animation: vg-pop .3s var(--sortie) both; animation-delay: calc(.2s + var(--d, 0) * 70ms); }
  .jouee .vg-loc { animation: vg-etire .4s var(--sortie) both; animation-delay: calc(.25s + var(--d, 0) * 90ms); }
  .jouee .vg-colonnes i { animation: vg-pousse .5s var(--sortie) both; animation-delay: calc(.15s + var(--d, 0) * 130ms); }
  .jouee .vg-colonnes > div > b { animation-delay: calc(.45s + var(--d, 0) * 130ms); }
  .jouee .vg-saisie > span { animation: vg-taper .8s steps(22, end) .15s both; }
  .jouee .vg-curseur { animation: vg-curseur 1.6s steps(1, end) .15s both; }
  /* Le résultat arrive vite après la frappe. Un délai plus long le laissait
     invisible quand l'onglet passait en arrière-plan pendant l'attente : le
     navigateur gèle alors les compteurs, et l'animation ne finissait jamais. */
  .jouee .vg-resultat { animation: vg-monte .4s var(--sortie) .95s both; }
  .jouee .vg-rang .vg-puce { animation: vg-pop .3s var(--sortie) both; animation-delay: calc(.7s + var(--d, 0) * 220ms); }
  .jouee .vg-ecarte { animation: vg-monte .45s var(--sortie) both, vg-ecarter .4s ease-out both; animation-delay: calc(var(--d, 0) * 110ms), 1.7s; }
  .jouee .vg-interrupteur.on { animation: vg-allume .25s var(--sortie) both; animation-delay: calc(.6s + var(--d, 0) * 260ms); }
  .jouee .vg-interrupteur.on::after { animation: vg-glisse .25s var(--sortie) both; animation-delay: calc(.6s + var(--d, 0) * 260ms); }
  .jouee .vg-fil::after { animation: vg-circule 1.6s linear .5s 3 both; }
  .jouee .vg-fil.retour::after { animation-name: vg-circule-retour; }
  .jouee .vg-bulle.assistant { animation-delay: 1.7s; }
  .jouee .vg-points { animation: vg-points 1.7s steps(1, end) .3s both; }
  .jouee .vg-points i { animation: vg-pulse .8s ease-in-out 3; animation-delay: calc(.3s + var(--i, 0) * 130ms); }
}

/* ------------------------------------------------------------ Services */
.services-grille { display: grid; gap: clamp(2rem, 5vw, 5rem); align-items: start; }
@media (min-width: 900px) { .services-grille { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); } }
/* Le titre ne se colle QUE dans la mise en deux colonnes. Sur téléphone,
   tout est sur une seule colonne : collé, il restait en place pendant que
   les services défilaient dessous, et les textes se superposaient. */
@media (min-width: 900px) { .services-tete { position: sticky; top: 6rem; } }
.services-tete .prose { margin-top: 1rem; }
.service { padding-block: clamp(1.75rem, 3vw, 2.5rem); border-top: 1px solid var(--filet); }
.service:last-child { border-bottom: 1px solid var(--filet); }
.service-tete { display: flex; align-items: center; gap: .85rem; margin-bottom: .75rem; }
.service-tete .ic { width: 24px; height: 24px; }
.service p { color: var(--encre-2); max-width: 40rem; }
.service ul { margin-top: 1.25rem; display: grid; gap: .55rem 1.5rem; }
@media (min-width: 560px) { .service ul { grid-template-columns: 1fr 1fr; } }
.service li { display: flex; gap: .6rem; align-items: flex-start; font-size: .9375rem; line-height: 1.5; }
.service li .ic { width: 16px; height: 16px; margin-top: .3rem; }
.service li b { font-weight: 600; }
.service li span { color: var(--encre-2); }
.lien {
  display: inline-flex; align-items: center; gap: .4rem; margin-top: 1.25rem;
  font-size: .9375rem; font-weight: 600; color: var(--bleu); text-decoration: none;
}
html.esdi-sombre .lien { color: #6fcfdc; }
.lien .ic { width: 16px; height: 16px; }
@media (hover: hover) and (pointer: fine) { .lien:hover { text-decoration: underline; text-underline-offset: 4px; } }

/* ------------------------------------------------------------ ESDI Manager */
/* Le seul aplat de couleur de la page : le produit maison. Blanc sur bleu
   profond, 8,6:1 au point le plus clair. Jamais sur le turquoise. */
.manager {
  background: linear-gradient(160deg, var(--bleu-nuit) 0%, var(--bleu-fonce) 60%, var(--bleu) 100%);
  color: #fff;
}
.manager-grille { display: grid; gap: clamp(2.5rem, 5vw, 4.5rem); align-items: center; }
@media (min-width: 960px) { .manager-grille { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); } }
.manager h2 { color: #fff; }
.manager .prose { color: rgb(255 255 255 / .82); }
.manager .prose strong { color: #fff; }
.manager ul { margin-top: 1.75rem; display: grid; gap: .8rem; }
.manager li { display: flex; gap: .8rem; align-items: flex-start; font-size: .9375rem; line-height: 1.5; color: rgb(255 255 255 / .9); }
.manager li .ic { color: #7fd8e4; margin-top: .15rem; }
.manager li b { color: #fff; font-weight: 600; }
.manager-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }
.manager-capture {
  border-radius: 12px; border: 1px solid rgb(255 255 255 / .16);
  box-shadow: 0 30px 80px -30px rgb(0 0 0 / .6), 0 2px 8px rgb(0 0 0 / .2);
  aspect-ratio: 16 / 10; object-fit: cover; width: 100%;
}
@media (min-width: 960px) { .manager-capture { transform: rotate(1.5deg) translateX(2%); } }

/* ------------------------------------------------------------ Locski */
/* Second produit maison, sur fond clair pour alterner avec le bleu profond
   d'ESDI Manager juste au-dessus. Le visuel est une famille d'avatars : cinq
   silhouettes qui se chevauchent légèrement, les adultes derrière, les enfants
   devant, comme une photo de groupe au pied des pistes. */
.locski { background: var(--surface); }
.locski-grille { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(2.5rem, 5vw, 4.5rem); align-items: center; }
@media (min-width: 960px) { .locski-grille { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }

.famille {
  position: relative; display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: 1.5rem;
  /* La rangée se mesure à la largeur de SA colonne : les tailles ci-dessous
     sont en cqw, donc les cinq silhouettes tiennent toujours dans la case,
     quelle que soit la largeur de l'écran. En pixels fixes, la cinquième
     débordait sur le texte. */
  container-type: inline-size;
}
/* Un sol : une ellipse en dégradé radial, décalée vers le bas, sans flou. */
.famille::after {
  content: ""; position: absolute; left: 6%; right: 6%; bottom: 0; height: 2rem;
  background: radial-gradient(ellipse at center, rgb(11 21 38 / .14), transparent 70%);
  z-index: 0;
}
html.esdi-sombre .famille::after { background: radial-gradient(ellipse at center, rgb(0 0 0 / .5), transparent 70%); }
.famille img {
  position: relative; z-index: 1; flex: none; width: auto;
  transition: transform .25s var(--sortie);
}
/* Tailles décroissantes : adultes, ado, enfants. Largeur totale ≈ 93 cqw
   après chevauchement (chaque image fait 0,83 fois sa hauteur). */
.famille img:nth-child(1) { height: 36cqw; margin-right: -8cqw; z-index: 1; }
.famille img:nth-child(2) { height: 36cqw; margin-right: -8cqw; z-index: 2; }
.famille img:nth-child(3) { height: 31cqw; margin-right: -8cqw; z-index: 3; }
.famille img:nth-child(4) { height: 25cqw; margin-right: -8cqw; z-index: 4; }
.famille img:nth-child(5) { height: 23cqw; z-index: 5; }
/* Sans unités de conteneur : tailles fixes, la rangée reste centrée et rognée. */
@supports not (height: 1cqw) {
  .famille { overflow: hidden; }
  .famille img:nth-child(1), .famille img:nth-child(2) { height: 200px; margin-right: -2.5rem; }
  .famille img:nth-child(3) { height: 172px; margin-right: -2.5rem; }
  .famille img:nth-child(4) { height: 140px; margin-right: -2.5rem; }
  .famille img:nth-child(5) { height: 128px; }
}
@media (hover: hover) and (pointer: fine) {
  .famille img:hover { transform: translateY(-6px); z-index: 6; }
}
@media (prefers-reduced-motion: reduce) { .famille img { transition: none; } }

.locski-logo { height: 44px; width: auto; margin-bottom: 1.25rem; }
/* Le logo Locski est bleu nuit : sur fond sombre, il se pose sur une pastille claire. */
html.esdi-sombre .locski-logo { background: #fff; padding: .5rem .7rem; border-radius: 10px; height: 56px; }
.locski-points { margin-top: 1.5rem; display: grid; gap: .75rem; }
.locski-points li { display: flex; gap: .7rem; align-items: flex-start; font-size: .9375rem; line-height: 1.5; color: var(--encre-2); }
.locski-points li .ic { margin-top: .15rem; }
.locski-points b { color: var(--encre); font-weight: 600; }
.locski-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.75rem; }
@media (max-width: 520px) { .locski-actions .btn { white-space: normal; height: auto; min-height: 3rem; padding-block: .7rem; line-height: 1.3; text-align: center; } }
.locski-statut { margin-top: 1rem; font-size: .875rem; color: var(--encre-3); }

/* ------------------------------------------------------------ Réalisations */
.travaux { display: grid; gap: 2rem 1.5rem; }
@media (min-width: 640px) { .travaux { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .travaux { grid-template-columns: repeat(4, 1fr); gap: 2rem 1.25rem; } }
.travail a { display: block; text-decoration: none; color: inherit; }
.travail img {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  border-radius: 10px; border: 1px solid var(--filet); box-shadow: var(--ombre-1);
  background: var(--surface);
  transition: transform .25s var(--sortie), box-shadow .25s var(--sortie);
}
@media (hover: hover) and (pointer: fine) {
  .travail a:hover img { transform: translateY(-4px); box-shadow: var(--ombre-2); }
}
.travail h3 { font-size: 1.0625rem; margin-top: 1rem; letter-spacing: -.01em; }
.travail p { font-size: .875rem; color: var(--encre-2); margin-top: .25rem; }

/* Les noms, en deux bandeaux qui défilent en sens contraires. C'est la
   preuve qui compte pour un commerçant de la vallée : il y reconnaît ses
   voisins. Une seule propriété animée, transform, sur une piste par rang :
   une couche de composition chacune, rien de commun avec les 85 flous qui
   faisaient tomber Safari. Mouvement constant, donc courbe linéaire. Pause au
   survol. Si l'utilisateur demande moins d'animation : arrêt, et la piste
   redevient défilable au doigt. */
.clients { margin-top: clamp(3rem, 5vw, 4rem); padding-top: clamp(2rem, 4vw, 3rem); border-top: 1px solid var(--filet); }
.clients-tete { display: grid; gap: 1rem 3rem; align-items: start; margin-bottom: 2.25rem; }
@media (min-width: 900px) { .clients-tete { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.clients-tete .prose { font-size: 1rem; }

/* 100vw compte la barre de défilement verticale : le bandeau déborderait de
   sa largeur (15 px) et ferait apparaître une barre horizontale. On rogne la
   section. « clip » ne crée pas de conteneur de défilement, contrairement à
   « hidden » : rien ne change pour le reste de la page. */
#realisations { overflow-x: clip; }
@supports not (overflow-x: clip) { #realisations { overflow-x: hidden; } }

.defile {
  /* Pleine largeur d'écran, en sortant du conteneur : les noms filent bord à bord. */
  width: 100vw; margin-left: calc(50% - 50vw);
  display: grid; gap: .875rem;
  /* Les extrémités s'estompent : un masque en dégradé, pas un flou. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.defile-rang { display: flex; overflow: hidden; }
.defile-piste {
  display: flex; flex: none; align-items: center;
  animation: defiler 95s linear infinite;
  will-change: transform;
}
.defile-droite .defile-piste { animation-direction: reverse; animation-duration: 110s; }
.defile-piste li {
  flex: none; white-space: nowrap;
  padding: .55rem 1.5rem; border-left: 1px solid var(--filet);
  font-size: .9375rem; font-weight: 500; color: var(--encre-2);
}
.defile-piste li i { font-style: normal; font-weight: 400; color: var(--encre-3); margin-left: .35rem; }
@keyframes defiler { to { transform: translateX(-100%); } }
@media (hover: hover) and (pointer: fine) {
  .defile-rang:hover .defile-piste { animation-play-state: paused; }
}
@media (prefers-reduced-motion: reduce) {
  .defile { -webkit-mask-image: none; mask-image: none; width: auto; margin-left: 0; }
  .defile-rang { overflow-x: auto; scrollbar-width: thin; padding-bottom: .25rem; }
  .defile-piste { animation: none; }
  .defile-piste[aria-hidden] { display: none; }
}

/* ------------------------------------------------------------ À propos */
.apropos { background: var(--surface); }
.apropos-grille { display: grid; gap: clamp(2rem, 5vw, 5rem); align-items: start; }
@media (min-width: 900px) { .apropos-grille { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); } }
.apropos .prose + .prose { margin-top: 1.25rem; }
.valeurs { margin-top: 2.25rem; display: grid; gap: 1.5rem; }
@media (min-width: 640px) { .valeurs { grid-template-columns: repeat(3, 1fr); gap: 1.5rem 2rem; } }
.valeur .ic { width: 22px; height: 22px; margin-bottom: .75rem; }
.valeur h3 { font-size: 1.0625rem; letter-spacing: -.01em; }
.valeur p { margin-top: .4rem; font-size: .9375rem; color: var(--encre-2); line-height: 1.55; }

/* ------------------------------------------------------------ Contact */
/* Le numéro de téléphone est l'appel à l'action : pour un commerçant de
   montagne, c'est ce qu'il cherche. Il est donc en taille d'affiche, cliquable. */
.contact { padding-block: clamp(3.5rem, 7vw, 5.75rem); }
.contact-grille { display: grid; gap: 2.5rem 4rem; align-items: end; }
@media (min-width: 900px) { .contact-grille { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); } }
.tel {
  display: inline-block; margin-top: 1.5rem;
  font-size: clamp(2rem, 5.6vw, 4rem); font-weight: 800; letter-spacing: -.04em; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--bleu); text-decoration: none;
  transition: color .15s var(--sortie);
}
html.esdi-sombre .tel { color: #6fcfdc; }
@media (hover: hover) and (pointer: fine) { .tel:hover { color: var(--turquoise); } }
.contact-autres { display: grid; gap: 1.25rem; }
.contact-autres a { display: inline-flex; align-items: center; gap: .6rem; color: var(--encre); text-decoration: none; font-weight: 500; }
.contact-autres a .ic { color: var(--turquoise); }
@media (hover: hover) and (pointer: fine) { .contact-autres a:hover { text-decoration: underline; text-underline-offset: 4px; } }
.contact-autres .adresse { color: var(--encre-2); font-size: .9375rem; line-height: 1.5; }
.contact-actions { margin-top: 2rem; display: flex; flex-wrap: wrap; gap: .75rem; }
.garanties { margin-top: 1.5rem; display: flex; flex-wrap: wrap; gap: .5rem 1.75rem; font-size: .875rem; color: var(--encre-2); }
.garanties span { display: inline-flex; align-items: center; gap: .45rem; }
.garanties .ic { width: 16px; height: 16px; }

/* ------------------------------------------------------------ Pied */
.pied { border-top: 1px solid var(--filet); padding-block: clamp(2.5rem, 5vw, 3.5rem) 1.5rem; font-size: .9375rem; }
.pied-grille { display: grid; gap: 2.5rem 2rem; }
@media (min-width: 640px) { .pied-grille { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .pied-grille { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: 2rem 3rem; } }
.pied .logo { height: 44px; }
.pied h3 { margin: 0 0 1rem; font-size: .875rem; font-weight: 700; letter-spacing: 0; line-height: 1.4; color: var(--encre); }
.pied ul { display: grid; gap: .6rem; }
.pied a { color: var(--encre-2); text-decoration: none; transition: color .15s var(--sortie); }
@media (hover: hover) and (pointer: fine) { .pied a:hover { color: var(--encre); text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--turquoise); } }
.pied .prose { font-size: .9375rem; margin-top: 1.1rem; max-width: 24rem; }
.pied-contact li { display: flex; gap: .65rem; align-items: flex-start; color: var(--encre-2); line-height: 1.5; }
.pied-contact .ic { color: var(--turquoise); width: 18px; height: 18px; margin-top: .2rem; }
.pied-contact a { font-variant-numeric: tabular-nums; }
.pied-bas {
  margin-top: 3rem; padding-top: 1.25rem; border-top: 1px solid var(--filet);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem 1.5rem;
  color: var(--encre-3); font-size: .8125rem;
}
.haut { display: inline-flex; align-items: center; gap: .4rem; color: var(--encre-2) !important; font-weight: 500; }
.haut .ic { width: 16px; height: 16px; transition: transform .18s var(--sortie); }
@media (hover: hover) and (pointer: fine) { .haut:hover .ic { transform: translateY(-2px); } }

.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
