/* ============================================================
   Pragmatech solutions — page d'accueil (MVP)

   Six stations. Trois portent une scène 3D, trois respirent.
   Chaque scène vit dans son cadre et suspend sa boucle de rendu
   dès qu'elle sort de l'écran : une seule calcule à la fois.

   Space Grotesk / Space Mono, auto-hébergées.
   Orange = actionnable. Cyan = mesuré. Aucune autre couleur.
   ============================================================ */

:root{
  --void:#06070a;
  --ink:#f2f5f7;
  --ink-2:rgb(242 245 247 / .58);
  --ink-3:rgb(242 245 247 / .34);
  --line:rgb(242 245 247 / .09);
  --line-2:rgb(242 245 247 / .16);
  --signal:#ff6b1a;
  --on-signal:#140800;
  --measure:#4dd9e8;
  /* Le gris de « solutions » dans la marque, mesuré sur le logo d'origine :
     rgb(113, 114, 116), soit --ink à 45 %. Ce n'est pas --ink-3 : la marque
     a sa propre valeur, et elle est la même sur la carte de visite. */
  --marque-gris:rgb(242 245 247 / .45);

  --bar:76px;
  --gut:clamp(22px, 5vw, 84px);
  --disp:'Space Grotesk', system-ui, sans-serif;
  --mono:'Space Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0;
  background:var(--void);
  color:var(--ink);
  font-family:var(--disp);
  font-size:16px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{ color:inherit; text-decoration:none; }
img{ max-width:100%; height:auto; display:block; }
ul,ol{ margin:0; padding:0; list-style:none; }

.skip{
  position:fixed; top:-100px; left:var(--gut); z-index:99;
  background:var(--signal); color:var(--on-signal);
  padding:.6rem 1rem; font:500 .8rem/1 var(--disp);
}
.skip:focus{ top:12px; }
:focus-visible{ outline:2px solid var(--signal); outline-offset:3px; }

.lab{
  margin:0;
  font:400 10px/1 var(--mono);
  letter-spacing:.18em; text-transform:uppercase; color:var(--ink-3);
}

/* ─────────────────────────── bannière ─────────────────────────── */
.topbar{
  position:fixed; inset:0 0 auto 0; z-index:40;
  height:var(--bar);
  background:color-mix(in srgb, var(--void) 62%, transparent);
  backdrop-filter:blur(16px) saturate(1.15);
  -webkit-backdrop-filter:blur(16px) saturate(1.15);
  border-bottom:1px solid var(--line);
}
.topbar__in{
  height:100%; padding-inline:var(--gut);
  display:flex; align-items:center; gap:clamp(16px,3vw,40px);
}
/* ═══ marque ═══
   Le mot-symbole est composé, non dessiné : Space Grotesk pour le nom,
   Space Mono espacé pour la ligne de service. Net à toute taille, sans
   image à charger, et la marque appartient enfin au même système
   typographique que le reste du site.

   Les proportions ne sont pas choisies ici : ce sont celles du recto de la
   carte de visite, 34/86 pour le corps de la ligne de service et 20/86
   pour le blanc qui l'en sépare. Un seul réglage, --corps, les tient
   ensemble — changer le corps du nom ne peut plus dériver du logo imprimé.
   La source de la marque et tous ses fichiers vivent dans marque/. */
.brand{
  flex:0 0 auto; display:block; width:max-content; line-height:1;
  --corps:20px;                 /* le corps du nom ; tout le reste en découle */
  /* L'oblique du logo, relevée sur le fichier d'origine par redressement.
     L'origine est le milieu du bas : le pied de la marque ne bouge pas,
     seul le haut part à droite — même transformation que sur la carte. */
  transform:skewX(-9.75deg);
  transform-origin:50% 100%;
}
.brand__n{
  display:block;
  font:600 var(--corps)/1 var(--disp);
  letter-spacing:-.035em; color:var(--ink);
}
.brand__s{
  display:block;
  margin-top:calc(var(--corps) * 20 / 86);
  font:400 calc(var(--corps) * 34 / 86)/1 var(--mono);
  letter-spacing:.42em; color:var(--marque-gris);
  /* Centre sous le nom, comme le mot-symbole d'origine. L'espacement
     ajoute un blanc apres la derniere lettre : sans compensation, le
     centrage optique tirerait a gauche. Un retrait d'un espacement
     entier vaut, sur une ligne centrée, un décalage d'un demi. */
  text-align:center; text-indent:.42em;
}

.nav{ margin-inline:auto; display:flex; gap:clamp(14px,2.4vw,34px); }
.nav__l{
  font:400 10px/1 var(--mono);
  letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink-2); padding:9px 0; position:relative;
  transition:color .18s ease;
}
.nav__l::after{
  content:''; position:absolute; left:0; right:100%; bottom:2px;
  height:1px; background:var(--signal);
  transition:right .26s cubic-bezier(.2,.7,.2,1);
}
.nav__l:hover{ color:var(--ink); }
.nav__l:hover::after{ right:0; }
.nav__l.is-here{ color:var(--ink); }
.nav__l.is-here::after{ right:0; background:var(--ink-3); }

