/* Mise en page et animations de la page d'accueil SolutIAa. Couleurs, police et boutons : marque.css
   Inspirée de resend.com (choix de Félix) : objets 3D posés dans des tuiles, démo qui s'exécute,
   rangée d'outils, nom géant en bas de page. Les états de départ des animations ne s'appliquent que
   sous html.js : sans script, tout est visible. */

:root {
  --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --eau-lueur: oklch(0.86 0.085 168 / 0.35);
  --fond-creux: oklch(0.12 0.003 260);
}

.page { max-width: var(--largeur); margin: 0 auto; padding: 0 var(--marge); }

html { scroll-behavior: smooth; scroll-padding-top: 5rem; }
/* Lenis (défilement doux) : il prend le relais du défilement du navigateur. On n'a repris de son lenis.css que
   l'essentiel (pas sa règle « iframe sans souris », au cas où un iframe reviendrait dans la page). */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: clip; }

.evitement { position: absolute; left: var(--e-4); top: -4rem; z-index: 10; padding: var(--e-3) var(--e-4); background: var(--craie); color: var(--nuit); border-radius: var(--rayon-btn); }
.evitement:focus { top: var(--e-4); }

/* Titres éclairés, comme chez Resend : le blanc s'éteint doucement vers le bas à droite.
   Un dégradé de lumière, jamais de couleur. Les crochets et « IA » gardent leur propre teinte. */
.lumiere {
  background: linear-gradient(to right bottom, var(--craie) 35%, oklch(0.97 0.002 260 / 0.5));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Le grand titre : la lumière tombe du haut, chaque lettre garde le même blanc d'un bout à l'autre de la ligne
   (vers la droite, le « n » de « solut[IA]n » s'éteignait et paraissait détaché : Félix, 15/10/2026) */
.promesse .lumiere { background-image: linear-gradient(to bottom, var(--craie) 45%, oklch(0.97 0.002 260 / 0.72)); }

/* ─── En-tête : fixé en haut, un trait apparaît quand on défile ─── */
.entete { position: sticky; top: 0; z-index: 5; background: oklch(0.145 0.003 260 / 0.92); border-bottom: 1px solid transparent; transition: border-color 0.3s var(--ease); }
@supports (backdrop-filter: blur(1px)) {
  .entete { background: oklch(0.145 0.003 260 / 0.78); backdrop-filter: blur(14px) saturate(1.2); }
}
.entete.defile { border-bottom-color: oklch(1 0 0 / 0.07); }
.entete-dedans { display: flex; align-items: center; justify-content: space-between; gap: var(--e-5); min-height: 4.5rem; }
.entete .logo { font-size: 1.5rem; }
.menu { display: flex; gap: var(--e-6); }
.menu a { position: relative; text-decoration: none; color: var(--craie); font-size: var(--t-petit); opacity: 0.72; transition: opacity 0.2s var(--ease); }
.menu a::after { content: ''; position: absolute; left: 0; right: 0; bottom: -5px; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: right; transition: transform 0.35s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .menu a:hover { opacity: 1; }
  .menu a:hover::after { transform: scaleX(1); transform-origin: left; }
}

/* Boutons propres à l'accueil */
.btn-petit { min-height: 2.5rem; padding: 0.5em 1.05em; font-size: var(--t-petit); }
/* Le bouton sombre éclairé de Resend : un liseré de lumière en haut, un fond qui s'assombrit vers le bas */
.btn-clair {
  background: linear-gradient(180deg, oklch(0.29 0.003 260), oklch(0.205 0.003 260));
  color: var(--craie);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.14), 0 0 0 1px oklch(1 0 0 / 0.1), 0 6px 20px -8px oklch(0 0 0 / 0.8);
}
@media (hover: hover) and (pointer: fine) {
  .btn-clair:hover { background: linear-gradient(180deg, oklch(0.33 0.003 260), oklch(0.24 0.003 260)); }
}
.btn-fleche { width: 1.05em; height: 1.05em; margin-left: 0.45em; margin-right: -0.15em; transition: transform 0.3s var(--ease); }
@media (hover: hover) and (pointer: fine) { .btn:hover .btn-fleche { transform: translateX(3px); } }
.rangee { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3); }
.rangee-centre { justify-content: center; margin-top: var(--e-2); }

/* ─── Haut de page : la photo du bureau à droite, fondue dans le noir ; le titre monte ligne par ligne ─── */
.heros { position: relative; isolation: isolate; display: grid; align-items: end; min-height: min(calc(100svh - 4.5rem), 54rem); padding: var(--e-8) 0 clamp(3rem, 2rem + 4vw, 6rem); overflow: hidden; }
.heros-photo {
  position: absolute; z-index: -1; top: 0; right: 0; bottom: 0; width: min(72%, 70rem); overflow: hidden;
  container-type: size;
  /* Cadrage de la photo : comme object-fit: cover, mais l'écran de code suit la photo au pixel près */
  --zoom: 1; --px: 0.38; --py: 0.5;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 42%), linear-gradient(to top, transparent 0%, #000 38%), linear-gradient(to bottom, transparent 0%, #000 18%);
  -webkit-mask-composite: source-in, source-in;
  mask-image: linear-gradient(to right, transparent 0%, #000 42%), linear-gradient(to top, transparent 0%, #000 38%), linear-gradient(to bottom, transparent 0%, #000 18%);
  mask-composite: intersect;
}
/* La photo (2000 × 1336) couvre tout le cadre ; --px et --py règlent où elle est coupée */
.photo-scene {
  --largeur: calc(max(100cqw, 149.7cqh) * var(--zoom));
  position: absolute;
  width: var(--largeur);
  aspect-ratio: 2000 / 1336;
  left: calc((100cqw - var(--largeur)) * var(--px));
  top: calc((100cqh - var(--largeur) / 1.497) * var(--py));
}
.photo-scene img { width: 100%; height: 100%; }
/* La ville derrière la vitre (site.js) : une pièce qui s'éteint, c'est un voile de la couleur de l'immeuble posé sur sa
   fenêtre, aux bords flous ; la télé, une lueur froide qui scintille par-dessus une autre fenêtre */
.ville { position: absolute; inset: 0; pointer-events: none; }
.piece { position: absolute; opacity: 0; filter: blur(1.5px); transition: opacity 0.15s ease-out; }
.piece.eteinte { opacity: 1; }
.tele { position: absolute; opacity: 0; background: oklch(0.85 0.01 250); mix-blend-mode: screen; filter: blur(1px); transition: opacity 0.06s linear; }
/* Les posters du mur (décor) : couchés dans la perspective du mur par site.js (le mur fuit vers la droite : leurs bords
   hauts et bas convergent vers son point de fuite, le côté droit est un peu plus petit ; Félix, 18/10/2026 : « ça ne prend
   pas du tout en compte la perspective du mur »). Passés en gris et assombris pour prendre la lumière de la pièce : la
   lampe, en bas à gauche, les éclaire de ce côté, ils s'éteignent vers le haut à droite. Collés à plat, sans scotch
   (« ça fait un peu trop cassos »), avec une ombre courte. La matière du poster (papier satiné, ondulations, reflet) est
   dans l'image (outils/posters). Sans script, pas de perspective : ils restent cachés. */
.affiches { position: absolute; inset: 0; pointer-events: none; }
html:not(.js) .affiches { display: none; }
.affiche { position: absolute; left: 0; top: 0; width: 100px; height: calc(100px * var(--rapport, 1)); transform-origin: 0 0; }
/* En WebGL (affiches.js), les feuilles souples et leurs ombres remplacent les affiches HTML, gardées pour les navigateurs
   sans WebGL et les « animations réduites » */
.affiches-toile { position: absolute; pointer-events: none; }
.affiches.en-webgl { display: none; }
/* La feuille, dans le plan du mur : collée un peu de travers, comme un post-it (Félix, 18/10/2026 : « un petit peu plus en
   post-it »), tenue par le haut ; son coin bas droit décolle et ombre le mur. Un courant d'air la fait bouger : le bas se
   balance à peine et le coin se soulève puis retombe (« animée, genre avec un petit peu de vent »), chaque feuille à son
   rythme (--d, --t). En « animations réduites », elle reste immobile. */
.feuille {
  position: absolute; inset: 0; isolation: isolate; transform-origin: 50% 0;
  transform: rotate(var(--r, 0deg));
  box-shadow: 1px 1px 2.5px oklch(0 0 0 / 0.55);
  filter: blur(0.25px);
  animation: vent var(--d, 6s) ease-in-out var(--t, 0s) infinite;
}
.feuille img { display: block; width: 100%; height: 100%; filter: grayscale(1) brightness(var(--b, 0.5)) contrast(var(--c, 0.96)); }
/* la punaise en haut au milieu, là où la feuille est tenue (Félix, 18/10/2026 : « un petit pins en haut des affiches ») :
   une tête ronde en métal, éclairée par la lampe d'en bas à gauche, son ombre portée vers le haut à droite */
.punaise {
  position: absolute; z-index: 2; left: 50%; top: 4.5%; width: 9%; aspect-ratio: 1; margin-left: -4.5%; border-radius: 50%;
  background: radial-gradient(circle at 36% 64%, oklch(0.78 0 0) 0 7%, oklch(0.5 0 0) 24%, oklch(0.28 0 0) 58%, oklch(0.16 0 0) 100%);
  box-shadow: 1.4px -1px 1.6px oklch(0 0 0 / 0.65), inset -0.6px 0.6px 0.8px oklch(0 0 0 / 0.5);
}
/* l'ombre du coin qui décolle, sous la feuille */
.feuille::before {
  content: ''; position: absolute; z-index: -1; right: 3%; bottom: 4%; width: 38%; height: 22%;
  box-shadow: 3px 5px 7px oklch(0 0 0 / 0.7); transform: rotate(5deg);
  animation: coin var(--d, 6s) ease-in-out var(--t, 0s) infinite;
}
/* la lumière : la lampe éclaire d'en bas à gauche ; le coin soulevé s'assombrit (il ne fait plus face à la lampe) */
.feuille::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(315deg, oklch(0 0 0 / 0.42) 0%, oklch(0 0 0 / 0.18) 9%, transparent 17%),
    linear-gradient(to top right, transparent 25%, oklch(0 0 0 / 0.45));
  animation: pli var(--d, 6s) ease-in-out var(--t, 0s) infinite;
}
@keyframes vent {
  0%, 100% { transform: rotate(var(--r, 0deg)) skewX(0deg) scaleY(1); }
  30% { transform: rotate(calc(var(--r, 0deg) + 0.5deg)) skewX(-0.9deg) scaleY(0.996); }
  55% { transform: rotate(calc(var(--r, 0deg) - 0.3deg)) skewX(0.6deg) scaleY(1); }
  78% { transform: rotate(calc(var(--r, 0deg) + 0.2deg)) skewX(-0.3deg) scaleY(0.998); }
}
@keyframes coin {
  0%, 100% { box-shadow: 3px 5px 7px oklch(0 0 0 / 0.7); }
  30% { box-shadow: 5px 8px 10px oklch(0 0 0 / 0.75); }
  55% { box-shadow: 2px 3px 5px oklch(0 0 0 / 0.6); }
}
@keyframes pli { 0%, 100% { opacity: 0.9; } 30% { opacity: 1; } 55% { opacity: 0.75; } }
@media (prefers-reduced-motion: reduce) { .feuille, .feuille::before, .feuille::after { animation: none; } }
/* La lumière des deux lampes tire sur le vert d'eau du site : une lueur douce autour des abat-jour (la vraie lampe à droite ; son reflet dans la vitre, à gauche, bien plus faible : à pleine force il faisait faux, Félix 17/10/2026), rien sur le mur
   (Félix, 17/10/2026 : « la lampe reflète une lumière vert d'eau comme les trucs de mon site »). Elle part des lampes
   elles-mêmes, la seule lumière de la pièce ; la tache sur la dalle de l'écran est de la même teinte (.ecran-reflet). */
