/* ==========================================================================
   THRPUB — Design system
   ========================================================================== */

:root {
  --bg: #050505;
  --bg-2: #0a0a0a;
  --card: #0f0f0f;
  --card-2: #151515;
  --card-3: #1c1c1c;
  --line: rgba(255, 255, 255, 0.08);
  --line-2: rgba(255, 255, 255, 0.14);
  --grid-line: rgba(255, 255, 255, 0.055);  /* trame du fond du site (n'affecte pas les orbes) */
  --text: #f4f4f1;
  --muted: #a0a09c;
  --dim: #6c6c69;

  --g1: #ffffff;
  --g2: #e6e6e6;
  --g3: #ffffff;
  --g4: #8d8d8d;
  --grad: linear-gradient(100deg, #ffffff 0%, #d6d6d6 45%, #8d8d8d 100%);

  --f-display: "Inter Tight", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-body: "Geist", "Inter Tight", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-serif: "Instrument Serif", "Times New Roman", Georgia, serif;

  --radius-s: 12px;
  --radius: 20px;
  --radius-l: 28px;
  --wrap: 1240px;
  --gutter: clamp(20px, 4vw, 40px);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --header-h: 84px;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* overflow-x: clip (et non hidden) : rien ne peut faire glisser la page sur le côté au doigt,
   sans créer de conteneur de défilement qui casserait les éléments sticky. hidden reste en
   repli pour les navigateurs qui ignorent clip. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 110px; overflow-x: clip; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  overflow-x: clip;
}
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
h1, h2, h3, h4 { margin: 0; font-family: var(--f-display); font-weight: 500; letter-spacing: -0.035em; line-height: 1.02; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
::selection { background: #fff; color: #000; }
:focus-visible { outline: 2px solid var(--g3); outline-offset: 3px; border-radius: 6px; }
[hidden] { display: none !important; }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Lien d'évitement : il ne doit apparaître qu'en navigation au CLAVIER. Avec un simple
   :focus, un appui du doigt suffisait à le faire surgir, et il restait affiché — un pavé
   blanc figé en haut à gauche, sous l'encoche de l'iPhone. D'où :focus-visible, et un
   décalage qui tient compte de la zone sécurisée (le site est en viewport-fit=cover). */
.skip-link {
  position: fixed; z-index: 1000;
  top: calc(env(safe-area-inset-top, 0px) + 10px); left: calc(env(safe-area-inset-left, 0px) + 10px);
  padding: 10px 16px; background: #fff; color: #000; border-radius: 999px;
  transform: translateY(-250%); transition: transform .3s;
}
.skip-link:focus { transform: none; }
.skip-link:focus:not(:focus-visible) { transform: translateY(-250%); }

/* Grain overlay */
body::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none; z-index: 999;
  opacity: .035;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: calc(var(--wrap) + var(--gutter) * 2); margin-inline: auto; padding-inline: var(--gutter); }
.wrap-narrow { max-width: calc(780px + var(--gutter) * 2); }
.section { padding-block: clamp(80px, 11vw, 150px); position: relative; }
.section-sm { padding-block: clamp(56px, 7vw, 90px); }

/* ---------- Typography ---------- */
.serif { font-family: var(--f-serif); font-style: italic; font-weight: 400; letter-spacing: -0.01em; }
.grad-text { background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.muted { color: var(--muted); }
.dim { color: var(--dim); }

.eyebrow {
  width: fit-content;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 7px 14px 7px 10px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: rgba(255,255,255,.03);
  font-size: 13px; font-weight: 500; color: var(--muted);
  letter-spacing: .01em;
}
.eyebrow::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #fff; box-shadow: 0 0 10px rgba(255,255,255,.6); }

.h-xl { font-size: clamp(2.9rem, 8.2vw, 7.4rem); line-height: .94; letter-spacing: -0.05em; }
.h-l  { font-size: clamp(2.3rem, 5.4vw, 4.6rem); line-height: .98; letter-spacing: -0.045em; }
.h-m  { font-size: clamp(1.8rem, 3.4vw, 2.9rem); line-height: 1.04; }
.h-s  { font-size: clamp(1.25rem, 1.8vw, 1.5rem); line-height: 1.15; letter-spacing: -0.02em; }
.lead { font-size: clamp(1.05rem, 1.35vw, 1.2rem); color: var(--muted); line-height: 1.6; max-width: 58ch; }
.h-l .serif, .h-m .serif, .h-xl .serif { color: #8d8d8d; }

.section-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 28px 40px; margin-bottom: clamp(40px, 6vw, 72px); }
.section-head > div { display: grid; gap: 20px; max-width: 900px; justify-items: start; }
.section-head.center { flex-direction: column; align-items: center; text-align: center; }
.section-head.center > div { justify-items: center; }

/* ---------- Buttons ---------- */
.btn {
  --h: 52px;
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  height: var(--h);
  padding: 0 8px 0 24px;
  border-radius: 999px;
  font-family: var(--f-display); font-size: 15px; font-weight: 500; letter-spacing: -0.01em;
  white-space: nowrap;
  transition: transform .5s var(--ease), background-color .3s, color .3s, border-color .3s, box-shadow .5s var(--ease);
  isolation: isolate;
}
.btn .btn-ico {
  display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 50%;
  transition: transform .5s var(--ease), background-color .3s;
  overflow: hidden;
}
.btn .btn-ico svg { width: 16px; height: 16px; transition: transform .5s var(--ease); }
.btn:hover .btn-ico svg { transform: rotate(-45deg); }
.btn:active { transform: scale(.97); }

.btn-primary { background: var(--text); color: #050505; }
.btn-primary .btn-ico { background: #050505; color: #fff; }
.btn-primary::before {
  content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit;
  background: var(--grad); filter: blur(18px); opacity: 0; transition: opacity .5s var(--ease);
}
.btn-primary:hover::before { opacity: .22; }

.btn-ghost { border: 1px solid var(--line-2); background: rgba(255,255,255,.03); color: var(--text); padding-right: 24px; }
.btn-ghost:hover { border-color: rgba(255,255,255,.35); background: rgba(255,255,255,.06); }
.btn-ghost.has-ico { padding-right: 8px; }
.btn-ghost .btn-ico { background: rgba(255,255,255,.08); }

.btn-sm { --h: 42px; font-size: 14px; padding-left: 18px; }
.btn-sm .btn-ico { width: 30px; height: 30px; }
.btn-sm.btn-ghost { padding-right: 18px; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

.link-arrow { display: inline-flex; align-items: center; gap: 8px; font-family: var(--f-display); font-weight: 500; font-size: 15px; color: var(--text); }
.link-arrow svg { width: 15px; height: 15px; transition: transform .45s var(--ease); }
.link-arrow:hover svg { transform: translateX(4px) rotate(-45deg); }
.link-arrow .u { background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size .45s var(--ease); }
.link-arrow:hover .u { background-size: 100% 1px; }

.tag { display: inline-flex; align-items: center; height: 30px; padding: 0 12px; border-radius: 999px; border: 1px solid var(--line-2); font-size: 13px; color: var(--muted); white-space: nowrap; }

/* ---------- Header ---------- */
.site-header { position: fixed; top: 0; left: 0; right: 0; z-index: 100; padding: 14px var(--gutter) 0; pointer-events: none; }
.nav {
  pointer-events: auto;
  max-width: var(--wrap); margin-inline: auto;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  height: 64px; padding: 0 8px 0 22px;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: background-color .5s var(--ease), border-color .5s var(--ease), backdrop-filter .5s, transform .6s var(--ease), box-shadow .5s;
}
.site-header.is-scrolled .nav {
  background: rgba(12, 12, 12, .72);
  border-color: var(--line);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 10px 40px rgba(0,0,0,.35);
}
.logo { display: inline-flex; align-items: center; justify-self: start; }
.logo img { height: 28px; width: auto; }
.nav-links { position: relative; display: flex; gap: 2px; padding: 4px; border-radius: 999px; }
.nav-links a {
  position: relative; z-index: 1; padding: 9px 16px; border-radius: 999px;
  font-family: var(--f-display); font-size: 15px; font-weight: 500; color: var(--muted);
  transition: color .35s var(--ease);
}
.nav-links a:hover, .nav-links a:focus-visible, .nav-links a[aria-current="page"] { color: var(--text); }
/* Pastille « verre » : sans JS elle se place sur la page active, avec JS elle suit le survol */
.nav-links:not(.has-pill) a[aria-current="page"] { background: rgba(255,255,255,.08); box-shadow: inset 0 1px 0 rgba(255,255,255,.18), 0 0 22px rgba(255,255,255,.10); }
.nav-pill {
  position: absolute; z-index: 0; top: 4px; left: 0; height: calc(100% - 8px); width: 0;
  border-radius: 999px; pointer-events: none; opacity: 0;
  background: linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,.04));
  border: 1px solid rgba(255,255,255,.16);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), inset 0 -1px 0 rgba(255,255,255,.04), 0 0 0 1px rgba(0,0,0,.2), 0 6px 22px rgba(0,0,0,.35), 0 0 26px rgba(255,255,255,.10);
  backdrop-filter: blur(12px) saturate(160%); -webkit-backdrop-filter: blur(12px) saturate(160%);
  transition: transform .55s var(--ease), width .55s var(--ease), opacity .35s var(--ease), box-shadow .5s var(--ease);
}
.nav-pill::after {
  content: ""; position: absolute; left: 50%; bottom: -5px; width: 18px; height: 2px; border-radius: 2px;
  background: #fff; box-shadow: 0 0 10px 2px rgba(255,255,255,.55); transform: translateX(-50%) scaleX(0); transition: transform .5s var(--ease);
}
.nav-pill.on { opacity: 1; }
.nav-pill.is-active { box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 0 0 1px rgba(0,0,0,.2), 0 6px 22px rgba(0,0,0,.35), 0 0 34px rgba(255,255,255,.16); }
.nav-pill.is-active::after { transform: translateX(-50%) scaleX(1); }
.mobile-menu nav a[aria-current="page"] { color: var(--text); }
.mobile-menu nav a:not([aria-current="page"]) { color: var(--muted); }
.nav-cta { justify-self: end; display: flex; align-items: center; gap: 8px; }
.burger { display: none; width: 48px; height: 48px; border-radius: 50%; background: rgba(255,255,255,.07); position: relative; }
.burger span { position: absolute; left: 15px; right: 15px; height: 1.5px; background: var(--text); border-radius: 2px; transition: transform .5s var(--ease), top .5s var(--ease); }
.burger span:nth-child(1) { top: 20px; }
.burger span:nth-child(2) { top: 27px; }
.menu-open .burger span:nth-child(1) { top: 23.5px; transform: rotate(45deg); }
.menu-open .burger span:nth-child(2) { top: 23.5px; transform: rotate(-45deg); }

/* Menu mobile : panneau latéral en verre qui glisse depuis la droite, par-dessus un
   voile flouté. Le header reste au-dessus (z-index 100) pour garder le burger cliquable. */
.mobile-menu { position: fixed; inset: 0; z-index: 90; visibility: hidden; transition: visibility .6s; overflow-x: clip; }
.menu-open .mobile-menu { visibility: visible; }
/* Le voile et le panneau débordent de --mm-bleed sous l'écran : sur iOS la barre de
   Safari fausse la hauteur du bloc fixe, et le bas du panneau se retrouvait visible —
   bord arrondi et limite du flou compris. En débordant, ce bord n'est jamais à l'image. */
.mobile-menu { --mm-bleed: 96px; }
.mm-scrim {
  position: absolute; inset: 0 0 calc(var(--mm-bleed) * -1); background: rgba(0,0,0,.55);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  opacity: 0; transition: opacity .5s var(--ease);
}
.menu-open .mm-scrim { opacity: 1; }
.mm-panel {
  position: absolute; top: 0; right: 0; bottom: calc(var(--mm-bleed) * -1); width: min(85vw, 380px);
  display: flex; flex-direction: column; gap: 28px;
  /* La marge basse compense le débord, sinon le pied du menu (poussé en bas par
     margin-top:auto) descendrait sous l'écran avec lui. */
  padding: max(16px, env(safe-area-inset-top, 0px)) 18px calc(var(--mm-bleed) + 26px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto; overscroll-behavior: contain;
  background: linear-gradient(200deg, rgba(255,255,255,.075), rgba(255,255,255,.015) 45%, rgba(255,255,255,.045)), rgba(5,5,5,.86);
  backdrop-filter: blur(28px) saturate(170%); -webkit-backdrop-filter: blur(28px) saturate(170%);
  border-left: 1px solid rgba(255,255,255,.12); border-radius: 26px 0 0 26px;
  box-shadow: inset 1px 0 0 rgba(255,255,255,.14), -30px 0 70px rgba(0,0,0,.6);
  transform: translateX(100%); transition: transform .6s var(--ease);
}
.menu-open .mm-panel { transform: none; }

.mm-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 4px 6px 18px; }
.mm-top .logo img { height: 26px; width: auto; }
.mm-close {
  width: 44px; height: 44px; flex-shrink: 0; border-radius: 50%; display: grid; place-items: center;
  color: var(--muted); border: 1px solid var(--line-2); background: rgba(255,255,255,.06);
  transition: color .35s var(--ease), border-color .35s var(--ease), background-color .35s var(--ease);
}
.mm-close:hover { color: var(--text); border-color: rgba(255,255,255,.28); background: rgba(255,255,255,.1); }
.mm-close svg { width: 20px; height: 20px; }

.mobile-menu nav { display: grid; }
.mobile-menu nav a {
  position: relative; display: flex; align-items: center; gap: 14px;
  padding: 16px 14px; border-radius: 16px;
  font-family: var(--f-display); font-size: 1.45rem; font-weight: 500; letter-spacing: -0.035em;
  transform: translateX(26px); opacity: 0;
  transition: transform .55s var(--ease), opacity .55s var(--ease), background-color .35s var(--ease);
}
/* filet de séparation, sauf sur la première ligne */
.mobile-menu nav a + a::before {
  content: ""; position: absolute; left: 14px; right: 14px; top: 0; height: 1px; background: var(--line);
}
.menu-open .mobile-menu nav a { transform: none; opacity: 1; }
.mobile-menu nav a:nth-child(2) { transition-delay: .06s; }
.mobile-menu nav a:nth-child(3) { transition-delay: .12s; }
.mobile-menu nav a:nth-child(4) { transition-delay: .18s; }
.mobile-menu nav a:nth-child(5) { transition-delay: .24s; }
.mobile-menu nav a:nth-child(6) { transition-delay: .3s; }
.mm-i { width: 22px; flex-shrink: 0; font-family: var(--f-body); font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums; }
.mm-l { flex: 1; }
.mobile-menu nav a svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--dim); transition: transform .4s var(--ease); }
.mobile-menu nav a[aria-current="page"] {
  background: rgba(255,255,255,.08); box-shadow: inset 0 1px 0 rgba(255,255,255,.16);
}
.mobile-menu nav a[aria-current="page"]::before,
.mobile-menu nav a[aria-current="page"] + a::before { opacity: 0; }
.mobile-menu nav a[aria-current="page"] svg { color: var(--text); transform: rotate(-45deg); }

.mobile-menu .mm-foot { margin-top: auto; display: grid; gap: 18px; color: var(--muted); }
.mm-foot .btn { width: 100%; justify-content: center; }
.mm-contact { display: grid; gap: 12px; padding-inline: 2px; }
.mm-contact a { display: flex; align-items: center; gap: 11px; font-size: 14px; color: var(--muted); transition: color .3s; }
.mm-contact a:hover { color: var(--text); }
.mm-contact svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--dim); }
.mm-social { display: flex; gap: 10px; padding-top: 2px; }
.mm-social a {
  width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid var(--line-2); background: rgba(255,255,255,.04); color: var(--muted);
  transition: color .4s var(--ease), border-color .4s var(--ease), background-color .4s var(--ease);
}
.mm-social a:hover { color: var(--text); border-color: rgba(255,255,255,.28); background: rgba(255,255,255,.08); }
.mm-social svg { width: 18px; height: 18px; }
@media (prefers-reduced-motion: reduce) {
  .mm-panel, .mobile-menu nav a { transition: none; transform: none; }
}