.topbar__end{ flex:0 0 auto; display:flex; align-items:center; gap:12px; }

.btn{
  display:inline-flex; align-items:center; gap:.6rem;
  padding:.6rem 1rem; min-height:38px;
  font:500 11.5px/1 var(--disp); letter-spacing:.01em;
  border:1px solid var(--line-2); color:var(--ink);
  background:none; cursor:pointer;
  transition:background .18s ease, border-color .18s ease;
}
.btn:hover{ border-color:var(--ink-3); background:rgb(255 255 255 / .06); }
.btn--primary{
  background:var(--signal); border-color:var(--signal); color:var(--on-signal);
  font-weight:700; min-height:46px; padding:.8rem 1.3rem; font-size:13px;
}
.btn--primary:hover{ background:#ff7d36; border-color:#ff7d36; }

.arw{
  width:14px; height:8px; flex:0 0 auto; background:currentColor;
  clip-path:polygon(0 45%,72% 45%,72% 0,100% 50%,72% 100%,72% 55%,0 55%);
  transition:transform .22s cubic-bezier(.2,.7,.2,1);
}
.btn:hover .arw{ transform:translateX(3px); }

.burger{
  display:none; width:44px; height:44px; padding:0;
  background:none; border:1px solid var(--line-2); cursor:pointer;
}
.burger span, .burger span::before, .burger span::after{
  display:block; width:16px; height:1px; background:var(--ink); margin-inline:auto;
  content:''; position:relative;
}
.burger span::before{ top:-5px; }
.burger span::after{ top:4px; }

/* ─────────────────────── station générique ─────────────────────── */
.st{
  position:relative;
  min-height:100svh;
  padding:var(--bar) var(--gut) clamp(28px,5vh,52px);
  display:flex; flex-direction:column; justify-content:center;
  isolation:isolate;
}

/* le cadre d'une scène : plein format, derrière le texte */
.field{ position:absolute; inset:0; z-index:0; overflow:hidden; }
.field__frame{
  position:absolute; inset:0; width:100%; height:100%;
  border:0; display:block; background:var(--void);
  opacity:0; transition:opacity .8s ease;
}
.field__frame.is-live{ opacity:1; }

.field__scrim{ position:absolute; inset:0; pointer-events:none; }

/* protège un titre posé à gauche */
.field__scrim--left{
  background:
    linear-gradient(to right,
      rgb(6 7 10 / .88) 0%, rgb(6 7 10 / .70) 26%, rgb(6 7 10 / .28) 48%, transparent 70%),
    linear-gradient(to bottom,
      rgb(6 7 10 / .55) 0%, transparent 18% 86%, rgb(6 7 10 / .55) 100%);
}
/* protège une bande de texte en bas */
.field__scrim--band{
  background:linear-gradient(to bottom,
    rgb(6 7 10 / .68) 0%, transparent 22% 52%,
    rgb(6 7 10 / .60) 82%, rgb(6 7 10 / .92) 100%);
}
/* la clôture : le champ recule derrière le formulaire */
.field__scrim--full{
  background:
    radial-gradient(70% 60% at 50% 52%, rgb(6 7 10 / .86) 0%, rgb(6 7 10 / .40) 60%, transparent 100%),
    linear-gradient(to bottom, rgb(6 7 10 / .78) 0%, transparent 26% 70%, rgb(6 7 10 / .9) 100%);
}

/* la ligne unique d'une station */
.line{
  position:relative; z-index:2; margin:0;
  font-weight:500; font-size:clamp(1.15rem,2.3vw,1.65rem);
  line-height:1.32; letter-spacing:-.02em; max-width:26ch;
  text-shadow:0 2px 30px rgb(6 7 10 / .85);
}

/* ═══════════ 01 · ouverture ═══════════ */
.open__t{
  position:relative; z-index:2; margin:0;
  max-width:min(26ch, 64vw);
  font-weight:700; font-size:clamp(2.3rem, 5.2vw, 4.25rem);
  line-height:1.02; letter-spacing:-.035em;
  text-shadow:0 2px 40px rgb(6 7 10 / .8);
}
.open__t span{ color:var(--ink-2); }


/* ═══════════ 02 · l'atelier ═══════════ */
/* La course de défilement pilote les trois actes de la scène, et c'est
   elle seule qui règle la sensibilité : page.js envoie p = -haut / course,
   où course = hauteur − 100svh. Allonger la hauteur ralentit la scène à
   défilement égal. Ici : 215 − 100 = 115svh de course.
   Voir la reprise au doigt plus bas, § pointeur grossier. */
.st--atelier{ position:relative; height:215svh; }
.atelier__stage{
  position:sticky; top:0; height:100svh;
  overflow:hidden; isolation:isolate;
}
.atelier__copy{
  position:absolute; z-index:2;
  left:var(--gut); right:var(--gut); bottom:clamp(30px,6vh,58px);
  display:grid; gap:clamp(16px,2.4vh,26px);
}
.acts{ display:grid; gap:9px; max-width:46ch; }
.act{
  display:grid; grid-template-columns:22px minmax(0,1fr); align-items:baseline;
  gap:0 12px;
  font:400 13.5px/1.5 var(--disp);
  color:var(--ink-3);
  transition:color .45s ease;
}
.act i{ height:1px; background:currentColor; display:block; transform:translateY(-4px); }
.act.is-on{ color:var(--ink); }
.act.is-on i{ background:var(--signal); }

/* ═══════════ 03 · domaines ═══════════ */
.st--dom{ padding-block:clamp(74px,14vh,150px); gap:clamp(28px,5vh,46px); }
.dom{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(215px,1fr));
  gap:1px; background:var(--line);
  border-block:1px solid var(--line);
}
.dom li{ background:var(--void); }
.dom a{
  display:block; height:100%;
  padding:clamp(22px,3.4vh,32px) clamp(18px,2vw,26px) clamp(26px,4vh,38px);
  transition:background .22s ease;
}
.dom a:hover{ background:rgb(255 255 255 / .028); }
.dom b{
  display:block; font-weight:700;
  font-size:clamp(1.3rem,2.3vw,1.75rem); letter-spacing:-.03em;
  margin-bottom:.42em;
}
.dom span{
  display:block; color:var(--ink-2);
  font-size:14px; line-height:1.55; max-width:26ch;
}
.dom a:hover b{ color:var(--ink); }