.lampe-lueur {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse 6% 7.5% at 49.5% 40.3%, oklch(0.86 0.085 168 / 0.15), oklch(0.86 0.085 168 / 0.05) 45%, transparent 100%),
    radial-gradient(ellipse 7.5% 10% at 57% 39.5%, oklch(0.86 0.085 168 / 0.42), oklch(0.86 0.085 168 / 0.16) 40%, transparent 100%);
}

/* L'écran de l'ordinateur : un petit éditeur de code posé sur la photo, déformé en perspective
   (site.js calcule la déformation à partir des quatre coins de l'écran sur la photo) */
/* L'écran de l'ordinateur : le bureau noir et son Dock sont peints dans la photo (outils/photo-bureau.py).
   Ici, posés en perspective sur les quatre coins de la dalle (site.js) : l'icône de l'application de code,
   sa fenêtre qui s'ouvre depuis le Dock, et le reflet de la lampe. Tout est mesuré dans un rectangle de 380 × 238,
   le même que dans photo-bureau.py (Dock de 120 à 256, case de l'appli à x = 182,5, y = 218,5). */
.ecran-code {
  position: absolute; left: 0; top: 0; width: 380px; height: 238px; overflow: hidden;
  transform-origin: 0 0;
  font-family: var(--police); font-size: 9.5px; font-weight: 480; line-height: 1.5; font-stretch: 94%;
  color: oklch(0.86 0.004 260);
  /* L'écran pris dans la lumière de la pièce, pas collé dessus (Félix, 15/10/2026 : « ça se voit clairement que l'écran
     n'est pas dans l'environnement de cette salle », « qu'il ait la luminosité de la salle ») : le texte moins lumineux
     et moins saturé, aussi doux que la photo ; les noirs restent profonds (relevés, l'écran paraissait gris) */
  filter: blur(0.45px) brightness(0.84) saturate(0.82);
}
/* Le bureau : noir, du même ton que l'appli de code (celui peint dans la photo paraissait gris autour d'elle :
   Félix, 15/10/2026, « l'écran qui est gris quand ça écrit »), avec la lueur vert d'eau basse derrière le Dock */
.ecran-bureau {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 62% 24% at 50% 106%, oklch(0.86 0.085 168 / 0.16), transparent 72%), oklch(0.11 0.004 260);
}
/* La barre de menus */
.ecran-menus {
  position: absolute; left: 0; right: 0; top: 0; height: 7px; display: flex; align-items: center; gap: 5.5px; padding: 0 8px;
  background: oklch(0.13 0.004 260 / 0.92); font-size: 4.3px; line-height: 1; color: oklch(0.9 0.004 260); white-space: nowrap;
}
.ecran-menus b { font-weight: 700; }
.menu-pomme { width: 4.6px; height: 5.4px; margin-right: 1px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23eee' d='M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701'/%3E%3C/svg%3E") center / contain no-repeat; }
.menus-droite { margin-left: auto; display: flex; align-items: center; gap: 5px; }
.menu-batterie { position: relative; width: 7px; height: 3.4px; border: 0.45px solid oklch(0.9 0.004 260 / 0.8); border-radius: 1px; }
.menu-batterie::before { content: ''; position: absolute; inset: 0.45px; right: 2px; border-radius: 0.4px; background: oklch(0.9 0.004 260); }
.menu-batterie::after { content: ''; position: absolute; right: -1.2px; top: 0.9px; width: 0.7px; height: 1.3px; border-radius: 0 0.4px 0.4px 0; background: oklch(0.9 0.004 260 / 0.8); }

/* Le Dock : une barre translucide, des icônes à coins arrondis, un point sous les applis ouvertes */
.ecran-dock {
  position: absolute; z-index: 1; left: 0; right: 0; bottom: 3px; margin: 0 auto; width: max-content;
  display: flex; align-items: flex-end; gap: 2.7px; padding: 2.5px 3.2px;
  border-radius: 5.5px; background: oklch(0.34 0.004 260 / 0.5);
  box-shadow: inset 0 0 0 0.5px oklch(1 0 0 / 0.16), 0 2px 7px oklch(0 0 0 / 0.45);
}
.dock-icone { position: relative; flex: none; width: 12.6px; height: 12.6px; }
.dock-icone img { display: block; width: 100%; height: 100%; border-radius: 22.6%; filter: drop-shadow(0 0.5px 0.7px oklch(0 0 0 / 0.5)); }
.dock-icone.actif::after { content: ''; position: absolute; left: 50%; bottom: -2.1px; width: 1.3px; height: 1.3px; margin-left: -0.65px; border-radius: 50%; background: oklch(0.88 0.004 260); }
.dock-appli::after { content: ''; position: absolute; left: 50%; bottom: -2.1px; width: 1.3px; height: 1.3px; margin-left: -0.65px; border-radius: 50%; background: oklch(0.88 0.004 260); opacity: 0; transition: opacity 0.3s; }
.dock-appli.active::after { opacity: 1; }
.dock-appli.saute { animation: saute 0.95s cubic-bezier(0.3, 0, 0.3, 1); }
@keyframes saute { 0%, 50%, 100% { transform: none; } 22% { transform: translateY(-7px); } 72% { transform: translateY(-4px); } }
.dock-calendrier { display: grid; justify-items: center; align-content: start; border-radius: 22.6%; background: oklch(0.98 0.002 260); box-shadow: 0 0.5px 0.7px oklch(0 0 0 / 0.5); overflow: hidden; }
.dock-calendrier b { margin-top: 1.5px; font-size: 2.5px; font-weight: 700; letter-spacing: 0.08px; color: oklch(0.63 0.21 27); line-height: 1; }
.dock-calendrier i { font-style: normal; font-size: 7.2px; font-weight: 400; line-height: 1.05; letter-spacing: -0.2px; color: oklch(0.2 0.004 260); }
.dock-separateur { flex: none; align-self: center; width: 0.5px; height: 11px; margin: 0 1.2px; background: oklch(1 0 0 / 0.25); }

.ecran-fenetre {
  /* agrandie à tout l'écran, sous la barre de menus et jusqu'au Dock : plus de bureau gris autour ; thème noir
     (Félix, 15/10/2026 : « l'écran qui est gris quand ça écrit ») */
  position: absolute; left: 0; top: 7px; width: 380px; height: 205px; overflow: hidden;
  display: grid; grid-template-rows: 15px 1fr;
  border-radius: 5px; background: oklch(0.115 0.004 260);
  box-shadow: 0 0 0 0.6px oklch(1 0 0 / 0.14), 0 10px 26px oklch(0 0 0 / 0.65);
  /* Fermée, elle est réduite dans l'icône du Dock */
  transform-origin: 174px 212px; transform: scale(0.04); opacity: 0;   /* l'origine exacte est posée par site.js, sur l'icône du Dock */
  transition: transform 0.42s cubic-bezier(0.55, 0, 0.75, 0.1), opacity 0.3s ease-in 0.1s;
}
.ecran-fenetre.ouverte { transform: none; opacity: 1; transition: transform 0.6s var(--ease-expo), opacity 0.2s ease-out; }
.fen-titre { display: flex; align-items: center; gap: 3.5px; padding: 0 7px; background: oklch(0.155 0.004 260); border-bottom: 0.6px solid oklch(0 0 0 / 0.5); font-size: 7px; color: oklch(0.6 0.004 260); }
.fen-titre i { width: 5px; height: 5px; border-radius: 50%; background: oklch(0.65 0.17 25); }
.fen-titre i:nth-child(2) { background: oklch(0.8 0.14 85); }
.fen-titre i:nth-child(3) { background: oklch(0.72 0.15 150); }
.fen-titre span { flex: 1; text-align: center; margin-right: 22px; }
.fen-corps { display: grid; grid-template-columns: 62px 1fr; min-height: 0; }
.fen-fichiers { list-style: none; margin: 0; padding: 7px 0 0; background: oklch(0.1 0.004 260); border-right: 0.6px solid oklch(0 0 0 / 0.45); font-size: 7.5px; color: oklch(0.62 0.004 260); }
.fen-fichiers li { padding: 1.5px 7px; white-space: nowrap; }
.fen-fichiers li.actif { background: oklch(0.2 0.006 260); color: oklch(0.92 0.004 260); }
.fen-editeur { position: relative; display: grid; grid-template-rows: 13px 1fr; min-height: 0; }
.fen-onglets { display: flex; background: oklch(0.1 0.004 260); }
.fen-onglet { display: flex; align-items: center; padding: 0 9px; background: oklch(0.115 0.004 260); border-top: 1px solid var(--eau); font-size: 7.5px; color: oklch(0.88 0.004 260); }
/* Le code défile vers le haut à mesure qu'il s'écrit : la zone reste toujours pleine, l'écran garde la même teinte */
.fen-code { position: relative; min-height: 0; overflow: hidden; }
.ecran-lignes { list-style: none; margin: 0; padding: 6px 8px 0 0; counter-reset: ligne var(--debut, 0); transition: transform 0.45s var(--ease-expo); }
.ecran-lignes.sans-glisse { transition: none; }
.ecran-lignes li { position: relative; padding-left: 26px; white-space: pre; counter-increment: ligne; font-variant-numeric: tabular-nums; }
.ecran-lignes li::before { content: counter(ligne); position: absolute; left: 0; width: 17px; text-align: right; color: oklch(0.45 0.004 260); }
/* Le terminal monte du bas de l'éditeur quand le programme est lancé */
.fen-terminal { position: absolute; left: 0; right: 0; bottom: 0; height: 34px; padding: 5px 9px; background: oklch(0.095 0.004 260); border-top: 0.6px solid oklch(1 0 0 / 0.08); transform: translateY(100%); transition: transform 0.4s var(--ease-expo); }
.fen-terminal.visible { transform: none; }
.fen-terminal p { margin: 0; white-space: pre; }
.fen-commande { color: oklch(0.65 0.004 260); }
.ecran-ok.passe { opacity: 0.45; }
.ecran-ok { color: var(--eau); }
.c-com { color: oklch(0.55 0.006 260); }
.c-mot { color: oklch(0.74 0.06 250); }
.c-txt, .c-num { color: var(--eau); }
.c-fn { color: oklch(0.95 0.004 260); font-weight: 600; }
/* Le curseur clignote au bout de la ligne qui s'écrit */
.curseur::after { content: ''; display: inline-block; width: 1px; height: 1.15em; margin-left: 1px; vertical-align: -0.22em; background: oklch(0.92 0.004 260); animation: clignote 1.05s steps(1) infinite; }
@keyframes clignote { 50% { opacity: 0; } }
/* Le pointeur de la souris (la flèche de macOS), un peu plus grand que nature pour qu'on le voie.
   La flèche est dans ::before : au clic, c'est elle qui rétrécit, par sa pointe. Avant, la propriété `scale` était posée
   sur le pointeur lui-même : CSS l'applique APRÈS le déplacement (translate), donc elle rétrécissait aussi la distance
   parcourue, et le pointeur sautait de 18 % vers le coin de l'écran à chaque clic, puis revenait (Félix, 17 et 18/10/2026 :
   « le clic se déplace au moment de cliquer sur l'appli »). */
.ecran-curseur {
  position: absolute; left: 0; top: 0; width: 6.5px; height: 10px; z-index: 2;
  transform: translate(250px, 120px);
  transition: transform var(--duree, 0.75s) cubic-bezier(0.45, 0, 0.2, 1);
  will-change: transform;
  filter: drop-shadow(0 0.5px 0.6px oklch(0 0 0 / 0.5));
}
.ecran-curseur::before {
  content: ''; position: absolute; inset: 0; transform-origin: 0 0; transition: transform 0.08s ease-out;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 20'%3E%3Cpath d='M1 1v15.5l4-3.7 2.9 6.2 2.6-1.1-2.8-6.1h5.3z' fill='%23fff' stroke='%23000' stroke-width='1.1' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
.ecran-curseur.clic::before { transform: scale(0.82); }
/* Le reflet de la lampe sur la dalle (à gauche), par-dessus la fenêtre. Sans mode de mélange (mix-blend-mode) : sur
   iPhone, Safari les appliquait mal pendant que le code s'écrit, et le grain posé en « superposition » devenait un
   voile gris (captures de Félix, 15/10/2026). Le grain de la photo n'est plus posé sur l'écran. */
/* les bords de la dalle sont adoucis, et un peu éclairés du côté de la lampe (à gauche), la seule lumière de la pièce :
   l'écran ne se découpe pas net sur la photo (la lueur vert d'eau du mur, retirée, débordait aussi ici) */
.ecran-reflet {
  position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 6px 1px oklch(0 0 0 / 0.22), inset 7px 2px 14px oklch(1 0 0 / 0.045);
}
/* la lampe se reflète sur la dalle, à gauche : une tache douce et un voile en biais */
.ecran-reflet::before {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 60% 55% at -6% 6%, oklch(0.9 0.06 168 / 0.1), oklch(0.9 0.06 168 / 0.03) 45%, transparent 70%),
    linear-gradient(112deg, oklch(1 0 0 / 0.04) 0%, oklch(1 0 0 / 0.012) 30%, transparent 46%);
}
/* le texte s'éteint un peu vers le bord droit, que la lampe n'éclaire pas, et le grain de la photo passe dessus */
.ecran-reflet::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, transparent 55%, oklch(0.11 0.004 260 / 0.28) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23g)'/%3E%3C/svg%3E");
}