/* ---------- Hero (home) ---------- */
.hero { position: relative; padding-top: calc(var(--header-h) + clamp(36px, 5vw, 64px)); overflow: hidden; }
.orb {
  position: absolute; z-index: 1; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,255,255,var(--a, .14)), rgba(255,255,255,0) 72%);
  will-change: transform;
}
.orb-1 { --a: .15; width: 900px; height: 900px; left: calc(50% - 700px); top: -380px; animation: orb-1 22s ease-in-out infinite alternate; }
.orb-2 { --a: .11; width: 760px; height: 760px; left: calc(50% + 40px); top: -160px; animation: orb-2 27s ease-in-out infinite alternate; }
.orb-3 { --a: .09; width: 620px; height: 620px; left: calc(50% - 310px); top: 260px; animation: orb-3 19s ease-in-out infinite alternate; }
@keyframes orb-1 { 0% { transform: translate(0, 0) scale(1); } 50% { transform: translate(260px, 120px) scale(1.15); } 100% { transform: translate(80px, 260px) scale(.9); } }
@keyframes orb-2 { 0% { transform: translate(0, 0) scale(1); } 50% { transform: translate(-320px, 180px) scale(.85); } 100% { transform: translate(-120px, -60px) scale(1.1); } }
@keyframes orb-3 { 0% { transform: translate(0, 0) scale(.9); } 50% { transform: translate(240px, -140px) scale(1.2); } 100% { transform: translate(-260px, -40px) scale(1); } }
.spot {
  position: absolute; z-index: 1; inset: 0;
  background: radial-gradient(520px circle at var(--sx, 50%) var(--sy, 30%), rgba(255,255,255,.07), transparent 60%);
  opacity: 0; transition: opacity .8s var(--ease);
}
body.spot-on .spot { opacity: 1; }
@media (max-width: 640px) {
  .orb-1 { width: 520px; height: 520px; left: -220px; top: -160px; }
  .orb-2 { width: 460px; height: 460px; left: 60px; top: 40px; }
  .orb-3 { width: 380px; height: 380px; left: -60px; top: 320px; }
}

/* z-index 3 : le voile noir du mur (.wall-shield, z-index 1) passe DERRIÈRE le titre,
   la preuve sociale et les boutons, sinon il les grise en remontant. */
