/* ============================================================
   Bonabona — Design system
   Charte issue du hero direction B (Bord) étendue à tout le site.
   ============================================================ */

:root{
  /* Couleurs OKLCH — palette froide minimale */
  --paper: oklch(98% 0 0);
  --paper-2: oklch(96.5% 0.002 240);
  --paper-3: oklch(94% 0.003 240);
  --ink: oklch(15% 0.012 240);
  --ink-soft: oklch(28% 0.008 240);
  --ink-mute: oklch(45% 0.006 240);
  --line: oklch(85% 0.004 240);
  --hairline: oklch(90% 0.005 240);

  /* Accent de lecture : le mot mis en <em> dans un titre. Deux régimes selon
     le fond, arbitrés le 29/07/2026 :

     - fond clair  → le rouge de charte, FIXE. Un titre qui se lit sur du papier
                     ne clignote pas.
     - fond sombre → le FLUO du cœur du nav, MOBILE. layout.js pose --peps-dark
                     en même temps que --peps, sur le même index : le mot change
                     donc de teinte à l'instant exact où le cœur change, effet
                     néon. Le rouge est exclu de cette déclinaison (3,4:1 sur
                     l'encre, il vibre). Fallback rose fluo quand le JS ne tourne
                     pas (reduced-motion, no-js). */
  --accent: #E8382F;
  --accent-dark: var(--peps-dark, #FF3D8A);

  /* Typo */
  --serif: "Bricolage Grotesque", Garamond, serif;
  --sans: "Inter Tight", -apple-system, system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, Menlo, monospace;

  /* Espacements */
  --safe: clamp(20px, 4.2vw, 56px);
  --maxw: 1280px;
  --maxw-prose: 720px;
  --maxw-read: 760px;

  /* Animation */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-soft: cubic-bezier(.16, 1, .3, 1);
}

/* Reset */
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
html, body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-weight:300;
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
body{visibility:hidden;min-height:100vh}
body.ready{visibility:visible}
body.no-js{visibility:visible}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
img, video{max-width:100%;display:block;height:auto}
ul, ol{list-style:none}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
::selection{background:var(--ink);color:var(--paper)}

/* Skip link */
.skip{
  position:absolute;left:-9999px;top:8px;
  background:var(--ink);color:var(--paper);
  padding:8px 12px;font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  z-index:1000;
}
.skip:focus{left:8px}

/* Container & layout */
.wrap{padding:0 var(--safe)}
.container{max-width:var(--maxw);margin:0 auto;padding:0 var(--safe)}
.prose{max-width:var(--maxw-prose);margin:0 auto;padding:0 var(--safe)}
.read{max-width:var(--maxw-read);margin:0 auto;padding:0 var(--safe)}

/* ============================================================
   HERO — partagé avec direction B (homepage uniquement)
   ============================================================ */

.stage{
  position:relative;width:100%;height:100svh;min-height:560px;
  overflow:hidden;background:var(--paper);isolation:isolate;
}
.stage--medium{height:72svh;min-height:480px}
.stage--small{height:54svh;min-height:380px}
.stage--inline{
  height:62svh;min-height:420px;
  border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline);
}
/* ============================================================
   VARIANTE SABLE — déclinaison home avec sable comme effet principal
   ============================================================ */

/* Hero variante sable : plein écran, sable foncé sur fond paper */
.stage--sand-hero{
  width:100%;height:100vh;min-height:600px;
  background:var(--paper);
}
.stage--sand-hero .sand{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  z-index:1;pointer-events:auto;cursor:crosshair;touch-action:pan-y;
}
/* Sur la stage sable hero, le pointer-events est neutralisé sur le contenu UI
   (sauf les CTAs) pour que le sable suive la souris partout. */
.stage--sand-hero .ui > *{pointer-events:none}
.stage--sand-hero .ui .cta{pointer-events:auto}

/* Mini-stage / divider sable inversée : fond ink, sable clair (paper) */
.stage--sand-inverted{
  background:var(--ink);color:var(--paper);
}
.stage--sand-inverted .sand{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  z-index:1;pointer-events:auto;cursor:crosshair;touch-action:pan-y;
}
.stage--sand-inverted .ui > *{pointer-events:none}
.stage--sand-inverted .ui .cta{pointer-events:auto}
/* Grain et vignette adaptés au fond ink */
.stage--sand-inverted .grain{
  mix-blend-mode:screen;opacity:.16;
  background-image:radial-gradient(rgba(250,250,250,.6) 1px,transparent 1px);
}
.stage--sand-inverted .vignette{
  background:radial-gradient(120% 100% at 50% 50%,transparent 55%,rgba(0,0,0,.35) 100%);
}

