/* ==========================================================================
   Botrophée — refonte 2026
   Concept : la lettre gravée. Filets « incisés », capitales lapidaires,
   or de marque en accent rare, anthracite de marque en fond.
   ========================================================================== */

:root{
  /* Couleurs — dérivées de la charte existante Botrophée */
  --ivory:#F6F5F3;
  --white:#FFFFFF;
  --ink:#16191B;
  --anthracite:#313538;
  --grey:#6B7073;
  --grey-l:#9A9EA1;
  --line:#E2DFDA;
  /* L'or est déclaré DEUX fois : en hexadécimal pour l'usage courant, et en
     composantes pour les variantes translucides. Sans ça, la valeur se
     recopiait à la main dans quatre `rgba()` disséminés, qu'un changement de
     teinte laissait en arrière. */
  --gold-rgb:240 182 10;
  --gold:rgb(var(--gold-rgb));
  --gold-soft:rgb(var(--gold-rgb) / .14);
  --gold-d:#D3A00C;         /* survol : même teinte, six points plus sombre */
  --brass:#876707;          /* or assombri : lisible sur fond clair */

  /* Type */
  --disp:'Marcellus',ui-serif,Georgia,serif;
  --sans:'Instrument Sans',system-ui,-apple-system,'Segoe UI',sans-serif;

  /* Rythme */
  --wrap:1240px;
  --pad:2rem;
  --sec:clamp(5.5rem,10vw,9.5rem);
  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:5.5rem;
  /* `clip` plutôt que `hidden` : garde-fou anti-débordement qui ne transforme
     pas l'élément en conteneur de défilement — l'en-tête collant continue donc
     de réagir à window.scrollY. */
  overflow-x:clip;
}
body{
  margin:0;background:var(--white);color:var(--anthracite);
  font-family:var(--sans);font-size:1rem;line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3{margin:0;font-family:var(--disp);font-weight:400;letter-spacing:-.012em;line-height:1.06}
p{margin:0}
ul,ol,dl,dd{margin:0;padding:0;list-style:none}

:focus-visible{outline:2px solid var(--brass);outline-offset:3px;border-radius:2px}

.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--ink);color:#fff;padding:.75rem 1.25rem}
.skip:focus{left:1rem;top:1rem}

.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:var(--pad)}