.hero-inner { position: relative; z-index: 3; display: grid; justify-items: center; text-align: center; gap: 28px; }
.hero h1 { max-width: none; }
.hero h1 .line { display: block; }
.hero h1 .serif { font-size: 1.06em; line-height: .9; padding-right: .06em; }
.shimmer {
  background: linear-gradient(100deg, #6f6f6f 0%, #8d8d8d 30%, #f4f4f1 50%, #8d8d8d 70%, #6f6f6f 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent !important;
  animation: shimmer 7s ease-in-out infinite;
}
.rotator { display: inline-block; white-space: nowrap; color: #9a9a9a; }
.rotator .ch { display: inline-block; transition: transform .75s var(--ease), opacity .6s var(--ease), filter .6s var(--ease); transition-delay: calc(var(--i, 0) * 18ms); will-change: transform, opacity, filter; }
.rotator .ch.is-out { transform: translateY(-45%) rotate(-4deg); opacity: 0; filter: blur(10px); }
.rotator .ch.is-pre { transform: translateY(45%) rotate(4deg); opacity: 0; filter: blur(10px); transition: none; }
@keyframes shimmer { 0%, 100% { background-position: 100% 0; } 50% { background-position: 0 0; } }

.proof { display: flex; align-items: center; gap: 14px; }
.avatars { display: flex; }
.avatars img { width: 38px; height: 38px; border-radius: 50%; border: 2px solid var(--bg); object-fit: cover; background: #222; margin-left: -10px; }
.avatars img:first-child { margin-left: 0; }
.proof-text { text-align: left; font-size: 14px; color: var(--muted); line-height: 1.3; }
.stars { display: flex; gap: 2px; color: #fff; margin-bottom: 3px; }
.stars svg { width: 14px; height: 14px; }

/* Project wall */
/* Le mur porte un masque en dégradé : un fond posé dessus serait effacé en haut
   et en bas. L'opacité est donc portée par ce conteneur, lui non masqué. */
.wall-shield {
  --shield-up: clamp(140px, 22vw, 300px);   /* remonte le fondu au-dessus du mur pour dissoudre la trame plus haut */
  display: flow-root; position: relative; z-index: 1; pointer-events: none;
  margin-top: calc(var(--shield-up) * -1); padding-top: var(--shield-up);
  background: linear-gradient(180deg, rgba(5,5,5,0) 0%, rgba(5,5,5,.45) 18%, var(--bg) 38%, var(--bg) 100%);
}
.wall {
  position: relative; margin-top: clamp(56px, 8vw, 96px);
  height: clamp(380px, 52vw, 640px);
  perspective: 1600px;
  mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 70%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 70%, transparent 100%);
}
.wall-inner {
  position: absolute; left: 50%; top: -10%;
  width: min(1600px, 160vw);
  display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(12px, 1.6vw, 24px);
  transform: translateX(-50%) rotateX(28deg) rotateZ(-8deg) scale(1.05);
  transform-origin: 50% 0;
}
/* Même garde que les murs 3D : animé et promu en couche GPU seulement à l'écran. */
.wall-col { display: flex; flex-direction: column; animation: wall-up 80s linear infinite; animation-play-state: paused; }
.wall.is-live .wall-col { animation-play-state: running; will-change: transform; }
.wall-col:nth-child(even) { animation-name: wall-down; animation-duration: 95s; }
.wall-col img { width: 100%; height: auto; margin-bottom: clamp(12px, 1.6vw, 24px); border-radius: 14px; border: 1px solid var(--line-2); box-shadow: 0 30px 60px rgba(0,0,0,.5); background: #111; }
@keyframes wall-up { from { transform: translateY(0); } to { transform: translateY(-50%); } }
@keyframes wall-down { from { transform: translateY(-50%); } to { transform: translateY(0); } }

/* ---------- Marquees ---------- */
.marquee { overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
.marquee-track { display: flex; width: max-content; animation: marquee var(--dur, 40s) linear infinite; }
.marquee:hover .marquee-track.pausable { animation-play-state: paused; }
.marquee-group { display: flex; align-items: center; flex-shrink: 0; }
@keyframes marquee { to { transform: translateX(-50%); } }

.logos { border-block: 1px solid var(--line); padding-block: 36px; background: var(--bg); }
.logos p { text-align: center; font-size: 14px; color: var(--dim); margin-bottom: 26px; }
.logos .marquee-group { gap: clamp(48px, 7vw, 96px); padding-right: clamp(48px, 7vw, 96px); }
.logos img { height: 30px; width: auto; opacity: .55; filter: grayscale(1) brightness(1.6); transition: opacity .3s; }
.logos img:hover { opacity: 1; }

.big-marquee { padding-block: clamp(40px, 6vw, 70px); border-block: 1px solid var(--line); }
.big-marquee .marquee-group { gap: .5em; padding-right: .5em; font-family: var(--f-display); font-weight: 500; font-size: clamp(3rem, 9vw, 8rem); letter-spacing: -0.05em; line-height: 1.1; white-space: nowrap; }
.big-marquee .serif { color: #8d8d8d; }
.big-marquee .dot { width: .25em; height: .25em; border-radius: 50%; background: #fff; flex-shrink: 0; }

/* ---------- Cards / generic ---------- */
.card {
  position: relative;
  background: linear-gradient(180deg, var(--card-2), var(--card));
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  overflow: hidden;
}
.card-glow::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: radial-gradient(500px circle at var(--mx, 50%) var(--my, 0%), rgba(255,255,255,.07), transparent 45%);
  opacity: 0; transition: opacity .4s;
}
.card-glow:hover::before { opacity: 1; }

/* ---------- Method (3 steps) ---------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.step { padding: 14px; display: flex; flex-direction: column; min-height: 520px; }
.step-visual { position: relative; height: 270px; border-radius: 18px; background: #0a0a0a; border: 1px solid var(--line); overflow: hidden; display: grid; place-items: center; }
.step-body { padding: 26px 14px 14px; display: grid; gap: 12px; align-content: start; flex: 1; }
.step-num { font-family: var(--f-display); font-size: 13px; color: var(--dim); letter-spacing: .08em; }
.step-body p { color: var(--muted); }
.step-body .btn { margin-top: 8px; justify-self: start; }

/* visual 1 — wireframe */
.wf { width: 78%; display: grid; gap: 10px; transform: rotate(-4deg); }
.wf-bar { display: flex; gap: 6px; align-items: center; padding: 10px 12px; border-radius: 10px; background: var(--card-3); border: 1px solid var(--line); }
.wf-bar i { width: 7px; height: 7px; border-radius: 50%; background: #333; }
.wf-bar b { margin-left: auto; height: 8px; width: 40%; border-radius: 6px; background: #2a2a2a; }
.wf-hero { padding: 18px; border-radius: 12px; background: var(--card-2); border: 1px solid var(--line); display: grid; gap: 8px; }
.wf-hero b { height: 12px; border-radius: 6px; background: #2c2c2c; }
.wf-hero b:nth-child(1) { width: 80%; } .wf-hero b:nth-child(2) { width: 55%; background: var(--grad); opacity: .85; } .wf-hero b:nth-child(3) { width: 30%; height: 22px; border-radius: 999px; background: #eee; margin-top: 6px; }
.wf-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.wf-grid b { height: 46px; border-radius: 10px; background: var(--card-2); border: 1px solid var(--line); }
.wf-cursor { position: absolute; right: 22%; bottom: 26%; width: 22px; color: #fff; filter: drop-shadow(0 4px 10px rgba(0,0,0,.6)); animation: cursor 5s var(--ease) infinite; }
@keyframes cursor { 0%,100% { transform: translate(0,0); } 40% { transform: translate(-60px,-70px); } 55% { transform: translate(-60px,-70px) scale(.85); } 70% { transform: translate(-60px,-70px); } }

/* visual 2 — code */
.code { width: 84%; border-radius: 12px; background: var(--card-2); border: 1px solid var(--line); font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.9; padding: 14px 16px; color: #8a8a86; transform: rotate(3deg); }
.code .k { color: #fff; } .code .s { color: #bdbdbd; } .code .f { color: #e6e6e6; } .code .c { color: #4d4d4d; }
.code-dots { display: flex; gap: 6px; margin-bottom: 8px; } .code-dots i { width: 8px; height: 8px; border-radius: 50%; background: #333; }
.perf { position: absolute; right: 16px; bottom: 16px; display: flex; align-items: center; gap: 10px; padding: 8px 14px 8px 8px; border-radius: 999px; background: rgba(20,20,20,.9); border: 1px solid var(--line-2); font-size: 13px; }
.perf svg { width: 30px; height: 30px; }

/* visual 3 — launch */
.launch { display: grid; justify-items: center; gap: 22px; width: 84%; }
.url-bar { width: 100%; display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-radius: 999px; background: var(--card-2); border: 1px solid var(--line-2); font-size: 14px; color: var(--muted); }
.url-bar svg { width: 14px; height: 14px; color: var(--muted); }
.url-bar .caret { width: 1.5px; height: 16px; background: var(--text); animation: blink 1s steps(1) infinite; margin-left: -6px; }
@keyframes blink { 50% { opacity: 0; } }
.launch-btn { position: relative; padding: 14px 34px; border-radius: 16px; background: var(--card-3); border: 1px solid var(--line-2); font-family: var(--f-display); font-weight: 500; font-size: 20px; }
.launch-btn span { background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.launch-btn::after { content: ""; position: absolute; inset: -30px; z-index: -1; background: var(--grad); filter: blur(40px); opacity: .25; border-radius: 50%; animation: pulse 3s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .45; transform: scale(1.1); } }

/* ---------- Featured projects (horizontal gallery) ---------- */
.hwork { position: relative; padding-block: clamp(40px, 6vw, 80px) clamp(80px, 11vw, 150px); }
.hwork-pin { display: flex; flex-direction: column; justify-content: center; gap: clamp(32px, 5vh, 56px); }
.hwork-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 28px 40px; }
.hwork-title { display: grid; gap: 20px; justify-items: start; }
.hwork-ctrl { display: flex; align-items: center; gap: 20px; }
.hwork-count { font-family: var(--f-display); font-size: 14px; color: var(--dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hwork-count b { color: var(--text); font-weight: 500; }
.hwork-bar { position: relative; width: 120px; height: 1px; background: var(--line-2); overflow: hidden; }
.hwork-bar i { position: absolute; inset: 0; background: var(--text); transform-origin: 0 50%; transform: scaleX(var(--p, 0)); }

.hwork-track {
  --side: max(var(--gutter), calc((100vw - var(--wrap)) / 2));
  --card-w: clamp(290px, 36vw, 540px);
  --gap: clamp(14px, 1.6vw, 22px);
  display: flex; gap: var(--gap);
  padding-left: var(--side); scroll-padding-inline: var(--side);
  overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity; overscroll-behavior: contain;
  scrollbar-width: none; padding-bottom: 6px;
}
.hwork-track::-webkit-scrollbar { display: none; }
.hwork-track::after { content: ""; flex: 0 0 max(1px, calc(var(--side) - var(--gap))); }
.hwork.is-pinned { padding-block: 0; }
.hwork.is-pinned .hwork-pin { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; padding-top: 70px; }
.hwork.is-pinned .hwork-track { --card-w: min(36vw, 540px, calc((100svh - 390px) * 1.19)); overflow: visible; scroll-snap-type: none; will-change: transform; }
/* Défilement piloté par le scroll (compositeur) : --hw-* calculés par main.js */
.hwork.is-pinned.is-sd { view-timeline: --hwork block; }
.hwork.is-pinned.is-sd .hwork-track { animation: hw-slide linear both; animation-timeline: --hwork; animation-range: cover var(--hw-start) cover var(--hw-end); }
.hwork.is-pinned.is-sd .hwork-bar i { animation: hw-bar linear both; animation-timeline: --hwork; animation-range: cover var(--hw-start) cover var(--hw-end); }
@keyframes hw-slide { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(calc(-1 * var(--hw-dist, 0px)), 0, 0); } }
@keyframes hw-bar { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.hcard { flex: 0 0 var(--card-w); scroll-snap-align: start; display: grid; gap: 18px; }
.hcard-media { position: relative; aspect-ratio: 1.19; border-radius: var(--radius-l); overflow: hidden; background: var(--card); border: 1px solid var(--line); isolation: isolate; }
.hcard-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transform: translateX(var(--shift, 0px)) scale(1.12); transition: filter .6s var(--ease); }
.hcard-media::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 55%, rgba(0,0,0,.55)); opacity: 0; transition: opacity .5s var(--ease); }
.hcard-tag { position: absolute; left: 14px; top: 14px; z-index: 1; background: rgba(0,0,0,.55); color: #fff; border-color: rgba(255,255,255,.18); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.hcard-meta { display: flex; align-items: baseline; gap: 16px; padding-inline: 4px; }
.hcard-num { font-family: var(--f-display); font-size: 14px; color: var(--dim); min-width: 2ch; }
.hcard-txt h3 { font-size: clamp(1.35rem, 2vw, 1.8rem); letter-spacing: -0.035em; transition: color .3s; }
.hcard-txt p { color: var(--muted); font-size: 14px; margin-top: 4px; }
.hcard-end .hcard-media { background: linear-gradient(160deg, var(--card-2), var(--bg)); border-style: dashed; border-color: var(--line-2); }
.hcard-end .hcard-media::after { display: none; }
.hcard-end-inner { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: space-between; padding: clamp(22px, 3vw, 36px); }
.hcard-end-count { font-size: 14px; color: var(--dim); }
.hcard-end-title { font-family: var(--f-display); font-weight: 500; font-size: clamp(2.2rem, 4vw, 3.6rem); letter-spacing: -0.045em; line-height: .98; }
.hcard-end-title .serif { color: #8d8d8d; }
.hcard-end .t-go { width: 60px; height: 60px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line-2); transition: all .5s var(--ease); }
.hcard-end .t-go svg { width: 20px; height: 20px; transition: transform .5s var(--ease); }
.hcard-end:hover .t-go { background: var(--text); color: #000; border-color: var(--text); }
.hcard-end:hover .t-go svg { transform: rotate(-45deg); }

/* ---------- Project grid (projets page & related) ---------- */
.pgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.ptile { display: grid; gap: 18px; }

/* ---------- Engagement (scroll text reveal) ---------- */
.engage { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(32px, 6vw, 90px); align-items: center; }
.reveal-text { font-family: var(--f-display); font-weight: 500; font-size: clamp(1.8rem, 3.4vw, 2.9rem); line-height: 1.12; letter-spacing: -0.035em; }
.reveal-text .w { opacity: .16; transition: opacity .25s linear; }
.reveal-text .w.on { opacity: 1; }
.engage-media { position: relative; border-radius: var(--radius-l); overflow: hidden; aspect-ratio: 1 / 1.02; border: 1px solid var(--line); }
.engage-media img { position: absolute; left: 0; top: -8%; width: 100%; height: 116%; object-fit: cover; object-position: 30% 50%; will-change: transform; }
.engage-copy { display: grid; gap: 22px; }
.engage-copy p.lead strong { color: var(--text); font-weight: 500; }

/* ---------- Impact bento ---------- */
.bento { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px; }
.b-quote { grid-column: span 7; grid-row: span 2; display: grid; grid-template-columns: 1fr 1fr; }
.b-quote .q-body { padding: clamp(28px, 3.5vw, 44px); display: flex; flex-direction: column; justify-content: space-between; gap: 30px; }
.b-quote h3 { font-size: clamp(1.9rem, 3.2vw, 2.8rem); }
.b-quote .q-media { position: relative; min-height: 320px; }
.b-quote .q-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.b-quote .q-media::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, var(--card-2), transparent 35%); }
.sign { display: flex; flex-direction: column; }
.sign strong { font-family: var(--f-display); font-weight: 500; font-size: 17px; }
.sign span { color: var(--dim); font-size: 14px; }
.b-stat { grid-column: span 5; padding: clamp(26px, 3vw, 36px); display: flex; flex-direction: column; justify-content: space-between; gap: 18px; min-height: 230px; }
.b-stat .num { font-family: var(--f-display); font-weight: 500; font-size: clamp(4rem, 8vw, 6.5rem); letter-spacing: -0.06em; line-height: .9; }
.b-stat .label { font-size: 13px; text-transform: uppercase; letter-spacing: .1em; color: var(--dim); }
.b-stat p { color: var(--muted); max-width: 38ch; }
.b-cta { grid-column: span 12; padding: clamp(30px, 4vw, 52px); display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 28px; background: radial-gradient(120% 180% at 100% 0%, rgba(255,255,255, .07), transparent 55%), linear-gradient(180deg, var(--card-2), var(--card)); }
.b-cta h3 { font-size: clamp(1.9rem, 3.6vw, 3.2rem); }
.b-cta p { color: var(--muted); margin-top: 10px; }

/* ---------- Targets ---------- */
/* Section posée sur un fond plein, fondu en haut et en bas : la trame du fond du
   site n'entre plus en concurrence avec les filets horizontaux. */
.sec-shade { background: linear-gradient(180deg, transparent 0%, var(--bg) 12%, var(--bg) 94%, transparent 100%); }
.targets { border-top: 1px solid var(--line); }
.target {
  position: relative; display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding-block: clamp(22px, 3vw, 36px); border-bottom: 1px solid var(--line);
  font-family: var(--f-display); font-weight: 500; font-size: clamp(1.8rem, 4.6vw, 4rem); letter-spacing: -0.045em; line-height: 1;
  color: var(--dim); transition: color .4s, padding .6s var(--ease);
}
.target .t-num { font-size: 14px; letter-spacing: 0; color: var(--dim); font-weight: 400; min-width: 3ch; }
.target .t-name { flex: 1; }
.target .t-go { width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line-2); color: var(--text); transition: all .5s var(--ease); flex-shrink: 0; }
.target .t-go svg { width: 18px; height: 18px; transition: transform .5s var(--ease); }
.target:hover { color: var(--text); padding-left: 14px; }
.target:hover .t-go { background: var(--text); color: #000; border-color: var(--text); }
.target:hover .t-go svg { transform: rotate(-45deg); }

/* ---------- Témoignages (carrousel) ---------- */
.author { display: flex; align-items: center; gap: 12px; min-width: 0; }
.author img, .tcard-initials { width: 50px; height: 50px; border-radius: 50%; object-fit: cover; flex-shrink: 0; border: 1px solid var(--line-2); }
.tcard-initials { display: grid; place-items: center; background: var(--card-3); font-family: var(--f-display); font-weight: 500; font-size: 16px; }
.author strong { display: block; font-family: var(--f-display); font-weight: 500; }
.author span { color: var(--dim); font-size: 14px; }


.tslider { position: relative; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent); mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent); }
/* Défilement automatique : aucun conteneur scrollable, donc la molette reste à la page */
/* Le ruban fait plus de 4000 px de large : promu en couche GPU en permanence, il
   dépassait le budget du compositeur mobile et disparaissait. `is-live` est posé par
   main.js tant qu'il est à l'écran. La règle de pause au focus reste APRÈS celle-ci :
   à spécificité égale, c'est la dernière qui gagne. */
.tslider-track { display: flex; width: max-content; padding-block: 6px 8px; animation: tmarquee var(--dur, 60s) linear infinite; animation-play-state: paused; }
.tslider-track.is-live { animation-play-state: running; will-change: transform; }
/* Aucune pause au survol : le ruban ne s'arrête que pour la navigation clavier */
.tslider:focus-within .tslider-track { animation-play-state: paused; }
.tslider-group { display: flex; }
@keyframes tmarquee { to { transform: translateX(-50%); } }
/* Mobile : à durée égale, le ruban traverse un écran étroit bien plus vite → on ralentit */
@media (max-width: 640px) { .tslider-track { animation-duration: calc(var(--dur, 60s) * 2.4); } }

.tcard {
  position: relative; flex: 0 0 clamp(300px, 40vw, 540px); margin-right: 16px;
  display: flex; flex-direction: column; gap: 26px; padding: clamp(24px, 3vw, 36px);
  border-radius: var(--radius-l); border: 1px solid var(--line);
  background: radial-gradient(120% 90% at 100% 0%, rgba(255,255,255,.06), transparent 55%), linear-gradient(180deg, var(--card-2), var(--card));
  overflow: hidden; transition: border-color .4s, transform .6s var(--ease);
}
.tcard:hover { border-color: var(--line-2); transform: translateY(-4px); }
.tcard-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.tcard-quote { margin: 0; flex: 1; font-family: var(--f-display); font-size: clamp(1.25rem, 1.9vw, 1.6rem); line-height: 1.35; letter-spacing: -0.02em; }
.tcard-quote::before { content: "« "; color: var(--dim); }
.tcard-quote::after { content: " »"; color: var(--dim); }
.tcard-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding-top: 22px; border-top: 1px solid var(--line); }
.tcard-project { display: inline-flex; align-items: center; gap: 10px; padding: 5px 14px 5px 5px; border-radius: 999px; border: 1px solid var(--line); font-family: var(--f-display); font-weight: 500; font-size: 14px; transition: border-color .3s, background-color .3s; }
.tcard-project:hover { border-color: rgba(255,255,255,.3); background: rgba(255,255,255,.04); }
.tcard-project img { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; }
.tcard-project small { display: block; font-family: var(--f-body); font-weight: 400; font-size: 11px; color: var(--dim); line-height: 1.1; }
.tcard-project svg { width: 13px; height: 13px; transition: transform .45s var(--ease); }
.tcard-project:hover svg { transform: rotate(-45deg); }
.tcard-mark { position: absolute; right: 24px; top: 28px; color: #fff; opacity: .05; pointer-events: none; }
.tcard-mark svg { width: 120px; height: 92px; }

@media (max-width: 640px) {
  .tcard { flex-basis: 86vw; }
  .tcard-mark svg { width: 80px; height: 62px; }
  /* Le pied de carte tient sur UNE ligne : le lien vers le projet reste à côté du nom
     du client au lieu de passer dessous. Le nom du projet est déjà affiché à gauche,
     on ne garde donc que le logo et la flèche ; le libellé reste dans le DOM pour
     donner son nom accessible au lien. */
  .tcard-foot { flex-wrap: nowrap; gap: 10px; }
  .author img, .tcard-initials { width: 42px; height: 42px; }
  .author strong, .author span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tcard-project { flex-shrink: 0; gap: 8px; padding: 4px 12px 4px 4px; }
  .tcard-project img { width: 32px; height: 32px; }
  .tcard-project > span {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}

/* ---------- Footer ---------- */
.footer-cta { position: relative; overflow: hidden; text-align: center; padding-block: clamp(56px, 7vw, 100px) clamp(60px, 8vw, 100px);
  background: var(--bg); }
/* Fondu placé AVANT le bloc CTA : la vignette de la fumée rend le bloc opaque dès
   son premier pixel, donc la transition doit se jouer sur la section précédente.
   z-index négatif = par-dessus la trame du fond, mais sous tout le contenu. */
.cta-fade {
  position: relative; z-index: -1; pointer-events: none;
  height: clamp(120px, 16vw, 220px); margin-top: calc(-1 * clamp(120px, 16vw, 220px));
  background: linear-gradient(180deg, transparent, var(--bg) 92%);
}
.footer-cta::before {
  content: ""; position: absolute; left: 50%; bottom: -40%; width: 1200px; height: 700px; transform: translateX(-50%); z-index: -1;
  background: radial-gradient(closest-side, rgba(255,255,255,.08), rgba(255,255,255,.03) 50%, transparent 75%);
  filter: blur(30px);
}
.footer-cta .inner { display: grid; justify-items: center; gap: 26px; }
.footer-cta h2 { max-width: 12ch; }

.site-footer { border-top: 1px solid var(--line); padding-top: clamp(48px, 6vw, 72px); overflow: hidden; background: var(--bg); }
.foot-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 40px; }
.foot-brand { display: grid; gap: 18px; align-content: start; }
.foot-brand img { height: 40px; width: auto; }
.foot-brand p { color: var(--muted); max-width: 34ch; font-size: 15px; }
.foot-col h3 { font-family: var(--f-body); font-size: 13px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); margin-bottom: 18px; }
.foot-col ul { display: grid; gap: 10px; }
.foot-col a { color: var(--muted); transition: color .3s; }
.foot-col a:hover { color: var(--text); }
.foot-word {
  margin-top: clamp(48px, 7vw, 90px);
  font-family: var(--f-display); font-weight: 600; letter-spacing: -0.07em; line-height: .72;
  font-size: clamp(5rem, 24vw, 22rem); text-align: center;
  background: linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,0) 85%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  user-select: none; pointer-events: none;
}
.foot-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 16px; padding-block: 24px calc(24px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--line); color: var(--dim); font-size: 14px; }
.foot-word + .foot-bottom { margin-top: 0; }
.foot-bottom a:hover { color: var(--text); }
.to-top { display: inline-flex; align-items: center; gap: 8px; }
.to-top svg { width: 14px; height: 14px; transform: rotate(-90deg); }

/* ---------- Page hero (inner pages) ---------- */
.page-hero { position: relative; padding-top: calc(var(--header-h) + clamp(36px, 5vw, 64px)); padding-bottom: clamp(40px, 6vw, 70px); overflow: hidden; }
.page-hero .inner { display: grid; gap: 24px; }
.page-hero.center .inner { justify-items: center; text-align: center; }
.breadcrumb { display: flex; flex-wrap: wrap; gap: 8px; font-size: 14px; color: var(--dim); }
.breadcrumb a:hover { color: var(--text); }
.breadcrumb span[aria-hidden] { opacity: .5; }

/* ---------- Case study ---------- */
.case-head { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: clamp(28px, 5vw, 80px); align-items: end; }
.case-head .lead { max-width: 52ch; }
.case-meta { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; margin-top: clamp(40px, 6vw, 64px); background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.case-meta div { background: var(--bg); padding: 20px 22px; display: grid; gap: 6px; }
.case-meta dt { font-size: 12px; text-transform: uppercase; letter-spacing: .1em; color: var(--dim); }
.case-meta dd { margin: 0; font-family: var(--f-display); font-weight: 500; font-size: 16px; }
.case-layout { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: clamp(32px, 6vw, 96px); align-items: start; }
.toc { position: sticky; top: 120px; display: grid; gap: 4px; }
.toc p { font-size: 12px; text-transform: uppercase; letter-spacing: .1em; color: var(--dim); margin-bottom: 10px; }
.toc a { position: relative; padding: 8px 0 8px 18px; color: var(--dim); font-size: 14px; line-height: 1.35; border-left: 1px solid var(--line); transition: color .3s, border-color .3s; }
.toc a:hover { color: var(--text); }
.toc a.active { color: var(--text); border-color: var(--g3); }

.next-project { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; min-height: 360px; }
.next-project .np-body { padding: clamp(28px, 4vw, 52px); display: grid; gap: 16px; }
.next-project .np-media { position: relative; align-self: stretch; margin: 12px; border-radius: 20px; overflow: hidden; min-height: 280px; }
.next-project .np-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.next-project:hover .np-media img { transform: scale(1.05); }

/* ---------- Prose ---------- */
.prose { font-size: 17.5px; line-height: 1.75; color: #c9c9c4; }
.prose > * + * { margin-top: 1.1em; }
.prose h2 { color: var(--text); font-size: clamp(1.6rem, 2.6vw, 2.2rem); line-height: 1.12; margin-top: 2.2em; margin-bottom: .2em; scroll-margin-top: 120px; }
.prose h2:first-child { margin-top: 0; }
.prose h3 { color: var(--text); font-size: 1.3rem; letter-spacing: -0.02em; margin-top: 1.8em; }
.prose strong { color: var(--text); font-weight: 600; }
.prose a { color: var(--text); background: linear-gradient(#fff, #fff) 0 100% / 100% 1px no-repeat; transition: background-size .3s; padding-bottom: 1px; }
.prose a:hover { background-size: 100% 2px; }
.prose ul { display: grid; gap: .7em; }
.prose ul li { position: relative; padding-left: 28px; }
.prose ul li::before { content: ""; position: absolute; left: 6px; top: .78em; width: 6px; height: 6px; border-radius: 50%; background: #fff; }
.prose blockquote { margin-inline: 0; padding: 22px 26px; border-left: 2px solid #fff; background: var(--card); border-radius: 0 var(--radius-s) var(--radius-s) 0; font-family: var(--f-serif); font-style: italic; font-size: 1.45em; line-height: 1.35; color: var(--text); }
.prose .section-block { padding-top: 0; }
.price-callout { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.price-callout div { padding: 22px; border-radius: var(--radius); border: 1px solid var(--line-2); background: var(--card); display: grid; gap: 6px; }
.price-callout span { font-size: 14px; color: var(--muted); line-height: 1.4; }
.price-callout strong { font-family: var(--f-display); font-size: 1.8rem; letter-spacing: -0.04em; }

/* ---------- Blog ---------- */
.post-featured { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 0; margin-bottom: 20px; }
.post-featured .pf-media { position: relative; margin: 12px; border-radius: 20px; overflow: hidden; min-height: 360px; }
.post-featured .pf-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.post-featured:hover .pf-media img { transform: scale(1.04); }
.post-featured .pf-body { padding: clamp(28px, 4vw, 52px); display: flex; flex-direction: column; justify-content: center; gap: 18px; }
.post-featured h2 { font-size: clamp(1.8rem, 3.2vw, 2.7rem); line-height: 1.05; }
.post-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.post { display: grid; gap: 16px; align-content: start; }
.post-media { aspect-ratio: 16/10; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); background: var(--card); }
.post-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.post:hover .post-media img { transform: scale(1.05); }
.post h3 { font-size: 1.35rem; line-height: 1.18; letter-spacing: -0.025em; }
.post p { color: var(--muted); font-size: 15px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.post-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; font-size: 13px; color: var(--dim); }
.post-meta .sep { width: 3px; height: 3px; border-radius: 50%; background: currentColor; }
.post-meta .cat { color: var(--text); }

.article-cover { border-radius: var(--radius-l); overflow: hidden; border: 1px solid var(--line); margin-block: clamp(32px, 5vw, 56px); aspect-ratio: 16/8; background: var(--card); }
.article-cover img { width: 100%; height: 100%; object-fit: cover; }
.author-box { display: flex; align-items: center; gap: 18px; margin-top: 56px; padding: 22px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); }
.author-box img { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; object-position: 50% 25%; }
.author-box div { flex: 1; }
.author-box strong { font-family: var(--f-display); font-weight: 500; font-size: 17px; }
.author-box p { color: var(--muted); font-size: 14px; }
.progress { position: fixed; left: 0; top: 0; height: 2px; width: 100%; z-index: 200; background: #fff; transform-origin: 0 50%; transform: scaleX(0); }

/* ---------- Pricing ---------- */
.tabs { display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 4px; padding: 5px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); }
.tab { height: 42px; padding: 0 18px; border-radius: 999px; font-size: 14px; color: var(--muted); font-family: var(--f-display); font-weight: 500; transition: color .3s, background-color .3s; }
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { background: var(--text); color: #000; }
.tab-panels { margin-top: 40px; }
/* Carte tarif « verre » : même recette que la pastille du header (fond translucide +
   backdrop-filter + liseré interne clair en haut), à plus grande échelle. Le .card
   qu'elle porte donne un fond opaque : on le remplace ici. */
.price-card {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  background: linear-gradient(150deg, rgba(255,255,255,.06), rgba(255,255,255,.014) 45%, rgba(255,255,255,.035)), rgba(0,0,0,.3);
  border-color: rgba(255,255,255,.11);
  backdrop-filter: blur(26px) saturate(170%);
  -webkit-backdrop-filter: blur(26px) saturate(170%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.17), inset 0 -1px 0 rgba(255,255,255,.04),
              0 1px 0 rgba(0,0,0,.35), 0 34px 80px rgba(0,0,0,.55);
}
/* Reflet : une lueur douce en haut à gauche, comme la spéculaire d'une plaque de verre. */
.price-card::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: radial-gradient(90% 60% at 12% -10%, rgba(255,255,255,.085), transparent 60%);
}
.price-card > * { position: relative; }
.price-main { padding: clamp(28px, 4vw, 52px); display: flex; flex-direction: column; gap: 22px; border-right: 1px solid rgba(255,255,255,.12); background: radial-gradient(120% 90% at 0% 0%, rgba(255,255,255, .04), transparent 55%); }
.price-main h2 { font-size: clamp(1.7rem, 2.8vw, 2.3rem); }
.price-main p { color: var(--muted); }
.price { display: grid; gap: 4px; padding-block: 12px; }
.price small { color: var(--dim); font-size: 14px; }
.price .amount { font-family: var(--f-display); font-weight: 500; font-size: clamp(3.1rem, 6.6vw, 5.2rem); letter-spacing: -0.05em; line-height: .9; font-variant-numeric: tabular-nums; }
.price .amount.text { font-size: clamp(2.4rem, 4.6vw, 3.6rem); }
.price .monthly { font-family: var(--f-display); font-size: 1.2rem; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.price .monthly span { color: var(--dim); font-size: 1rem; }
.price .monthly:has([data-price]) span { color: var(--text); }
.pay-note { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; color: var(--text); padding: 10px 14px; border-radius: 12px; background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.13); box-shadow: inset 0 1px 0 rgba(255,255,255,.16); align-self: flex-start; white-space: nowrap; }
.price-side { padding: clamp(28px, 4vw, 52px); display: flex; flex-direction: column; gap: 22px; }
.price-side h3 { font-size: 1rem; font-family: var(--f-body); font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
.checks { display: grid; gap: 13px; }
.checks li { display: flex; align-items: flex-start; gap: 12px; }
.checks svg { flex-shrink: 0; width: 22px; height: 22px; margin-top: 1px; color: var(--text); }
.indep { margin-top: auto; padding: 18px; border-radius: var(--radius-s); background: rgba(255,255,255, .055); border: 1px solid rgba(255,255,255,.12); box-shadow: inset 0 1px 0 rgba(255,255,255,.14); font-size: 14px; color: var(--muted); }
.indep strong { color: var(--text); font-weight: 500; }

.timeline { display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px; counter-reset: s; position: relative;
  /* de l'air sous le titre : les arcs montent jusqu'à 62 px au-dessus des cartes */
  margin-top: clamp(50px, 7vw, 96px); }
/* Flèches tracées d'une étape à l'autre : le calque déborde en haut pour que les
   arcs enjambent les cartes (le gap de 16px ne suffirait pas à les loger). */
.tl-arrows { position: absolute; left: 0; right: 0; top: -58px; height: calc(100% + 116px);
  pointer-events: none; z-index: 2; overflow: visible; }
/* Trait épais, bouts ronds : un tracé au feutre blanc. L'irrégularité vient de la
   géométrie du chemin (pas d'un filtre SVG, trop coûteux à recalculer au scroll). */
.tl-arrows path { fill: none; stroke: #fff; stroke-width: 3.6; stroke-linecap: round;
  stroke-linejoin: round; opacity: .82; }
.tl-arrows .ink2 { stroke-width: 1.5; opacity: .3; }
/* Pointe : triangle PLEIN, chemin à part. Le liseré reprend la couleur du remplissage
   pour arrondir très légèrement les angles. Son opacité est pilotée image par image
   depuis main.js (fondu à l'arrivée), ne pas la fixer ici. */
.tl-arrows .tip { fill: #fff; stroke: #fff; stroke-width: 1.6; }

/* Carte atteinte par la flèche : elle s'allume, grossit et s'incline légèrement. */
.tl { transition: transform .7s var(--ease), border-color .7s var(--ease), box-shadow .7s var(--ease); }
.tl:nth-of-type(even) { --tilt: 0.8deg; }
.tl.is-lit { transform: scale(1.03) rotate(var(--tilt, -0.8deg));
  border-color: rgba(255,255,255,.3);
  box-shadow: 0 22px 60px rgba(0,0,0,.55), 0 0 34px rgba(255,255,255,.07); }
.tl.is-lit .tl-num { background: #fff; color: #000; border-color: #fff; }
@media (prefers-reduced-motion: reduce) { .tl.is-lit { transform: none; } }
.tl { padding: 28px 24px; display: grid; gap: 14px; align-content: start; }
.tl-num { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line-2); font-family: var(--f-display); font-weight: 500; font-size: 15px; }
.tl:hover .tl-num { background: #fff; color: #000; border-color: #fff; }
.tl h3 { font-size: 1.3rem; letter-spacing: -0.025em; }
.tl p { color: var(--muted); font-size: 15px; }

.faq { display: grid; gap: 10px; }
.faq details { border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); transition: border-color .3s; }
.faq details[open] { border-color: var(--line-2); }
.faq summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 20px; padding: 22px 24px; font-family: var(--f-display); font-weight: 500; font-size: 1.1rem; letter-spacing: -0.015em; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary i { position: relative; width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--line-2); flex-shrink: 0; transition: transform .4s var(--ease); }
.faq summary i::before, .faq summary i::after { content: ""; position: absolute; left: 50%; top: 50%; width: 10px; height: 1.5px; background: currentColor; transform: translate(-50%, -50%); }
.faq summary i::after { transform: translate(-50%, -50%) rotate(90deg); transition: transform .4s var(--ease); }
.faq details[open] summary i::after { transform: translate(-50%, -50%) rotate(0); }
.faq .faq-a { padding: 0 24px 22px; color: var(--muted); max-width: 70ch; }

/* ---------- Contact ---------- */
.contact-layout { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: clamp(32px, 6vw, 90px); align-items: start; }
.contact-info { display: grid; gap: 28px; position: sticky; top: 120px; }
.contact-lines { display: grid; gap: 10px; }
.contact-line { display: flex; align-items: center; gap: 14px; padding: 16px 18px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); transition: border-color .3s; }
.contact-line:hover { border-color: var(--line-2); }
.contact-line .ic { width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; background: rgba(255,255,255,.06); }
.contact-line .ic svg { width: 18px; height: 18px; }
.contact-line small { display: block; color: var(--dim); font-size: 13px; }
.contact-person { display: flex; align-items: center; gap: 14px; }
.contact-person img { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; object-position: 50% 25%; }

.form { padding: clamp(24px, 3.5vw, 44px); position: relative; }
.form-body { display: grid; gap: 22px; }
.field { display: grid; gap: 8px; }
.field label, .field legend { font-size: 14px; color: var(--muted); }
.field label em, .field legend em { font-style: normal; color: var(--dim); }
.field input, .field textarea {
  width: 100%; padding: 15px 18px; border-radius: 14px;
  background: #0a0a0a; border: 1px solid var(--line-2); color: var(--text);
  transition: border-color .3s, box-shadow .3s; font-size: 16px;
}
.field textarea { min-height: 150px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: #555; }
.field input:focus, .field textarea:focus { outline: none; border-color: rgba(255,255,255, .6); box-shadow: 0 0 0 4px rgba(255,255,255, .1); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
fieldset.field { border: 0; margin: 0; padding: 0; min-width: 0; }
.pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.pill input { position: absolute; opacity: 0; pointer-events: none; }
.pill span { display: inline-flex; align-items: center; height: 40px; padding: 0 16px; border-radius: 999px; border: 1px solid var(--line-2); font-size: 14px; color: var(--muted); cursor: pointer; transition: all .25s; }
.pill span:hover { color: var(--text); border-color: rgba(255,255,255,.3); }
.pill input:checked + span { background: var(--text); color: #000; border-color: var(--text); }
.pill input:focus-visible + span { outline: 2px solid var(--g3); outline-offset: 2px; }
.consent { display: flex; gap: 12px; align-items: flex-start; font-size: 14px; color: var(--muted); }
.consent input { margin-top: 3px; width: 18px; height: 18px; accent-color: var(--g2); flex-shrink: 0; }
.consent a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-status { font-size: 15px; padding: 14px 18px; border-radius: 14px; }
.form-status.err { background: rgba(255, 90, 90, .08); border: 1px solid rgba(255, 90, 90, .3); color: #ffd0d0; }
.form .btn[disabled] { opacity: .6; pointer-events: none; }

/* Envoi réussi : les champs s'effacent en cascade, la carte se redimensionne (JS),
   puis la coche se trace et le message monte. */
.form-body > * { transition: opacity .4s var(--ease), transform .5s var(--ease), filter .4s var(--ease); transition-delay: calc(var(--i, 0) * 45ms); }
.form.is-leaving .form-body > * { opacity: 0; transform: translateY(-14px) scale(.98); filter: blur(6px); }
.form-done { display: grid; justify-items: center; text-align: center; gap: 18px; padding: clamp(28px, 6vw, 72px) 0 clamp(16px, 3vw, 32px); }
.form-done[hidden] { display: none; }
.form-done .h-m { max-width: 16ch; outline: none; }
.form-done p { max-width: 44ch; }
.form-done p a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.fd-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 8px; }
.fd-mark { position: relative; width: 96px; height: 96px; margin-bottom: 10px; color: var(--text); }
.fd-mark svg { position: relative; width: 100%; height: 100%; overflow: visible; }
.fd-mark::before { /* halo */
  content: ""; position: absolute; inset: -60%; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,255,255,.16), rgba(255,255,255,0) 70%);
  opacity: 0; transform: scale(.4);
}
.fd-ring { stroke-dasharray: 277; stroke-dashoffset: 277; transform: rotate(-90deg); transform-origin: 50% 50%; }
.fd-check { stroke-dasharray: 60; stroke-dashoffset: 60; }
.fd-wave { position: absolute; inset: 0; border-radius: 50%; border: 1px solid rgba(255,255,255,.5); opacity: 0; }
.fd-in { opacity: 0; transform: translateY(18px); filter: blur(6px); }
.form.is-sent .fd-mark::before { animation: fd-halo 1.4s var(--ease) .1s forwards; }
.form.is-sent .fd-ring { animation: fd-draw .8s cubic-bezier(.65, 0, .35, 1) forwards; }
.form.is-sent .fd-check { animation: fd-draw .45s cubic-bezier(.65, 0, .35, 1) .65s forwards; }
.form.is-sent .fd-mark svg { animation: fd-pop .5s cubic-bezier(.34, 1.56, .64, 1) 1s; }
.form.is-sent .fd-wave { animation: fd-wave 1.6s var(--ease) 1s forwards; }
.form.is-sent .fd-wave + .fd-wave { animation-delay: 1.25s; }
.form.is-sent .fd-in { animation: fd-rise .8s var(--ease) forwards; animation-delay: calc(.85s + var(--i) * 90ms); }
@keyframes fd-draw { to { stroke-dashoffset: 0; } }
@keyframes fd-pop { 50% { transform: scale(1.08); } }
@keyframes fd-halo { 40% { opacity: 1; transform: scale(1); } to { opacity: .55; transform: scale(1); } }
@keyframes fd-wave { from { opacity: .7; transform: scale(1); } to { opacity: 0; transform: scale(2.1); } }
@keyframes fd-rise { to { opacity: 1; transform: none; filter: none; } }
@media (prefers-reduced-motion: reduce) {
  .form-body > * { transition: none; }
  .form.is-sent .fd-mark::before, .form.is-sent .fd-ring, .form.is-sent .fd-check,
  .form.is-sent .fd-mark svg, .form.is-sent .fd-wave, .form.is-sent .fd-in { animation: none; }
  .form.is-sent .fd-ring, .form.is-sent .fd-check { stroke-dashoffset: 0; }
  .form.is-sent .fd-in { opacity: 1; transform: none; filter: none; }
  .form.is-sent .fd-mark::before { opacity: .55; transform: none; }
}

/* ---------- 404 ---------- */
.notfound { position: relative; overflow: hidden; min-height: 80vh; display: grid; place-items: center; text-align: center; padding-top: var(--header-h); }
.notfound .inner { display: grid; gap: 22px; justify-items: center; }
.notfound .code404 { font-family: var(--f-display); font-weight: 600; font-size: clamp(7rem, 26vw, 16rem); letter-spacing: -0.07em; line-height: .8; }

/* ---------- Reveal animations ---------- */
.js [data-reveal] { opacity: 0; transform: translateY(28px); transition: opacity 1s var(--ease), transform 1s var(--ease); transition-delay: var(--d, 0s); }
.js [data-reveal].in { opacity: 1; transform: none; }
.js .split .line-in { display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.js .split .line-in > span { display: block; transform: translateY(105%); transition: transform 1.1s var(--ease); transition-delay: var(--d, 0s); }
.js .split.in .line-in > span { transform: none; }
.js .split.is-split-done .line-in { overflow: visible; }

/* ---------- Responsive ---------- */
@media (max-width: 1080px) {
  .steps { grid-template-columns: 1fr; }
  .step { min-height: 0; display: grid; grid-template-columns: 1fr 1fr; align-items: center; }
  .b-quote, .b-stat { grid-column: span 12; }
  .b-stat { grid-column: span 6; }
  .timeline { grid-template-columns: repeat(2, 1fr); row-gap: 64px; }   /* place pour la flèche qui change de ligne */
  .post-grid { grid-template-columns: repeat(2, 1fr); }
  .case-layout { grid-template-columns: 1fr; }
  .toc { display: none; }
  .foot-grid { grid-template-columns: 1fr 1fr 1fr; }
  .foot-brand { grid-column: 1 / -1; }
}

@media (max-width: 860px) {
  :root { --header-h: 76px; }
  .nav { grid-template-columns: 1fr auto; padding-left: 20px; }
  .nav-links { display: none; }
  .nav-cta .btn { display: none; }
  .burger { display: block; }
  .logo img { height: 26px; }
  .site-header .nav { background: rgba(12,12,12,.72); border-color: var(--line); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); }
  .menu-open .site-header .nav { background: transparent; border-color: transparent; box-shadow: none; }
  /* Menu ouvert : le header du site s'efface entièrement. Il dépassait du panneau (logo
     et barre de verre à gauche de la sidebar). La sidebar porte son propre logo et sa
     propre croix, tout reste donc à l'intérieur du panneau. */
  .site-header { transition: opacity .3s var(--ease), visibility .3s; }
  .menu-open .site-header { opacity: 0; visibility: hidden; }
  .hwork-ctrl .btn { display: none; }
  .hwork.is-pinned .hwork-pin { height: auto; padding-top: 0; gap: 28px; }
  .hwork.is-pinned .hwork-track { --card-w: min(82vw, 440px, calc((100svh - 380px) * 1.19)); }
  .pgrid { grid-template-columns: 1fr; }
  .engage { grid-template-columns: 1fr; }
  .engage-media { aspect-ratio: 4/3; }
  .b-quote { grid-template-columns: 1fr; }
  .b-quote .q-media { order: -1; min-height: 300px; }
  .b-quote .q-media::after { background: linear-gradient(0deg, var(--card-2), transparent 40%); }
  .case-head { grid-template-columns: 1fr; }
  .case-meta { grid-template-columns: repeat(2, 1fr); }
  .next-project { grid-template-columns: 1fr; }
  .next-project .np-media { order: -1; margin-bottom: 0; }
  .post-featured { grid-template-columns: 1fr; }
  .price-card { grid-template-columns: 1fr; }
  .price-main { border-right: 0; border-bottom: 1px solid rgba(255,255,255,.12); }
  .contact-layout { grid-template-columns: 1fr; }
  .contact-info { position: static; }
}

@media (max-width: 640px) {
  body { font-size: 15.5px; }
  .hero h1 { font-size: clamp(2.4rem, 11.4vw, 3.4rem); }
  .hero h1 .serif { font-size: .98em; }
  /* Titres des heros de page : les coupures de lignes sont écrites en dur dans le HTML.
     Au plancher de 2.9rem, les lignes les plus longues (« Conditions générales »,
     « croissance digitale. ») dépassent de quelques pixels la largeur disponible et le
     navigateur les recoupe — le titre se tasse alors sur la gauche. Une taille pilotée
     par la largeur de l'écran leur laisse la place d'aller jusqu'au bord droit. */
  .h-xl { font-size: clamp(2.2rem, 10.5vw, 7.4rem); }
  .step { grid-template-columns: 1fr; }
  .step-visual { height: 230px; }
  .post-grid, .timeline { grid-template-columns: 1fr; }
  .timeline { gap: 104px; }  /* de la place pour les flèches entre cartes empilées : en dessous, l'arc se replie en crochet */
  .b-stat { grid-column: span 12; }
  .field-row { grid-template-columns: 1fr; }
  .case-meta { grid-template-columns: 1fr; }
  .price-callout { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: 1fr 1fr; }
  .target .t-go { width: 42px; height: 42px; }
  .btn-row { width: 100%; }
  .hero .btn-row { justify-content: center; }
  /* Titre « Les briques fondamentales » : le bouton « Voir les tarifs » partageait la
     ligne du flex et écrasait le titre sur la gauche. Il passe dessous, le titre prend
     toute la largeur. */
  .svc-head { flex-direction: column; align-items: flex-start; gap: 24px; }
  .svc-head > div { width: 100%; max-width: none; }
  /* Les deux lignes sont écrites en dur dans le HTML et « Les briques fondamentales »
     frôle la largeur de l'écran : sans garde-fou le navigateur la recoupe et le titre se
     tasse à gauche. Même plafond que .h-l (2.3rem), donc même taille que les autres
     titres de section ; la part en vw ne prend le relais que sous ~410 px de large, où
     la ligne ne rentrerait plus. */
  .svc-head .h-l { font-size: clamp(1.85rem, 8.9vw, 2.3rem); letter-spacing: -0.05em; }
  .prose { font-size: 16.5px; }
  .wall-inner { grid-template-columns: repeat(3, 1fr); width: 190vw; }
  .wall-col:nth-child(4) { display: none; }
  /* Onglets : grille de deux colonnes, boutons pleins plutôt qu'une pilule
     qui se replie mal. Le conteneur perd son cadre, chaque onglet porte le sien. */
  .tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: 100%;
    padding: 0; border: 0; background: none; border-radius: 0; }
  .tab { height: 48px; padding: 0 10px; border-radius: 12px;
    background: var(--card); border: 1px solid var(--line); color: var(--muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    transition: color .3s, background-color .3s, border-color .3s; }
  .tab[aria-selected="true"] { background: var(--text); color: #000; border-color: var(--text); }
  /* Boutons pleine largeur dans les cartes : le libellé reste centré sur toute la
     largeur et la pastille se cale en bout, au lieu de flotter collée au texte. */
  .price-main .btn-row .btn, .price-side .btn-row .btn {
    --h: 56px; width: 100%; justify-content: center; padding: 0 52px;
  }
  .price-main .btn-row .btn .btn-ico, .price-side .btn-row .btn .btn-ico {
    position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  }
  /* Toujours sur une seule ligne : le bloc rétrécit avec l'écran plutôt que de passer à la ligne. */
  .pay-note { align-self: stretch; justify-content: center; gap: 6px;
    font-size: clamp(9.5px, 2.8vw, 14px); padding: 9px 8px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .js [data-reveal] { opacity: 1; transform: none; }
  .js .split .line-in > span { transform: none; }
  .reveal-text .w { opacity: 1; }
}

/* ---------- Services : grille illustrée ----------
   Illustrations SVG (illustrations.py) animées en boucle, uniquement quand la grille est
   à l'écran : `is-live` est posé par l'IIFE « animations lourdes » de main.js.
   Au pointeur (desktop) : la carte s'incline (--rx/--ry), l'illustration glisse en
   parallaxe (--px/--py) et un reflet suit le curseur (--mx/--my). */
.svc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.svc-card { position: relative; display: flex; flex-direction: column; padding: 8px; border: 1px solid var(--line); border-radius: var(--radius-l); background: var(--card);
  transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .6s var(--ease), border-color .5s; }
.svc-card.is-tilt { transition: transform .12s linear, border-color .5s; }
.svc-card:hover { border-color: var(--line-2); }
.svc-stage { position: relative; overflow: hidden; border-radius: 20px; padding: 26px 22px 18px;
  background-color: #0a0a0a;
  background-image: linear-gradient(rgba(255,255,255,.035) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.035) 1px, transparent 1px), radial-gradient(80% 80% at 50% 0%, rgba(255,255,255,.07), transparent 70%);
  background-size: 24px 24px, 24px 24px, auto; }
.svc-stage .ill { transform: translate(calc(var(--px, 0) * -14px), calc(var(--py, 0) * -10px)) scale(1.04); transition: transform .3s ease-out; }
.svc-num { position: absolute; top: 14px; left: 16px; font-size: 12px; color: var(--dim); }
.svc-glare { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .4s;
  background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,.12), transparent 60%); }
.svc-card:hover .svc-glare { opacity: 1; }
.svc-body { display: grid; gap: 14px; padding: 22px 16px 16px; justify-items: start; align-content: start; flex: 1; }
.svc-top { display: flex; justify-content: space-between; gap: 12px; width: 100%; }
.svc-top .serif { color: #8d8d8d; font-size: 1.1rem; }
.svc-top h3 { font-size: 1.6rem; letter-spacing: -0.035em; }
.svc-go { flex-shrink: 0; width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line-2); transition: background-color .5s var(--ease), color .5s; }
.svc-go svg { width: 15px; height: 15px; transition: transform .5s var(--ease); }
.svc-card:hover .svc-go { background: var(--text); color: #000; }
.svc-card:hover .svc-go svg { transform: rotate(-45deg); }
.svc-body p { color: var(--muted); font-size: 14.5px; line-height: 1.55; }
.svc-body .tag { margin-top: auto; }

/* Illustrations : rendu */
.ill { display: block; width: 100%; height: auto; overflow: visible; }
.ill .f1 { fill: #111; } .ill .f2 { fill: #1a1a1a; } .ill .f3 { fill: #2a2a2a; } .ill .mu { fill: #6c6c69; } .ill .hi { fill: #f4f4f1; }
.ill .ln { stroke: rgba(255,255,255,.09); stroke-width: 1; } .ill .ln2 { stroke: rgba(255,255,255,.2); stroke-width: 1; }
.ill line.ln { fill: none; }
.ill text { font-family: var(--f-body); }
.ill .tx-s { font-size: 11px; fill: #a0a09c; }
.ill .tx-d { font-size: 10px; fill: #050505; font-weight: 600; }
.ill .tx-b { font-family: var(--f-display); font-size: 17px; font-weight: 500; fill: #f4f4f1; }
.ill .tx-serif { font-family: "Instrument Serif", serif; font-size: 40px; fill: #f4f4f1; }
.ill .tx-big { font-family: var(--f-display); font-size: 36px; font-weight: 500; fill: #8d8d8d; }
.ill .il-line { stroke-dasharray: 420; }
.ill .il-cursor { transform: var(--from); }
.ill .il-bars rect { transform-box: fill-box; transform-origin: 50% 100%; }
.ill .il-float, .ill .il-fan1, .ill .il-fan2, .ill .il-logo, .ill .il-badge, .ill .il-btn { transform-box: fill-box; transform-origin: 50% 50%; }
.ill .il-sw circle { transform-box: fill-box; transform-origin: center; }
.ill .il-spin { transform-origin: 120px 130px; }

/* Illustrations : boucles (en pause hors écran), décalées d'une carte à l'autre */
.svc-card { --dl: calc(var(--i) * -.7s); }
.ill .il-cursor { animation: il-cur 4.2s var(--ease) infinite var(--dl); }
.ill .il-btn { animation: il-press 4.2s ease infinite var(--dl); }
.ill .il-badge { animation: il-pop 4.2s var(--ease) infinite var(--dl); }
.ill .il-float { animation: il-float 5s ease-in-out infinite var(--dl); }
.ill .il-bars rect { animation: il-bars 4.2s var(--ease) infinite; }
.ill .il-bars rect:nth-child(2) { animation-delay: .08s; } .ill .il-bars rect:nth-child(3) { animation-delay: .16s; }
.ill .il-bars rect:nth-child(4) { animation-delay: .24s; } .ill .il-bars rect:nth-child(5) { animation-delay: .32s; }
.ill .il-bars rect:nth-child(6) { animation-delay: .4s; }  .ill .il-bars rect:nth-child(7) { animation-delay: .48s; }
.ill .il-line { animation: il-draw 4.2s var(--ease) infinite var(--dl); }
.ill .il-type { animation: il-type 4.2s steps(26) infinite; }
.ill .il-fan1 { animation: il-fan1 5s ease-in-out infinite; }
.ill .il-fan2 { animation: il-fan2 5s ease-in-out infinite; }
.ill .il-logo { animation: il-logo 6s var(--ease) infinite; }
.ill .il-spin { animation: il-spin 40s linear infinite; }
.ill .il-sw circle { animation: il-sw 3s ease-in-out infinite; }
.ill .il-sw circle:nth-child(2) { animation-delay: .2s; } .ill .il-sw circle:nth-child(3) { animation-delay: .4s; }
.ill .il-pulse { animation: il-pulse 1.8s ease-in-out infinite; }
.svc-grid .ill * { animation-play-state: paused; }
.svc-grid.is-live .ill * { animation-play-state: running; }
@keyframes il-cur { 0%, 15% { transform: var(--from); } 45%, 75% { transform: var(--to); } 100% { transform: var(--from); } }
@keyframes il-press { 0%, 46%, 56%, 100% { transform: scale(1); } 50% { transform: scale(.9); } }
@keyframes il-pop { 0%, 50% { transform: scale(1); } 56% { transform: scale(1.45); } 64%, 100% { transform: scale(1); } }
@keyframes il-float { 50% { transform: translateY(-7px); } }
@keyframes il-bars { 0% { transform: scaleY(.15); } 40%, 85% { transform: scaleY(1); } 100% { transform: scaleY(.15); } }
@keyframes il-draw { 0% { stroke-dashoffset: 420; } 50%, 85% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: -420; } }
@keyframes il-type { 0% { clip-path: inset(0 100% 0 0); } 55%, 90% { clip-path: inset(0 0 0 0); } 100% { clip-path: inset(0 100% 0 0); } }
@keyframes il-fan1 { 50% { transform: rotate(-5deg) translateX(-8px); } }
@keyframes il-fan2 { 50% { transform: rotate(5deg) translate(6px, -6px); } }
@keyframes il-logo { 0%, 20% { transform: none; } 45%, 70% { transform: scale(1.1) rotate(-12deg); } 100% { transform: none; } }
@keyframes il-spin { to { transform: rotate(360deg); } }
@keyframes il-sw { 50% { transform: translateY(-5px); } }
@keyframes il-pulse { 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) {
  .ill * { animation: none !important; }
  .svc-card { transform: none !important; }
}
@media (max-width: 1080px) { .svc-grid { grid-template-columns: 1fr 1fr; } }
.svc-item { display: grid; }

/* Bordures éclairées : une lumière suit le pointeur sur toute la grille et allume le bord
   (::before, masqué au liseré) et le fond (::after) des cartes proches. --bx/--by posés
   par main.js (desktop) ; hors écran par défaut, donc invisible au tactile. */
.svc-card { --bx: -999px; --by: -999px; }
.svc-card::before, .svc-card::after { content: ""; position: absolute; inset: -1px; border-radius: inherit; pointer-events: none; }
.svc-card::before { padding: 1px; z-index: 2;
  background: radial-gradient(340px circle at var(--bx) var(--by), rgba(255,255,255,.75), rgba(255,255,255,.12) 40%, transparent 70%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.svc-card::after { z-index: 0; background: radial-gradient(420px circle at var(--bx) var(--by), rgba(255,255,255,.06), transparent 60%); }
.svc-stage, .svc-body { position: relative; z-index: 1; }

/* Desktop 3 colonnes : quinconce (colonne du milieu décalée) + parallaxe par colonne
   (--py posé par main.js tant que la grille est proche de l'écran). */
@media (min-width: 1081px) {
  .svc-grid { align-items: start; padding-bottom: 90px; }
  .svc-item { transform: translateY(var(--py, 0px)); }
  .svc-item:nth-child(3n+2) { margin-top: 90px; }
}

/* Mobile : pile en éventail au scroll. Chaque .svc-item reste collé sous le header ;
   main.js y pose --depth (0 -> 1 quand la carte suivante le recouvre) et la carte
   recouverte bascule de ±3,5° en alternance, recule un peu et s'assombrit. */
@media (max-width: 640px) {
  .svc-grid { display: block; padding-bottom: 12px; }
  .svc-item { position: sticky; top: calc(var(--header-h) + 14px + var(--i) * 6px); margin-bottom: 18px;
    --s: -1; --k: min(var(--depth, 0), 1);
    transform: translateX(calc(var(--k) * var(--s) * 10px)) rotate(calc(var(--k) * var(--s) * 3.5deg)) scale(calc(1 - var(--k) * .03));
    transform-origin: 50% 60%; will-change: transform; }
  /* Assombrissement par un voile noir en opacité (composité) et non par filter: brightness(),
     qui repeignait toute la carte et son illustration animée à chaque image du scroll. */
  .svc-item::after { content: ""; position: absolute; inset: 0; z-index: 3; border-radius: var(--radius-l);
    background: #000; pointer-events: none; opacity: calc(min(var(--depth, 0), 2) * .2); will-change: opacity; }
  /* Carte entièrement recouverte : son illustration ne se voit plus, on la met en pause. */
  .svc-grid.is-live .svc-item.is-buried .ill * { animation-play-state: paused; }
  .svc-item:nth-child(even) { --s: 1; }
  .svc-item:last-child { margin-bottom: 0; }
  .svc-item .svc-card { box-shadow: 0 -20px 40px -10px rgba(0,0,0,.7); }
}
@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  .svc-item { position: static; transform: none; }
  .svc-item, .svc-item::after { will-change: auto; }
  .svc-item::after { display: none; }
}

/* ---------- Cartes projets (page Projets) ----------
   Panneau complet : visuel 3D (project_wall) encadré, puis titre, accroche, secteur et domaine.
   Cartes affichées en permanence (pas de data-reveal). */
.ptile-3d { display: flex; flex-direction: column; gap: 0; padding: 10px; transition: border-color .5s var(--ease); }
.ptile-3d:hover { border-color: var(--line-2); }
.ptile-3d .hcard-media { aspect-ratio: 1.3; border-radius: 20px; }
.ptile-body { display: grid; gap: 14px; padding: 24px 16px 18px; }
.ptile-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.ptile-top h2 { font-size: clamp(1.3rem, 2.1vw, 1.75rem); letter-spacing: -0.035em; }
.ptile-go { flex-shrink: 0; width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line-2); color: var(--muted); transition: all .5s var(--ease); }
.ptile-go svg { width: 16px; height: 16px; transition: transform .5s var(--ease); }
.ptile-3d:hover .ptile-go { background: var(--text); color: #000; border-color: var(--text); }
.ptile-3d:hover .ptile-go svg { transform: rotate(-45deg); }
.ptile-body > p { color: var(--muted); font-size: 15px; line-height: 1.55; max-width: 46ch; }
.ptile-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 4px; padding-top: 18px; border-top: 1px solid var(--line); }
.ptile-dom { margin-left: auto; font-size: 13px; color: var(--dim); }
@media (max-width: 640px) {
  .ptile-3d { padding: 8px; }
  .ptile-body { padding: 20px 12px 14px; gap: 12px; }
  .ptile-go { width: 38px; height: 38px; }
  .ptile-dom { display: none; }   /* pas de domaine sur mobile */
}

/* ---------- Réalisations : visuel 3D (colonnes de la page d'accueil) ---------- */
.hcard-3d .hcard-media { background: #0a0a0a; }
.hcard-3d .hcard-media::after { display: none; }
.hcard-3d .hcard-tag { z-index: 3; }
.rv-3d { position: absolute; inset: 0; overflow: hidden; perspective: 1400px; background: radial-gradient(80% 70% at 50% 25%, rgba(255,255,255,.08), transparent 60%), #0a0a0a; transition: transform .8s var(--ease); }
.rv-3d::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; background: linear-gradient(180deg, rgba(10,10,10,.55), transparent 22%, transparent 72%, rgba(10,10,10,.92)); }
.hcard-3d .rv-3d img, .np-media .rv-3d img { position: static; inset: auto; width: 100%; height: auto; transform: none; object-fit: initial; }
.rv-wall { position: absolute; left: 50%; top: -30%; width: 125%; display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; transform: translateX(-50%) rotateX(28deg) rotateZ(-14deg); transform-origin: 50% 0; }
/* Les colonnes ne sont animees (et promues en couche GPU) que pendant qu'elles sont a
   l'écran : `is-live` est posé par main.js. Avec `will-change` permanent sur les 15+
   colonnes de la galerie, le compositeur mobile dépassait son budget mémoire, laissait
   tomber les couches et les cartes apparaissaient vides, animation figée. */
.rv-wcol { display: flex; flex-direction: column; animation: rv-col-up 36s linear infinite; animation-delay: var(--start); animation-play-state: paused; }
.rv-wcol:nth-child(2) { animation-name: rv-col-down; }
.rv-3d.is-live .rv-wcol { animation-play-state: running; will-change: transform; }
.hcard-3d .rv-wcol img, .np-media .rv-wcol img { margin-bottom: 12px; border-radius: 8px; box-shadow: 0 20px 40px rgba(0,0,0,.55); }
@keyframes rv-col-up { from { transform: translateY(0); } to { transform: translateY(-50%); } }
@keyframes rv-col-down { from { transform: translateY(-50%); } to { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .rv-wcol { animation: none; } }
/* Survol : l'animation continue, la carte grossit légèrement */
.hcard-3d:hover .rv-3d, .hcard-3d:focus-visible .rv-3d,
.next-project:hover .rv-3d, .next-project:focus-visible .rv-3d { transform: scale(1.06); }
/* neutralise le zoom d'image de la carte : ici c'est le mur qui bouge */
.next-project:hover .np-media .rv-3d img { transform: none; }

/* ---------- Page projet : écran desktop + mobile ---------- */
.case-shots {
  display: grid; grid-template-columns: minmax(0, 1fr) clamp(190px, 20%, 270px);
  gap: clamp(16px, 2vw, 26px); margin-top: clamp(28px, 4vw, 48px);
}
.case-shots.one { grid-template-columns: 1fr; }
.case-shots figure { position: relative; margin: 0; border: 1px solid var(--line); border-radius: var(--radius-l); overflow: hidden; background: var(--card); }
.case-shots .cs-d { aspect-ratio: 16 / 10; }
.case-shots .cs-d img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
/* Le téléphone se cale sur la hauteur de sa capture, il ne s'étire pas sur celle de
   l'écran desktop : une capture courte laissait sinon une grande zone noire vide.
   `max-height` borne les captures très longues pour garder une silhouette de téléphone. */
.case-shots .cs-m { align-self: start; border-radius: 28px; padding: 7px; background: #0b0b0b; box-shadow: 0 26px 60px rgba(0,0,0,.5); }
.cs-screen { position: relative; overflow: hidden; border-radius: 21px; background: #000; max-height: clamp(420px, 44vw, 580px); }
/* La capture garde toute sa largeur : en `cover`, dès que le cadre est plus étroit que
   l'image, les côtés étaient rognés et le texte du site coupé. Seul le bas dépasse,
   masqué par le cadre — c'est le comportement voulu d'un téléphone qui montre le
   haut d'une page. */
.cs-screen img { width: 100%; height: auto; display: block; }
.case-shots-note { margin-top: 14px; font-size: 13px; color: var(--dim); }
@media (max-width: 860px) {
  .case-shots { grid-template-columns: 1fr; justify-items: center; }
  .case-shots .cs-d { width: 100%; }
  .case-shots .cs-m { width: min(260px, 68%); }
}

/* ---------- Bloc CTA final : fond de fumée ---------- */
/* Le bruit fractal est calculé par le GPU (shader WebGL) : le thread principal reste
   libre, donc le scroll ne saccade jamais. Repli CSS si WebGL est indisponible. */
.footer-cta { isolation: isolate; }
.footer-cta .inner { position: relative; z-index: 2; }
.footer-cta h2 { text-shadow: 0 4px 40px rgba(0,0,0,.55); }
.cta-smoke { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; contain: paint; }
.cta-smoke::after { content: ""; position: absolute; inset: 0; background: radial-gradient(74% 64% at 50% 54%, transparent 18%, rgba(5,5,5,.58) 58%, var(--bg) 88%); }
.cta-smoke-gl { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 1.2s var(--ease); }
.cta-smoke.gl-on .cta-smoke-gl { opacity: .42; }
/* Repli : nuages flous animés, sans filtre coûteux */
.cta-smoke .sm {
  position: absolute; inset: -12%; opacity: .38; will-change: transform;
  background:
    radial-gradient(38% 42% at 28% 40%, rgba(255,255,255,.75), transparent 68%),
    radial-gradient(34% 40% at 72% 58%, rgba(255,255,255,.55), transparent 70%),
    radial-gradient(52% 34% at 50% 88%, rgba(255,255,255,.4), transparent 72%);
  filter: blur(40px);
  animation: cta-drift 26s ease-in-out infinite alternate;
}
.cta-smoke.gl-on .sm { display: none; }
@keyframes cta-drift { to { transform: translate3d(-6%, -5%, 0) scale(1.15); } }
@media (prefers-reduced-motion: reduce) { .cta-smoke .sm { animation: none; } }


/* ---------- Fond du site ----------
   L'ancien fond des heros, rendu fixe et unique pour toutes les pages : une seule
   trame, donc plus de décalage entre une grille fixe et une grille qui défile.
   Orbes et vitesses reprises telles quelles du hero. */
.site-bg { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.site-bg::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background-image: linear-gradient(var(--grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(ellipse 82% 72% at 50% 42%, #000 28%, transparent 85%);
  -webkit-mask-image: radial-gradient(ellipse 82% 72% at 50% 42%, #000 28%, transparent 85%);
  opacity: .75;
}

@media (max-width: 640px) {
  .site-bg .orb-1 { width: 520px; height: 520px; left: -220px; top: -160px; }
  .site-bg .orb-2 { width: 460px; height: 460px; left: 60px; top: 40px; }
  .site-bg .orb-3 { width: 380px; height: 380px; left: -60px; top: 320px; }
}
@media (prefers-reduced-motion: reduce) { .site-bg .orb { animation: none; } }

/* ---------- Questionnaire projet (page privée) ---------- */
.brief-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: clamp(32px, 5vw, 72px); align-items: start; }
.brief-toc a { display: flex; align-items: center; gap: 10px; }
.brief-toc a span { font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums; }
.brief-toc a::after { content: ""; width: 6px; height: 6px; margin-left: auto; border-radius: 50%; background: var(--text); opacity: 0; transform: scale(.4); transition: opacity .3s, transform .3s; }
.brief-toc a.is-done::after { opacity: .9; transform: none; }
.brief-save { margin-top: 14px; font-size: 12px; color: var(--dim); }
.brief-form.form { padding: 0; }
.brief-form .form-body { gap: 18px; }
.brief-step, .brief-send { padding: clamp(22px, 3.5vw, 40px); scroll-margin-top: calc(var(--header-h, 80px) + 20px); }
.brief-step h2 { display: flex; align-items: baseline; gap: 14px; margin-bottom: clamp(20px, 3vw, 30px); }
.brief-n { font-family: var(--f-body, inherit); font-size: 14px; color: var(--dim); font-variant-numeric: tabular-nums; }
.brief-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 16px; }
.brief-grid > .field { grid-column: 1 / -1; }
.brief-grid > .field.half { grid-column: auto; }
.brief-form .field textarea { min-height: 112px; }
.brief-form .hint { font-size: 13px; color: var(--dim); margin-top: -4px; }
.brief-form .req { font-weight: 400; color: var(--text); }
.brief-form .q-autre { margin-top: 8px; }
.brief-send { display: grid; gap: 20px; position: relative; }
.brief-form .form-done { padding-inline: clamp(22px, 4vw, 48px); }
@media (max-width: 1080px) {
  .brief-layout { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .brief-grid { grid-template-columns: 1fr; }
  .brief-step h2 { gap: 10px; }
}

/* ---------- Fluidité du scroll sur écrans tactiles ----------
   Sur mobile/tablette, deux effets coûtent cher à chaque image du défilement :
   le flou d'arrière-plan du header fixe (recalculé sur tout ce qui passe dessous,
   orbes animés compris) et le grain plein écran posé par-dessus toute la page.
   On garde le même rendu à l'œil avec un fond plus opaque, sans flou. */
@media (hover: none), (max-width: 860px) {
  body::after { display: none; }
  .site-header .nav, .site-header.is-scrolled .nav {
    background: rgba(12, 12, 12, .94);
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .menu-open .site-header .nav { background: transparent; }
}