/* Stage CTA finale : grand bandeau sable inversé en bas de la home variante */
.stage--cta{
  height:78vh;min-height:520px;
  border-top:1px solid var(--ink);
}
.cta-final{
  display:flex;flex-direction:column;gap:clamp(20px,3vh,32px);
  align-items:center;text-align:center;max-width:920px;
}
.cta-final__title{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(40px,7vw,108px);line-height:1.02;letter-spacing:-.022em;
  margin:0;
}
.cta-final__sub{
  font-family:var(--sans);font-weight:300;
  font-size:clamp(15px,1.2vw,18px);line-height:1.55;
  max-width:50ch;opacity:.85;margin:0;
}
.cta-final__buttons{
  display:flex;gap:14px;flex-wrap:wrap;justify-content:center;
  margin-top:8px;pointer-events:auto;
}
.cta--ghost{background:transparent;color:#fff;border-color:#fff;opacity:.78}
.cta--ghost:hover{opacity:1;background:transparent;color:#fff;border-color:#fff}

/* THEME SABLE GLOBAL — effet pixel sur les cards et composants secondaires */
.theme-sand .card{
  border-color:var(--ink);
  background-image:
    /* coins de pixels au repos */
    linear-gradient(to right, var(--ink) 0%, var(--ink) 8px, transparent 8px),
    linear-gradient(to right, transparent calc(100% - 8px), var(--ink) calc(100% - 8px)),
    linear-gradient(to bottom, var(--ink) 0%, var(--ink) 8px, transparent 8px),
    linear-gradient(to bottom, transparent calc(100% - 8px), var(--ink) calc(100% - 8px));
  background-size:8px 1px, 8px 1px, 1px 8px, 1px 8px;
  background-position:top left, top right, top left, bottom left;
  background-repeat:no-repeat;
}
.theme-sand .card::after{
  content:"";position:absolute;inset:auto 0 0 0;height:0;
  background-image:radial-gradient(rgba(10,10,14,.55) 1px,transparent 1px);
  background-size:5px 5px;
  transition:height .5s var(--ease);
  pointer-events:none;
}
.theme-sand .card{position:relative;overflow:hidden}
.theme-sand .card:hover::after{height:42%}
.theme-sand .card:hover .card__title{transform:translateX(4px)}
.theme-sand .card__title{transition:transform .35s var(--ease)}

/* THEME SABLE : sections--minimal et items prennent un look pixel discret */
.theme-sand .item{border-top-style:dashed;border-top-width:1px}
.theme-sand .kpi{border-right-style:dashed}

/* ============================================================
   THEME PIXEL — grille 12 colonnes avec bordures verticales NATURELLES.
   Les cards sont posées en grid 12-col sans gap, chacune span 4 (3 cards) ou
   span 3 (4 cards). Les bordures des cards forment des lignes verticales
   parfaitement alignées sur les multiples de 1/12 du container.
   Pas de pattern background avec calc bricolé.
   ============================================================ */
.theme-pixel-bg main{background-color:var(--paper)}

/* Cards en vraie grille 12-col, bordures qui se collapsent entre cards */
.theme-pixel-bg .cards{
  display:grid;
  grid-template-columns:repeat(12, 1fr);
  gap:0;
  border-top:1px solid var(--hairline);
  border-bottom:1px solid var(--hairline);
}
.theme-pixel-bg .cards .card{
  grid-column:span 4;
  border:none;
  border-left:1px solid var(--hairline);
  background-image:none;
  transform:none !important;
  box-shadow:none;
}
.theme-pixel-bg .cards .card:hover{
  background-color:var(--paper-2);
  transform:none !important;
}
.theme-pixel-bg .cards .card:last-child{border-right:1px solid var(--hairline)}

/* 4 cards (section métier) → span 3 chacune */
.theme-pixel-bg #metier .cards .card{grid-column:span 3}

@media (max-width:1024px){
  .theme-pixel-bg .cards .card,
  .theme-pixel-bg #metier .cards .card{grid-column:span 6}
}
@media (max-width:600px){
  .theme-pixel-bg .cards .card,
  .theme-pixel-bg #metier .cards .card{grid-column:span 12}
}

/* Posts blog : également en grid 12-col, full-width avec bordures hairline */
.theme-pixel-bg .posts{
  display:grid;
  grid-template-columns:repeat(12, 1fr);
  gap:0;
  border-top:1px solid var(--hairline);
}
.theme-pixel-bg .posts .post{
  grid-column:span 12;
  display:grid;
  grid-template-columns:repeat(12, 1fr);
  border-bottom:1px solid var(--hairline);
}
.theme-pixel-bg .posts .post .post__date{grid-column:span 2}
.theme-pixel-bg .posts .post .post__title{grid-column:span 8}
.theme-pixel-bg .posts .post .post__cat{grid-column:span 2;text-align:right}
@media (max-width:760px){
  .theme-pixel-bg .posts .post{grid-template-columns:1fr;gap:8px}
  .theme-pixel-bg .posts .post .post__date,
  .theme-pixel-bg .posts .post .post__title,
  .theme-pixel-bg .posts .post .post__cat{grid-column:span 1;text-align:left}
}

/* Container : on pose des verticales aux mêmes 12-col positions, mais en hairline
   très subtil, sur toute la hauteur du container. Le bg-image fait tomber les
   verticales pile sur les bordures des cards puisqu'elles partagent la même grille. */
.theme-pixel-bg .container{
  position:relative;
}
.theme-pixel-bg .container::before{
  content:"";
  position:absolute;inset:0;pointer-events:none;z-index:0;
  background-image:linear-gradient(to right, rgba(20,22,26,.045) 1px, transparent 1px);
  /* La cellule = (largeur intérieure du container) / 12.
     Les verticales tombent à 0/12, 1/12, ..., 12/12 du container intérieur. */
  background-size:calc((100% - 2 * var(--safe)) / 12) 100%;
  background-position:var(--safe) 0;
  background-repeat:repeat;
}
.theme-pixel-bg .container > *{position:relative;z-index:1}

.theme-pixel-bg .section{background:transparent}
.theme-pixel-bg .section--minimal{background:transparent}
.theme-pixel-bg .section--dark{background:var(--ink)}
.theme-pixel-bg .section--dark .container::before{display:none}

/* ============================================================
   HERO A-PROPOS — grid 2 colonnes : texte à gauche, sable à droite
   avec obstacle triangulaire au centre du visuel.
   ============================================================ */
/* Hero À propos : split titre + portrait réduit (refonte juin 2026). */
/* Hero éditorial : titre géant en mix-blend par-dessus la vue de Marseille.
   .apropos-hero est isolé (isolation:isolate) + fond paper → le titre (z-index 2,
   mix-blend:difference, blanc) s'inverse pixel par pixel sur l'image (z-index 0) ET
   sur le fond clair là où il déborde. Le titre passe sur l'image via un margin-right
   négatif ; le panneau (sous-titre / CTA / méta) reste en bas à gauche, sans blend. */
.apropos-hero{
  position:relative;isolation:isolate;background:var(--paper);overflow:hidden;
  max-width:var(--maxw);margin:0 auto;
  padding:calc(var(--safe) * 2.2) var(--safe) clamp(48px,7vh,96px);
  border-bottom:1px solid var(--hairline);
  display:grid;
  grid-template-columns:1fr minmax(0,44%);
  grid-template-areas:"title media" "panel media";
  column-gap:clamp(24px,4vw,56px);align-items:start;
}
.apropos-hero__media{
  grid-area:media;margin:0;position:relative;z-index:0;align-self:stretch;
  min-height:clamp(380px,54vh,580px);
  overflow:hidden;border:1px solid var(--hairline);border-radius:3px;
  background:var(--paper-2);
}
.apropos-hero__media img{width:100%;height:100%;object-fit:cover;display:block}
.apropos-hero__grain{
  position:absolute;inset:0;pointer-events:none;z-index:1;
  mix-blend-mode:multiply;opacity:.36;
  background-image:radial-gradient(rgba(20,22,26,.5) 1px,transparent 1px);
  background-size:3px 3px;
}
.apropos-hero__title{
  grid-area:title;z-index:2;position:relative;align-self:start;
  margin:0 clamp(-210px,-13vw,-80px) 0 0;
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(40px,6.6vw,108px);line-height:.95;letter-spacing:-.026em;
  mix-blend-mode:difference;color:#fff;
}
.apropos-hero__panel{
  grid-area:panel;z-index:2;position:relative;
  display:flex;flex-direction:column;align-items:flex-start;gap:22px;
  margin-top:clamp(28px,5vh,56px);
}
/* Révélation séquencée au chargement (image → titre → panneau). */
.apropos-hero__media.reveal-up{transition-delay:.04s}
.apropos-hero__title.reveal-up{transition-delay:.16s}
.apropos-hero__panel.reveal-up{transition-delay:.3s}
.apropos-hero__sub{
  font-family:"Inter Tight",sans-serif;font-weight:300;
  font-size:clamp(15px,1.2vw,19px);line-height:1.6;
  color:var(--ink-soft);max-width:42ch;margin:0;
}
.apropos-hero .meta{
  display:flex;gap:20px;flex-wrap:wrap;margin-top:6px;
  font-family:var(--mono);font-size:11px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--ink-mute);
}
.apropos-hero .meta span{display:inline-flex;align-items:center;gap:8px}
.apropos-hero .meta i{font-style:normal;width:5px;height:5px;background:currentColor;border-radius:999px;display:inline-block}

/* Animation auto en boucle : l'image glisse vers la droite pour libérer entièrement
   le titre qu'elle chevauche (qui repasse alors en noir net sur le fond clair), tient
   un instant, puis revient à sa position initiale. overflow:hidden sur .apropos-hero
   coupe proprement le débord à droite. Desktop uniquement (en mobile le titre est
   empilé sous l'image, pas de chevauchement). */
@keyframes apropos-hero-reveal{
  0%, 16%   { transform:translateX(0); }
  47%, 61%  { transform:translateX(54%); }
  92%, 100% { transform:translateX(0); }
}
@media (min-width:881px){
  .apropos-hero__media{animation:apropos-hero-reveal 11s var(--ease-soft) infinite;will-change:transform}
}
@media (prefers-reduced-motion:reduce){
  .apropos-hero__media{animation:none}
}

/* ============================================================
   Page À propos — section "Le terrain avant la technologie" (refonte juin 2026).
   Contenu (titre + ADN + 3 engagements numérotés) à gauche, image portrait de
   l'atelier à droite. Chaque engagement : trait qui se trace + révélation en
   cascade (stagger). L'image révèle avec un léger dézoom.
   ============================================================ */
.terrain{padding:clamp(64px,10vh,128px) 0}
.terrain__inner{
  max-width:var(--maxw);margin:0 auto;padding:0 var(--safe);
  display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(40px,6vw,104px);
  align-items:center;
}
.terrain__title{margin:0 0 22px}
.terrain__lede{margin:0 0 clamp(30px,5vh,52px);max-width:44ch}
.terrain__list{list-style:none;margin:0;padding:0}
.terrain__item{
  position:relative;display:grid;grid-template-columns:auto 1fr;
  gap:6px 22px;align-items:baseline;padding:22px 0 24px;
}
.terrain__item.reveal-up{transition-delay:calc(var(--stagger,0) * 110ms)}
/* Trait qui se trace au scroll (cascade via --stagger, un cran après l'apparition). */
.terrain__item::before{
  content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:var(--ink);transform:scaleX(0);transform-origin:left;
  transition:transform .9s var(--ease-soft);
  transition-delay:calc(var(--stagger,0) * 110ms + .12s);
}
.terrain__item.in::before{transform:scaleX(1)}
.terrain__num{
  font-family:var(--mono);font-size:12px;letter-spacing:.16em;
  color:var(--ink-mute);padding-top:3px;
}
.terrain__text{margin:0;font-size:clamp(15px,1.15vw,17px);line-height:1.55;color:var(--ink-soft)}
.terrain__media{
  margin:0;position:relative;overflow:hidden;
  border:1px solid var(--hairline);border-radius:4px;
  aspect-ratio:4/5;background:var(--paper-2);
}
.terrain__media img{
  width:100%;height:100%;object-fit:cover;display:block;
  transform:scale(1.08);transition:transform 1.3s var(--ease-soft);
}
.terrain__media.in img{transform:scale(1)}
@media (max-width:880px){
  .terrain__inner{grid-template-columns:1fr;gap:clamp(26px,5vh,40px)}
  .terrain__media{aspect-ratio:3/2}
}

/* Section « Pourquoi » (application sur mesure) : texte + image. */
.why-grid{display:grid;grid-template-columns:1.2fr .8fr;gap:clamp(32px,5vw,72px);align-items:center}
.why-grid__media{margin:0}
.why-grid__media img{width:100%;aspect-ratio:4/5;object-fit:cover;border:1px solid var(--hairline);border-radius:3px;display:block}
@media (max-width:880px){
  .why-grid{grid-template-columns:1fr;gap:30px}
  .why-grid__media img{aspect-ratio:16/10;max-height:60vh}
}

@media (max-width:880px){
  .apropos-hero{
    grid-template-columns:1fr;grid-template-areas:"media" "title" "panel";
    row-gap:clamp(20px,4vh,30px);padding-top:calc(var(--safe) + 64px);
  }
  .apropos-hero__media{min-height:0;aspect-ratio:3/4;max-height:56vh}
  .apropos-hero__title{margin:0;font-size:clamp(38px,11vw,64px)}
}

/* Stage a-propos (legacy) : sable cellular-automaton qui s'écoule */
.stage--apropos{
  width:100%;
  height:100vh;min-height:600px;
  background:var(--paper);
}
.stage--apropos .sand{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  z-index:1;pointer-events:auto;cursor:crosshair;
  touch-action:pan-y;
}
/* Sur la stage sable : le grain et la vignette restent en mode clair (mêmes valeurs que
   le hero principal) — la zone "papier" est claire, la zone sable est noire mais c'est
   le canvas qui peint, pas le grain. */
/* Sur la stage a-propos, on désactive pointer-events sur le contenu UI
   pour que la souris atteigne directement le canvas sable (sauf le CTA). */
.stage--apropos .ui > *{pointer-events:none}
.stage--apropos .ui .cta{pointer-events:auto}
.stage--apropos .hero h1{
  font-size:clamp(40px,7.2vw,108px);
  letter-spacing:-.02em;line-height:.98;
  max-width:24ch;
}
.stage--apropos .hero .sub{align-items:end}
@media (max-width:760px){
  .stage--apropos .hero h1{font-size:clamp(36px,9vw,72px);max-width:none}
}

/* Mini-stage divider inversée : fond noir, fluide WebGL clair en surface, label central */
.stage--divider{
  height:clamp(180px,28vh,300px);min-height:180px;
  background:var(--ink);
  border-top:1px solid var(--ink);border-bottom:1px solid var(--ink);
}
.stage--divider .ui{padding:clamp(20px,4vh,40px) var(--safe)}
.divider__label{
  font-family:var(--mono);font-size:11px;letter-spacing:.3em;text-transform:uppercase;
  text-align:center;line-height:1.6;
}
.divider__label em{
  display:block;margin-top:6px;
  font-family:var(--serif);font-style:italic;font-size:clamp(18px,2vw,26px);
  letter-spacing:-.005em;text-transform:none;
}

/* Sur les stages inversées (data-fluid-invert), le grain et la vignette s'adaptent : */
.stage[data-fluid-invert] .grain,
.stage--divider .grain{
  mix-blend-mode:screen;opacity:.16;
  background-image:radial-gradient(rgba(250,250,250,.6) 1px,transparent 1px);
}
.stage[data-fluid-invert] .vignette,
.stage--divider .vignette{
  background:radial-gradient(120% 100% at 50% 50%,transparent 55%,rgba(0,0,0,.35) 100%);
}
.stage--inline .ui{padding:clamp(40px,8vh,80px) var(--safe)}
.ui--centered{display:flex !important;align-items:center;justify-content:center;text-align:center}

/* ============================================================
   APROPOS SPLIT — 2 colonnes pleine largeur, image flush à gauche,
   texte à droite sur fond paper grainé (rappel du hero sans animation).
   ============================================================ */
.apropos-split{
  display:grid;
  grid-template-columns:minmax(0, 1fr) minmax(0, 1.2fr);
  width:100%;
  border-top:1px solid var(--hairline);
  border-bottom:1px solid var(--hairline);
  background:var(--paper);
}
.apropos-split__image{
  position:relative;background:var(--paper-2);overflow:hidden;
  min-height:520px;
}
.apropos-split__image img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  /* Photo d'équipe néo-rétro : les personnages occupent le tiers bas du cadre,
     le reste est du ciel. Sans ce calage, le cover centre et leur coupe la tête. */
  object-position:center 78%;
}
.apropos-split__text{
  position:relative;background:var(--paper);
  display:flex;align-items:center;
  padding:clamp(60px,9vh,120px) var(--safe);
  isolation:isolate;
}
.apropos-split__grain{
  position:absolute;inset:0;pointer-events:none;z-index:0;
  mix-blend-mode:multiply;opacity:.32;
  background-image:radial-gradient(rgba(20,22,26,.55) 1px,transparent 1px);
  background-size:3px 3px;
  -webkit-mask-image:radial-gradient(ellipse at center,#000 60%,transparent 100%);
          mask-image:radial-gradient(ellipse at center,#000 60%,transparent 100%);
}
.apropos-split__inner{
  position:relative;z-index:1;max-width:540px;
}
.apropos-split__inner .section__title{margin:0 0 24px;max-width:none}
.apropos-split__inner .section__lede{margin:0;max-width:48ch}

@media (max-width:880px){
  .apropos-split{grid-template-columns:1fr}
  .apropos-split__image{min-height:auto;aspect-ratio:4/3}
}

/* ============================================================
   OBJECTIF — blueprint 3 colonnes sur fond noir quadrillé
   Pas de canvas, pure géométrie : barres horizontales qui se tracent,
   chiffres romains, lignes verticales entre colonnes, motif SVG signature.
   ============================================================ */
.objectif-grid{
  position:relative;
  background:var(--ink);color:var(--paper);
  padding:clamp(80px,12vh,160px) 0;
  overflow:hidden;
}
/* Fine ligne horizontale en haut pour cadrer le bandeau */
.objectif-grid::after{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;background:rgba(250,250,250,.18);
}

/* Container max-width centré + quadrillage 12-col POSÉ SUR LE CONTAINER
   (pas sur la section). Calcul identique à .theme-pixel-bg .container::before,
   donc bordures des promises + verticales du quadrillage tombent pile aux mêmes
   positions par construction. */
.objectif-grid__container{
  position:relative;z-index:1;
  max-width:var(--maxw);margin:0 auto;
  padding:0 var(--safe);
}
.objectif-grid__container::before{
  content:"";
  position:absolute;inset:0;pointer-events:none;z-index:0;
  background-image:linear-gradient(to right, rgba(250,250,250,.06) 1px, transparent 1px);
  background-size:calc((100% - 2 * var(--safe)) / 12) 100%;
  background-position:var(--safe) 0;
  background-repeat:repeat;
}
.objectif-grid__container > *{position:relative;z-index:1}

.objectif-grid__head{
  display:grid;grid-template-columns:1fr auto;gap:32px;align-items:start;
  margin-bottom:clamp(40px,6vh,72px);
}
.objectif-grid__title{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(36px,5.4vw,80px);line-height:1.02;letter-spacing:-.018em;
  margin:0;max-width:18ch;color:var(--paper);
}
.objectif-grid__title em{font-style:italic;font-weight:400;color:var(--accent-dark)}
/* Le motif de tête de section : l'étoile pixel (pixicon spark, dimensions
   posées inline par layout.js), qui respire en boucle au lieu de tourner.
   L'ancien SVG « 3 axes croisés » rotatif a été remplacé en juillet 2026. */
.objectif-grid__mark{flex-shrink:0;margin-top:8px}

/* Grid 12-col explicite : chaque promise span 4 → bordures alignées par
   construction sur les multiples de 4/12 du container (= mêmes positions
   que le quadrillage de fond). */
.objectif-grid__cols{
  display:grid;grid-template-columns:repeat(12, 1fr);gap:0;
  border-top:1px solid rgba(250,250,250,.18);
  border-bottom:1px solid rgba(250,250,250,.18);
}

.promise{
  grid-column:span 4;
  padding:clamp(40px,6vh,72px) clamp(24px,3vw,44px);
  border-left:1px solid rgba(250,250,250,.18);
  display:flex;flex-direction:column;gap:clamp(24px,3.5vh,40px);
  position:relative;
}
.promise:last-child{border-right:1px solid rgba(250,250,250,.18)}
.promise__word{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(26px,2.8vw,44px);line-height:1.05;letter-spacing:-.012em;
  margin:0;color:var(--paper);
}
.promise__bar{
  height:1px;background:rgba(250,250,250,.18);position:relative;overflow:hidden;
}
.promise__bar > span{
  position:absolute;left:0;top:0;bottom:0;width:0;background:#fff;
  transition:width 1.4s cubic-bezier(.2,.7,.2,1);
  /* Le délai s'enchaîne via --stagger posé par layout.js */
  transition-delay:calc(var(--stagger, 0) * 220ms + 200ms);
}
.promise.in .promise__bar > span{width:100%}
.promise__hint{
  font-size:14px;line-height:1.55;color:rgba(250,250,250,.7);margin:0;
  max-width:34ch;
}

@media (max-width:880px){
  .objectif-grid__head{grid-template-columns:1fr}
  .objectif-grid__mark{display:none}
  .promise{grid-column:span 12;border-bottom:1px solid rgba(250,250,250,.18)}
  .promise:last-child{border-bottom:none;border-right:none}
}

/* ============================================================
   STAGE OBJECTIF (legacy, plus utilisée mais conservée)
   ============================================================ */
   Vraie coupure visuelle entre la section "Comprenons" (claire) et la
   section "Sur mesure" (preview projets, claire aussi). Rappelle le footer
   global mais en plus court (50svh).
   ============================================================ */
.stage--objectif{
  height:62svh;min-height:480px;
  background:var(--ink);color:var(--paper);
  border-top:1px solid var(--ink);border-bottom:1px solid var(--ink);
}
.stage--objectif .sand{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  z-index:1;cursor:crosshair;touch-action:pan-y;
}
.stage--objectif .grain{
  mix-blend-mode:screen;opacity:.16;
  background-image:radial-gradient(rgba(250,250,250,.6) 1px,transparent 1px);
}
.stage--objectif .vignette{
  background:radial-gradient(120% 100% at 50% 50%,transparent 55%,rgba(0,0,0,.35) 100%);
}
.stage--objectif .ui{padding:clamp(48px,8vh,88px) var(--safe)}
.stage--objectif .ui > *{pointer-events:none}

/* Bloc Objectif : label mono, titre énorme italique, sub explicatif */
.objectif{
  display:flex;flex-direction:column;gap:clamp(18px,3vh,28px);
  align-items:center;text-align:center;max-width:980px;
}
.objectif__label{
  font-family:var(--mono);font-size:11px;letter-spacing:.32em;text-transform:uppercase;
  margin:0;opacity:.9;
}
.eyebrow-mini{
  font-family:var(--mono);font-size:11px;letter-spacing:.32em;text-transform:uppercase;
  margin:0;
}
.objectif__title{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(40px,7.5vw,116px);line-height:1.02;letter-spacing:-.022em;
  margin:0;
}
.objectif__title em{font-style:italic;font-weight:400}
.objectif__sub{
  font-family:var(--sans);font-weight:300;
  font-size:clamp(15px,1.2vw,18px);line-height:1.55;
  max-width:54ch;opacity:.85;margin:0;
}

/* COMPRENONS : bloc texte centré, sobre, qui prolonge la section Approche */
.prose-block{max-width:760px;margin:0 auto;text-align:center;display:flex;flex-direction:column;gap:clamp(18px,3vh,28px)}
.comprenons__title{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(28px,4vw,52px);line-height:1.06;letter-spacing:-.018em;
  color:var(--ink);margin:0;
}
.comprenons__title em{font-style:italic;color:var(--accent)}
.comprenons__text{
  font-size:clamp(15px,1.15vw,18px);line-height:1.6;color:var(--ink-soft);margin:0;
}

.fluid{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;pointer-events:none}
.grain{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  mix-blend-mode:multiply;opacity:.32;
  background-image:radial-gradient(rgba(20,22,26,.55) 1px,transparent 1px);
  background-size:3px 3px;
  mask-image:radial-gradient(ellipse at center,#000 60%,transparent 100%);
}
.vignette{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  background:radial-gradient(120% 100% at 50% 50%,transparent 55%,rgba(8,9,11,.06) 100%);
}

/* UI overlay — z-index ET mix-blend-mode ensemble (cf. correctif du 2026-05-14).
   Grid 1fr auto : la zone hero prend tout l'espace, le foot meta reste collé en bas.
   Padding-top élevé pour décoller le contenu du nav-fixed (~62px) et donner
   de l'air au titre. */
.ui{
  position:absolute;inset:0;z-index:10;
  display:grid;grid-template-rows:1fr auto;
  padding:clamp(110px,18vh,200px) var(--safe) var(--safe);
  pointer-events:none;
  mix-blend-mode:difference;color:#fff;
}
.ui > *{pointer-events:auto}
/* Le hero est collé en bas mais on laisse un grand espace avant la meta foot
   pour aérer (le CTA ne touche plus la ligne Marseille · Application web…) */
.ui .hero{align-self:end;margin-bottom:clamp(48px,8vh,104px)}

/* NAV — couleurs natives en blanc, mix-blend-mode sur .ui ci-dessus */
.nav{display:flex;align-items:center;justify-content:space-between;gap:24px}
.brand{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(20px,1.6vw,26px);letter-spacing:-.01em;line-height:1;
  display:flex;align-items:baseline;gap:10px;
}
.brand .dot{width:6px;height:6px;border-radius:999px;background:#fff;display:inline-block;transform:translateY(-2px)}
.links{display:flex;gap:clamp(14px,2vw,28px);font-size:13px;letter-spacing:.04em;text-transform:uppercase;font-weight:400}
.links a{position:relative;padding:6px 0}
.links a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:#fff;
  transform:scaleX(0);transform-origin:left;transition:transform .5s var(--ease);
}
.links a:hover::after, .links a:focus-visible::after, .links a.is-active::after{transform:scaleX(1)}
.links a:focus-visible{outline:none}
@media (max-width:760px){
  .links{display:none}
  .nav-mobile-toggle{display:flex}
}

/* Hero content */
.hero{align-self:center;display:grid;grid-template-columns:1fr;align-items:end;gap:clamp(24px,4vh,40px)}
.eyebrow{
  font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  display:flex;align-items:center;gap:14px;
}
.eyebrow .bar{display:inline-block;width:34px;height:1px;background:#fff}
.hero h1{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(56px,10.5vw,176px);line-height:.92;letter-spacing:-.022em;
  max-width:18ch;
}
.hero h1 .word{display:inline-block;overflow:hidden;vertical-align:bottom}
.hero h1 .word > span{display:inline-block;transform:translateY(110%);will-change:transform}
.hero .sub{
  display:flex;flex-direction:column;align-items:flex-start;gap:18px;
  padding-top:14px;border-top:1px solid #fff;margin-top:6px;
}
.hero .sub p{max-width:46ch;font-size:clamp(14px,1.05vw,16px);line-height:1.55;margin:0}

.cta{
  display:inline-flex;align-items:center;gap:14px;
  padding:14px 18px;border:1px solid #fff;
  font-size:13px;letter-spacing:.16em;text-transform:uppercase;font-weight:400;
  background:transparent;color:#fff;
  transition:background .35s ease, color .35s ease, transform .35s var(--ease);
}
.cta:hover{background:#fff;color:#000}
.cta .arrow{display:inline-block;width:20px;height:1px;background:currentColor;position:relative}
.cta .arrow::after{
  content:"";position:absolute;right:0;top:-3px;width:7px;height:7px;
  border-top:1px solid currentColor;border-right:1px solid currentColor;transform:rotate(45deg);
}

/* Foot inside hero */
.foot{display:flex;align-items:end;justify-content:space-between;gap:24px;font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase}
.foot .meta{display:flex;gap:18px;flex-wrap:wrap}
.foot .meta span{display:inline-flex;align-items:center;gap:8px}
.foot .meta i{font-style:normal;width:5px;height:5px;background:#fff;border-radius:999px;display:inline-block}
.scroll{display:inline-flex;align-items:center;gap:10px}
.scroll .line{display:inline-block;width:48px;height:1px;background:#fff;opacity:.6;position:relative;overflow:hidden}
.scroll .line::before{
  content:"";position:absolute;inset:0;background:#fff;
  transform:translateX(-100%);animation:slide 3.4s ease-in-out infinite;
}
@keyframes slide{0%{transform:translateX(-100%)}50%{transform:translateX(0)}100%{transform:translateX(100%)}}
@media (max-width:640px){
  .foot{font-size:10px}
  .foot .meta{gap:12px}
}

/* ============================================================
   BREADCRUMB — fil d'Ariane minimaliste sur pages article/projet
   ============================================================ */

.breadcrumb{
  padding:calc(var(--safe) * 1.4) 0 0;
  background:var(--paper);
}
.breadcrumb .container{padding-top:0;padding-bottom:0}
.breadcrumb ol{
  list-style:none;margin:0;padding:0;
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-mute);
}
.breadcrumb li{display:inline-flex;align-items:center}
.breadcrumb li + li::before{content:"/";margin-right:8px;color:var(--ink-mute);opacity:.5}
.breadcrumb a{
  color:var(--ink-soft);text-decoration:none;border-bottom:1px solid transparent;
  transition:border-color .25s var(--ease);
}
.breadcrumb a:hover{border-bottom-color:var(--ink-soft)}
.breadcrumb li[aria-current="page"]{color:var(--ink)}

/* ============================================================
   SECONDARY HERO — pages autres que homepage (pas de WebGL)
   ============================================================ */

.hero-static{
  position:relative;
  padding:calc(var(--safe) * 2.5) var(--safe) calc(var(--safe) * 1.6);
  background:var(--paper);
  border-bottom:1px solid var(--hairline);
  min-height:64svh;display:flex;align-items:flex-end;
}
.hero-static .container{width:100%}
.hero-static .eyebrow{color:var(--ink-soft);margin-bottom:24px}
.hero-static .eyebrow .bar{background:var(--ink-soft)}
.hero-static h1{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(44px,7.5vw,128px);line-height:.96;letter-spacing:-.022em;
  color:var(--ink);max-width:18ch;
}
.hero-static .sub{
  margin-top:clamp(28px,4vh,42px);padding-top:18px;
  border-top:1px solid var(--hairline);
  display:grid;grid-template-columns:1fr auto;gap:24px;align-items:end;
}
.hero-static .sub p{font-size:clamp(15px,1.15vw,18px);line-height:1.55;color:var(--ink-soft);max-width:54ch}

/* Page blog : hero 2 colonnes (intro + carte « à la une »). */
.blog-hero{min-height:auto;align-items:center;padding-top:calc(var(--safe) * 2.6)}
.blog-hero__grid{display:grid;grid-template-columns:1fr minmax(340px,440px);gap:clamp(32px,5vw,72px);align-items:center;width:100%}
.blog-hero__intro{display:flex;flex-direction:column}
.blog-hero h1{font-size:clamp(40px,5.2vw,76px);max-width:12ch}
.blog-hero .sub{grid-template-columns:1fr;gap:18px;margin-top:clamp(22px,3vh,34px)}
.blog-hero .sub p{max-width:46ch}

/* Carte « à la une » encadrée, dans la charte. */
.blog-lead{display:flex;flex-direction:column;border:1px solid var(--ink);border-radius:4px;overflow:hidden;background:var(--paper);text-decoration:none;color:var(--ink);transition:transform .5s var(--ease-soft),box-shadow .5s var(--ease-soft)}
.blog-lead:hover{transform:translateY(-4px);box-shadow:0 18px 40px -24px rgba(8,8,10,.5)}
.blog-lead__viz{position:relative;aspect-ratio:16/9;overflow:hidden;border-bottom:1px solid var(--ink);background:var(--paper-2)}
.blog-lead__viz img{width:100%;height:100%;object-fit:cover}
.blog-lead__tag{position:absolute;top:12px;left:12px;background:var(--ink);color:var(--paper);font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:5px 10px;border-radius:999px}
.blog-lead__body{padding:clamp(18px,2vw,24px);display:flex;flex-direction:column;gap:10px}
.blog-lead__meta{font-family:var(--mono);font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-mute)}
.blog-lead__title{font-family:var(--serif);font-weight:400;font-size:clamp(20px,1.7vw,26px);line-height:1.12;color:var(--ink);margin:0}
.blog-lead__resume{font-size:14px;line-height:1.55;color:var(--ink-soft);margin:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.blog-lead__more{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink);display:inline-flex;align-items:center;gap:8px;margin-top:2px}
@media (max-width:880px){
  .blog-hero__grid{grid-template-columns:1fr;gap:32px}
  .blog-hero h1{font-size:clamp(40px,11vw,64px)}
}

/* CTA contextualisé (clair) — pour les pages standard */
.btn{
  display:inline-flex;align-items:center;gap:14px;
  padding:14px 18px;border:1px solid var(--ink);color:var(--ink);
  font-size:13px;letter-spacing:.16em;text-transform:uppercase;font-weight:400;
  background:transparent;
  transition:background .35s ease, color .35s ease, transform .35s var(--ease);
}
.btn:hover{background:var(--ink);color:var(--paper);transform:translateY(-1px)}
.btn--primary{background:var(--ink);color:var(--paper)}
.btn--primary:hover{background:transparent;color:var(--ink)}
.btn .arrow{display:inline-block;width:20px;height:1px;background:currentColor;position:relative}
.btn .arrow::after{
  content:"";position:absolute;right:0;top:-3px;width:7px;height:7px;
  border-top:1px solid currentColor;border-right:1px solid currentColor;transform:rotate(45deg);
}

/* ============================================================
   SECTIONS
   ============================================================ */

.section{padding:clamp(80px,12vh,160px) 0;border-top:1px solid var(--hairline)}
.section:first-of-type{border-top:none}
.section--dark{
  background:var(--ink);color:var(--paper);border-top:none;
  position:relative;overflow:hidden;
}
/* Touche fluide parcimonieuse : grain papier subtil rappelant le hero */
.section--dark::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  opacity:.18;mix-blend-mode:screen;
  background-image:radial-gradient(rgba(250,250,250,.7) 1px,transparent 1px);
  background-size:3px 3px;
  mask-image:radial-gradient(ellipse at center,#000 50%,transparent 100%);
}
/* Et un halo fluide statique en gradient — rappelle l'esprit du WebGL sans le coût */
.section--dark::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(80% 60% at 20% 30%, rgba(250,250,250,.06) 0%, transparent 60%),
    radial-gradient(60% 40% at 80% 70%, rgba(250,250,250,.04) 0%, transparent 55%);
}
.section--dark > *{position:relative;z-index:1}
.section--dark .section__num, .section--dark .section__lede, .section--dark .item__text{color:rgba(250,250,250,.72)}
.section--dark .section__title{color:var(--paper)}
/* Sur fond encre, l'accent passe au jaune (cf. --accent-dark) : le rouge de
   charte n'y tient pas le contraste et vibre. Aucune section sombre n'emploie
   .section__title aujourd'hui, la règle est là pour que ça reste vrai si on en
   ajoute une. */
.section--dark .section__title em{color:var(--accent-dark)}
.section--dark .btn{border-color:var(--paper);color:var(--paper)}
.section--dark .btn:hover{background:var(--paper);color:var(--ink)}
.section--dark .btn--primary{background:var(--paper);color:var(--ink)}
.section--dark .btn--primary:hover{background:transparent;color:var(--paper)}
.section--minimal{padding:clamp(60px,9vh,120px) 0}

/* ============================================================
   FLUID DIVIDER — bande de transition entre 2 sections
   Pure CSS (pas de WebGL pour rester léger), drift animé en boucle.
   Usage : <div class="fluid-divider"><span class="label">— en mouvement —</span></div>
   ============================================================ */
.fluid-divider{
  position:relative;height:clamp(140px,22vh,240px);
  background:var(--paper);overflow:hidden;
  border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline);
  isolation:isolate;
}
.fluid-divider::before, .fluid-divider::after{
  content:"";position:absolute;inset:-40%;pointer-events:none;
  border-radius:50%;will-change:transform;
}
.fluid-divider::before{
  background:radial-gradient(circle, rgba(20,22,26,.10) 0%, transparent 50%);
  animation:fluid-drift-a 22s ease-in-out infinite;
}
.fluid-divider::after{
  background:radial-gradient(circle, rgba(20,22,26,.06) 0%, transparent 55%);
  animation:fluid-drift-b 28s ease-in-out infinite;
}
@keyframes fluid-drift-a{
  0%, 100%{transform:translate(-15%, -5%) scale(1)}
  33%{transform:translate(10%, 8%) scale(1.1)}
  66%{transform:translate(-8%, 12%) scale(.95)}
}
@keyframes fluid-drift-b{
  0%, 100%{transform:translate(12%, 5%) scale(1.05)}
  50%{transform:translate(-10%, -8%) scale(1.15)}
}
.fluid-divider .label{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:5;
  mix-blend-mode:difference;color:#fff;
  font-family:var(--mono);font-size:11px;letter-spacing:.3em;text-transform:uppercase;
  text-align:center;line-height:1.6;
}
.fluid-divider .label em{font-family:var(--serif);font-style:italic;font-size:18px;letter-spacing:-.005em;text-transform:none;display:block;margin-top:6px}
@media (prefers-reduced-motion: reduce){
  .fluid-divider::before, .fluid-divider::after{animation:none}
}

.section__head{
  display:flex;flex-direction:column;gap:clamp(16px,2vh,24px);
  margin-bottom:clamp(40px,6vh,80px);
}
/* Si la section__head contient encore un .section__num quelque part, on revient en grille 2-col */
.section__head:has(.section__num){
  display:grid;grid-template-columns:140px 1fr;gap:clamp(24px,4vw,72px);
}
.section__num{
  font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-mute);padding-top:8px;
}
.section__title{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(32px,5vw,72px);line-height:1.02;letter-spacing:-.02em;
  color:var(--ink);max-width:22ch;
}
.section__title em{font-style:italic;font-weight:400;color:var(--accent)}
.section__lede{
  font-size:clamp(15px,1.1vw,17px);line-height:1.6;color:var(--ink-soft);
  max-width:56ch;margin-top:18px;
}
@media (max-width:760px){
  .section__head{grid-template-columns:1fr;gap:14px}
  .section__num{padding-top:0}
}

/* Manifeste : titre énorme + lede */
.manifeste{padding:clamp(100px,14vh,180px) var(--safe);text-align:left}
.manifeste h2{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(40px,7vw,120px);line-height:.96;letter-spacing:-.025em;
  color:var(--ink);max-width:18ch;
}
.manifeste h2 em{font-style:italic}
.manifeste .lede{
  margin-top:clamp(28px,4vh,48px);
  font-size:clamp(15px,1.15vw,18px);line-height:1.6;color:var(--ink-soft);
  max-width:54ch;
}

/* Items grid (3 colonnes, peuvent être les 3 piliers de l'approche) */
.items{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:clamp(24px,3vw,48px)}
.item{display:flex;flex-direction:column;gap:14px;padding-top:24px;border-top:1px solid var(--ink)}
.item__num{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute)}
.item__title{font-family:var(--serif);font-weight:400;font-size:clamp(18px,1.5vw,22px);letter-spacing:-.005em;color:var(--ink)}
.item__text{font-size:clamp(14px,1vw,15px);line-height:1.6;color:var(--ink-soft)}

/* Méthode (alignée gauche, 4 étapes verticales avec gros numéros) */
.steps{display:grid;gap:0}
.step{
  display:grid;grid-template-columns:140px 1fr;gap:clamp(24px,4vw,72px);
  padding:clamp(28px,4vh,48px) 0;border-top:1px solid var(--hairline);
}
.step:last-child{border-bottom:1px solid var(--hairline)}
.step__num{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute);padding-top:8px}
.step__title{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(24px,3vw,40px);line-height:1.1;letter-spacing:-.018em;color:var(--ink);
  margin-bottom:10px;
}
.step__title em{font-style:italic}
.step__text{font-size:clamp(15px,1.1vw,16px);line-height:1.6;color:var(--ink-soft);max-width:62ch}
@media (max-width:760px){.step{grid-template-columns:1fr;gap:8px}.step__num{padding-top:0}}