/* ═══════════ 04 · le modèle ═══════════ */
.st--net{ justify-content:flex-end; }
.line--net{ margin-bottom:clamp(6px,2vh,22px); }

/* ═══════════ 05 · souveraineté ═══════════ */
.st--sov{
  padding-block:clamp(110px,24vh,240px);
  align-items:flex-start;
  gap:clamp(16px,2.6vh,26px);
}
.sov__sub{
  margin:0;
  font:400 10px/1 var(--mono); letter-spacing:.18em;
  text-transform:uppercase; color:var(--ink-3);
}
.sov{
  margin:0; max-width:20ch;
  font-weight:700; font-size:clamp(1.9rem,4.4vw,3.4rem);
  line-height:1.06; letter-spacing:-.034em;
}

/* la crête : une seule ligne, l'horizon de Zermatt sous le texte.
   Le Cervin vit entre 23 et 65 % de la hauteur du bandeau : rien
   ne doit venir s'y poser. */
.crete{
  position:relative; align-self:stretch;
  height:clamp(150px,26vh,280px);
  margin-top:clamp(4px,1.6vh,18px);
}
@media (max-width:760px){ .crete{ height:clamp(120px,20vh,190px); } }

/* ═══════════ 06 · invitation ═══════════ */
.st--end{ justify-content:center; align-items:center; text-align:center; }
.end__in{ position:relative; z-index:2; display:grid; gap:clamp(26px,4.5vh,44px); justify-items:center; }
.line--end{ max-width:22ch; font-size:clamp(1.35rem,2.9vw,2.15rem); font-weight:700; letter-spacing:-.03em; }