.heros-dedans { width: 100%; }
.heros-texte { display: grid; gap: var(--e-5); justify-items: start; max-width: 46rem; }
.promesse { font-size: clamp(2.625rem, 1.1rem + 4.7vw, 5.5rem); line-height: 0.98; }
/* sur les téléphones très étroits (320 px), un peu plus petit : « Enfin la solution » tient sur une ligne */
@media (max-width: 22.5rem) { .promesse { font-size: 2.3rem; } }
/* « Enfin la solution » s'efface au clavier, puis « Solut[IA]a » s'écrit (site.js) ; « pour automatiser votre entreprise. » reste.
   Le nom est caché tant que le script ne l'écrit pas : sans JavaScript ou en « animations réduites », la phrase reste entière. */
.nom-final { display: none; }
.nom-final.ecrit { display: inline; }
.promesse .logo-crochet { font-family: var(--police-code); font-weight: 200; margin: 0 -0.15em; }
.ligne { position: relative; display: block; overflow: hidden; padding-bottom: 0.12em; margin-bottom: -0.12em; }
/* Une lettre du nom qui s'écrit apparaît en se précisant (site.js) ; celles qui ne sont pas entre crochets portent la même
   lumière que le titre (dans un élément qui s'anime, le dégradé du parent ne dessine plus le texte) */
.lettre-arrive { animation: lettre-arrive 0.34s var(--ease) both; }
.lettre-lumiere { background-image: linear-gradient(to bottom, var(--craie) 45%, oklch(0.97 0.002 260 / 0.72)); -webkit-background-clip: text; background-clip: text; color: transparent; }
@keyframes lettre-arrive { from { opacity: 0; filter: blur(0.12em); } to { opacity: 1; filter: blur(0); } }
/* Une lettre effacée du grand titre s'évapore sur place : une copie (posée par site.js) qui se brouille et s'efface */
.lettre-fantome { position: absolute; pointer-events: none; white-space: pre; color: var(--craie); will-change: opacity, filter; animation: lettre-fantome 0.4s var(--ease) forwards; }
@keyframes lettre-fantome { from { opacity: 0.9; filter: blur(0); } to { opacity: 0; filter: blur(0.12em); } }
.ligne-dedans { display: inline-block; white-space: nowrap; }   /* pas de retour à la ligne : la frappe du nom ne casse plus la ligne autour du curseur */
.heros-texte .legende { margin-top: calc(var(--e-2) * -1); }

html.js .heros-photo { opacity: 0; transform: scale(1.06); }
html.js .ligne-dedans { transform: translateY(105%); }
html.js .entree { opacity: 0; transform: translateY(14px); }

html.js body.pret .heros-photo { opacity: 1; transform: none; transition: opacity 1.4s ease-out, transform 2.4s var(--ease-expo); }
html.js body.pret .ligne-dedans { transform: none; transition: transform 1s var(--ease-expo) calc(0.15s + var(--i) * 0.09s); }
html.js body.pret .entree { opacity: 1; transform: none; transition: opacity 0.8s ease-out calc(0.25s + var(--i) * 0.09s), transform 1s var(--ease-expo) calc(0.25s + var(--i) * 0.09s); }

/* ─── « Solution » devient « Solut[IA]a » au clavier (site.js) : le curseur efface « ion », puis tape « [IA]a ».
   Sans script, le logo s'affiche directement. Avec, il part de « Solution » dès le premier affichage. ─── */
.ancien { display: none; }
html.js [data-mot] .ancien { display: inline; }
html.js [data-mot]:not(.anime) :is(.logo-crochet, .logo-ia, .sig-cr, .sig-ia, .nouveau) { display: none; }
[data-mot] .cache { display: none !important; }
.curseur-mot { position: relative; display: inline-block; width: 0; height: 0.84em; vertical-align: -0.06em; align-self: baseline; }
.curseur-mot::after {
  content: ''; position: absolute; left: 0.02em; top: 0; bottom: 0; width: 0.075em; border-radius: 1px;
  background: var(--eau); animation: clignote-mot 1.05s steps(1) infinite;
}
.curseur-mot.fini::after { opacity: 0; animation: none; transition: opacity 0.4s ease-out; }
/* « Félix Lucas. » : les lettres pas encore tapées gardent leur place (le nom centré ne bouge pas pendant la frappe) */
.pas-tape { visibility: hidden; }
@keyframes clignote-mot { 50% { opacity: 0; } }
.signature .curseur-mot::after { box-shadow: 0 0 0.12em oklch(0.86 0.085 168 / 0.6); }

/* ─── Apparitions au défilement ─── */
html.js .revele { opacity: 0; transform: translateY(18px); }
html.js .revele.vu { opacity: 1; transform: none; transition: opacity 0.7s ease-out, transform 0.9s var(--ease-expo); }

/* ─── Sections ─── */
/* Chaque section s'ouvre sur un trait fin qui s'efface vers les bords, et une lumière douce venue d'en haut */
.bloc { position: relative; padding: var(--e-9) 0; }
.bloc::before { content: ''; position: absolute; top: 0; left: 50%; width: min(76rem, 100%); height: 1px; transform: translateX(-50%); background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.14), transparent); }
.bloc::after { content: ''; position: absolute; top: 0; left: 50%; width: min(44rem, 90%); height: 11rem; transform: translateX(-50%); background: radial-gradient(ellipse at top, oklch(1 0 0 / 0.05), transparent 70%); pointer-events: none; }
.bloc-tete { display: grid; gap: var(--e-4); max-width: 46rem; margin-bottom: var(--e-8); }
.bloc-tete.centre { justify-items: center; text-align: center; margin-inline: auto; }
.bloc-tete.centre .chapo { margin-inline: auto; }
h2.grand { font-size: clamp(2.75rem, 1.4rem + 5vw, 5.5rem); line-height: 1; }

/* ─── Les tuiles en relief, façon resend.com : la tuile en métal sablé et son objet gravé sont une courte vidéo en
   boucle, rendue à l'avance (outils/icones-3d). La tuile occupe 85 % de l'image : la vidéo déborde de la boîte
   d'autant, et son fond (celui de la page) est rogné au ras des coins arrondis. ─── */