/* Bande "guide" (3 mots clés alignés) */
.kpis{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:0;
  border-top:1px solid var(--ink);border-bottom:1px solid var(--ink);
}
.kpi{
  padding:clamp(28px,4vh,48px) clamp(24px,3vw,40px);
  border-right:1px solid var(--hairline);
}
.kpi:last-child{border-right:none}
@media (max-width:760px){.kpi{border-right:none;border-bottom:1px solid var(--hairline)}.kpi:last-child{border-bottom:none}}
.kpi__num{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute);margin-bottom:14px}
.kpi__title{font-family:var(--serif);font-weight:400;font-style:italic;font-size:clamp(28px,3vw,40px);line-height:1;color:var(--ink)}

/* Cartes projet / réalisation */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:clamp(20px,2.4vw,32px)}
.card{
  display:flex;flex-direction:column;gap:14px;
  border:1px solid var(--hairline);background:var(--paper);
  transition:border-color .35s ease, transform .35s var(--ease);
}
.card:hover{border-color:var(--ink);transform:translateY(-2px)}
.card__viz{
  aspect-ratio:4/3;background:var(--paper-2);position:relative;overflow:hidden;
  border-bottom:1px solid var(--hairline);
}
.card__viz img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.card__viz svg{position:absolute;inset:0;width:100%;height:100%;color:var(--ink-mute)}
.card__viz--placeholder{
  background:var(--paper-2);
  background-image:repeating-linear-gradient(45deg,transparent 0 12px,rgba(20,22,26,.04) 12px 13px);
}
.card__body{padding:18px 20px 22px;display:flex;flex-direction:column;gap:8px}
.card__cat{font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute)}
.card__title{font-family:var(--serif);font-weight:400;font-size:clamp(18px,1.4vw,22px);letter-spacing:-.005em;color:var(--ink);line-height:1.2}
.card__sub{font-size:13px;line-height:1.5;color:var(--ink-soft)}
.card__row{display:flex;justify-content:space-between;align-items:baseline;gap:14px;margin-top:auto;padding-top:8px;border-top:1px solid var(--hairline);font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--ink-mute)}