.ask{ display:grid; gap:12px; justify-items:center; width:min(100%,520px); }
.ask__lab{
  font:400 9.5px/1 var(--mono); letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-3);
}
.ask__row{ display:flex; gap:10px; width:100%; flex-wrap:wrap; }
.ask__in{
  flex:1 1 220px; min-width:0;
  padding:.8rem 1rem; min-height:46px;
  background:rgb(6 7 10 / .6); color:var(--ink);
  border:1px solid var(--line-2);
  font:400 14px/1 var(--disp);
}
.ask__in::placeholder{ color:var(--ink-3); }
.ask__in:focus{ outline:none; border-color:var(--measure); }
.ask__in:focus-visible{ outline:2px solid var(--measure); outline-offset:2px; }

/* ─────────────────────────── pied ─────────────────────────── */
.foot{ border-top:1px solid var(--line); padding:clamp(38px,7vh,64px) var(--gut) clamp(34px,6vh,56px); }
.foot__in{ display:grid; gap:clamp(20px,3vh,30px); }
/* Pas d'opacite ici : elle se multipliait a celle du jeton de couleur
   et faisait tomber la ligne de service a 2,9:1. Les teintes sont
   posees directement, et tiennent le seuil AA. */
/* Au pied, la marque est plus petite mais garde ses proportions : seul le
   corps change, les rapports 34/86 et 20/86 suivent. */
.brand--foot{ --corps:18px; }
.brand--foot .brand__n{ color:var(--ink-2); }
/* Le pas vertical vient du remplissage des liens, pas de l'espacement
   de la grille : au doigt, une cible de 10 px de haut est intouchable.
   Meme traitement que le menu du haut, qui portait deja son padding. */
.foot__nav{ display:flex; flex-wrap:wrap; gap:0 clamp(14px,2vw,30px); margin-block:-7px; }
.foot__nav a{
  font:400 10px/1 var(--mono); letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink-3); transition:color .18s ease;
  padding-block:7px;            /* 10 + 14 = 24 px, le minimum WCAG 2.2 */
}
.foot__nav a:hover{ color:var(--ink-2); }
.foot__note{ margin:0; font:400 11px/1.6 var(--mono); letter-spacing:.06em; color:var(--ink-3); }