.tuile {
  position: relative; isolation: isolate;
  width: clamp(7rem, 5.5rem + 4vw, 9.25rem); aspect-ratio: 1; margin-bottom: var(--e-4);
}
.tuile::after {
  content: ''; position: absolute; z-index: -1; left: 14%; right: 14%; bottom: -14%; height: 28%;
  background: radial-gradient(ellipse at top, var(--eau-lueur), transparent 70%); filter: blur(14px); opacity: 0.8;
}
.tuile-video {
  position: absolute; inset: -9.1%; width: 118.2%; height: 118.2%; max-width: none; display: block;
  clip-path: inset(7.4% round 17%);
}

/* ─── Ce qui prend du temps : les crochets se referment autour de chaque tâche ─── */
.mots { list-style: none; margin: 0; padding: 0; display: grid; }
.mots li { position: relative; display: flex; align-items: baseline; justify-content: space-between; gap: var(--e-5); padding: var(--e-4) 0 var(--e-5); }
.mots li::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: var(--trait); transform-origin: left; }
/* les tâches s'écrivent comme du code, crochets compris (Félix, 15/10/2026 : « en typo typique codage ») */
.mot { font-family: var(--police-code); font-size: clamp(1.75rem, 0.75rem + 3.4vw, 4.25rem); font-weight: 500; letter-spacing: -0.03em; line-height: 1.1; color: var(--craie); white-space: nowrap; }
.mot .cr { display: inline-block; font-family: var(--police-code); font-weight: 300; color: var(--gris-2); }
.mot .cr:first-child { margin-right: 0.04em; }
.mot .cr:last-child { margin-left: 0.04em; }
.desc { color: var(--gris); text-align: right; font-size: var(--t-chapo); }
.relance-mot { margin-top: var(--e-6); font-size: var(--t-chapo); color: var(--gris); }
.relance-mot a { color: var(--craie); text-underline-offset: 0.2em; }

html.js .mots li::before { transform: scaleX(0); }
html.js .mot { color: var(--gris-2); }
html.js .mot .cr { opacity: 0; }
html.js .mot .cr:first-child { transform: translateX(-0.45em); }
html.js .mot .cr:last-child { transform: translateX(0.45em); }
html.js .desc { opacity: 0; transform: translateY(8px); }
html.js .mots li.vu::before { transform: scaleX(1); transition: transform 1.1s var(--ease-expo); }
html.js .mots li.vu .mot { color: var(--craie); transition: color 0.5s ease 0.15s; }
html.js .mots li.vu .mot .cr { opacity: 1; transform: none; transition: opacity 0.4s ease-out 0.1s, transform 0.7s var(--ease-expo) 0.1s; }
html.js .mots li.vu .desc { opacity: 1; transform: none; transition: opacity 0.6s ease-out 0.35s, transform 0.8s var(--ease-expo) 0.35s; }

/* ─── Vos outils : la rangée d'icônes de Resend, l'outil choisi s'allume ─── */
.outils { display: grid; gap: var(--e-6); justify-items: center; }
.outils-rangee { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--e-5) var(--e-2); max-width: 64rem; }
.outil {
  appearance: none; background: none; border: 0; padding: 0; margin: 0;
  display: grid; justify-items: center; gap: var(--e-2); width: 4.75rem;
  color: var(--gris-2); font: inherit; font-size: var(--t-legende); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.outil-icone {
  display: grid; place-items: center; width: 3.5rem; aspect-ratio: 1; border-radius: 14px;
  background: linear-gradient(180deg, oklch(0.19 0.003 260), oklch(0.145 0.003 260));
  box-shadow: inset 0 0 0 1px oklch(1 0 0 / 0.08), inset 0 1px 0 oklch(1 0 0 / 0.06);
  transition: box-shadow 0.3s var(--ease), transform 0.3s var(--ease), background 0.3s var(--ease);
}
.outil svg { width: 1.45rem; height: 1.45rem; color: var(--gris); transition: color 0.3s var(--ease); }
.outil-icone-ia { font-family: var(--police-code); display: flex; align-items: center; justify-content: center; gap: 0.05em; font-size: 0.78rem; font-weight: 650; letter-spacing: -0.02em; color: var(--gris); transition: color 0.3s var(--ease); }
.outil-icone-ia b { font-weight: 250; color: var(--gris-2); }
.outil[aria-selected="true"] .outil-icone-ia { color: var(--eau); }
@media (hover: hover) and (pointer: fine) { .outil:hover .outil-icone-ia { color: var(--craie); } .outil[aria-selected="true"]:hover .outil-icone-ia { color: var(--eau); } }
.outil-nom { transition: color 0.3s var(--ease); }
.outil:active .outil-icone { transform: scale(0.95); }
.outil[aria-selected="true"] .outil-icone {
  background: linear-gradient(180deg, oklch(0.24 0.003 260), oklch(0.17 0.003 260));
  box-shadow: inset 0 0 0 1px oklch(1 0 0 / 0.2), inset 0 1px 0 oklch(1 0 0 / 0.14), 0 12px 30px -12px var(--eau-lueur);
}
.outil[aria-selected="true"] svg { color: var(--eau); }
.outil[aria-selected="true"] .outil-nom { color: var(--craie); }
@media (hover: hover) and (pointer: fine) {
  .outil:hover .outil-icone { transform: translateY(-2px); }
  .outil:hover svg, .outil:hover .outil-nom { color: var(--craie); }
  .outil[aria-selected="true"]:hover svg { color: var(--eau); }
}
.outil-detail { width: 100%; max-width: 40rem; display: grid; justify-items: center; gap: var(--e-2); padding: var(--e-6) var(--e-6) var(--e-5); text-align: center; }
.outil-titre { font-family: var(--police-code); font-weight: 560; font-size: clamp(1.625rem, 1.2rem + 1.5vw, 2.25rem); line-height: 1.1; letter-spacing: -0.04em; }
.outil-titre .cr, .atout-titre .cr { font-family: var(--police-code); font-weight: 200; color: var(--gris-2); }
.outil-phrase { font-size: var(--t-chapo); max-width: 30em; }
.outil-detail.change > * { animation: change 0.45s var(--ease-expo); }
@keyframes change { from { opacity: 0; transform: translateY(6px); } }

/* ─── Panneau éclairé : un liseré de lumière sur le bord haut ─── */
.eclaire { position: relative; isolation: isolate; background: linear-gradient(to bottom, oklch(0.2 0.003 260), var(--nuit-2) 45%); border: 1px solid var(--trait); border-radius: var(--rayon); }
.eclaire::before { content: ''; position: absolute; top: -1px; left: 12%; right: 12%; height: 1px; background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.45), transparent); }
.eclaire::after { content: ''; position: absolute; z-index: -1; top: 0; left: 18%; right: 18%; height: 7rem; background: radial-gradient(ellipse at top, oklch(1 0 0 / 0.07), transparent 70%); pointer-events: none; }

/* ─── La démo : une fenêtre comme l'éditeur de Resend, la règle s'exécute ligne par ligne ─── */
.fenetre {
  position: relative; overflow: hidden; border-radius: 16px; background: var(--fond-creux);
  border: 1px solid var(--trait);
  box-shadow: 0 50px 120px -40px oklch(0 0 0 / 0.95), inset 0 1px 0 oklch(1 0 0 / 0.05);
}
.fenetre::before { content: ''; position: absolute; z-index: 1; top: 0; left: 20%; right: 20%; height: 1px; background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.4), transparent); }
.fenetre-barre { display: flex; align-items: center; gap: var(--e-4); height: 2.75rem; padding: 0 var(--e-3) 0 var(--e-4); border-bottom: 1px solid var(--trait); }
.fenetre-points { display: flex; gap: 7px; }
.fenetre-points i { width: 10px; height: 10px; border-radius: 50%; background: oklch(0.3 0.004 260); }
.fenetre-titre { flex: 1; text-align: center; }
.fenetre-rejouer { display: grid; place-items: center; width: 2rem; height: 2rem; border: 0; border-radius: 8px; background: none; color: var(--gris-2); cursor: pointer; transition: color 0.2s var(--ease), background-color 0.2s var(--ease); }
.fenetre-rejouer svg { width: 1rem; height: 1rem; }
@media (hover: hover) and (pointer: fine) { .fenetre-rejouer:hover { color: var(--craie); background: var(--nuit-3); } }

.fenetre-corps { display: grid; grid-template-columns: 12.5rem minmax(0, 1.2fr) minmax(0, 1fr); min-height: 27rem; }
.fenetre-onglets { display: flex; flex-direction: column; gap: 2px; padding: var(--e-3); border-right: 1px solid var(--trait); }
.onglet {
  display: flex; align-items: center; gap: var(--e-3); padding: 0.55rem 0.75rem; border: 0; border-radius: 8px;
  background: none; color: var(--gris); font: inherit; font-size: var(--t-petit); text-align: left; white-space: nowrap; cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}
.onglet svg { flex: none; width: 1rem; height: 1rem; color: var(--gris-2); transition: color 0.2s var(--ease); }
.onglet[aria-selected="true"] { background: var(--nuit-3); color: var(--craie); }
.onglet[aria-selected="true"] svg { color: var(--eau); }
@media (hover: hover) and (pointer: fine) { .onglet:hover { color: var(--craie); } }

/* La règle : numéros de ligne, verbe à gauche, le reste à droite. La ligne en cours s'éclaire,
   celles déjà faites passent en blanc. */
.regle { list-style: none; margin: 0; padding: var(--e-5) 0; border-right: 1px solid var(--trait); font-size: var(--t-petit); counter-reset: ligne; }
.regle li {
  position: relative; counter-increment: ligne;
  display: grid; grid-template-columns: 3rem 7.25rem minmax(0, 1fr); align-items: baseline;
  padding: 0.42rem var(--e-5) 0.42rem 0; line-height: 1.45;
  transition: background-color 0.35s var(--ease);
}
.regle li::before { content: counter(ligne); padding-right: var(--e-4); text-align: right; color: oklch(0.42 0.004 260); font-variant-numeric: tabular-nums; transition: color 0.3s var(--ease); }
.regle .mot-cle { padding-right: var(--e-3); color: var(--gris-2); font-weight: 600; overflow-wrap: anywhere; transition: color 0.3s var(--ease); }
.regle .texte { color: var(--gris-2); transition: color 0.3s var(--ease); }
.regle li.faite .mot-cle { color: var(--gris); }
.regle li.faite .texte { color: var(--craie); }
.regle li.en-cours { background: oklch(1 0 0 / 0.045); }
.regle li.en-cours::before { color: var(--eau); }
.regle li.en-cours .mot-cle { color: var(--eau); }
.regle li.en-cours .texte { color: var(--craie); }