/* Statut « En développement » : pastille mono discrète + point qui respire.
   Pose sur les pages outils (détail projet + page labo), à la place de tout
   lien direct vers l'app tant qu'elle n'est pas stabilisée. */
.status-dev{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-soft);background:var(--paper);
  padding:7px 13px;border:1px solid var(--hairline);border-radius:999px;white-space:nowrap;
}
.status-dev::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ink);flex:none}
.status-dev--pin{position:absolute;top:12px;left:12px;z-index:2}
@media (prefers-reduced-motion:no-preference){
  .status-dev::before{animation:statusPulse 2.4s var(--ease-soft) infinite}
}
@keyframes statusPulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.3;transform:scale(.7)}}

/* Liste blog */
.posts{display:grid;gap:0;border-top:1px solid var(--hairline)}
.post{
  display:grid;grid-template-columns:140px 1fr 200px;gap:clamp(24px,4vw,48px);
  padding:clamp(24px,3.5vh,40px) 0;border-bottom:1px solid var(--hairline);
  align-items:baseline;transition:padding-left .35s var(--ease);
}
/* Survol cohérent : la ligne survolée reste pleine, les autres s'estompent.
   L'effet brutal de décalage (padding-left) est remplacé. */
.posts:hover .post{opacity:.4;transition:opacity .35s var(--ease)}
.posts .post:hover{opacity:1}