/* ─────────────────── moniteur de rendu (?mon=1) ─────────────────── */
.mon{
  position:fixed; right:12px; bottom:12px; z-index:60;
  background:color-mix(in srgb, #0b0e13 94%, transparent);
  border:1px solid var(--line-2); backdrop-filter:blur(8px);
  padding:9px 13px; display:none;
}
.mon.is-on{ display:block; }
.mon b{
  display:block; margin-bottom:6px;
  font:400 8.5px/1 var(--mono); letter-spacing:.18em;
  text-transform:uppercase; color:var(--ink-3); font-weight:400;
}
.mon div{ font:400 10.5px/1.75 var(--mono); letter-spacing:.04em; color:var(--ink-3); }
.mon .on{ color:var(--measure); }

/* ─────────────────────────── responsive ─────────────────────────── */
@media (max-width:900px){
  .topbar__in{ justify-content:space-between; }
  .burger{ display:block; }
  .topbar__end .btn{ display:none; }
  .nav{
    display:none; position:fixed; inset:var(--bar) 0 auto 0; z-index:39;
    flex-direction:column; gap:0; padding:4px var(--gut) 18px;
    background:color-mix(in srgb, var(--void) 96%, transparent);
    backdrop-filter:blur(16px); border-bottom:1px solid var(--line);
  }
  .nav.is-open{ display:flex; }
  .nav__l{ padding:16px 0; border-bottom:1px solid var(--line); font-size:11px; }
  .nav__l::after{ display:none; }
}

@media (max-width:640px){
  .open__t{ max-width:none; }
  .field__scrim--left{
    background:linear-gradient(to bottom,
      rgb(6 7 10 / .78) 0%, rgb(6 7 10 / .5) 42%, rgb(6 7 10 / .35) 70%, rgb(6 7 10 / .85) 100%);
  }
  .acts{ max-width:none; }
  .line{ max-width:none; }
}

/* ─── pointeur grossier : la course reprend ce que le doigt lui prend ───
   Au doigt, un seul geste emporte plusieurs hauteurs d'écran, là où une
   molette avance par crans. La course tactile est donc plus longue que
   celle du bureau : 150svh contre 115.

   Le test porte sur le POINTEUR, pas sur la largeur, et c'est tout le
   principe : la sensibilité dépend de la façon dont on fait défiler, pas
   de la taille de la fenêtre. Une tablette de 900 px se manipule au doigt
   et doit être ralentie ; une fenêtre de navigateur rétrécie sur un
   ordinateur garde sa molette et n'en a aucun besoin. `hover:none` écarte
   au passage les écrans tactiles pilotés à la souris.

   Il y avait ici, sous `max-width:640px`, une course raccourcie à 150svh
   de hauteur — 50svh de course seulement. Elle visait la densité de la
   scène en portrait, mais elle réglait en fait la sensibilité, et elle
   rendait le téléphone trois fois plus nerveux que l'écran de bureau.
   Elle est retirée : la largeur ne décide plus de rien ici. */
@media (hover:none) and (pointer:coarse){
  .st--atelier{ height:250svh; }
}

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *{ animation:none !important; transition-duration:.001ms !important; }
}

/* ============================================================
   PAGES INTÉRIEURES
   Même grammaire que l'accueil : filets à 1 px, étiquettes en
   mono, une seule scène par page et seulement quand elle dit
   quelque chose. Le texte porte, la 3D ponctue.
   ============================================================ */

.page{ padding:calc(var(--bar) + clamp(56px,11vh,124px)) var(--gut) 0; }
/* pas de max-width en ch sur le conteneur : l'unite se calcule sur 16 px
   et bridait le titre a moins de la moitie de sa largeur utile. */
.page__head{ display:grid; gap:clamp(14px,2.2vh,22px); }
.page h1{
  margin:0; font-weight:700; max-width:18em;
  font-size:clamp(2rem,4.4vw,3.4rem); line-height:1.02; letter-spacing:-.035em;
}
.page__lede{ margin:0; color:var(--ink-2); font-size:clamp(15.5px,1.5vw,17.5px); max-width:56ch; }