/* L'aperçu : ce qui se passe pour de vrai, les éléments arrivent par le bas */
.apercu {
  position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; gap: var(--e-2);
  padding: var(--e-5);
  background: radial-gradient(ellipse 80% 50% at 50% 0%, oklch(1 0 0 / 0.04), transparent 70%);
}
.apercu > * { flex: none; }
.apercu { padding-top: 3.75rem; }
.apercu-tete { position: absolute; top: 0; left: var(--e-5); right: var(--e-5); display: flex; align-items: center; gap: 0.5rem; height: 2.75rem; border-bottom: 1px solid var(--trait); font-size: var(--t-legende); color: var(--gris-2); }
.apercu-tete svg { width: 0.95rem; height: 0.95rem; color: var(--gris); }
html.js .apercu > * { opacity: 0; transform: translateY(10px) scale(0.98); }
html.js .apercu > .on { opacity: 1; transform: none; transition: opacity 0.35s ease-out, transform 0.55s var(--ease-expo); }

.bulle { max-width: 85%; padding: 0.6em 0.95em; border-radius: 18px; font-size: var(--t-petit); line-height: 1.4; }
.bulle.client { align-self: flex-start; background: var(--nuit-3); color: var(--craie); border-bottom-left-radius: 6px; transform-origin: left bottom; }
.bulle.bot { align-self: flex-end; background: var(--craie); color: var(--nuit); border-bottom-right-radius: 6px; transform-origin: right bottom; }
.bulle.ecrit { display: inline-flex; gap: 4px; padding: 0.85em 1em; }
.bulle.ecrit span { width: 6px; height: 6px; border-radius: 50%; background: var(--gris-2); animation: point 1s ease-in-out infinite; }
.bulle.ecrit span:nth-child(2) { animation-delay: 0.15s; }
.bulle.ecrit span:nth-child(3) { animation-delay: 0.3s; }
@keyframes point { 0%, 60%, 100% { opacity: 0.35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }
.marque { align-self: center; margin: var(--e-1) 0; font-size: var(--t-petit); color: var(--eau); }
.marque .cr, .etiquette .cr { color: var(--gris-2); font-weight: 250; }
.code { font-family: var(--police-code); letter-spacing: -0.01em; }   /* un mot entre crochets, dans la démo */

.carte { display: grid; gap: 0.35rem; padding: 0.8rem 0.95rem; border-radius: 12px; background: var(--nuit-2); border: 1px solid var(--trait); font-size: var(--t-petit); }
.carte-tete { display: flex; align-items: center; gap: 0.5rem; font-size: var(--t-legende); color: var(--gris-2); }
.carte-tete svg { width: 0.95rem; height: 0.95rem; color: var(--gris); }
.carte-titre { font-weight: 600; color: var(--craie); }
.carte-ligne { display: flex; justify-content: space-between; gap: var(--e-4); color: var(--gris); }
.carte-ligne b { font-weight: 500; color: var(--craie); }
.carte-ligne.eteinte { color: var(--gris-2); }
.etiquette { font-size: var(--t-legende); color: var(--eau); white-space: nowrap; }
.puces { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.2rem; }
.puce { padding: 0.2rem 0.6rem; border-radius: 6px; background: var(--nuit-3); color: var(--gris); font-size: var(--t-legende); }
.puce.choisie { background: var(--craie); color: var(--nuit); }
.journal { display: flex; gap: var(--e-3); font-size: var(--t-legende); color: var(--gris); }
.journal time { color: var(--gris-2); font-variant-numeric: tabular-nums; }
.faux-bouton { justify-self: start; padding: 0.35rem 0.85rem; border-radius: 6px; background: var(--craie); color: var(--nuit); font-size: var(--t-legende); font-weight: 600; transition: transform 0.15s var(--ease), background-color 0.3s var(--ease); }
.faux-bouton.appuye { transform: scale(0.94); background: oklch(0.85 0.003 260); }
.notif { display: grid; grid-template-columns: auto 1fr; gap: 0.15rem 0.7rem; padding: 0.75rem 0.85rem; border-radius: 18px; background: oklch(0.24 0.003 260 / 0.95); box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.08), 0 14px 30px -14px oklch(0 0 0 / 0.9); font-size: var(--t-petit); line-height: 1.35; }
.notif-icone { grid-row: span 2; display: grid; place-items: center; width: 2.1rem; height: 2.1rem; border-radius: 9px; background: linear-gradient(180deg, oklch(0.3 0.003 260), oklch(0.18 0.003 260)); color: var(--eau); font-size: 0.72rem; font-weight: 650; letter-spacing: -0.02em; }
.notif-tete { display: flex; justify-content: space-between; gap: var(--e-3); color: var(--craie); font-weight: 600; }
.notif-tete time { color: var(--gris-2); font-weight: 400; font-size: var(--t-legende); }
.notif p { color: var(--gris); }
.demo-note { margin-top: var(--e-4); text-align: center; }