/* ── Filet incisé : la signature structurelle ─────────────────────────── */
.section{padding-block:var(--sec);position:relative}
.section::before{
  content:"";position:absolute;inset-inline:var(--pad);top:0;height:1px;
  background:var(--line);box-shadow:0 1px 0 rgba(255,255,255,.85);
}
.section--ivory{background:var(--ivory)}
.section--ivory::before{box-shadow:none}
.section--dark{background:var(--anthracite);color:#EDECEA}
.section--dark::before{background:rgba(255,255,255,.14);box-shadow:0 1px 0 rgba(0,0,0,.45)}

/* ── Sur-titres ───────────────────────────────────────────────────────── */
.eyebrow{
  display:flex;align-items:center;gap:.7rem;margin-bottom:1.5rem;
  font-size:.6875rem;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:var(--brass);
}
.eyebrow::before{content:"";width:2rem;height:2px;background:var(--gold);flex:none}
.eyebrow--on-dark{color:var(--gold)}

/* ── Boutons ──────────────────────────────────────────────────────────── */
.btn{
  --bg:var(--ink);--fg:#fff;--bd:var(--ink);
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  padding:.8rem 1.4rem;border:1px solid var(--bd);background:var(--bg);color:var(--fg);
  font-family:var(--sans);font-size:.8125rem;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;cursor:pointer;white-space:nowrap;
  transition:background .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease),transform .3s var(--ease);
}
.btn--lg{padding:1.05rem 2rem;font-size:.8125rem}
.btn--full{width:100%}
.btn--gold{--bg:var(--gold);--fg:#241900;--bd:var(--gold)}
.btn--gold:hover{--bg:var(--gold-d);--bd:var(--gold-d)}
.btn--ghost{--bg:transparent;--fg:var(--anthracite);--bd:var(--line)}
.btn--ghost:hover{--bd:var(--anthracite)}
.btn:active{transform:translateY(1px)}

/* ── Logotype ─────────────────────────────────────────────────────────
   « CONCEPTION LETTRAGE » en Marcellus très espacé, « BOTROPHÉE » en dessous
   entre deux filets or terminés par un losange. Tout se centre sur un même
   axe, et les filets s'arrêtent exactement à l'aplomb des lettres du dessus.
   Aucun élément de balisage ajouté : les filets sont deux pseudo-éléments.
   --------------------------------------------------------------------- */
/* Une seule mesure commande tout le verrou : `--fs`. Le second rang, les
   filets, les losanges et tous les écarts en dérivent, si bien que changer
   `--fs` — c'est ce que fait le pied de page — redimensionne le logo sans
   jamais en déformer les proportions.
   `width:max-content` : dans l'en-tête, `flex:none` suffisait à coller le bloc
   à son texte, mais le pied de page le place dans une cellule de grille où il
   s'étirait sur toute la colonne. */
.mark{
  --fs:clamp(1rem,1.5vw,1.45rem);
  display:flex;flex-direction:column;align-items:center;
  width:max-content;line-height:1;flex:none;
}
/* La marge NÉGATIVE annule l'écart que l'interlettrage ajoute APRÈS la
   dernière lettre. Sans elle, la boîte dépasse les lettres d'un cran à droite :
   tout ce qui se centre là-dessous se retrouve décalé, et les filets
   finiraient au-delà du « E » de LETTRAGE au lieu de tomber pile dessous. */
.mark__name{
  font-family:var(--disp);font-size:var(--fs);
  letter-spacing:.16em;margin-right:-.16em;text-transform:uppercase;
}
/* Second rang dans la MÊME police que le premier — c'est ce qui donne au
   verrou son unité — à 58 % de sa taille, très largement interlettré.
   `padding-inline` retient les filets en deçà des lettres du dessus : dans le
   modèle, le rang or n'atteint pas les bords, il s'inscrit dedans. */
.mark__sub{
  --tr:.58em;
  display:flex;align-items:center;align-self:stretch;
  padding-inline:1.9em;gap:1.35em;margin-top:.34em;
  font-family:var(--disp);font-size:calc(var(--fs) * .58);
  letter-spacing:var(--tr);text-transform:uppercase;color:var(--brass);
  transition:letter-spacing .5s var(--ease);
}
/* Le trait et le losange sont un MASQUE, pas une image : la couleur vient de
   `currentColor`, donc l'ornement suit le laiton du texte et aucune valeur
   n'est figée dans le SVG.
   `flex:1 1 0` + `min-width:0` : les filets prennent ce qui reste et ne pèsent
   rien dans la largeur naturelle du bloc — c'est la ligne du dessus qui la
   commande, jamais l'inverse. */
.mark__sub::before,.mark__sub::after{
  content:"";flex:1 1 0;min-width:0;height:.5em;background:currentColor;
  --masque:
    linear-gradient(#000,#000) left center/calc(100% - .35em) 1px no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 7'%3E%3Cpath d='M3.5 0 7 3.5 3.5 7 0 3.5Z'/%3E%3C/svg%3E") right center/.5em .5em no-repeat;
  -webkit-mask:var(--masque);mask:var(--masque);
}
/* Le losange doit pointer vers le texte : le filet de droite est le miroir
   exact de celui de gauche, pas une seconde règle à maintenir. */
.mark__sub::after{transform:scaleX(-1)}
/* Correction optique. Le texte est centré entre deux filets égaux, mais son
   écart de queue le décale d'autant vers la gauche : on rend cet écart au
   filet de gauche. Il vaut `--tr`, donc il suit l'interlettrage au survol. */
.mark__sub::before{margin-right:var(--tr);transition:margin-right .5s var(--ease)}
/* Au survol, l'interlettrage s'ouvre. Les filets absorbent la différence :
   la largeur du logo ne bouge pas d'un pixel et rien ne se recompose. */
/* `a.mark` et non `.mark` : le verrou sert aussi de titre dans la section
   « À propos », où il n'est pas cliquable. Une réaction au survol y
   promettrait une action qui n'existe pas. */
a.mark:hover .mark__sub,
a.mark:focus-visible .mark__sub{--tr:.7em}

/* Sur fond sombre les deux encres s'inversent : le nom passe au blanc, et le
   second rang à l'or vif — le laiton, taillé pour le fond clair, n'y tiendrait
   pas le contraste (2,3:1 contre 6,7:1). */
.mark--dark .mark__name{color:#fff}
.mark--dark .mark__sub{color:var(--gold)}

/* ── En-tête ──────────────────────────────────────────────────────────── */
.hdr{position:fixed;inset:0 0 auto;z-index:100;transition:background .35s var(--ease),box-shadow .35s var(--ease)}
.hdr__in{
  max-width:var(--wrap);margin-inline:auto;padding:1.5rem var(--pad);
  display:flex;align-items:center;gap:2rem;transition:padding .35s var(--ease);
}
.hdr.is-stuck{background:rgba(255,255,255,.92);backdrop-filter:blur(14px);box-shadow:0 1px 0 var(--line)}
.hdr.is-stuck .hdr__in{padding-block:.9rem}

.nav{display:flex;align-items:center;gap:2.1rem;margin-left:auto}
.nav>a:not(.btn){
  position:relative;font-size:.875rem;font-weight:500;padding-block:.35rem;
  transition:color .25s var(--ease);
}
.nav>a:not(.btn)::after{
  content:"";position:absolute;left:0;bottom:0;width:100%;height:1px;
  background:var(--gold);transform:scaleX(0);transform-origin:left;
  transition:transform .35s var(--ease);
}
.nav>a:not(.btn):hover::after{transform:scaleX(1)}
.nav__cta{display:none}
.hdr__cta{flex:none}
.burger{display:none}

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero{padding-top:clamp(8rem,15vw,11.5rem);padding-bottom:clamp(4rem,8vw,7rem);background:var(--white)}
.hero__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.02fr);gap:clamp(2.5rem,6vw,5.5rem);align-items:center}
.hero__h1{font-size:clamp(2.7rem,6.1vw,4.9rem);letter-spacing:-.02em}
.hero__sub{max-width:34ch;margin-top:1.6rem;font-size:1.0625rem;color:var(--grey);line-height:1.7}
/* Une colonne de grille en `max-content` : sa largeur est celle du PLUS LARGE
   des deux libellés, et les deux boutons s'y étirent. Ils se retrouvent donc
   à la même taille sans qu'aucune valeur ne soit écrite en dur — changer un
   texte réaccorde les deux. En flex, chacun gardait sa largeur de contenu. */
.hero__act{display:grid;grid-template-columns:max-content;gap:.75rem;margin-top:2.4rem}

.hero__facts{display:flex;flex-wrap:wrap;gap:2.5rem;margin-top:3.5rem;padding-top:1.75rem;position:relative}
.hero__facts::before{content:"";position:absolute;inset-inline:0;top:0;height:1px;background:var(--line);box-shadow:0 1px 0 #fff}
.hero__facts dt{font-family:var(--disp);font-size:1.35rem;line-height:1}
.hero__facts dt sup{font-size:.55em;vertical-align:super}
.hero__facts dd{margin-top:.3rem;font-size:.75rem;letter-spacing:.11em;text-transform:uppercase;color:var(--grey)}

/* Vitrine : deux panneaux en 7/10, décalés et légèrement superposés.
   Grille de 24 colonnes plutôt que deux colonnes égales : posés côte à côte,
   chaque panneau serait limité à la moitié de la largeur et le bloc perdrait
   un cinquième de sa hauteur. En se chevauchant sur deux colonnes, ils font
   respectivement 15/24 et 11/24 — soit plus large chacun que la moitié. */
.hero__vis{position:relative;display:grid;grid-template-columns:repeat(24,1fr)}
/* Ombre portée en trois couches : un contact serré qui pose la photo sur la
   page, une diffusion moyenne, puis une nappe large et très pâle. Une seule
   couche donnerait soit un liseré dur, soit un halo flou — c'est l'empilement
   qui fait la profondeur. Teinte prise sur --ink et non sur du noir pur :
   sur l'ivoire, un noir franc vire au gris sale.
   L'ombre est portée par .pane et non par .pane::after, qui est en overflow
   caché et la rognerait au ras du cadre. */
.pane{
  margin:0;position:relative;overflow:hidden;background:var(--ivory);
  box-shadow:
    0 3px 8px rgba(22,25,27,.20),
    0 16px 30px -2px rgba(22,25,27,.34),
    0 40px 74px -4px rgba(22,25,27,.46);
}

/* Les panneaux portent `data-rise` : leur transition vient de la règle de
   révélation, qui ignore box-shadow et impose un retard échelonné à toutes
   les propriétés — l'ombre du second panneau serait arrivée une demi-seconde
   après le curseur. On redéclare donc ici, avec plus de spécificité, un
   retard par propriété : différé pour l'entrée, nul pour l'ombre.
   Le décalage de l'entrée passe par --d, puisqu'on écrase transition-delay. */
.hero__vis .pane{
  --d:0s;
  transition:
    opacity .8s var(--ease) var(--d),
    transform .8s var(--ease) var(--d),
    box-shadow .55s var(--ease) 0s;
}
/* Préfixés par .hero__vis, sinon le `--d:0s` de la règle ci-dessus, plus
   spécifique, l'emporterait et les deux panneaux entreraient d'un coup. */
.hero__vis .pane--a{--d:.16s}
.hero__vis .pane--b{--d:.32s}
.pane img{width:100%;height:100%;object-fit:cover;transform:scale(var(--z,1));transition:transform 1.1s var(--ease)}
.pane::after{content:"";position:absolute;inset:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.07);pointer-events:none}
/* Même rangée : c'est ce qui autorise le recouvrement. Le second panneau
   vient après dans le DOM, il passe donc au-dessus — son ombre tombe sur le
   premier, ce qui est le bon sens de lecture.
   Le décalage est en pourcentage : il se résout sur la largeur du conteneur
   et reste donc proportionnel à toutes les tailles d'écran. */
.pane--a{grid-area:1/1/2/16;aspect-ratio:7/10}
.pane--b{grid-area:1/14/2/25;aspect-ratio:7/10;margin-top:30%}
.hero__vis:hover .pane img{transform:scale(calc(var(--z,1) * 1.03))}
/* Même déclencheur que le zoom ci-dessus : la vitrine réagit d'un bloc.
   Ombre seule, pas de déplacement : `transform` sert déjà à la révélation,
   le surcharger ici ferait sauter les panneaux au survol pendant l'entrée. */
.hero__vis:hover .pane{
  box-shadow:
    0 4px 10px rgba(22,25,27,.22),
    0 22px 42px -2px rgba(22,25,27,.38),
    0 56px 96px -6px rgba(22,25,27,.52);
}

/* ── En-têtes de section ──────────────────────────────────────────────── */
.shead{margin-bottom:clamp(3rem,5vw,4.5rem);max-width:none}
.shead__h{font-size:clamp(2.1rem,4.3vw,3.5rem)}
.shead__p{max-width:46ch;margin-top:1.4rem;color:var(--grey);font-size:1.0625rem}
.shead--row{display:grid;grid-template-columns:1fr auto;gap:2.5rem;align-items:end}
.shead__p--tight{max-width:38ch;margin-top:0;text-align:right}
.shead--mid{text-align:center;max-width:34rem;margin-inline:auto}
.shead--mid .eyebrow{justify-content:center}

/* ── À propos : deux générations ──────────────────────────────────────
   L'en-tête de section est mutualisé avec les sections claires ; seules les
   couleurs changent ici, le fond anthracite renversant le contraste.
   --------------------------------------------------------------------- */
.section--dark .shead__h{color:#fff}
.section--dark .shead__p{color:#C7C9CA}

/* Aucun encadré, aucune ombre : la hiérarchie tient à la police et au vide.
   L'écart entre les deux colonnes reste inférieur à celui des sections
   voisines — rapprochées, elles se lisent comme un diptyque. */
/* L'écart et la couleur du tracé sont nommés : le raccord du volet de fusion
   a besoin de l'un pour retrouver l'axe des colonnes, et de l'autre pour que
   les filets sous les portraits et les traits du raccord soient la même
   encre (voir plus bas). */
.gens{
  --gap:clamp(2rem,4.5vw,3.5rem);
  --trait:rgb(var(--gold-rgb) / .8);
  /* Le halo : deux ombres portées sur la forme peinte, une serrée pour le
     contact, une large pour la diffusion. `drop-shadow` et non `box-shadow` —
     l'ombre doit épouser le trait, pas la boîte qui le contient. Elle ne peut
     donc pas cohabiter avec un masque : le masque s'applique APRÈS le filtre
     et découperait le halo. D'où des traits peints en dégradés, pas masqués. */
  --halo:drop-shadow(0 0 2px rgb(var(--gold-rgb) / .5))
         drop-shadow(0 0 7px rgb(var(--gold-rgb) / .28));
  display:grid;grid-template-columns:1fr 1fr;gap:var(--gap);
}
/* Le filet sous chaque portrait. Un pseudo-élément et non une bordure : une
   bordure ne prend pas de dégradé, et il en faut un — le trait s'allume au
   milieu de la colonne, là où part la descente, et s'éteint aux deux bouts.
   Les colonnes s'étirent à la hauteur de la rangée, les filets tombent donc
   au même niveau même quand un texte est plus court. */
.gens > .gen:not(.gen--fusion){
  position:relative;
  padding-bottom:clamp(1.25rem,2.5vw,1.9rem);
}
.gens > .gen:not(.gen--fusion)::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(to right,
    rgb(var(--gold-rgb) / 0), rgb(var(--gold-rgb) / .8) 50%, rgb(var(--gold-rgb) / 0));
  filter:var(--halo);
}
.gen__n{font-family:var(--disp);font-size:clamp(1.5rem,2.6vw,2rem);line-height:1.15;color:#fff}
.gen__r{margin-top:.85rem;font-size:.6875rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.gen__y{margin-top:.4rem;font-size:.8125rem;letter-spacing:.05em;color:#8E9294}
.gen__p{margin-top:1.35rem;max-width:46ch;color:#C7C9CA;font-size:1rem;line-height:1.75}

/* Le volet de fusion traverse les deux colonnes et se centre : les portraits
   racontent chacun une maison, celui-ci ce qu'elles sont devenues ensemble.
   Le texte s'élargit un peu mais reste borné : au-delà d'une soixantaine de
   signes, l'œil perd la ligne suivante. */
.gen--fusion{
  --con:clamp(2.2rem,4vw,3.2rem);          /* longueur du raccord sous l'écart */
  grid-column:1/-1;position:relative;text-align:center;
  margin-top:0;                            /* l'écart de grille suffit */
  padding-top:calc(var(--con) + clamp(1.5rem,3vw,2.4rem));
}
.gen--fusion .gen__p{max-width:62ch;margin-inline:auto}
/* Le titre devient un logo : il perd ses propres réglages de police, qui
   viendraient contredire ceux du verrou. `--fs` est posé sur `.mark` et non
   sur le titre — déclaré sur l'élément lui-même, celui de `.mark` l'emporterait
   sur une valeur seulement héritée. */
.gen__n--logo{font:inherit;line-height:1}
.gen__n--logo .mark{--fs:clamp(1.15rem,2.2vw,1.75rem);margin-inline:auto}
.gen--fusion .gen__y{margin-top:.9rem}

/* ── Le raccord ───────────────────────────────────────────────────────
   Tracé orthogonal : deux descentes depuis l'axe des colonnes, une traverse
   qui les relie, une descente centrale vers le bloc.
   Chaque segment est un CALQUE de fond distinct, avec son propre dégradé le
   long de sa longueur. Les descentes ne font qu'un pixel de large : leur
   position en pourcentage se résout donc presque exactement, et leur dégradé
   peut courir à la verticale — ce qu'un tracé dessiné en arrêts nets sur une
   seule couche horizontale ne permettait pas.
   L'intensité monte vers le bas : le tracé s'allume à mesure qu'il approche
   du bloc qu'il désigne.
   `top` négatif d'un écart de grille : le tracé démarre exactement sous les
   filets des portraits, sans quoi il flotterait 56 px plus bas.
   --------------------------------------------------------------------- */
.gen--fusion::before{
  content:"";position:absolute;left:0;right:0;
  top:calc(var(--gap) * -1);
  height:calc(var(--gap) + var(--con));
  /* PAS 25 % : l'écart de grille sépare les deux colonnes, leur axe tombe donc
     à un quart de la largeur MOINS un quart de cet écart. À 1440 px la
     différence est de 14 px — assez pour que la descente rate sa colonne. */
  --x1:calc(25% - var(--gap) / 4);
  --x2:calc(75% + var(--gap) / 4);
  --descente:linear-gradient(to bottom, rgb(var(--gold-rgb) / .1), rgb(var(--gold-rgb) / .8));
  background:
    var(--descente) var(--x1) 0 / 1px 50% no-repeat,
    var(--descente) var(--x2) 0 / 1px 50% no-repeat,
    linear-gradient(to right,
      rgb(var(--gold-rgb) / 0) var(--x1),
      rgb(var(--gold-rgb) / .4) calc(var(--x1) + 1px),
      rgb(var(--gold-rgb) / .85) 50%,
      rgb(var(--gold-rgb) / .4) calc(var(--x2) - 1px),
      rgb(var(--gold-rgb) / 0) var(--x2)) 0 calc(50% - .5px) / 100% 1px no-repeat,
    linear-gradient(to bottom, rgb(var(--gold-rgb) / .85), rgb(var(--gold-rgb) / 1))
      50% 100% / 1px 50% no-repeat;
  filter:var(--halo);
}
/* La pointe : un carré dont on ne garde que deux côtés, tourné d'un quart de
   tour. Elle reste à taille fixe — une pointe étirée n'en est plus une. */
.gen--fusion::after{
  content:"";position:absolute;left:50%;
  top:calc(var(--con) - 11px);margin-left:-5px;
  width:9px;height:9px;transform:rotate(45deg);
  border-right:1.5px solid var(--trait);border-bottom:1.5px solid var(--trait);
  filter:var(--halo);
}

/* ── Galerie réalisations : onglets par catégorie ─────────────────────── */
.tabs{
  display:flex;flex-wrap:wrap;gap:clamp(1.4rem,3.2vw,2.8rem);
  margin-bottom:clamp(2rem,3.5vw,3rem);
  border-bottom:1px solid var(--line);box-shadow:0 1px 0 rgba(255,255,255,.85);
}
.tab{
  position:relative;appearance:none;-webkit-appearance:none;background:none;border:0;
  padding:0 0 1.05rem;cursor:pointer;font-family:var(--sans);
  font-size:.75rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--grey);transition:color .3s var(--ease);
}
/* Le trait actif s'aligne sur le filet du conteneur : `bottom:0` plutôt que
   `-1px`, sinon le défilement horizontal du mobile le rogne. */
.tab::after{
  content:"";position:absolute;inset-inline:0;bottom:0;height:2px;background:var(--gold);
  transform:scaleX(0);transform-origin:left;transition:transform .45s var(--ease);
}
.tab:hover,.tab[aria-selected="true"]{color:var(--ink)}
.tab[aria-selected="true"]::after{transform:scaleX(1)}

/* `.panel` porte aussi `.grid` (display:grid) : le sélecteur d'attribut est
   plus spécifique et l'emporte donc sur l'affichage de la grille. */
.panel[hidden]{display:none}
.panel{animation:panelIn .55s var(--ease) both}
/* Décalage négatif : le panneau est maintenant en overflow:hidden, un
   contour posé à l'extérieur serait rogné et invisible au clavier. */
.panel:focus-visible{outline:2px solid var(--gold);outline-offset:-2px}
@keyframes panelIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* ── Bandes défilantes ────────────────────────────────────────────────
   Deux rangées par catégorie, en sens opposés. Chaque rangée contient
   deux jeux d'images identiques et se translate de -50 %, soit exactement
   un jeu : au bout de l'animation le second jeu occupe la place du
   premier, la boucle est invisible.
   Le -50 % n'est juste que si l'écart entre les deux jeux est le même
   qu'entre deux images. D'où le `padding-right` sur `.mq__set` plutôt
   qu'un `gap` sur la rangée : chaque jeu embarque son propre écart de
   fin, les deux moitiés font donc rigoureusement la même largeur.
   --------------------------------------------------------------------- */
.mq{--mq-gap:clamp(.6rem,1.2vw,1rem);--mq-h:clamp(190px,26vw,300px);
  display:grid;gap:var(--mq-gap);overflow:hidden}
.mq__row{display:flex;width:max-content;animation:mqDefile calc(var(--n) * 2.6s) linear infinite}
.mq__row--rev{animation-direction:reverse}
.mq__set{display:flex;gap:var(--mq-gap);padding-right:var(--mq-gap)}
@keyframes mqDefile{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* Survol : on fige. La consigne d'origine ralentissait ; en CSS un
   changement de durée provoque un saut, alors qu'une pause est nette et
   laisse vraiment regarder la pièce. Le survol porte sur toute la bande,
   sinon la photo visée s'échapperait sous le curseur. */
.mq:hover .mq__row{animation-play-state:paused}

.mq__i{
  margin:0;position:relative;overflow:hidden;flex:0 0 auto;
  height:var(--mq-h);background:var(--ivory);
}
.mq__i img{display:block;width:auto;height:100%;transition:transform .8s var(--ease)}
.mq__i::after{content:"";position:absolute;inset:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.07);pointer-events:none}
.mq__i figcaption{
  position:absolute;inset:auto 0 0;padding:2.5rem 1rem 1rem;color:#fff;
  background:linear-gradient(to top,rgba(22,25,27,.88),rgba(22,25,27,0));
  opacity:0;transform:translateY(8px);transition:opacity .4s var(--ease),transform .4s var(--ease);
}
.mq__i:hover img{transform:scale(1.05)}
.mq__i:hover figcaption{opacity:1;transform:none}
.mq__t{display:block;font-family:var(--disp);font-size:1rem;line-height:1.25}
.mq__c{display:block;margin-top:.3rem;font-size:.625rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}

/* Les vignettes ouvrent l'agrandissement : elles deviennent cliquables, et
   celles du premier jeu deviennent aussi des boutons pour le clavier (voir
   main.js — le jeu dupliqué reste `aria-hidden`, donc hors tabulation). */
.mq__i{cursor:zoom-in}
.mq__i:focus-visible{outline:2px solid var(--gold);outline-offset:-2px}

/* ── Sortie du carrousel : toute la catégorie en grille ───────────────
   Aucune image n'est dupliquée ni reconstruite en JavaScript. Les rangées
   et les jeux passent en `display:contents` : ils s'effacent de la mise en
   page et leurs figures deviennent directement les cases de la grille. Il
   ne reste qu'à masquer le jeu en double — celui qui ne sert qu'à boucler.
   --------------------------------------------------------------------- */
.gal__all{margin-top:clamp(1.75rem,3.5vw,2.5rem);display:flex;justify-content:center}
.mq.is-grid{
  grid-template-columns:repeat(auto-fill,minmax(clamp(130px,17vw,190px),1fr));
  overflow:visible;
}
.mq.is-grid .mq__row,
.mq.is-grid .mq__set{display:contents}
/* `display:contents` ne suffit pas à arrêter le défilement : la rangée ne
   dessine plus rien, mais son animation infinie continue de tourner. */
.mq.is-grid .mq__row{animation:none}
.mq.is-grid .mq__set[aria-hidden="true"]{display:none}
/* En grille, la hauteur ne commande plus : c'est la colonne qui fixe la
   largeur, et le rapport 7/10 des vignettes qui fixe la hauteur. */
.mq.is-grid .mq__i{height:auto;aspect-ratio:7/10}
.mq.is-grid .mq__i img{width:100%;height:100%;object-fit:cover}

/* ── Agrandissement ───────────────────────────────────────────────────
   Une fenêtre claire posée sur le fond assombri, comme une pièce encadrée :
   carton blanc, photo montée dans son passe-partout ivoire, cartel dessous.
   Le contraste s'inverse donc à l'intérieur — encre sur blanc — pendant que
   les commandes, elles, restent blanches sur le fond sombre autour.
   `max-height` porte sur la photo et non sur le dialogue : c'est elle qui
   doit tenir à l'écran, le cartel se plaçant dessous quelle que soit sa
   proportion. `dvh` suit la barre d'adresse mobile, qui se rétracte.
   --------------------------------------------------------------------- */
.lb{
  width:min(92vw,1040px);max-width:none;max-height:none;
  padding:0;border:0;background:none;color:var(--ink);overflow:visible;
}
.lb::backdrop{background:rgba(16,18,20,.9)}
.lb[open]{animation:lbIn .4s var(--ease) both}
@keyframes lbIn{from{opacity:0;transform:translateY(10px) scale(.985)}to{opacity:1;transform:none}}
.lb__win{
  margin:0;display:grid;gap:clamp(1rem,2vw,1.5rem);
  padding:clamp(.8rem,1.4vw,1.15rem);background:var(--white);
  /* Deux couches : un contact net qui décolle la fenêtre du fond, et une
     ombre longue et diffuse qui lui donne sa distance. */
  box-shadow:0 4px 14px rgba(0,0,0,.28),0 34px 80px -14px rgba(0,0,0,.6);
}
/* Le passe-partout : fond ivoire pour les photos non rectangulaires, et un
   filet incisé à l'intérieur, comme sur les vignettes de la galerie. */
.lb__stage{position:relative;display:grid;place-items:center;background:var(--ivory)}
.lb__stage img{
  display:block;width:auto;max-width:100%;
  max-height:min(64dvh,660px);object-fit:contain;
}
.lb__stage::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.07);
}
.lb__cap{text-align:center;padding-bottom:clamp(.4rem,1.2vw,.85rem)}
.lb__t{display:block;font-family:var(--disp);font-size:clamp(1.15rem,2vw,1.4rem);line-height:1.3}
/* Le bouton lui-même reste nu : le code est une donnée, le cadre en dessous
   porte l'action. Deux rôles, deux formes — souligner aussi le code aurait
   laissé croire à deux commandes distinctes. */
.lb__r{
  display:block;margin:.7rem auto 0;appearance:none;-webkit-appearance:none;
  background:none;border:0;padding:.25rem .35rem;cursor:pointer;font:inherit;
}
/* Libellé et numéro sur une seule ligne, alignés sur leur ligne de base : le
   gris nomme, le laiton porte la valeur. Deux couleurs suffisent à séparer
   les deux rôles, sans ajouter de séparateur. */
.lb__ref{
  display:flex;justify-content:center;align-items:baseline;gap:.6rem;
  font-family:var(--sans);font-size:.6875rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;
}
.lb__label{color:var(--grey)}
.lb__num{color:var(--brass)}
/* `.btn--ghost` fournit le cadre, la casse et l'espacement ; il ne reste que
   l'écart au code. Le survol du bouton entier allume la bordure, sinon elle
   ne réagirait qu'au passage sur le cadre lui-même. */
.lb__go{margin-top:.95rem}
.lb__r:hover .lb__go,
.lb__r:focus-visible .lb__go{--bd:var(--anthracite)}
.lb__r:focus-visible{outline:2px solid var(--brass);outline-offset:4px}

/* Le champ reçoit la référence : un bref halo or signale où le code a atterri,
   parce que le défilement amène en bas d'une page longue et que la valeur
   ajoutée en haut du texte passerait autrement inaperçue. */
@keyframes champRecu{
  from{box-shadow:0 0 0 2px var(--gold)}
  to{box-shadow:0 0 0 2px rgb(var(--gold-rgb) / 0)}
}
.is-recu{animation:champRecu 1.6s var(--ease) both}

/* Les trois commandes partagent la même base : un carré transparent dont on
   ne dessine que deux bordures, tournées d'un quart de tour selon le rôle.
   Elles restent blanches : toutes trois vivent HORS de la fenêtre claire, sur
   le fond assombri. Les flèches sont ancrées à `.lb__stage`, donc leur
   `top:50 %` tombe au centre exact de la photo, et non de la fenêtre entière
   dont le cartel décalerait le milieu vers le bas. */
.lb__x,.lb__step{
  position:absolute;z-index:1;appearance:none;-webkit-appearance:none;
  background:none;border:0;padding:1rem;cursor:pointer;
  color:rgba(255,255,255,.72);transition:color .3s var(--ease);
}
.lb__x:hover,.lb__step:hover{color:#fff}
.lb__x:focus-visible,.lb__step:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.lb__x::before,.lb__x::after,.lb__step::before{
  content:"";display:block;width:.7rem;height:.7rem;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
}
/* La croix : deux traits pleins superposés plutôt que deux chevrons. */
.lb__x{top:-3.3rem;right:-.5rem;width:3rem;height:3rem;padding:0;display:grid;place-items:center}
.lb__x::before,.lb__x::after{
  position:absolute;width:1.05rem;height:0;border-right:0;border-bottom:1.5px solid currentColor;
}
.lb__x::before{transform:rotate(45deg)}
.lb__x::after{transform:rotate(-45deg)}
.lb__step{top:50%;transform:translateY(-50%)}
.lb__step--prev{left:-4.2rem}
.lb__step--next{right:-4.2rem}
.lb__step--prev::before{transform:rotate(135deg)}
.lb__step--next::before{transform:rotate(-45deg)}

/* ── Processus ────────────────────────────────────────────────────────── */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(2rem,4vw,3.5rem);counter-reset:s}
.step{position:relative;padding-top:1.6rem}
.step::before{content:"";position:absolute;inset-inline:0;top:0;height:1px;background:var(--line);box-shadow:0 1px 0 #fff}
.step__n{display:block;font-family:var(--disp);font-size:.9rem;letter-spacing:.2em;color:var(--brass)}
.step h3{margin-top:1.1rem;font-size:1.5rem}
.step p{margin-top:.7rem;color:var(--grey);font-size:.9375rem;line-height:1.7;max-width:32ch}

/* ── Catalogues ───────────────────────────────────────────────────────── */
.cats-row{display:grid;grid-template-columns:repeat(5,1fr);gap:clamp(1rem,2vw,1.75rem)}
.cbook{display:block}
.cbook__c{
  display:block;position:relative;overflow:hidden;aspect-ratio:209/271;background:var(--ivory);
  box-shadow:0 1px 2px rgba(0,0,0,.06),0 10px 24px -12px rgba(0,0,0,.28);
  transition:transform .45s var(--ease),box-shadow .45s var(--ease);
}
.cbook__c::before{
  content:"";position:absolute;inset:0 auto 0 0;width:6px;z-index:2;
  background:linear-gradient(90deg,rgba(0,0,0,.28),rgba(0,0,0,0));
}
.cbook__c img{width:100%;height:100%;object-fit:cover}
.cbook:hover .cbook__c{transform:translateY(-6px);box-shadow:0 2px 4px rgba(0,0,0,.08),0 22px 38px -16px rgba(0,0,0,.36)}
.cbook__m{display:flex;flex-direction:column;gap:.3rem;margin-top:1rem}
.cbook__m b{font-family:var(--disp);font-weight:400;font-size:1.0625rem;line-height:1.3}
.cbook__m i{font-style:normal;font-size:.6875rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--brass)}

/* ── CTA + formulaire ─────────────────────────────────────────────────── */
.cta{background:var(--ink);color:#fff;padding-block:var(--sec)}
.cta__grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2.5rem,6vw,5.5rem);align-items:start}
.cta__h{font-size:clamp(2.2rem,4.5vw,3.6rem);color:#fff}
.cta__h span{color:var(--gold)}
.cta__p{margin-top:1.5rem;max-width:40ch;color:#A8ABAD;font-size:1.0625rem;line-height:1.75}
.cta__dir{margin-top:3rem;display:grid;gap:0}
.cta__dir li{
  display:flex;flex-wrap:wrap;gap:.4rem 1.5rem;align-items:baseline;
  padding:1.1rem 0;border-top:1px solid rgba(255,255,255,.13);
}
.cta__dir li:last-child{border-bottom:1px solid rgba(255,255,255,.13)}
/* 8.5rem : la base doit dépasser le plus long libellé, « TEXTO SEULEMENT »,
   qui mesure 133 px une fois en capitales et interlettré. Avec `nowrap`, le
   `min-width:auto` d'un élément flex vaut la largeur de son texte et
   l'emporte sur une base plus étroite — la rangée trop longue s'élargissait
   alors seule et sa valeur partait 12 px à droite des autres. */
.cta__dir span{flex:0 0 8.5rem;white-space:nowrap;font-size:.6875rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--grey-l)}
.cta__dir a{font-size:1.0625rem;transition:color .25s var(--ease)}
.cta__dir a:hover{color:var(--gold)}

/* ── « (Texto seulement) » ────────────────────────────────────────────
   Mention accolée au numéro, dans la même graisse et la même taille que
   lui — seule la couleur la met en retrait. `nowrap` : elle ne doit jamais
   se couper en deux lignes, sinon on lit « (Texto » et l'avertissement se
   perd. La taille suit le lien voisin, qui n'est pas la même des deux côtés.
   --------------------------------------------------------------------- */
.note{font-style:normal;white-space:nowrap}
.cta__dir .note{font-size:1.0625rem;color:var(--grey-l)}
.ft__tel .note{font-size:.9375rem;color:var(--grey)}

.fwrap{background:var(--white);color:var(--anthracite);padding:clamp(1.75rem,3vw,2.5rem)}
.form__lead{font-size:.9375rem;color:var(--grey);line-height:1.6;margin-bottom:1.75rem}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
.fld{display:flex;flex-direction:column;gap:.45rem;margin-bottom:1rem}
.fld label{font-size:.75rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--anthracite)}
.fld label b{color:var(--brass)}
.fld input,.fld textarea,.fld select{
  width:100%;font:inherit;font-size:.9375rem;color:var(--anthracite);
  padding:.72rem .85rem;border:1px solid var(--line);border-radius:0;background:var(--ivory);
  transition:border-color .25s var(--ease),background .25s var(--ease);
}
.fld textarea{resize:vertical;min-height:6.5rem;line-height:1.6}
.fld input:focus,.fld textarea:focus,.fld select:focus{outline:none;border-color:var(--anthracite);background:#fff}
.fld input:user-invalid,.fld textarea:user-invalid{border-color:#B4231C;background:#FFF6F5}
/* ── Demandes multiples ───────────────────────────────────────────────
   Tant qu'il n'y en a qu'une, rien ne doit trahir la mécanique : ni en-tête,
   ni séparateur, ni numéro. Le formulaire reste exactement celui d'avant.
   C'est le script qui pose `is-multi` dès la deuxième demande.
   --------------------------------------------------------------------- */
.dmd:not(.is-multi) .dmd__h{display:none}
/* Le filet ne sépare qu'ENTRE deux demandes : posé en bordure haute à partir
   du deuxième bloc, il ne peut pas se retrouver seul en tête de liste. */
.dmd.is-multi .dmd__i + .dmd__i{
  margin-top:1.5rem;padding-top:1.4rem;border-top:1px solid var(--line);
}
.dmd__h{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.9rem}
.dmd__t{font-size:.6875rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--brass)}
/* Croix de retrait : deux traits pleins tournés d'un quart de tour, comme
   celle de l'agrandissement. Zone tactile de 36 px pour un signe de 10. */
.dmd__x{
  position:relative;flex:none;width:2.25rem;height:2.25rem;margin:-.6rem -.6rem -.6rem 0;
  appearance:none;-webkit-appearance:none;background:none;border:0;padding:0;
  cursor:pointer;color:var(--grey-l);transition:color .25s var(--ease);
}
.dmd__x:hover{color:var(--ink)}
.dmd__x:focus-visible{outline:2px solid var(--brass);outline-offset:-2px}
.dmd__x::before,.dmd__x::after{
  content:"";position:absolute;top:50%;left:50%;width:.65rem;height:1px;
  margin:-.5px 0 0 -.325rem;background:currentColor;
}
.dmd__x::before{transform:rotate(45deg)}
.dmd__x::after{transform:rotate(-45deg)}

/* Le « + » est dessiné, pas écrit : un signe typographique se serait décalé
   de la ligne de base du libellé et aurait changé de dessin selon la police
   de secours. Deux filets d'un pixel restent identiques partout. */
.dmd__add{margin-bottom:1.25rem}
.dmd__plus{position:relative;flex:none;width:.7rem;height:.7rem}
.dmd__plus::before,.dmd__plus::after{content:"";position:absolute;background:currentColor}
.dmd__plus::before{inset:calc(50% - .5px) 0}
.dmd__plus::after{inset:0 calc(50% - .5px)}

.sel{position:relative;display:block}
.sel::after{
  content:"";position:absolute;right:.95rem;top:50%;width:.45rem;height:.45rem;
  border-right:1.5px solid var(--grey);border-bottom:1.5px solid var(--grey);
  transform:translateY(-70%) rotate(45deg);pointer-events:none;
}
.sel select{appearance:none;-webkit-appearance:none;padding-right:2.2rem}

.drop{
  position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.35rem;padding:1.6rem 1rem;text-align:center;cursor:pointer;
  border:1px dashed var(--line);background:var(--ivory);
  transition:border-color .25s var(--ease),background .25s var(--ease);
}
.drop:hover,.drop.is-over{border-color:var(--gold);background:var(--gold-soft)}
.drop input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
.drop__t{font-size:.9375rem}
.drop__t b{color:var(--brass);text-decoration:underline;text-underline-offset:3px}
.drop__h{font-size:.75rem;color:var(--grey)}
.drop__list{display:grid;gap:.3rem;font-size:.8125rem;color:var(--grey)}
.drop__list:not(:empty){margin-top:.6rem}

.form__note{margin-top:.9rem;font-size:.75rem;color:var(--grey);text-align:center}
.form__note b{color:var(--brass)}
.form__ok{
  margin-top:1rem;padding:.9rem 1rem;background:var(--gold-soft);
  border-left:2px solid var(--gold);font-size:.875rem;line-height:1.55;
}

/* ── Pied de page ─────────────────────────────────────────────────────── */
.ft{background:var(--ivory);padding-top:clamp(3.5rem,6vw,5rem);color:var(--anthracite)}
.ft__grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.4fr;gap:clamp(2rem,4vw,3rem)}
/* Le pied de page n'a pas la largeur de l'en-tête : sa première colonne fait
   environ 320 px, la ligne principale y est donc plafonnée un cran plus bas. */
.mark--ft{--fs:clamp(1rem,1.25vw,1.2rem)}
.ft__tag{margin-top:1.25rem;max-width:30ch;font-size:.9375rem;color:var(--grey);line-height:1.65}
.ft__col{display:flex;flex-direction:column;align-items:flex-start;gap:.6rem}
.ft__col h3{
  margin-bottom:.5rem;font-family:var(--sans);font-size:.6875rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;color:var(--grey);
}
.ft__tel{display:flex;flex-wrap:wrap;align-items:baseline;gap:.55rem}
.ft__col a{font-size:.9375rem;color:var(--anthracite);transition:color .25s var(--ease)}
.ft__col a:hover{color:var(--brass)}
.ft__col address{font-style:normal;font-size:.9375rem;line-height:1.65;color:var(--anthracite)}
/* Même corps et même encre que les liens voisins, sans le comportement : le
   pied de page garde son alignement, mais l'adresse n'ouvre plus rien. */
.ft__mail{font-size:.9375rem;color:var(--anthracite)}

.ft__base{
  display:flex;flex-wrap:wrap;justify-content:space-between;gap:.75rem;
  margin-top:clamp(3rem,5vw,4rem);padding-block:1.6rem;position:relative;
}
.ft__base::before{content:"";position:absolute;inset-inline:var(--pad);top:0;height:1px;background:var(--line);box-shadow:0 1px 0 #fff}
.ft__base p{font-size:.8125rem;color:var(--grey)}
.ft__base p:first-child{font-weight:600;letter-spacing:.11em;text-transform:uppercase;color:var(--anthracite)}

/* ── Apparition au défilement ─────────────────────────────────────────── */
[data-rise]{opacity:0;transform:translateY(18px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
[data-rise].is-in{opacity:1;transform:none}
[data-rise-d="1"]{transition-delay:.08s}
[data-rise-d="2"]{transition-delay:.16s}
[data-rise-d="3"]{transition-delay:.24s}
[data-rise-d="4"]{transition-delay:.32s}
[data-rise-d="6"]{transition-delay:.48s}

/* ==========================================================================
   Adaptatif
   ========================================================================== */
@media (max-width:1080px){
  .cats-row{grid-template-columns:repeat(3,1fr)}
  .ft__grid{grid-template-columns:1fr 1fr;row-gap:3rem}
}

@media (max-width:900px){
  :root{--pad:1.5rem}
  .hdr__cta{display:none}
  .burger{
    display:flex;flex-direction:column;justify-content:center;gap:5px;margin-left:auto;
    width:2.75rem;height:2.75rem;padding:0;border:1px solid var(--line);background:rgba(255,255,255,.7);
    cursor:pointer;align-items:center;
  }
  .burger span{display:block;width:1.1rem;height:1.5px;background:var(--anthracite);transition:transform .35s var(--ease),opacity .25s var(--ease)}
  .burger[aria-expanded="true"] span:first-child{transform:translateY(3.25px) rotate(45deg)}
  .burger[aria-expanded="true"] span:last-child{transform:translateY(-3.25px) rotate(-45deg)}

  .nav{
    position:fixed;inset:0 0 auto;padding:6rem var(--pad) 2.5rem;margin:0;
    flex-direction:column;align-items:stretch;gap:0;
    background:var(--white);box-shadow:0 20px 40px -20px rgba(0,0,0,.3);
    transform:translateY(-100%);opacity:0;visibility:hidden;
    transition:transform .45s var(--ease),opacity .35s var(--ease),visibility .45s;
  }
  .nav.is-open{transform:none;opacity:1;visibility:visible}
  .nav>a:not(.btn){padding:1.05rem 0;font-size:1.125rem;border-bottom:1px solid var(--line)}
  .nav>a:not(.btn)::after{display:none}
  .nav__cta{display:flex;margin-top:1.75rem}

  .hero__grid{grid-template-columns:1fr;gap:3rem}
  .hero__vis{order:-1}
  .hero__sub{max-width:none}
  /* Les trois faits chiffrés sautent sous 900 px : empilés, ils repoussaient
     la suite d'un écran entier pour redire ce que la section « À propos »
     développe déjà (40 ans, deuxième génération). */
  .hero__facts{display:none}
  /* ── « À propos » resserré ─────────────────────────────────────────
     Les deux portraits RESTENT côte à côte, même sur téléphone : c'est ce
     face-à-face qui rend le raccord lisible, et un empilement l'aurait réduit
     à une flèche verticale sans rien à réunir. On ne touche donc qu'aux
     retraits, à l'écart des colonnes et au corps du texte.
     `.section--dark` ne sert qu'ici — pas besoin de cibler l'id. */
  .section--dark{padding-block:clamp(2.5rem,6.5vw,4rem)}
  .section--dark .shead{margin-bottom:1.75rem}
  .section--dark .shead__h{font-size:clamp(1.8rem,7.4vw,2.6rem)}
  /* On resserre `--gap`, pas `gap` : le raccord remonte de cette valeur pour
     rejoindre le filet du portrait, et les descentes s'en servent pour
     retrouver l'axe des colonnes. Écrire l'écart en dur ici désaccordait les
     deux, et le tracé démarrait au-dessus du filet. */
  .gens{--gap:clamp(1rem,3vw,1.75rem)}
  .gen__n{font-size:clamp(1.05rem,4.2vw,1.45rem)}
  .gen__p{margin-top:.9rem;max-width:none}
  .gen--fusion{--con:2rem}
  .gen--fusion .gen__p{max-width:none}
  .cta__grid{grid-template-columns:1fr;gap:3rem}
  .steps{grid-template-columns:1fr;gap:0}
  .step{padding-block:1.6rem}
  .step p{max-width:none}
  .shead--row{grid-template-columns:1fr;align-items:start;gap:1.4rem}
  .shead__p--tight{text-align:left;max-width:46ch}
  .grid{grid-template-columns:repeat(2,1fr)}
  .cats-row{grid-template-columns:repeat(2,1fr)}
}

@media (max-width:620px){
  .hero__h1{font-size:clamp(2.3rem,9vw,3rem)}
  /* Sous 620 px, la colonne prend toute la largeur : `max-content` y ferait
     déborder le plus long libellé, que `white-space:nowrap` empêche de se
     replier. L'étirement de la grille suffit, plus besoin de `width:100%`. */
  .hero__act{grid-template-columns:1fr}
  .hero__vis{gap:.6rem}
  .cats-row{grid-template-columns:repeat(2,1fr)}

  /* Portraits en vis-à-vis sur 155 px de colonne : à 16 px le texte tomberait
     à dix-neuf signes par ligne, sous le seuil où l'œil peut encore enjamber.
     On descend le corps et on resserre l'interlettrage du rôle, qui prenait
     quatre lignes à lui seul. Le volet de fusion garde sa taille : il occupe
     toute la largeur. */
  .gens > .gen:not(.gen--fusion) .gen__p{font-size:.8125rem;line-height:1.6;margin-top:.7rem}
  .gens > .gen:not(.gen--fusion) .gen__r{font-size:.5625rem;letter-spacing:.1em;margin-top:.6rem}
  .gens > .gen:not(.gen--fusion) .gen__y{font-size:.6875rem;margin-top:.3rem}
  .gens > .gen:not(.gen--fusion){padding-bottom:1rem}
  /* Onglets en 2x2. Sur une seule ligne il faudrait 422 px pour 327
     disponibles — « Médailles & rubans » en prend 143 à lui seul. La bande
     défilante rognait donc le quatrième onglet, ce qui se lit comme un bug
     plutôt que comme une invitation à faire défiler.
     Le filet passe du conteneur à chaque onglet : sur deux rangées, un filet
     unique en bas laisserait la première rangée flotter au-dessus de rien.
     Le trait actif descend à -1px pour couvrir ce filet au lieu de s'y poser. */
  .tabs{display:grid;grid-template-columns:1fr 1fr;gap:0;
    border-bottom:0;box-shadow:none;overflow:visible}
  .tab{font-size:.6875rem;letter-spacing:.12em;padding:.8rem 0;text-align:left;
    border-bottom:1px solid var(--line)}
  .tab::after{bottom:-1px}
  .row2{grid-template-columns:1fr;gap:0}
  .cta__dir span{flex-basis:100%}

  /* Agrandissement : la fenêtre occupe presque toute la largeur, il ne reste
     donc plus de marge autour pour poser les commandes. Elles passent sur la
     photo, sur une pastille sombre qui les rend lisibles quelle que soit
     l'image — et la zone tactile atteint 46 px sans grossir le chevron. */
  .lb{width:96vw}
  .lb__x,.lb__step{
    padding:0;background:rgba(16,18,20,.62);color:#fff;
    display:grid;place-items:center;width:2.9rem;height:2.9rem;
  }
  .lb__x{top:.45rem;right:.45rem}
  .lb__step--prev{left:.45rem}
  .lb__step--next{right:.45rem}
  .lb__stage img{max-height:56dvh}

  /* ── « Demande de soumission » resserrée ───────────────────────────
     1 978 px empilés, la section la plus longue du site. On rogne les
     interstices, jamais les zones cliquables : les champs gardent 46 px
     de haut et le bouton 52, au-dessus du seuil tactile.
     ----------------------------------------------------------------- */
  .cta{padding-block:clamp(3.25rem,8vw,4.5rem)}
  .cta__grid{gap:2rem}
  .cta__h{font-size:clamp(1.95rem,7.6vw,2.6rem)}
  /* Trois lignes pour inviter à parler du projet, juste au-dessus d'un titre
     qui invite déjà et d'une accroche de formulaire qui redit la même chose.
     Sur mobile on garde le titre et l'accroche, on saute l'intermédiaire. */
  .cta__p{display:none}
  .cta__dir{margin-top:1.75rem}
  .cta__dir li{padding:.8rem 0}

  .fwrap{padding:1.25rem 1.1rem}
  .form__lead{margin-bottom:1.15rem}
  .fld{gap:.3rem;margin-bottom:.7rem}
  .fld input,.fld select{padding-block:.6rem}      /* 46 px de haut */
  .fld textarea{min-height:5rem;padding-block:.6rem}
  .drop{padding:1rem .85rem;gap:.25rem}
  .form__note{margin-top:.7rem}
  /* ── Pied de page resserré ─────────────────────────────────────────
     Les dix liens de Navigation et Produits, empilés l'un sous l'autre,
     coûtaient à eux seuls près de 500 px. Les deux listes restent donc
     côte à côte ; la marque et le bloc de contact prennent toute la
     largeur, l'adresse et le courriel ne tenant pas sur une demi-colonne.
     Le rembourrage des liens n'est PAS réduit : à 39 px ils sont déjà
     sous les 44 px recommandés pour une cible tactile. */
  .ft{padding-top:1.75rem}
  .ft__grid{grid-template-columns:1fr 1fr;row-gap:1.25rem;column-gap:1.25rem}
  .ft__brand,.ft__col--wide{grid-column:1/-1}
  /* Le slogan du pied de page reprend presque mot pour mot le sous-titre du
     hero, et la colonne « Produits » juste en dessous énumère déjà les six
     familles. Deux lignes pour une redite : on le saute sur mobile. */
  .ft__tag{display:none}
  .ft__base{flex-direction:column;margin-top:1.25rem;padding-block:.85rem;gap:.25rem}

  /* Densité identique au grand écran : on retombe sur l'écart de .6rem de
     `.ft__col` et on retire le rembourrage vertical des liens.
     Les liens ne font alors plus que 22 px de haut — trop peu pour le pouce.
     On rattrape la cible tactile avec un ::after transparent qui déborde de
     4 px au-dessus et en dessous : 30 px touchables sans toucher à la mise
     en page. Pas plus de 4 px, sinon les zones de deux liens voisins se
     chevaucheraient (l'écart n'est que de 9,6 px) et le tap deviendrait
     ambigu. */
  .ft__col a{position:relative;padding-block:0}
  .ft__col a::after{content:"";position:absolute;inset:-4px 0;z-index:1}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
  [data-rise]{opacity:1;transform:none}
  /* La règle ci-dessus écraserait la durée du défilé, qui sauterait donc
     à sa position finale (-50 %) et y resterait. On coupe l'animation et
     on rend la bande poussable à la main ; le second jeu, qui ne servait
     qu'à la boucle, devient un doublon inutile. */
  .mq__row{animation:none!important;transform:none!important;width:100%;overflow-x:auto}
  .mq__set[aria-hidden="true"]{display:none}
}