.band{
  padding-block:clamp(46px,8.5vh,96px);
  margin-top:clamp(46px,8.5vh,96px);
  border-top:1px solid var(--line);
}
.band > .lab{ display:block; margin-bottom:clamp(20px,3.4vh,34px); }
.band h2{
  margin:0 0 clamp(16px,2.6vh,26px); font-weight:700;
  font-size:clamp(1.4rem,2.8vw,2rem); line-height:1.06; letter-spacing:-.03em;
  max-width:24ch;
}
.band__lede{ margin:0 0 clamp(26px,4vh,40px); color:var(--ink-2); max-width:54ch; font-size:15.5px; }

/* ── grilles génériques ── */
.rows{ display:grid; gap:1px; background:var(--line); border-block:1px solid var(--line); }
.rows > *{ background:var(--void); }
/* Les filets ne viennent PAS du fond du conteneur qui transparaitrait
   dans les espaces : quand la derniere ligne est incomplete, les cellules
   vides laissent voir ce fond sur toute leur surface — un pave gris clair.
   Chaque cellule porte donc son propre liseré d'un pixel ; ceux de deux
   voisines se superposent exactement dans l'espace d'un pixel et n'en
   forment qu'un. Une cellule vide ne dessine rien. */
.cols{ display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:1px; }
.cols > *{
  background:var(--void);
  box-shadow:0 0 0 1px var(--line);
  padding:clamp(20px,3vh,28px) clamp(18px,2vw,26px);
}

/* ── solutions : quatre familles ── */
.fam{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.9fr);
  gap:clamp(18px,3vw,54px);
  padding:clamp(28px,4.6vh,44px) 0;
}
.fam h2{
  margin:0; font-weight:700;
  font-size:clamp(1.3rem,2.6vw,1.9rem); line-height:1.08; letter-spacing:-.03em;
  max-width:18ch;
}
.fam ul{ display:grid; gap:10px; align-content:start; }
.fam li{
  display:grid; grid-template-columns:18px minmax(0,1fr); gap:0 12px;
  align-items:baseline; color:var(--ink-2); font-size:14.5px;
}
.fam li::before{ content:''; height:1px; background:var(--measure); opacity:.55; transform:translateY(-4px); }

/* ── secteurs ── */
.sect b{ display:block; font-weight:700; font-size:1.15rem; letter-spacing:-.025em; margin-bottom:.35em; }
.sect span{ display:block; color:var(--ink-2); font-size:14px; line-height:1.55; }

/* ── approche : la séquence est réelle, donc numérotée ── */
.steps{ counter-reset:s; }
.step{
  display:grid; grid-template-columns:56px minmax(0,1fr);
  gap:0 clamp(14px,2.2vw,28px);
  padding:clamp(24px,4vh,38px) 0;
}
.step::before{
  counter-increment:s; content:"0" counter(s);
  font:400 11px/1.6 var(--mono); color:var(--ink-3);
}
.step h2{ margin:0 0 .45em; font-weight:700; font-size:clamp(1.15rem,2.2vw,1.5rem); letter-spacing:-.028em; }
.step p{ margin:0; color:var(--ink-2); font-size:15px; max-width:54ch; }

/* Les critères de preuve ne forment pas une séquence : les numéroter
   ferait croire à un ordre qui n'existe pas. Un tiret à la place. */
.crit{ counter-reset:none; }
.crit .step::before{ counter-increment:none; content:"—"; }

/* ── scène en bandeau (cône, nappe) ── */
.stage{
  position:relative;
  height:clamp(340px, 56svh, 560px);
  border:1px solid var(--line);
  overflow:hidden; isolation:isolate;
}
.stage__line{
  position:absolute; z-index:2; left:clamp(18px,2.2vw,30px); bottom:clamp(20px,3.4vh,32px);
  margin:0; max-width:26ch;
  font-weight:500; font-size:clamp(1.05rem,2vw,1.45rem);
  line-height:1.34; letter-spacing:-.02em;
  text-shadow:0 2px 30px rgb(6 7 10 / .85);
}