/* ─── FCUTZ : des onglets qui avancent seuls, un écran de téléphone qui change ─── */
.vitrine { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 27rem); gap: var(--e-7); align-items: center; max-width: 66rem; margin: 0 auto; }
.vitrine-onglets { display: grid; gap: var(--e-2); }
.v-onglet {
  position: relative; overflow: hidden; display: grid; gap: 0.2rem; padding: var(--e-4) var(--e-5);
  border: 1px solid transparent; border-radius: 12px; background: none; font: inherit; text-align: left; cursor: pointer;
  transition: background-color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.v-titre { font-size: 1.1875rem; font-weight: 600; letter-spacing: -0.015em; color: var(--gris); transition: color 0.3s var(--ease); }
.v-texte { font-size: var(--t-petit); color: var(--gris-2); }
.v-avance { position: absolute; left: var(--e-5); right: var(--e-5); bottom: 0; height: 1px; background: var(--eau); transform: scaleX(0); transform-origin: left; }
.v-onglet[aria-selected="true"] { background: linear-gradient(180deg, oklch(0.2 0.003 260), oklch(0.165 0.003 260)); border-color: var(--trait); }
.v-onglet[aria-selected="true"] .v-titre { color: var(--craie); }
.v-onglet[aria-selected="true"] .v-texte { color: var(--gris); }
@media (hover: hover) and (pointer: fine) { .v-onglet:hover .v-titre { color: var(--craie); } }
/* La barre fine sous l'onglet actif avance ; au bout, l'onglet suivant prend la main */
/* La barre fine sous l'onglet actif suit la vidéo (site.js) ; au bout, l'onglet suivant prend la main */
.vitrine:not(.auto) .v-avance { opacity: 0; }

.vitrine-ecran { margin: 0; display: grid; gap: var(--e-4); justify-items: center; }
/* Le vrai iPhone 3D : des vidéos rendues sur le fond du site, fondues sur les bords pour ne laisser voir aucun cadre */
.telephone3d {
  position: relative; width: 100%; max-width: 27rem; aspect-ratio: 720 / 1200;
  -webkit-mask-image: radial-gradient(ellipse 70% 62% at 50% 50%, #000 70%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 62% at 50% 50%, #000 70%, transparent 100%);
}
.tel-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.5s ease-out; }
.tel-video.actif { opacity: 1; }
/* Si l'appareil refuse la lecture automatique (iPhone ou iPad en mode économie d'énergie) : un bouton pour la lancer */
.tel-lecture {
  position: absolute; left: 50%; top: 50%; width: 3.75rem; height: 3.75rem; translate: -50% -50%;
  display: grid; place-items: center; border: 0; border-radius: 50%; cursor: pointer;
  background: oklch(0.97 0.002 260 / 0.92); color: var(--nuit); box-shadow: 0 12px 30px -8px oklch(0 0 0 / 0.8);
}
.tel-lecture[hidden] { display: none; }
.tel-lecture svg { width: 1.5rem; height: 1.5rem; margin-left: 3px; }

/* L'iPhone 3D interactif (js/telephone.js) : le modèle dans un canvas, et par-dessus l'écran, une vraie page de
   393 x 852 posée sur la dalle par une matrice de perspective. Une lumière vert d'eau derrière, comme autour du PC. */
.legende-demo { display: none; }
.vitrine-ecran .legende { display: grid; gap: var(--e-1); max-width: 24rem; text-align: center; }
.vitrine-ecran .legende strong { color: var(--craie); font-weight: 600; }
.legende-petite { color: var(--gris-2); opacity: 0.8; }
.lien-discret { padding: 0; border: 0; background: none; font: inherit; color: var(--gris); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.lien-discret:hover { color: var(--craie); }
.en-demo .legende-video, .en-demo .tel-video, .en-demo .tel-lecture { display: none; }
.en-demo .legende-demo { display: block; }
.vitrine.en-demo .telephone3d {
  width: min(100%, 27rem, calc(88svh * 0.6)); -webkit-mask-image: none; mask-image: none; aspect-ratio: 0.6;
}
.en-demo .telephone3d::before {
  content: ""; position: absolute; inset: 8% -10%; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 50% 46% at 50% 54%, oklch(0.86 0.09 165 / 0.13), transparent 70%);
}
.tel-canvas { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; touch-action: pan-y; cursor: grab; }
.tel-canvas.saisi { cursor: grabbing; }
.tel-ecran {
  position: absolute; left: 0; top: 0; z-index: 2; width: 393px; height: 852px; overflow: hidden;
  transform-origin: 0 0; border-radius: 56px; background: #000; color: #fff;
  font-family: -apple-system, "SF Pro Text", system-ui, "Segoe UI", sans-serif;
}
.tel-ecran[hidden] { display: none; }
.tel-appli { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #000; opacity: 0; pointer-events: none; transition: opacity 0.35s ease-out; }
.tel-appli.visible { opacity: 1; pointer-events: auto; }
/* La barre d'état et l'îlot dynamique, posés sur l'appli comme sur un vrai iPhone (l'appli commence 59 pt plus bas) */
.tel-statut { position: absolute; inset: 0 0 auto; z-index: 3; height: 54px; pointer-events: none; display: grid; grid-template-columns: 1fr 126px 1fr; align-items: center; padding-top: 4px; }
.tel-statut time { justify-self: center; padding-right: 6px; font-size: 17px; font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.tel-ilot { align-self: start; margin-top: 7px; height: 37px; border-radius: 20px; background: #000; }
.tel-icones { justify-self: center; display: flex; align-items: center; gap: 6px; padding-left: 6px; }
.tel-icones svg { fill: currentColor; }
.tel-barre { position: absolute; left: 50%; bottom: 8px; z-index: 3; width: 139px; height: 5px; translate: -50% 0; border-radius: 3px; background: #fff; opacity: 0.85; pointer-events: none; }
.tel-reflet {
  position: absolute; inset: 0; z-index: 4; pointer-events: none; border-radius: inherit;
  background: linear-gradient(118deg, transparent 0 34%, oklch(1 0 0 / 0.055) 46%, transparent 58%) var(--reflet, 50%) 0 / 260% 100% no-repeat;
}
/* La notification d'une nouvelle réservation, comme celle que reçoit Félix */
.tel-notif {
  position: absolute; left: 10px; right: 10px; top: 58px; z-index: 5; display: grid; grid-template-columns: 38px 1fr auto; gap: 10px; align-items: start;
  padding: 12px 14px; border: 0; border-radius: 24px; text-align: left; font: inherit; color: #fff; cursor: pointer;
  background: oklch(0.27 0.004 260 / 0.82); -webkit-backdrop-filter: blur(24px) saturate(1.6); backdrop-filter: blur(24px) saturate(1.6);
  box-shadow: 0 10px 30px -10px oklch(0 0 0 / 0.7);
  transform: translateY(-140%); opacity: 0; transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease-out;
}
.tel-notif.tombe { transform: none; opacity: 1; }
.tel-notif[hidden] { display: none; }
.tel-notif img { width: 38px; height: 38px; border-radius: 9px; }
.tel-notif-texte { display: grid; gap: 1px; font-size: 15px; line-height: 1.3; }
.tel-notif-texte b { font-weight: 600; }
.tel-notif time { font-size: 13px; color: oklch(1 0 0 / 0.55); }
/* Sur un écran tactile, il faut toucher l'écran du téléphone avant de s'en servir : sinon, en faisant défiler
   la page du doigt, on resterait coincé dans l'appli */
.tel-voile { position: absolute; inset: 0; z-index: 6; display: grid; place-items: end center; padding: 0 0 110px; border: 0; background: none; cursor: pointer; }
.tel-voile[hidden] { display: none; }
.tel-voile span { padding: 12px 22px; border-radius: 999px; background: oklch(0.97 0.002 260 / 0.94); color: #0b0c0e; font: 600 17px/1.2 var(--police); box-shadow: 0 12px 30px -8px oklch(0 0 0 / 0.8); }

.exemple-fin { display: grid; justify-items: center; text-align: center; margin-top: var(--e-8); }
.citation { margin: 0 0 var(--e-5); padding: 0; }
.citation p { font-family: var(--police-titre); font-size: clamp(1.625rem, 1.1rem + 1.8vw, 2.5rem); font-weight: 500; letter-spacing: -0.035em; line-height: 1.15; max-width: 20em; }

/* ─── TrimSync : le texte à gauche, deux vraies captures de l'appli à droite (la seconde un peu plus bas) ─── */
.produit { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 30rem); gap: var(--e-8); align-items: center; max-width: 68rem; margin: 0 auto; }
.produit-inverse { grid-template-columns: minmax(0, 30rem) minmax(0, 1fr); }
.produit-inverse .produit-ecrans { order: -1; }
.produit-texte { display: grid; gap: var(--e-5); justify-items: start; }
.produit + .produit { margin-top: calc(var(--e-8) * 1.5); }
.produit-texte h3 { margin: 0; font-family: var(--police-titre); font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.25rem); font-weight: 500; letter-spacing: -0.035em; line-height: 1.1; color: var(--craie); text-wrap: balance; }
.produit-points { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-3); }
.produit-points li { position: relative; padding-left: var(--e-5); color: var(--gris); }
.produit-points li::before { content: ''; position: absolute; left: 0; top: 0.8em; width: 0.7rem; height: 1px; background: var(--eau); }
.produit-points b { color: var(--craie); font-weight: 600; }
.produit-ecrans { margin: 0; display: grid; gap: var(--e-4); justify-items: center; }
/* Le visuel d'un exemple : deux vrais iPhone 3D (les mêmes que les vidéos de FCUTZ), fondus sur les bords dans le fond du site */
.produit-visuel { display: block; width: 100%; max-width: 30rem; height: auto; -webkit-mask-image: radial-gradient(ellipse 74% 68% at 50% 50%, #000 66%, transparent 100%); mask-image: radial-gradient(ellipse 74% 68% at 50% 50%, #000 66%, transparent 100%); }
@media (max-width: 860px) {
  .produit { grid-template-columns: 1fr; gap: var(--e-7); }
  .produit-ecrans { order: -1; }
}

/* ─── Aperçu de ce que j'ai déjà fait (accueil) : une ligne par exemple, avec la vraie icône de l'appli ; le détail est sur /realisations ─── */
.realisations-liste { list-style: none; margin: 0 auto; padding: 0; max-width: 46rem; display: grid; border-bottom: 1px solid var(--trait); }
.realisation-ligne {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--e-5); padding: var(--e-5) var(--e-3);
  border-top: 1px solid var(--trait); color: var(--craie); text-decoration: none; transition: background-color 0.3s var(--ease);
}
.realisation-icone { display: block; width: 3.5rem; height: 3.5rem; border-radius: 22.5%; box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08); }
.realisation-corps { display: grid; gap: 0.25rem; min-width: 0; }
.realisation-titre { font-size: 1.1875rem; font-weight: 600; letter-spacing: -0.015em; line-height: 1.25; }
.realisation-texte { font-size: var(--t-petit); color: var(--gris); }
.realisation-fleche { width: 1.1rem; height: 1.1rem; color: var(--gris-2); transition: transform 0.3s var(--ease), color 0.3s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .realisation-ligne:hover { background: oklch(1 0 0 / 0.035); }
  .realisation-ligne:hover .realisation-fleche { transform: translateX(4px); color: var(--craie); }
}
.realisations-fin { margin-top: var(--e-7); }

/* ─── La page « Ce que j'ai fait » : un haut de page court, puis les exemples ─── */
.bloc-haut { padding-block: var(--e-8) var(--e-7); }
.bloc-haut .bloc-tete { margin-bottom: 0; }
.retour { color: var(--gris-2); font-size: var(--t-petit); text-decoration: none; transition: color 0.2s var(--ease); }
.retour:hover { color: var(--craie); }

/* ─── La méthode : quatre étapes, les traits se dessinent ─── */
.etapes { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--e-6); }
.etapes li { position: relative; display: grid; gap: var(--e-3); align-content: start; padding-top: var(--e-5); }
.etapes li::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: var(--trait); transform-origin: left; }
.etape-num { display: block; font-family: var(--police-titre); font-size: clamp(3.5rem, 2rem + 4vw, 6rem); font-weight: 200; letter-spacing: -0.04em; line-height: 0.85; color: var(--gris-2); }
.etapes h3 { font-size: 1.1875rem; }
.etapes p { color: var(--gris); }
.methode-fin { display: grid; justify-items: center; gap: var(--e-5); margin-top: var(--e-8); text-align: center; }
.prix { font-size: var(--t-chapo); }

html.js .etapes li::before { transform: scaleX(0); }
html.js .etapes .etape-num, html.js .etapes h3, html.js .etapes p { opacity: 0; transform: translateY(16px); }
html.js .etapes.vu li::before { transform: scaleX(1); transition: transform 1.1s var(--ease-expo) calc(var(--i) * 0.14s); }
html.js .etapes.vu .etape-num, html.js .etapes.vu h3, html.js .etapes.vu p { opacity: 1; transform: none; transition: opacity 0.6s ease-out calc(0.15s + var(--i) * 0.14s), transform 0.9s var(--ease-expo) calc(0.15s + var(--i) * 0.14s); }

/* ─── Qui je suis ─── */
.qui { display: grid; justify-items: center; text-align: center; gap: var(--e-4); }
.qui h2 { font-size: clamp(3.75rem, 1.5rem + 8vw, 8.5rem); line-height: 0.95; }
.qui .chapo { max-width: 28em; margin-inline: auto; }
/* La vignette 3D de Félix : sa photo détourée dans une carte carrée en métal, la tête qui dépasse du bord haut, en
   calques transparents rendus comme les icônes (outils/icones-3d, objet portrait), alignés au pixel. Elle bascule sous la
   souris et sous le doigt (js/site.js). Félix est dans la carte, sans ombre portée (« je suis censé être dans la
   vignette »), découpé par le masque (la face de la carte, ouverte vers le haut pour la tête) au ras du bord bas.
   Derrière, la tranche répétée fait l'épaisseur de la vignette entière, la tête qui dépasse comprise (« que ma tête
   dépasse mais qu'elle ait une profondeur du même type que la vignette »). Chaque calque est réduit (ou agrandi)
   d'autant qu'il avance (ou recule), pour que tout tombe pile de face. */
.vignette-felix { --recul: 960; position: relative; isolation: isolate; width: min(100%, 20rem); aspect-ratio: 1000 / 1078; margin-bottom: var(--e-5); perspective: calc(var(--recul) * 1px); }
.vignette-felix::after {
  content: ''; position: absolute; z-index: -1; left: 18%; right: 18%; bottom: 3%; height: 16%;
  background: radial-gradient(ellipse at top, var(--eau-lueur), transparent 70%); filter: blur(18px); opacity: 0.8;
}
.vf-carte { position: absolute; inset: 0; transform-style: preserve-3d; will-change: transform; }
.vf-carte > * { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.vf-tranche { transform: translateZ(calc(var(--n) * -4px)) scale(calc(1 + var(--n) * 4 / var(--recul))); }
/* Félix vivant (js/site.js) : le canvas de la vidéo couvre exactement sa photo carrée, telle que le studio la pose dans
   le cadre de la vignette (outils/icones-3d, objet portrait) ; il remplace la photo dès sa première image */
.vf-figure > * { position: absolute; display: block; }
.vf-photo { inset: 0; width: 100%; height: 100%; }
.vf-vivant { left: -5.311%; top: -8.471%; width: 109.87%; height: 101.92%; opacity: 0; transform-origin: 50% 100%; will-change: transform; }
.vignette-felix.vivant .vf-vivant { opacity: 1; }
.vignette-felix.vivant .vf-photo { opacity: 0; }
.vf-source { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.vf-calque {
  transform: translateZ(calc(var(--z) * 1px)) scale(calc(1 - var(--z) / var(--recul)));
  -webkit-mask-image: url(/img/vignette/masque.png?v=2); mask-image: url(/img/vignette/masque.png?v=2);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
/* le reflet de la lumière sur le métal, là où passe le pointeur (sur la carte seulement, pas sur Félix) */
.vf-reflet {
  transform: translateZ(0.5px); pointer-events: none; opacity: var(--eclat, 0.4);
  background: radial-gradient(circle at var(--rx, 34%) var(--ry, 22%), oklch(1 0 0 / 0.17), oklch(1 0 0 / 0.04) 30%, transparent 55%);
  -webkit-mask-image: url(/img/vignette/carte.webp?v=2); mask-image: url(/img/vignette/carte.webp?v=2);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.atouts-qui { list-style: none; margin: var(--e-6) 0 var(--e-4); padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--e-5) var(--e-7); }
.atouts-qui li { display: grid; gap: var(--e-1); max-width: 15rem; }
.atout-titre { font-family: var(--police-code); font-weight: 560; letter-spacing: -0.02em; }

/* ─── Contact : le formulaire et la carte SMS côte à côte ─── */
/* Le formulaire d'abord (le mail est la porte principale), le numéro en dessous */
.contact { display: grid; gap: var(--e-5); max-width: 48rem; margin: 0 auto; }
.formulaire { padding: var(--e-6); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e-5) var(--e-4); }
.champ-large { grid-column: 1 / -1; }
.champ textarea { resize: vertical; min-height: 8rem; line-height: 1.5; }
.facultatif { color: var(--gris-2); }
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.formulaire-pied { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-4) var(--e-5); }
.formulaire-pied a { color: inherit; }
.etat-envoi { min-height: 1.5em; color: var(--gris); }
.etat-envoi.erreur { color: oklch(0.78 0.12 30); }
.envoye { display: grid; gap: var(--e-3); padding: var(--e-7) var(--e-6); text-align: center; animation: apparait 0.6s var(--ease-expo); }
.envoye h3 { font-size: var(--t-h3); }
@keyframes apparait { from { opacity: 0; transform: translateY(10px) scale(0.98); } }
.btn[disabled] { opacity: 0.6; cursor: progress; }

.sms { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--e-3) var(--e-6); padding: var(--e-5) var(--e-6); border: 1px solid var(--trait); border-radius: var(--rayon); }
.sms-texte { display: grid; gap: var(--e-2); }
.sms h3 { font-size: 1.0625rem; }
.sms-boutons { grid-column: 1 / -1; }
.sms-numero { font-family: var(--police-titre); font-weight: 580; font-size: clamp(2rem, 1.6rem + 1.4vw, 2.625rem); line-height: 1; letter-spacing: -0.035em; text-decoration: none; font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (hover: hover) and (pointer: fine) { .sms-numero:hover { color: var(--eau); } }
.sms .doux { font-size: var(--t-petit); }

/* ─── Pied de page : le nom en très grand, coupé par le sol, la lumière suit le pointeur ─── */
@property --x { syntax: '<percentage>'; inherits: true; initial-value: 50%; }
@property --y { syntax: '<percentage>'; inherits: true; initial-value: 30%; }
.pied { position: relative; overflow: hidden; padding-top: var(--e-9); }
.pied-appel { display: grid; justify-items: center; gap: var(--e-6); margin-bottom: clamp(3rem, 2rem + 4vw, 6rem); text-align: center; }
.pied-phrase { font-family: var(--police-titre); font-weight: 580; font-size: clamp(2.75rem, 1.2rem + 5.4vw, 6rem); line-height: 0.98; letter-spacing: -0.05em; }
.signature {
  position: relative; display: grid; justify-content: center; overflow: hidden;
  font-family: var(--police); font-weight: 650; font-size: clamp(4.5rem, 21vw, 19.5rem);
  letter-spacing: -0.045em; line-height: 1; height: 0.8em; padding-top: 0.14em;
  user-select: none; -webkit-user-select: none;
}
.signature::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.16), transparent); }
.signature-mot {
  grid-area: 1 / 1; white-space: nowrap;
  background: linear-gradient(180deg, oklch(0.27 0.003 260), oklch(0.165 0.003 260) 26%, oklch(0.15 0.003 260));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.sig-cr, .signature-mot .sig-ia { font-family: var(--police-code); }
.sig-cr { font-weight: 200; margin: 0 -0.13em; }
.signature-mot .sig-ia { color: oklch(0.3 0.045 168); text-shadow: 0 0 0.12em oklch(0.86 0.085 168 / 0.25); }
/* La couche éclairée : seulement le bord des lettres, qui s'allume autour du pointeur, comme une arête de métal qui
   prend la lumière (Félix, 15/10/2026 : « il faudrait que ce soit juste les bords des lettres qui s'illuminent » ;
   avant, tout l'intérieur des lettres s'éclaircissait en une tache) */
.signature-lumiere {
  background: none; color: transparent;
  -webkit-text-stroke: max(1.25px, 0.0075em) oklch(0.93 0.03 168);
  /* (pas de filtre de lueur : avec lui, le navigateur dessinait cette couche comme une image, en basse définition, et
     le bord des lettres sortait en escalier, Félix 18/10/2026 : « pixellisé ») */
  -webkit-mask-image: radial-gradient(circle 1.1em at var(--x) var(--y), #000, transparent 70%);
  mask-image: radial-gradient(circle 1.1em at var(--x) var(--y), #000, transparent 70%);
}
.signature-lumiere .sig-ia { color: transparent; text-shadow: none; -webkit-text-stroke-color: var(--eau); }
/* Sans souris, la lumière balaie le nom toute seule */
@media (hover: none), (pointer: coarse) {
  .signature { animation: balaie 9s ease-in-out infinite alternate; }
}
@keyframes balaie { from { --x: 12%; --y: 25%; } to { --x: 88%; --y: 45%; } }

.pied-dedans { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--e-4); padding-top: var(--e-6); padding-bottom: var(--e-6); }
.pied .logo { font-size: 1.25rem; }
.pied a { text-underline-offset: 0.25em; }

/* ─── La barre d'action du téléphone ─── */
.barre-action { display: none; }

/* ─── Tablette ─── */
@media (max-width: 64rem) {
  /* Deux rangées de six plutôt qu'une rangée de onze et une icône seule */
  .outils-rangee { max-width: 33rem; }
  .fenetre-corps { grid-template-columns: 11rem minmax(0, 1fr); }
  .apercu { grid-column: 1 / -1; border-top: 1px solid var(--trait); min-height: 19rem; }
  .regle { border-right: 0; }
  .etapes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e-7) var(--e-6); }
}
@media (max-width: 60rem) {
  .vitrine { grid-template-columns: 1fr; gap: var(--e-6); }
  .vitrine-ecran { order: -1; }
}