/* Image de l'article mise en avant, suit le curseur dans la section. */
#blog,.peek-zone{position:relative;overflow:clip}
.post-peek{
  position:absolute;top:0;left:0;z-index:5;
  width:clamp(220px,21vw,320px);aspect-ratio:4/3;
  overflow:hidden;border:1px solid var(--hairline);
  opacity:0;transform:translate(-9999px,-9999px);
  transition:opacity .4s var(--ease);will-change:transform,opacity;
}
.post-peek.is-on{opacity:1}
.post-peek img{width:100%;height:100%;object-fit:cover;display:block}
@media (max-width:760px){.post-peek{display:none}}
.post__date{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute)}
.post__title{font-family:var(--serif);font-weight:400;font-size:clamp(20px,2vw,30px);line-height:1.15;letter-spacing:-.012em;color:var(--ink)}
.post__title em{font-style:italic}
.post__cat{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);text-align:right}
@media (max-width:760px){.post{grid-template-columns:1fr;gap:8px}.post__cat{text-align:left}}

/* Form (contact) */
.form{display:grid;gap:clamp(16px,2vh,24px);max-width:560px}
.field{display:grid;gap:8px}
.field label{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute)}
.field input, .field textarea, .field select{
  font:inherit;color:var(--ink);
  padding:12px 0;border:none;border-bottom:1px solid var(--ink);
  background:transparent;width:100%;
  transition:border-color .25s ease;
}
.field input:focus, .field textarea:focus, .field select:focus{outline:none;border-color:var(--ink)}
.field textarea{min-height:120px;resize:vertical}
.field--inline{display:flex;align-items:center;gap:10px;font-size:13px}
.field--inline input{width:auto}
.form .btn{justify-self:start;margin-top:10px}

/* ============================================================
   FOOTER GLOBAL — stage sable inversée fusion + CTA + footer
   Fond noir, sable blanc qui suit la souris, contenu en mix-blend-mode difference
   ============================================================ */