/* ── à propos ── */
/* Le portrait dessiné a été retiré de la page le 26.08.2026, à la demande
   de Lucas. Le bloc n'a donc plus de colonne d'identité : il se lit d'un
   seul tenant, le nom en tête et le texte dessous. Le fichier source vit
   toujours dans labo-3d/portrait-fe427333.svg si la question revient. */
.who{ display:grid; gap:clamp(18px,2.6vh,28px); }
.who__id b{ display:block; font-weight:700; font-size:clamp(1.3rem,2.4vw,1.7rem); letter-spacing:-.03em; }
.who__id span{ display:block; margin-top:.4em; font:400 10px/1 var(--mono); letter-spacing:.16em; text-transform:uppercase; color:var(--ink-3); }
.who__t{ display:grid; gap:1em; color:var(--ink-2); font-size:15.5px; max-width:58ch; }
.who__t b{ color:var(--ink); font-weight:500; }

/* ── contact ── */
.form{ display:grid; gap:clamp(16px,2.6vh,24px); max-width:640px; }
.f{ display:grid; gap:8px; }
.f label{ font:400 9.5px/1 var(--mono); letter-spacing:.16em; text-transform:uppercase; color:var(--ink-3); }
.f input, .f textarea, .f select{
  padding:.85rem 1rem; min-height:48px;
  background:rgb(255 255 255 / .03); color:var(--ink);
  border:1px solid var(--line-2); border-radius:0;
  font:400 15px/1.5 var(--disp); width:100%;
}
.f textarea{ min-height:150px; resize:vertical; }
.f input::placeholder, .f textarea::placeholder{ color:var(--ink-3); }
/* Un filet d'un pixel qui change de teinte ne fait pas un indicateur de
   focus : WCAG 2.2 (2.4.11) demande une surface et un contraste tenus.
   Le filet reste pour la souris, l'anneau apparait au clavier. */
.f input:focus, .f textarea:focus, .f select:focus{ outline:none; border-color:var(--measure); }
.f input:focus-visible, .f textarea:focus-visible, .f select:focus-visible{
  outline:2px solid var(--measure); outline-offset:2px;
}
.f2{ display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:clamp(14px,2vw,20px); }
.form__note{ margin:0; color:var(--ink-3); font-size:13px; max-width:52ch; }
.form__note a{ color:var(--measure); }

.direct{ display:grid; gap:14px; align-content:start; }
/* Lien isole, donc soumis a la taille de cible : il ne beneficie pas
   de l'exception des liens en pleine phrase. */
.direct a{ color:var(--measure); font:400 14px/1.5 var(--mono); letter-spacing:.02em;
  display:inline-block; padding-block:3px; }
.direct a:hover{ text-decoration:underline; }

/* Lien en pleine phrase : la couleur seule ne suffit pas (WCAG 1.4.1).
   Soulignement discret, decale, qui s'affirme au survol. */
.art a, .consent span a, .form__note a, .page__lede a, p a{
  text-decoration:underline;
  text-underline-offset:.22em;
  text-decoration-thickness:1px;
  text-decoration-color:color-mix(in srgb, currentColor 45%, transparent);
}
.art a:hover, .consent span a:hover, .form__note a:hover, p a:hover{
  text-decoration-color:currentColor;
}

/* ── pages légales : les articles sont une séquence ── */
.legal{ counter-reset:c; max-width:70ch; }
.art{
  display:grid; grid-template-columns:48px minmax(0,1fr);
  gap:0 clamp(14px,2.2vw,26px);
  padding:clamp(22px,3.6vh,32px) 0;
  border-top:1px solid var(--line);
}
.art::before{
  counter-increment:c; content:"0" counter(c);
  font:400 11px/1.7 var(--mono); color:var(--ink-3);
}
.art h2{ margin:0 0 .5em; font-weight:700; font-size:1.15rem; letter-spacing:-.025em; max-width:none; }
.art p{ margin:0; color:var(--ink-2); font-size:14.5px; }
.art p + p{ margin-top:.7em; }
.art a{ color:var(--measure); }
.art b{ color:var(--ink); font-weight:500; }
.art code{ font:400 13px/1 var(--mono); color:var(--measure); }