/* ─── Tablette en portrait (l'iPad de Félix) : la photo, recadrée par la hauteur, laissait l'ordi hors de l'écran.
   Comme sur téléphone, elle passe au-dessus du texte, cadrée sur l'ordi, en plus grand ─── */
@media (min-width: 48.01rem) and (max-width: 64rem) and (orientation: portrait) {
  .heros { min-height: 0; padding-top: 0; }
  .heros-photo {
    position: relative; z-index: 0; width: 100%; height: 34rem; margin-bottom: -6rem;
    --zoom: 1.6; --px: 0.8; --py: 0.5;
    -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 40%); mask-image: linear-gradient(to top, transparent 0%, #000 40%);
  }
  .heros-dedans { position: relative; z-index: 1; }
}

/* ─── Téléphone ─── */
/* ─── « Mon propre salon, en pilote automatique » : la scène du bot (js/pilote.js) ─── */
.pilote { display: grid; gap: var(--e-6); max-width: 66rem; margin: 0 auto; }
.pilote-legende {
  display: flex; flex-direction: column; align-items: center; gap: var(--e-2); min-height: 6.6rem; text-align: center;
  font-size: clamp(1.625rem, 1.05rem + 2.4vw, 2.625rem); font-weight: 580; line-height: 1.08; letter-spacing: -0.035em; color: var(--craie);
  transition: opacity 0.22s var(--ease), translate 0.22s var(--ease);
}
.pilote-legende.change { opacity: 0; translate: 0 0.4rem; }
.pilote-num { font-family: var(--police-code); font-size: 0.5em; font-weight: 400; letter-spacing: 0; color: var(--eau); }
.pilote-scene { display: grid; grid-template-columns: minmax(0, 1.2fr) 3.5rem minmax(0, 0.75fr) 3.5rem minmax(0, 1.05fr); align-items: center; }
.pilote-panneau, .pilote-rond {
  background: var(--nuit-2); border: 1px solid var(--trait); border-radius: 16px;
  opacity: 0.5; transition: opacity 0.4s var(--ease), border-color 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.pilote-panneau { display: grid; align-content: start; gap: var(--e-3); min-height: 19rem; padding: var(--e-4); }
.pilote-panneau.actif, .pilote-bot.actif .pilote-rond { opacity: 1; border-color: oklch(0.86 0.085 168 / 0.55); box-shadow: 0 0 2.2rem oklch(0.86 0.085 168 / 0.1); }
.pilote-tete { display: flex; align-items: center; gap: var(--e-3); padding-bottom: var(--e-3); border-bottom: 1px solid var(--trait); }
.pilote-avatar { display: grid; place-items: center; flex: none; width: 2.125rem; height: 2.125rem; border-radius: 50%; background: var(--nuit-3); font-weight: 600; font-size: var(--t-petit); }
.pilote-nom { display: grid; font-weight: 600; font-size: var(--t-petit); }
.pilote-nom small { font-weight: 400; font-size: var(--t-legende); color: var(--gris-2); }
.pilote-fil { display: flex; flex-direction: column; gap: var(--e-2); }
.pilote-bulle {
  max-width: 88%; padding: 0.55rem 0.8rem; border-radius: 16px; font-size: var(--t-petit); line-height: 1.35;
  opacity: 0; translate: 0 0.5rem; transition: opacity 0.35s var(--ease), translate 0.35s var(--ease);
}
.pilote-bulle.vue { opacity: 1; translate: 0 0; }
.pilote-bulle.client { align-self: flex-start; background: var(--nuit-3); border-bottom-left-radius: 5px; }
.pilote-bulle.bot { align-self: flex-end; background: oklch(0.86 0.085 168 / 0.16); border: 1px solid oklch(0.86 0.085 168 / 0.32); border-bottom-right-radius: 5px; }
.pilote-bulle.points { display: flex; gap: 4px; padding: 0.75rem 0.85rem; }
.pilote-bulle.points i { width: 6px; height: 6px; border-radius: 50%; background: var(--gris); animation: pilote-saut 0.9s ease-in-out infinite; }
.pilote-bulle.points i:nth-child(2) { animation-delay: 0.15s; }
.pilote-bulle.points i:nth-child(3) { animation-delay: 0.3s; }
@keyframes pilote-saut { 0%, 60%, 100% { translate: 0 0; opacity: 0.5; } 30% { translate: 0 -4px; opacity: 1; } }
/* les liens : une lumière vert d'eau y file d'un panneau à l'autre */
.pilote-lien { position: relative; height: 2px; border-radius: 2px; background: var(--trait); overflow: hidden; }
.pilote-lien i { position: absolute; top: 0; bottom: 0; left: -45%; width: 45%; opacity: 0; background: linear-gradient(90deg, transparent, var(--eau), transparent); }
.pilote-lien.va i { animation: pilote-va 0.8s ease-in-out forwards; }
.pilote-lien.revient i { animation: pilote-revient 0.8s ease-in-out forwards; }
@keyframes pilote-va { from { left: -45%; opacity: 1; } to { left: 100%; opacity: 1; } }
@keyframes pilote-revient { from { left: 100%; opacity: 1; } to { left: -45%; opacity: 1; } }
/* le bot : un rond avec [ia], et ce qu'il a compris juste dessous */
.pilote-bot { display: grid; justify-items: center; align-content: center; gap: var(--e-3); min-height: 19rem; text-align: center; }
.pilote-rond { display: grid; place-items: center; width: 5.5rem; height: 5.5rem; border-radius: 50%; }
.pilote-rond b { font-family: var(--police-code); font-weight: 500; font-size: 1.25rem; color: var(--eau); }
.pilote-bot.actif .pilote-rond { animation: pilote-respire 1.6s ease-in-out infinite; }
@keyframes pilote-respire { 50% { box-shadow: 0 0 2.6rem oklch(0.86 0.085 168 / 0.22); } }
.pilote-bot-nom { font-weight: 600; font-size: var(--t-petit); color: var(--gris); }
.pilote-puce {
  min-height: 2.9rem; padding: 0.5rem 0.8rem; border: 1px solid oklch(0.86 0.085 168 / 0.4); border-radius: 12px; font-size: var(--t-legende); line-height: 1.35; color: var(--craie);
  background: oklch(0.86 0.085 168 / 0.08); opacity: 0; translate: 0 0.4rem; transition: opacity 0.35s var(--ease), translate 0.35s var(--ease);
}
.pilote-puce.vue { opacity: 1; translate: 0 0; }
/* l'agenda : les créneaux de la journée, le bot les parcourt */
.pilote-creneaux { display: grid; gap: 0.35rem; margin: 0; padding: 0; list-style: none; }
.pilote-creneaux li { display: flex; align-items: center; gap: var(--e-3); padding: 0.5rem 0.7rem; border: 1px solid transparent; border-radius: 10px; background: var(--nuit-3); font-size: var(--t-petit); transition: background-color 0.25s, border-color 0.25s, color 0.25s; }
.pilote-creneaux time { flex: none; width: 2.6rem; font-family: var(--police-code); font-size: var(--t-legende); color: var(--gris-2); }
.pilote-creneaux li.libre { background: none; border: 1px dashed var(--trait); color: var(--gris-2); }
.pilote-creneaux li.scan { border-color: oklch(0.86 0.085 168 / 0.7); background: oklch(0.86 0.085 168 / 0.1); }
.pilote-creneaux li.trouve { border: 1px solid var(--eau); background: oklch(0.86 0.085 168 / 0.14); color: var(--craie); animation: pilote-respire 1.1s ease-in-out infinite; }
.pilote-creneaux li.pris { border: 1px solid oklch(0.86 0.085 168 / 0.6); background: oklch(0.86 0.085 168 / 0.18); color: var(--craie); }
.pilote-creneaux li.pris::after { content: '✓'; margin-left: auto; color: var(--eau); }
.pilote-points { display: flex; justify-content: center; gap: 0.5rem; margin: 0; padding: 0; list-style: none; }
.pilote-points li { width: 6px; height: 6px; border-radius: 3px; background: var(--trait); transition: width 0.3s var(--ease), background-color 0.3s; }
.pilote-points li.actif { width: 1.5rem; background: var(--eau); }
.pilote-sr { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.pilote.fini .pilote-panneau { opacity: 0.9; }
.pilote-note { max-width: 40rem; margin: var(--e-5) auto 0; text-align: center; }
@media (max-width: 48rem) {
  .pilote-scene { grid-template-columns: 1fr; }
  .pilote-lien { width: 2px; height: 2.25rem; margin: 0 auto; }
  .pilote-lien i { left: 0; right: 0; width: auto; height: 45%; top: -45%; background: linear-gradient(180deg, transparent, var(--eau), transparent); }
  .pilote-lien.va i { animation-name: pilote-va-v; }
  .pilote-lien.revient i { animation-name: pilote-revient-v; }
  .pilote-panneau, .pilote-bot { min-height: 0; }
  .pilote-fil { min-height: 11rem; }
  .pilote-bot { gap: var(--e-2); }
  .pilote-legende { min-height: 7.4rem; }
}
@keyframes pilote-va-v { from { top: -45%; opacity: 1; } to { top: 100%; opacity: 1; } }
@keyframes pilote-revient-v { from { top: 100%; opacity: 1; } to { top: -45%; opacity: 1; } }

/* Au doigt (Félix, 18/10/2026 : « le responsive téléphone ») : les petits liens de texte (logo, retour, mentions, numéro, « Dites-la-moi »)
   mesuraient 14 à 24 px de haut, trop peu pour le pouce. Leur zone de toucher grandit vers le haut et le bas (padding + marge
   négative : rien ne bouge à l'écran) jusqu'à environ 44 px. */
@media (pointer: coarse) {
  .logo, .retour, .pied a, .relance-mot a, .formulaire-pied a, .sms a, .sms-numero {
    padding-block: 0.7rem; margin-block: -0.7rem; position: relative;
  }
  .pied-dedans p a { display: inline-block; }
  .fenetre-rejouer { width: 2.75rem; height: 2.75rem; margin: -0.375rem; }
}
@media (max-width: 48rem) {
  .menu { display: none; }
  /* L'iPhone de la démo, plus haut, pour que son écran reste lisible */
  .vitrine.en-demo .telephone3d { aspect-ratio: 0.52; width: min(100%, 25rem, calc(84svh * 0.52)); }
  .heros { min-height: 0; padding-top: 0; }
  .heros-photo {
    position: relative; z-index: 0; width: 100%; height: 21rem; margin-bottom: -3.5rem;
    --zoom: 1.75; --px: 0.8; --py: 0.16;   /* le cadre monte pour garder les affiches du mur, dont TrimSync (Félix, 18/10/2026 : « on voit pas l'affiche TrimSync, elle est coupée par le haut ») */
    -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 45%); mask-image: linear-gradient(to top, transparent 0%, #000 45%);
  }
  .heros-dedans { position: relative; z-index: 1; }
  .mots li { flex-direction: column; align-items: flex-start; gap: var(--e-1); }
  .desc { text-align: left; font-size: var(--t-corps); }
  .outils-rangee { gap: var(--e-4) 0; }
  .outil { width: 25%; min-width: 4.5rem; }
  .outil-detail { padding: var(--e-5) var(--e-4); }

  .fenetre-barre { padding-left: var(--e-3); }
  /* Le titre tient sur une ligne : coupé par des points de suspension plutôt que caché */
  .fenetre-titre { min-width: 0; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .fenetre-corps { grid-template-columns: 1fr; min-height: 0; }
  /* Les onglets glissent sous le doigt : le bord droit s'efface pour montrer qu'il y en a d'autres */
  .fenetre-onglets {
    flex-direction: row; overflow-x: auto; scrollbar-width: none; border-right: 0; border-bottom: 1px solid var(--trait); padding: var(--e-2);
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 3rem), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 3rem), transparent);
  }
  .fenetre-onglets.au-bout { -webkit-mask-image: none; mask-image: none; }
  .fenetre-onglets .onglet { flex: none; }
  .fenetre-onglets::-webkit-scrollbar { display: none; }
  .regle { padding: var(--e-4) 0; font-size: var(--t-legende); }
  .regle li { grid-template-columns: 2.25rem 6rem minmax(0, 1fr); padding-right: var(--e-4); }
  .regle li::before { padding-right: var(--e-3); }
  .apercu { min-height: 18rem; padding: 3.5rem var(--e-4) var(--e-4); }
  .apercu-tete { left: var(--e-4); right: var(--e-4); }

  .etapes { grid-template-columns: 1fr; gap: var(--e-6); }
  .formulaire { grid-template-columns: 1fr; padding: var(--e-5); }
  .sms { grid-template-columns: 1fr; padding: var(--e-5); }
  .atouts-qui { flex-direction: column; align-items: center; gap: var(--e-4); }

  .pied { padding-bottom: 5.5rem; }
  .pied-dedans { flex-direction: column; align-items: flex-start; }

  .barre-action {
    position: fixed; z-index: 6; left: var(--e-3); right: var(--e-3); bottom: calc(var(--e-3) + env(safe-area-inset-bottom, 0px));
    display: grid; grid-template-columns: 1fr auto; gap: var(--e-2); padding: var(--e-2);
    border-radius: 14px; background: oklch(0.18 0.003 260 / 0.94); border: 1px solid var(--trait);
    box-shadow: 0 20px 40px -12px oklch(0 0 0 / 0.85);
    transform: translateY(calc(100% + 2rem)); transition: transform 0.5s var(--ease-expo);
  }
  @supports (backdrop-filter: blur(1px)) { .barre-action { background: oklch(0.18 0.003 260 / 0.82); backdrop-filter: blur(12px); } }
  .barre-action .btn { min-height: 2.875rem; }
  .barre-action .btn-sombre { padding-inline: 1.5em; }
  .barre-action.visible { transform: none; }
}

/* ─── Moins d'animations demandées : tout est posé d'emblée ─── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.js .heros-photo, html.js .ligne-dedans, html.js .entree, html.js .revele,
  html.js .mots li::before, html.js .mot .cr, html.js .desc, html.js .apercu > *,
  html.js .etapes li::before, html.js .etapes .etape-num, html.js .etapes h3, html.js .etapes p {
    opacity: 1 !important; transform: none !important;
  }
  .curseur-mot { display: none; }
  html.js .mot { color: var(--craie); }
  .signature { animation: none; }
  .curseur::after { animation: none; }
}