.cta-foot{
  position:relative;
  background:var(--ink);color:var(--paper);
  overflow:hidden;isolation:isolate;
  min-height:560px;
}
.cta-foot__sand{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  z-index:1;cursor:crosshair;touch-action:pan-y;
}
.cta-foot .grain{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  mix-blend-mode:screen;opacity:.16;
  background-image:radial-gradient(rgba(250,250,250,.6) 1px,transparent 1px);
  background-size:3px 3px;
  mask-image:radial-gradient(ellipse at center,#000 60%,transparent 100%);
}
.cta-foot .vignette{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  background:radial-gradient(120% 100% at 50% 50%,transparent 55%,rgba(0,0,0,.35) 100%);
}
/* Même règle que le hero (.ui) : c'est le conteneur qui porte le
   mix-blend-mode:difference + color:#fff. Tout le contenu s'inverse
   uniformément quand le sable blanc passe dessous. */
.cta-foot__inner{
  position:relative;z-index:10;
  padding:clamp(96px,14vh,180px) var(--safe) clamp(28px,3vh,40px);
  pointer-events:none;
  mix-blend-mode:difference;color:#fff;
}
.cta-foot__inner > *{pointer-events:auto}
.cta-foot__inner a, .cta-foot__inner .cta{pointer-events:auto}

/* Le grand titre + le sous-titre gardent l'inversion mix-blend (effet stylé,
   reste lisible car grand). Les éléments interactifs en sont exclus et ont
   des pastilles de fond solides. */
.cta-foot__cta{
  max-width:var(--maxw);margin:0 auto clamp(72px,10vh,120px);
  padding-bottom:clamp(72px,10vh,120px);
  border-bottom:1px solid rgba(250,250,250,.3);
  display:flex;flex-direction:column;gap:24px;align-items:flex-start;
}
.cta-foot__title{
  font-family:var(--serif);font-weight:400;font-style:italic;
  font-size:clamp(40px,7vw,108px);line-height:.96;letter-spacing:-.022em;
  margin:0;max-width:18ch;
  color:#fff;
}
/* Le titre du CTA est déjà tout en italique : l'accent passe par la couleur
   seule, comme sur les planches où le mot souligné garde le style du titre. */
.cta-foot__title em{font-style:inherit;color:var(--accent-dark)}
.cta-foot__sub{
  font-size:clamp(15px,1.2vw,18px);line-height:1.55;
  max-width:54ch;margin:0;
  color:#fff;
}
.cta-foot__buttons{display:flex;gap:14px;flex-wrap:wrap;margin-top:8px}

/* CTAs du footer : même traitement que le hero — transparent + bord blanc,
   l'inversion vient du mix-blend du conteneur. Pas de pastille (sinon le
   backdrop-filter casse le blend uniforme). */
.cta-foot .cta{
  border-radius:999px;
  transition:background .3s ease, color .3s ease, transform .3s var(--ease);
}
.cta-foot .cta:hover{transform:translateY(-1px)}

/* Site-foot : conteneur transparent, contenu clair. Chaque lien a une
   pastille translucide pour rester lisible par-dessus le sable. */
.cta-foot .site-foot{
  background:transparent;padding:0;color:#fff;
}
.cta-foot .site-foot__grid{padding-bottom:clamp(48px,6vh,72px)}
.cta-foot .site-foot__bottom{border-top:1px solid rgba(255,255,255,.3)}
.cta-foot .site-foot__brand,
.cta-foot .site-foot__tagline,
.cta-foot .site-foot h4,
.cta-foot .site-foot__bottom{color:#fff}
.cta-foot .site-foot ul a{
  display:inline-block;color:#fff;
  padding:5px 12px;margin:-5px -12px;border-radius:999px;
  transition:opacity .25s ease;
}
.cta-foot .site-foot ul a:hover{opacity:.6}

@media (max-width:880px){
  .cta-foot__inner{padding-top:clamp(80px,12vh,140px)}
}

/* Footer LEGACY (référencé ailleurs si besoin) */
.site-foot{
  background:var(--ink);color:var(--paper);
  padding:clamp(60px,8vh,100px) var(--safe) clamp(28px,3vh,40px);
}
.site-foot__grid{
  display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr 1fr;gap:clamp(24px,4vw,56px);
  max-width:var(--maxw);margin:0 auto;
}
@media (max-width:880px){.site-foot__grid{grid-template-columns:1fr 1fr}}
@media (max-width:560px){.site-foot__grid{grid-template-columns:1fr}}
.site-foot__brand{font-family:'Silkscreen',var(--mono);font-weight:700;font-size:clamp(24px,2.6vw,36px);letter-spacing:.02em;text-transform:uppercase;color:var(--paper);margin-bottom:14px}
.site-foot__tagline{font-size:14px;line-height:1.55;color:rgba(250,250,250,.72);max-width:38ch}
.site-foot h4{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;font-weight:400;color:rgba(250,250,250,.6);margin-bottom:18px}
.site-foot ul{display:grid;gap:10px}
.site-foot a{color:var(--paper);font-size:14px;transition:opacity .25s}
.site-foot a:hover{opacity:.7}
.site-foot__bottom{
  margin-top:clamp(48px,6vh,72px);padding-top:24px;
  border-top:1px solid rgba(250,250,250,.18);
  max-width:var(--maxw);margin-left:auto;margin-right:auto;
  display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px;
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(250,250,250,.6);
}

/* ============================================================
   Garde-fous : cacher les trous résiduels (champs Notion vides)
   ============================================================ */
.post__cat:empty,
.post__date:empty,
.kpi__title:empty,
.kpi__num:empty,
.item__text:empty,
.step__text:empty,
.card__cat:empty,
.card__sub:empty,
.card__row:empty,
.section__lede:empty,
.section__num:empty{display:none}
/* Si une cellule client OU date est vide dans une card__row, on rééquilibre */
.card__row > span:empty{display:none}
.card__row:has(> span:only-of-type){justify-content:flex-end}

/* ============================================================
   Reveal au scroll (IntersectionObserver via layout.js)
   ============================================================ */
.reveal-up{opacity:0;transform:translateY(28px);transition:opacity .9s var(--ease), transform .9s var(--ease)}
.reveal-up.in{opacity:1;transform:none}

/* Stagger naturel : les items d'une grille apparaissent en cascade légère */
.items .item.reveal-up,
.kpis .kpi.reveal-up,
.steps .step.reveal-up,
.cards .card.reveal-up,
.posts .post.reveal-up{
  transition-delay:calc(var(--stagger, 0) * 70ms);
}

/* Cartes (réalisations / applications métier) : arrivée plus posée.
   Translation plus ample + léger zoom, courbe très douce, cascade
   plus marquée → fin du « pop » brutal. */
.cards .card.reveal-up{
  transform:translateY(46px) scale(.965);
  transition:opacity 1.05s var(--ease-soft), transform 1.05s var(--ease-soft);
  transition-delay:calc(var(--stagger, 0) * 120ms);
}
.cards .card.reveal-up.in{transform:none}

/* Underline animée sur les <em> des titres de section, au scroll */
.section__title em,
.manifeste h2 em{
  position:relative;display:inline-block;
}
.section__title em::after,
.manifeste h2 em::after{
  content:"";position:absolute;left:0;right:0;bottom:.04em;height:2px;
  /* Encre, et surtout pas currentColor : depuis que le mot est en --accent,
     un trait rouge sous un mot rouge dirait deux fois la même chose. Le trait
     reste une animation de scroll discrète, l'accent reste unique. */
  background:var(--ink);opacity:.22;
  transform:scaleX(0);transform-origin:left;
  transition:transform 1.2s var(--ease) .25s;
}
.reveal-up.in .section__title em::after,
.reveal-up.in.manifeste h2 em::after,
.in.section__title em::after,
.in .section__title em::after,
.manifeste.reveal-up.in h2 em::after{
  transform:scaleX(1);
}
.section--dark .section__title em::after{opacity:.45;background:var(--paper)}

/* Hover renforcé sur les cards : élévation + ligne subtile */
.card{
  transition:border-color .35s ease, transform .45s var(--ease), box-shadow .45s var(--ease);
}
.card:hover{
  border-color:var(--ink);transform:translateY(-3px);
  box-shadow:0 18px 48px -28px rgba(20,22,26,.18);
}
.card__viz{transition:transform .8s var(--ease)}
.card:hover .card__viz{transform:scale(1.02)}
.card__viz img{transition:transform .8s var(--ease)}
.card:hover .card__viz img{transform:scale(1.04)}

/* Indicateur de catégorie : petit point qui apparaît au hover */
.card__cat{position:relative;padding-left:0;transition:padding-left .3s var(--ease)}
.card:hover .card__cat{padding-left:14px}
.card__cat::before{
  content:"";position:absolute;left:0;top:50%;
  width:6px;height:6px;background:var(--ink);border-radius:999px;
  transform:translateY(-50%) scale(0);transition:transform .3s var(--ease);
}
.card:hover .card__cat::before{transform:translateY(-50%) scale(1)}

/* Posts : la flèche qui apparaît au hover */
.post{position:relative}
.post::after{
  content:"→";position:absolute;right:8px;top:50%;
  font-family:var(--mono);font-size:14px;color:var(--ink);
  transform:translate(-12px, -50%);opacity:0;
  transition:transform .35s var(--ease), opacity .35s var(--ease);
}
.post:hover::after{transform:translate(0, -50%);opacity:.7}
@media (max-width:760px){.post::after{display:none}}

/* Touche fluide subtile sur les sections--minimal aussi : grain papier très léger */
.section--minimal{position:relative;overflow:hidden}
.section--minimal::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  opacity:.04;
  background-image:radial-gradient(rgba(20,22,26,.4) 1px,transparent 1px);
  background-size:4px 4px;
  mask-image:radial-gradient(ellipse at center,#000 30%,transparent 80%);
}
.section--minimal > *{position:relative;z-index:1}

/* Manifeste : halo radial doux derrière le titre */
.manifeste{position:relative;overflow:hidden}
.manifeste::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(60% 50% at 30% 40%, rgba(20,22,26,.025) 0%, transparent 65%);
}
.manifeste > *{position:relative;z-index:1}

/* Hero static : reveal du titre mot-par-mot (animé au load via layout.js) */
.hero-static h1{opacity:0;transform:translateY(18px);transition:opacity .9s var(--ease), transform .9s var(--ease)}
.hero-static.is-revealed h1{opacity:1;transform:none}
.hero-static .sub{opacity:0;transform:translateY(12px);transition:opacity .9s var(--ease) .25s, transform .9s var(--ease) .25s}
.hero-static.is-revealed .sub{opacity:1;transform:none}

/* CTA dans nav-static : magnetic + halo subtil */
.nav-static .nav__cta{position:relative;overflow:hidden}
.nav-static .nav__cta::before{
  content:"";position:absolute;inset:0;background:var(--ink);
  transform:translateY(100%);transition:transform .35s var(--ease);
}
.nav-static .nav__cta:hover{color:var(--paper)}
.nav-static .nav__cta:hover::before{transform:translateY(0)}
.nav-static .nav__cta > *{position:relative;z-index:1}

/* ============================================================
   GABARIT ARTICLE — colonne de lecture unifiée (--maxw-read),
   sommaire latéral sticky, images de corps, FAQ.
   ============================================================ */

/* Corps : largeur et centrage gérés par .article-layout. */
.prose-article{
  max-width:none;margin:0;padding:clamp(36px,5vh,60px) 0 clamp(48px,7vh,84px);
  font-size:17px;line-height:1.75;color:var(--ink-soft);
}
.prose-article > *:first-child{margin-top:0}
.prose-article h2{position:relative;font-family:var(--serif);font-weight:400;font-size:clamp(26px,3vw,38px);line-height:1.15;color:var(--ink);margin:52px 0 18px;letter-spacing:-.014em;scroll-margin-top:96px}
.prose-article h3{font-family:var(--serif);font-weight:500;font-size:clamp(20px,2.2vw,26px);color:var(--ink);margin:34px 0 12px;scroll-margin-top:96px}
.prose-article p{margin-bottom:20px}
.prose-article a:not(.anchor){color:var(--ink);border-bottom:1px solid var(--ink-mute);transition:border-color .25s}
.prose-article a:not(.anchor):hover{border-color:var(--ink)}
.prose-article blockquote{margin:36px 0;padding-left:24px;border-left:2px solid var(--ink);font-family:var(--serif);font-style:italic;font-size:clamp(18px,1.6vw,22px);color:var(--ink)}
.prose-article ul, .prose-article ol{margin:20px 0;padding-left:24px}
.prose-article ul li{list-style:disc;margin-bottom:10px}
.prose-article ol li{list-style:decimal;margin-bottom:10px}
.prose-article code{font-family:var(--mono);font-size:14px;background:var(--paper-2);padding:2px 6px;border-radius:3px}

/* Ancre discrète sur les titres (apparaît au survol, desktop). */
.prose-article h2 .anchor{position:absolute;left:-1.1em;top:.05em;color:var(--ink-mute);text-decoration:none;border:0;opacity:0;transition:opacity .2s;font-weight:400}
.prose-article h2:hover .anchor{opacity:.45}
.prose-article h2 .anchor:hover{opacity:1}
@media (max-width:1080px){ .prose-article h2 .anchor{display:none} }

/* Images de corps : pleine largeur de lecture + légende. */
.prose-article figure{margin:clamp(34px,5vh,56px) 0}
.prose-article figure img{width:100%;margin:0;border:1px solid var(--hairline);border-radius:2px}
.prose-article figcaption{margin-top:10px;font-family:var(--mono);font-size:12px;letter-spacing:.02em;color:var(--ink-mute);text-align:center}

/* Hero article (titre + chapô + méta) sur l'axe de lecture. */
.article-hero{padding:calc(var(--safe) * 2) 0 0;background:var(--paper)}
.article-hero__cat{display:inline-block;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-mute)}
.article-hero h1{font-family:var(--serif);font-weight:400;font-style:italic;font-size:clamp(32px,5vw,58px);line-height:1.04;letter-spacing:-.02em;color:var(--ink);margin:14px 0 0}
.article-hero__lede{margin:20px 0 0;font-size:clamp(16px,1.4vw,20px);line-height:1.55;color:var(--ink-soft);max-width:60ch}
.article-hero__meta{margin-top:24px;padding-top:16px;border-top:1px solid var(--hairline);display:flex;flex-wrap:wrap;gap:10px 22px;font-family:var(--mono);font-size:12px;letter-spacing:.03em;color:var(--ink-mute)}

/* Cover sur l'axe de lecture. */
.article-cover{margin:clamp(26px,4vh,40px) auto 0;aspect-ratio:16/9;overflow:hidden;border:1px solid var(--hairline);border-radius:2px}
.article-cover img{width:100%;height:100%;object-fit:cover}

/* Corps : centré sur l'axe de lecture (--maxw-read), exactement comme le
   hero, la cover, la FAQ et « à lire aussi ». Le sommaire se loge dans la
   marge gauche sans jamais décaler ce corps (cf. média ≥ 1280px). */
.article-shell{position:relative;max-width:var(--maxw-read);margin:0 auto;padding:0 var(--safe)}

/* Sommaire — par défaut en haut du corps, encadré et repliable. */
.article-toc{
  margin:0 auto clamp(10px,2vh,20px);max-width:var(--maxw-read);
  border:1px solid var(--hairline);border-radius:3px;padding:14px 18px;background:var(--paper-2);
  font-family:var(--mono);
}
.article-toc__box{font-size:13px}
.article-toc__box > summary{list-style:none;cursor:pointer;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-mute)}
.article-toc__box > summary::-webkit-details-marker{display:none}
.article-toc__box[open] > summary{margin-bottom:12px}
.article-toc ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.article-toc li{margin:0}
.article-toc a{display:block;padding:4px 0;color:var(--ink-soft);text-decoration:none;line-height:1.4;transition:color .2s,border-color .2s}
.article-toc a:hover{color:var(--ink)}
.article-toc a.is-active{color:var(--ink)}

/* ≥ 1280px : le sommaire passe dans la marge gauche, sticky, hors flux,
   donc le corps reste parfaitement centré sur l'axe de lecture. */