/* ── pied de page des pages intérieures ── */
.page + .foot, .band + .foot{ margin-top:clamp(46px,8.5vh,96px); }

@media (max-width:760px){
  .fam{ grid-template-columns:1fr; }
  .step{ grid-template-columns:40px minmax(0,1fr); }
  .art{ grid-template-columns:34px minmax(0,1fr); }
}

/* le filet de la bande et celui de la première rangée se superposaient */
.band > .rows:first-of-type{ border-top:0; }
.band > .legal .art:first-child{ border-top:0; }

/* ── solutions : chaque famille porte son objet, encadré comme le cône ── */
.fam{ align-items:center; }
.fam__obj{
  position:relative; overflow:hidden;
  height:clamp(250px, 34svh, 340px);
  border:1px solid var(--line);
}
.fam__txt{ display:grid; gap:clamp(14px,2.2vh,20px); align-content:center; }
@media (max-width:760px){
  .fam__obj{ height:clamp(220px, 30svh, 280px); }
}

/* ── solutions : les familles alternent, l'objet passe d'un côté à l'autre ──
   Le rythme casse l'effet d'échelle d'une colonne d'objets tous alignés. */
.fam:nth-of-type(even) .fam__obj{ grid-column:2; grid-row:1; }
.fam:nth-of-type(even) .fam__txt{ grid-column:1; grid-row:1; }

@media (max-width:760px){
  /* en colonne unique, l'alternance n'a plus de sens : l'objet reprend sa place */
  .fam:nth-of-type(even) .fam__obj,
  .fam:nth-of-type(even) .fam__txt{ grid-column:auto; grid-row:auto; }
}

/* ── contraste : --ink-3 à 34 % donnait 2,82:1, sous le seuil AA de 4,5 ──
   48 % le porte à 4,61:1. Concerne les étiquettes mono, les libellés de
   formulaire et les numéros d'article — tous du texte, donc tous soumis. */
:root{ --ink-3:rgb(242 245 247 / .48); }

/* pot de miel : hors écran, jamais masqué par display:none (les robots le lisent) */
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

.consent{ display:grid; grid-template-columns:22px minmax(0,1fr); gap:0 12px; align-items:start; cursor:pointer; }
.consent input{ width:22px; height:22px; margin:0; accent-color:var(--signal); }
.consent span{ color:var(--ink-2); font-size:13.5px; line-height:1.55; }
.consent a{ color:var(--measure); }

/* ═══════════ impression ═══════════
   Les pages légales et la fiche de contact sont ce qu'on imprime ou
   ce qu'on enregistre en PDF. Sur papier, le fond noir coûte de l'encre
   et les scènes 3D ne veulent rien dire : on rend un document lisible,
   et on donne les adresses des liens, qui deviennent sinon invisibles. */
@media print{
  :root{ --void:#fff; --ink:#111; --ink-2:#333; --ink-3:#555;
         --line:#ccc; --line-2:#999; }
  html,body{ background:#fff; color:#111; }
  .topbar, .burger, .skip, .field, .crete, .stage, .mon,
  .btn, .ask, .form, .foot__nav{ display:none !important; }
  .st, .page, .band{ min-height:0; padding-block:0 1.2cm; page-break-inside:avoid; }
  h1,h2,h3{ page-break-after:avoid; }
  a{ color:#111; text-decoration:underline; }
  /* Une adresse imprimée sans son lien ne mène nulle part. */
  .art a[href^="http"]::after, .art a[href^="mailto"]::after,
  .legal a[href^="http"]::after, .legal a[href^="mailto"]::after{
    content:" (" attr(href) ")"; font-size:.85em; color:#555; word-break:break-all;
  }
  .foot{ border-top:1px solid #ccc; }
  .foot__note{ color:#555; }
}