@media (min-width:1280px){
  .article-toc{
    position:absolute;top:0;right:100%;height:100%;width:198px;
    margin:0 clamp(28px,2.6vw,52px) 0 0;padding:0;border:0;border-radius:0;background:none;
  }
  .article-toc__box{position:sticky;top:104px;max-height:calc(100vh - 140px);overflow:auto}
  .article-toc__box > summary{margin-bottom:16px}
  .article-toc ol{border-left:1px solid var(--hairline)}
  .article-toc a{padding:5px 0 5px 16px;margin-left:-1px;border-left:2px solid transparent}
  .article-toc a.is-active{border-left-color:var(--ink)}
}

/* FAQ (accordéon) */
.article-faq{padding-top:0}
.article-faq__title{font-family:var(--serif);font-weight:400;font-style:italic;font-size:clamp(26px,3vw,38px);color:var(--ink);margin:0 0 24px;letter-spacing:-.014em}
.faq-list{border-top:1px solid var(--hairline)}
.faq-item{border-bottom:1px solid var(--hairline)}
.faq-item > summary{list-style:none;cursor:pointer;padding:18px 0;font-size:clamp(16px,1.3vw,18px);color:var(--ink);font-weight:500;display:flex;justify-content:space-between;gap:16px;align-items:baseline}
.faq-item > summary::-webkit-details-marker{display:none}
.faq-item > summary::after{content:"+";font-family:var(--mono);color:var(--ink-mute);font-weight:400}
.faq-item[open] > summary::after{content:"–"}
.faq-item__a{padding:0 0 20px;color:var(--ink-soft);font-size:15.5px;line-height:1.65;max-width:64ch}
.faq-item__a a{color:var(--ink);border-bottom:1px solid var(--ink-mute)}

/* ============================================================
   NAV FIXE GLOBAL — inversion automatique par mix-blend-mode.
   Le nav entier est en mix-blend-mode:difference avec un texte blanc : il
   s'inverse PIXEL PAR PIXEL contre ce qui défile dessous, exactement comme le
   grand titre du hero. Sur fond clair, le texte vire au noir ; sur fond noir ou
   sable noir, il vire au blanc ; à cheval, chaque portion de lettre prend la
   couleur opposée du fond local. Remplace l'ancien double système (.on-dark par
   sondage de section + échantillonnage du sable) qui basculait l'élément entier
   au seuil et ne gérait pas les fonds à cheval.
   IMPORTANT : le mix-blend doit être posé sur .nav-fixed LUI-MÊME (la racine du
   stacking context fixed) pour se mélanger avec la page ; sur un enfant il
   s'isolerait dans le contexte du nav et resterait blanc partout. Pas de pastille
   de fond ni de voile flou : opaques, ils virent au damier sous le mix-blend.
   ============================================================ */
/* Voile flou LOCALISÉ : deux halos flous derrière le logo (gauche) et le groupe
   liens + CTA (droite), au lieu d'une bande pleine largeur. Calques SÉPARÉS (hors
   .nav-fixed, sinon avalés par le mix-blend du nav), positionnés par `layout.js`
   sur les bbox réelles (recalc au resize / chargement des fonts). z-index entre le
   contenu (≤10) et le nav (100), sous le panneau burger (99). Masque radial doux
   pour estomper les bords (aucune arête). */
.nav-veil{
  position:fixed;z-index:90;
  pointer-events:none;border-radius:999px;
  -webkit-backdrop-filter:blur(8px);
  backdrop-filter:blur(8px);
  -webkit-mask-image:radial-gradient(ellipse at center,#000 45%,transparent 75%);
  mask-image:radial-gradient(ellipse at center,#000 45%,transparent 75%);
}
@media (prefers-reduced-motion:reduce){.nav-veil{backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px)}}

.nav-fixed{
  position:fixed;top:0;left:0;right:0;z-index:100;
  padding:18px var(--safe);
  pointer-events:none;
  mix-blend-mode:difference;
}
.nav-fixed > *{pointer-events:auto}
.nav-fixed__inner{
  display:flex;align-items:center;justify-content:space-between;gap:18px;
  max-width:none;
}

/* Texte du nav en blanc : c'est le mix-blend du conteneur qui l'inverse selon le
   fond. Pas de transition de couleur (l'inversion suit le fond en temps réel). */
.nav-fixed .brand,
.nav-fixed .links a,
.nav-fixed__cta{
  color:#fff;
  border-radius:999px;
  transition:transform .3s var(--ease);
}
/* Neutralise le trait underline hérité du .links générique du hero */
.nav-fixed .links a::after{display:none !important;content:none !important}

.nav-fixed .brand{
  font-family:'Silkscreen',var(--mono);font-weight:700;font-size:clamp(14px,1.2vw,17px);
  letter-spacing:.06em;text-transform:uppercase;line-height:1;
  display:flex;align-items:center;gap:10px;
  padding:9px 16px;
}
.nav-fixed .brand .dot{width:6px;height:6px;border-radius:999px;background:currentColor;display:inline-block}
/* Cœur pixel Bonabona (7×6, unité 3px). Fallback sans JS : monochrome
   currentColor, compatible mix-blend. Avec JS, layout.js (section 2b2) pose un
   calque couleur par-dessus (.brand-heart-fx, HORS nav) : le rouge de la charte
   ne peut pas vivre dans le nav, le mix-blend difference l'inverserait. */
.brand-heart{width:21px;height:18px;position:relative;display:inline-block;flex:none}
.brand-heart::before{
  content:"";position:absolute;left:0;top:0;width:3px;height:3px;background:transparent;
  box-shadow:
    3px 0,6px 0,12px 0,15px 0,
    0 3px,3px 3px,6px 3px,9px 3px,12px 3px,15px 3px,18px 3px,
    0 6px,3px 6px,6px 6px,9px 6px,12px 6px,15px 6px,18px 6px,
    3px 9px,6px 9px,9px 9px,12px 9px,15px 9px,
    6px 12px,9px 12px,12px 12px,
    9px 15px;
}
.brand-heart.has-fx::before{display:none}

/* Calque couleur du cœur (créé par layout.js, calé sur la bbox du spacer
   .brand-heart). Au-dessus du nav (z 101) : il échappe au mix-blend et garde ses
   vraies couleurs. La couleur glisse dans --heart-color (palette peps, JS).
   Survol du logo (.is-burst) : chaque pixel s'écarte du centre (--dx/--dy posés
   inline par JS, en px ENTIERS : en subpixel l'antialiasing rend les cellules
   pâles et floues), départ vif avec rebond et cascade radiale (--bd), retour
   souple. */
.brand-heart-fx{position:fixed;z-index:101;pointer-events:none}
.brand-heart-fx i{
  position:absolute;display:block;
  background:var(--peps,#E8382F);
  transition:transform .55s var(--ease-soft),background-color .9s linear;
}
.brand-heart-fx.is-burst i{
  transform:translate(var(--dx),var(--dy));
  transition:transform .4s cubic-bezier(.3,1.55,.55,1),background-color .9s linear;
  transition-delay:var(--bd,0s),0s;
}
@media (prefers-reduced-motion:reduce){
  .brand-heart-fx i{transition:none}
  .brand-heart-fx.is-burst i{transform:none}
}

/* ============================================================
   PIXICONS — jeu d'icônes pixel de la marque, même langage que le
   cœur du nav. <span class="pixicon" data-pixicon="nom" data-px="4">
   rempli par layout.js (section 2b3) en cellules px entiers.
   Encre au repos (currentColor). Au survol de l'icône ou d'un
   ancêtre [data-pixicon-hover] : les pixels s'écartent (.is-burst)
   et prennent la couleur peps du moment (--peps sur :root, la même
   rotation de palette que le cœur). Purement décoratif.
   ============================================================ */
.pixicon{position:relative;display:inline-block;flex:none}
.pixicon i{
  position:absolute;display:block;background:currentColor;
  transition:transform .55s var(--ease-soft),background-color .5s ease;
}
.pixicon.is-burst i{
  transform:translate(var(--dx),var(--dy));
  background:var(--peps,#E8382F);
  transition:transform .4s cubic-bezier(.3,1.55,.55,1),background-color .25s ease;
  transition-delay:var(--bd,0s),0s;
}
/* Respiration lente (étoile de la section Objectif) : léger écartement
   périodique par cellule, ondulation radiale via le délai --bd. Suspendue
   pendant le burst (le survol prend la main). */
.pixicon--breathe i{animation:pixi-breathe 4.2s ease-in-out infinite;animation-delay:var(--bd,0s)}
.pixicon--breathe.is-burst i{animation:none}
@keyframes pixi-breathe{
  0%,100%{transform:translate(0,0)}
  50%{transform:translate(calc(var(--dx)*.4),calc(var(--dy)*.4))}
}
@media (prefers-reduced-motion:reduce){
  .pixicon i{transition:none;animation:none !important}
  .pixicon.is-burst i{transform:none;background:currentColor}
}

/* Emplacements : icône d'accompagnement en coin droit des têtes de
   section (burst au survol du head entier). Masquée en mobile, où le
   titre occupe toute la largeur. */
.section__head{position:relative}
.section__head > .pixicon{position:absolute;right:0;top:6px}
.apropos-split__inner{position:relative}
.apropos-split__inner > .pixicon{position:absolute;right:0;top:6px}
@media (max-width:880px){
  .section__head > .pixicon,
  .apropos-split__inner > .pixicon{display:none}
}
/* Sections sur fond noir (Objectif) : icônes en paper. */
.objectif-grid .pixicon{color:var(--paper)}
/* Contact : bulle en ponctuation de la ligne d'actions (le flex du bloc
   l'aligne et l'espace via son gap). */
.contact-hero .pixicon{color:var(--ink-soft)}

.nav-fixed .links{display:flex;gap:4px;margin-left:auto;font-size:12px;letter-spacing:.04em;text-transform:uppercase;font-weight:400}
.nav-fixed .links a{position:relative;padding:9px 15px}
/* Feedback survol / lien actif : un soulignement fin (compatible mix-blend,
   contrairement à une pastille de fond opaque qui virerait au damier). */
.nav-fixed .links a::before{
  content:"";position:absolute;left:15px;right:15px;bottom:4px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:left;
  transition:transform .35s var(--ease);
}
.nav-fixed .links a:hover::before,
.nav-fixed .links a.is-active::before{transform:scaleX(1)}
.nav-fixed .links a:focus-visible{outline:2px solid currentColor;outline-offset:2px}

.nav-fixed__cta{
  display:inline-flex;align-items:center;gap:10px;
  padding:11px 18px;
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  border:1px solid currentColor;
}
.nav-fixed__cta:hover{transform:translateY(-1px)}

/* Burger : caché en desktop, visible < 880px */
.nav-burger{
  display:none;
  width:44px;height:44px;border-radius:999px;
  align-items:center;justify-content:center;flex-direction:column;gap:6px;
  color:#fff;background:transparent;
  flex-shrink:0;
}
.nav-burger span{
  display:block;width:22px;height:1.5px;background:currentColor;
  transition:transform .35s var(--ease), opacity .25s ease;
}
.nav-burger[aria-expanded="true"] span:nth-child(1){transform:translateY(3.75px) rotate(45deg)}
.nav-burger[aria-expanded="true"] span:nth-child(2){transform:translateY(-3.75px) rotate(-45deg)}

/* Panneau plein écran */
.nav-panel{
  position:fixed;inset:0;z-index:99;
  background:var(--ink);color:var(--paper);
  display:flex;flex-direction:column;justify-content:center;
  padding:clamp(80px,14vh,140px) var(--safe) var(--safe);
  opacity:0;transform:translateY(-12px);
  transition:opacity .4s var(--ease), transform .4s var(--ease);
  pointer-events:none;
}
.nav-panel.is-open{opacity:1;transform:none;pointer-events:auto}
.nav-panel__links{display:flex;flex-direction:column;gap:clamp(8px,2vh,18px)}
.nav-panel__links a{
  font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:clamp(28px,7vw,52px);line-height:1.1;letter-spacing:-.018em;
  color:var(--paper);padding:6px 0;
  border-bottom:1px solid rgba(250,250,250,.14);
  transition:padding-left .3s var(--ease), opacity .3s ease;
}
.nav-panel__links a:hover,
.nav-panel__links a.is-active{padding-left:14px;opacity:.7}
.nav-panel__cta{
  font-family:var(--mono) !important;font-style:normal !important;
  font-size:13px !important;letter-spacing:.16em;text-transform:uppercase;
  display:inline-flex;align-items:center;gap:12px;
  margin-top:clamp(24px,4vh,40px);padding:16px 24px !important;
  border:1px solid var(--paper);border-radius:999px;align-self:flex-start;
}
.nav-panel__cta:hover{background:var(--paper);color:var(--ink);padding-left:24px !important}
.nav-panel__foot{
  display:flex;gap:24px;flex-wrap:wrap;margin-top:clamp(40px,6vh,72px);
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(250,250,250,.6);
}
.nav-panel__foot a:hover{color:var(--paper)}

body.nav-open{overflow:hidden}

@media (max-width:880px){
  .nav-fixed{padding:14px 16px}
  .nav-fixed .links{display:none}
  .nav-fixed__cta{display:none}
  .nav-burger{display:flex}
}
@media (min-width:881px){
  .nav-panel{display:none}
}

/* Pages sans hero plein écran : on réserve un padding-top pour ne pas que
   le contenu passe sous le nav fixé. Le hero plein écran de la home n'en
   a pas besoin (il couvre toute la viewport). */
.has-static-hero{padding-top:0} /* hero-static a déjà son top padding suffisant */

/* ============================================================
   CONTACT — parcours guidé en modal + backdrop verre pixelisé
   Le formulaire classique reste le repli sans JavaScript (#contact-fallback,
   réaffiché via <noscript>). Le modal (JS) pose une question à la fois ;
   pendant qu'il est ouvert, #main est pixelisé (filtre SVG #mat-pixelate,
   carreaux fins) et l'overlay pose la glace dépolie + les joints de carreaux.
   Erreurs ramenées dans l'encre (pas d'accent coloré, cf. design system).
   ============================================================ */

/* Hero contact plein écran : titre + bouton mis en avant + accès email direct */
.contact-hero{min-height:100svh;display:flex;align-items:center;padding:clamp(80px,10vh,120px) var(--safe) clamp(48px,7vh,80px);background:var(--paper);border-bottom:1px solid var(--hairline)}
.contact-hero .container{width:100%}
/* Hero contact en deux colonnes : le combiné rouge en lévitation à droite
   équilibre un hero qui était très vide de ce côté. */
.contact-hero__grid{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(32px,5vw,80px);align-items:center}
.contact-hero__media{margin:0;justify-self:center;max-width:420px;width:100%}
.contact-hero__media img{
  width:100%;aspect-ratio:4/5;object-fit:cover;display:block;
  border-radius:3px;
  /* La lévitation est portée par le CSS, pas par l'image : elle flotte et son
     ombre respire en même temps, ce qui vend le poids suspendu. */
  animation:contact-float 7s var(--ease-soft) infinite;
  box-shadow:0 40px 60px -34px rgba(20,22,26,.42);
}
@keyframes contact-float{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(-14px)}
}
@media (max-width:880px){
  .contact-hero__grid{grid-template-columns:1fr;gap:40px}
  /* Sous le texte et plus petite : en mobile le hero fait déjà 100svh, une
     image à taille égale pousserait les actions hors de l'écran. */
  .contact-hero__media{max-width:260px;justify-self:start;order:2}
}
@media (prefers-reduced-motion:reduce){
  .contact-hero__media img{animation:none}
}
.contact-hero h1{font-family:var(--serif);font-weight:400;font-style:italic;font-size:clamp(44px,8vw,120px);line-height:.96;letter-spacing:-.022em;color:var(--ink);max-width:16ch}
.contact-hero__sub{margin-top:clamp(20px,3vh,32px);font-size:clamp(16px,1.3vw,20px);line-height:1.5;color:var(--ink-soft);max-width:52ch}
.contact-hero__actions{margin-top:clamp(30px,5vh,52px);display:flex;flex-wrap:wrap;align-items:center;gap:16px 28px}
.contact-hero__start{font-size:14px;padding:17px 26px}
.contact-hero__or{font-size:14px;color:var(--ink-mute)}
.contact-hero__or a{color:var(--ink);border-bottom:1px solid var(--ink-mute);padding-bottom:1px}
.contact-hero__or a:hover{border-color:var(--ink)}
/* Repli formulaire : masqué en mode normal, réaffiché par <noscript> */
.contact-fallback-sec{display:none}

/* Coordonnées : toujours visibles, sous le formulaire */
.contact-coords__grid{display:grid;grid-template-columns:repeat(3,auto);gap:clamp(28px,6vw,80px);justify-content:start}
.contact-coords__label{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute);margin-bottom:12px}
.contact-coords__email{font-family:var(--serif);font-style:italic;font-size:clamp(20px,1.6vw,24px);color:var(--ink);border-bottom:1px solid var(--ink-mute)}
.contact-coords__text{font-size:15px;line-height:1.6;color:var(--ink-soft)}
.contact-coords__links{display:grid;gap:8px}
.contact-coords__links a{border-bottom:1px solid var(--hairline);padding-bottom:4px}
@media (max-width:640px){.contact-coords__grid{grid-template-columns:1fr;gap:26px}}

/* Page derrière le modal : scroll bloqué + pixelisation (carreaux S) */
body.contact-open{overflow:hidden}
body.contact-open #main{filter:url(#mat-pixelate)}

/* Overlay verre dépoli + joints de carreaux + reflet diagonal */
.contact-overlay{
  position:fixed;inset:0;z-index:200;
  background-color:rgba(250,250,250,.28);
  -webkit-backdrop-filter:blur(2.5px);backdrop-filter:blur(2.5px);
  background-image:
    repeating-linear-gradient(to right, rgba(20,22,26,.05) 0 1px, transparent 1px 12px),
    repeating-linear-gradient(to bottom, rgba(20,22,26,.05) 0 1px, transparent 1px 12px),
    linear-gradient(125deg, rgba(255,255,255,.16), rgba(255,255,255,0) 46%);
  opacity:0;transition:opacity .4s var(--ease-soft);
}
.contact-overlay.is-open{opacity:1}

/* Modal centré */
.contact-modal{
  position:fixed;z-index:201;top:50%;left:50%;
  transform:translate(-50%,-47%);
  width:min(460px,92vw);
  opacity:0;pointer-events:none;
  transition:opacity .45s var(--ease-soft), transform .45s var(--ease-soft);
}
.contact-modal.is-open{opacity:1;transform:translate(-50%,-50%);pointer-events:auto}
.contact-modal__card{
  background:var(--paper);border:1px solid var(--line);border-radius:16px;
  box-shadow:0 34px 70px -24px rgba(8,8,10,.5);overflow:hidden;
}
.contact-modal__bar{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid var(--hairline)}
.contact-modal__tag{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink)}
.contact-modal__count{margin-left:auto;font-family:var(--mono);font-size:11px;letter-spacing:.12em;color:var(--ink-mute)}
.contact-modal__close{font-size:22px;line-height:1;color:var(--ink-mute);width:26px;height:26px;display:flex;align-items:center;justify-content:center;border-radius:6px}
.contact-modal__close:hover{color:var(--ink)}
.contact-modal__prog{height:2px;background:var(--hairline)}
.contact-modal__prog>i{display:block;height:100%;width:0;background:var(--ink);transition:width .55s var(--ease-soft)}
.contact-modal__stage{padding:clamp(24px,4vw,34px);min-height:300px;display:flex}

/* Moteur d'étapes (rendu par JS, une question à la fois) */
.cstep{flex:1;display:flex;flex-direction:column;width:100%;animation:cstepIn .5s var(--ease-soft)}
@keyframes cstepIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.cstep__q{font-family:var(--serif);font-style:italic;font-weight:400;font-size:clamp(23px,4.4vw,30px);line-height:1.12;letter-spacing:-.01em;color:var(--ink);margin-bottom:10px}
.cstep__hint{font-size:13.5px;color:var(--ink-mute);margin-bottom:24px;line-height:1.5}
.cstep__input{width:100%;font-family:var(--serif);font-style:italic;font-size:clamp(19px,4vw,23px);color:var(--ink);background:none;border:none;border-bottom:1.5px solid var(--line);padding:7px 2px;outline:none;transition:border-color .3s}
.cstep__input::placeholder{color:var(--ink-mute);opacity:.55;font-style:italic}
.cstep__input:focus{border-color:var(--ink)}
.cstep__input.is-err{border-color:var(--ink-soft)}
textarea.cstep__input{resize:none;line-height:1.45;min-height:84px}
.cstep__choices{display:flex;flex-direction:column;gap:9px}
.cchoice{display:flex;align-items:center;gap:13px;width:100%;text-align:left;padding:12px 15px;border:1px solid var(--line);border-radius:10px;background:var(--paper);color:var(--ink);font-size:15px;transition:border-color .2s,transform .2s,background .2s,color .2s}
.cchoice:hover{border-color:var(--ink);transform:translateX(4px)}
.cchoice:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.cchoice.is-sel{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.cchoice__key{font-family:var(--mono);font-size:11px;width:21px;height:21px;flex:none;display:flex;align-items:center;justify-content:center;border:1px solid currentColor;border-radius:5px;opacity:.55}
.cstep__err{font-family:var(--mono);font-size:11px;letter-spacing:.04em;color:var(--ink-soft);margin-top:11px;min-height:13px}
.cstep__foot{display:flex;align-items:center;gap:14px;margin-top:auto;padding-top:24px}
.cstep__ok{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;padding:10px 18px;border-radius:8px;background:var(--ink);color:var(--paper);transition:transform .2s}
.cstep__ok:hover{transform:translateY(-2px)}
.cstep__enter{font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--ink-mute)}
.cstep__back{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-mute);background:none;border:none;cursor:pointer;margin-left:auto}
.cstep__back:hover{color:var(--ink)}
.cstep__recap{display:flex;flex-direction:column;gap:5px;margin-top:14px}
.cstep__recap-row{font-size:13px;color:var(--ink-soft);display:flex;gap:9px}
.cstep__recap-row span{font-family:var(--mono);font-size:11px;color:var(--ink-mute)}
@media (max-width:520px){.contact-modal{width:94vw}.contact-modal__stage{min-height:auto}}

/* Reduced motion */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{animation-duration:.001ms !important;transition-duration:.001ms !important}
  .scroll .line::before{animation:none;transform:none}
  .reveal-up,
  .cards .card.reveal-up{opacity:1;transform:none}
}
