/* ============================================================================
   mariam-kamagate-3 — direction « CIRE PERDUE » (E4, 0 banni / 12 premium)
   Planche de fonderie : six planches d'objets légendés, aplats entiers,
   frontières franches. Aucun dégradé de teinte (seuls conic-gradient à stops
   JUMEAUX). Aucune grille visible, aucune classe .card répétée.
   Charte E3 : tokens extraits du terrain abidjanais, 11 paires mesurées.
   ============================================================================ */

/* ── Polices self-hostées ─────────────────────────────────────────────────
   Métriques de repli MESURÉES à fontTools sur les .woff2 réellement servis :
   ascent/descent/lineGap viennent de la table OS/2 de chaque fichier,
   size-adjust du rapport des largeurs moyennes sur [a-z ] contre le repli
   système. C'est ce dispositif qui a donné CLS 0 sur la version précédente. */
@font-face {
  font-family: 'FrankRuhlLibre';
  src: url('/assets/fonts/FrankRuhlLibre.woff2') format('woff2');
  font-weight: 300 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Commissioner';
  src: url('/assets/fonts/Commissioner.woff2') format('woff2');
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'OverpassMono';
  src: url('/assets/fonts/OverpassMono.woff2') format('woff2');
  font-weight: 300 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'display-repli';
  src: local('Georgia'), local('Times New Roman'), local('Liberation Serif');
  ascent-override: 95.70%; descent-override: 33.40%; line-gap-override: 0%;
  size-adjust: 94.51%;
}
@font-face {
  font-family: 'corps-repli';
  src: local('Arial'), local('Helvetica'), local('Liberation Sans');
  ascent-override: 101.70%; descent-override: 20.60%; line-gap-override: 0%;
  size-adjust: 93.74%;
}
@font-face {
  font-family: 'mono-repli';
  src: local('Courier New'), local('Liberation Mono');
  ascent-override: 88.30%; descent-override: 38.30%; line-gap-override: 0%;
  size-adjust: 102.67%;
}

:root {
  /* — Charte E3, ancrée terrain (design-system.md § Charte) — */
  --attieke: #F2F0EE;        /* semoule de manioc — fond de page */
  --wenge: #140D0A;          /* bois quasi noir des ateliers — encre, aplat sombre */
  --aluzinc: #A3AAAE;        /* tôle ondulée des toitures — filets, surfaces neutres */
  --jaune-cocody: #EBC53A;   /* carrosserie des woro-woro de Cocody — métal coulé, accents */
  --woro-vert: #1D6D3E;      /* carrosserie Adjamé/Attécoubé/Marcory/Koumassi */
  --bougainvillee: #AE2997;  /* bractées de bougainvillée */
  --gbaka: #8A512E;          /* carrosserie du minibus « L'Abidjanais » — porte le CTA */
  --laiton: #725531;         /* bronze patiné des poids à peser l'or */
  --cuir: #593C2C;           /* sandales lêkê du marché d'Adjamé */

  --font-display: 'FrankRuhlLibre', 'display-repli', Georgia, serif;
  --font-body: 'Commissioner', 'corps-repli', Arial, sans-serif;
  --font-mono: 'OverpassMono', 'mono-repli', 'Courier New', monospace;

  /* Encre et métal par défaut : chaque planche les redéfinit (voir § planches).
     Toute paire employée ici figure dans les CONTRASTE: mesurés de la charte. */
  --encre: var(--wenge);
  --fond: var(--attieke);
  --metal: var(--laiton);      /* métal coulé sur fond clair — --attieke dessus = 6,04 */
  --sur-metal: var(--attieke);
  --filet: color-mix(in srgb, var(--encre) 30%, transparent);

  --pas: clamp(1.15rem, 3.4vw, 2.1rem);
  --marge: clamp(1.15rem, 5vw, 5.5rem);

  /* Garde de visage — garde-fou 7 de la direction. Fraction de la hauteur du
     cadre photo SOUS laquelle un élément a le droit de chevaucher le portrait.
     Au-dessus : rien. Ce n'est pas une consigne, c'est une contrainte
     géométrique — la v2 avait amputé un visage avec une simple consigne. */
  --visage-bas: 58%;

  /* Jetons des pièces de bronze (SVG) — chaque planche peut les redéfinir. */
  --piece-corps: var(--laiton);
  --piece-filet: var(--aluzinc);
  --piece-detail: var(--jaune-cocody);
}

*, *::before, *::after { box-sizing: border-box; }

/* PAS de `scroll-behavior: smooth` ici, et c'est mesuré : il fait animer TOUT
   défilement programmatique, y compris `scrollTo()`. Sur ce site (11 006 px de
   haut à 390 px de large), la sonde d'audit défile par pas de 422 px toutes les
   90 ms — avec le lissage, la page n'atteignait jamais le bas : 17 animations
   sur 18 restaient à une progression de 0 et le site se mesurait comme figé,
   alors qu'il ne l'était pas. Le confort d'un lien d'ancre ne vaut pas ça. */
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--attieke);
  color: var(--wenge);
  font-family: var(--font-body);
  font-size: clamp(1.02rem, 0.97rem + 0.28vw, 1.16rem);
  line-height: 1.62;
  font-weight: 380;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }

a { color: inherit; }

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

.saut-contenu {
  position: absolute; left: -9999px; top: 0;
  background: var(--wenge); color: var(--attieke);
  padding: .8rem 1.2rem; z-index: 99; font-family: var(--font-mono); font-size: .82rem;
}
.saut-contenu:focus { left: .6rem; top: .6rem; }

/* ══════════════════════════════════════════════════════════════════════════
   LE DISPOSITIF — « LES POIDS DANS LA PHRASE » (famille « empreinte »,
   position « au fil du texte »). Un mot qui compte est un CREUX gravé dans
   l'aplat ; le bronze y coule à la lecture, au survol et au doigt ; on remonte,
   le métal se retire, le creux reste.

   inline-block est OBLIGATOIRE (garde-fou 1) : box-shadow:inset n'a aucun effet
   sur une boîte inline pure, et text-shadow n'a pas de mot-clé inset — sans lui
   la bascule creux → posé, qui donne son nom à la direction, n'existe pas.
   ══════════════════════════════════════════════════════════════════════════ */
.poids {
  position: relative;
  display: inline-block;
  padding: .02em .22em .06em;
  font-weight: 620;
  font-style: normal;
  color: var(--encre);
  isolation: isolate;
  /* le creux : ombre haute sombre + ombre basse claire, à l'intérieur */
  box-shadow:
    inset .07em .07em 0 color-mix(in srgb, var(--encre) 34%, transparent),
    inset -.06em -.06em 0 color-mix(in srgb, var(--sur-metal) 42%, transparent);
  transition:
    color 380ms cubic-bezier(.19, 1, .22, 1),
    box-shadow 380ms cubic-bezier(.19, 1, .22, 1),
    transform 120ms cubic-bezier(.19, 1, .22, 1);
}
/* la couche de métal : elle EXISTE déjà, on lève un cache (réf. B — découpe,
   pas opacité). Elle monte du bas vers le haut : c'est une coulée. */
.poids::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--metal);
  clip-path: inset(100% 0 0 0);
  transition: clip-path 380ms cubic-bezier(.19, 1, .22, 1);
}
.poids[data-coule='1'] {
  color: var(--sur-metal);
  /* l'ombre BASCULE DE SENS : creusé → posé (réf. C jouée à l'envers) */
  box-shadow:
    .09em .1em 0 color-mix(in srgb, var(--encre) 46%, transparent),
    inset 0 0 0 1px color-mix(in srgb, var(--sur-metal) 22%, transparent);
  /* échelles DISSOCIÉES : le métal s'assied, il ne zoome pas (réf. D) */
  transform: scaleY(1.035) scaleX(.992) translateY(2px);
}
.poids[data-coule='1']::before { clip-path: inset(0 0 0 0); }

/* Sur les planches sombres et colorées, le métal coulé est le jaune de Cocody
   (--wenge dessus = 11,52 mesuré). Sur l'attiéké, c'est le laiton
   (--attieke dessus = 6,04 mesuré). Les deux états sont AA des deux côtés. */
.planche--sombre, .planche--couleur { --metal: var(--jaune-cocody); --sur-metal: var(--wenge); }

/* ══════════════════════════════════════════════════════════════════════════
   LES PLANCHES — six aplats entiers, frontières franches, zéro fondu.
   ══════════════════════════════════════════════════════════════════════════ */
.planche {
  position: relative;
  padding: clamp(3.2rem, 8vw, 6.6rem) var(--marge) clamp(3.6rem, 8vw, 7rem);
  background: var(--fond);
  color: var(--encre);
}
.planche--elle       { --fond: var(--attieke);       --encre: var(--wenge);   padding-top: clamp(1rem, 3vw, 2.2rem); }
.planche--gestes     { --fond: var(--woro-vert);     --encre: var(--attieke); }
.planche--domaines   { --fond: var(--wenge);         --encre: var(--attieke); }
.planche--terrain    { --fond: var(--laiton);        --encre: var(--attieke); }
.planche--refus      { --fond: var(--bougainvillee); --encre: var(--attieke); }
.planche--contact    { --fond: var(--gbaka);         --encre: var(--attieke); }

.planche__index {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: .3em .6em;
  border: 1px solid var(--filet);
  margin-bottom: 1.1rem;
  cursor: default;
  transition: background-color 260ms cubic-bezier(.19,1,.22,1),
              color 260ms cubic-bezier(.19,1,.22,1);
}
.planche__titre {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.05rem, 6.2vw, 4.1rem);
  line-height: .98;
  letter-spacing: -.018em;
  margin: 0 0 1.1rem;
  max-width: 21ch;
}
.planche__chapo {
  max-width: 60ch;
  font-size: clamp(1.06rem, 1rem + .45vw, 1.28rem);
  line-height: 1.58;
  margin: 0 0 clamp(2rem, 4vw, 3.2rem);
}
.legende-planche {
  font-family: var(--font-mono);
  font-size: .73rem;
  line-height: 1.65;
  letter-spacing: .01em;
  max-width: 74ch;
  margin: clamp(2.2rem, 4vw, 3.4rem) 0 0;
  padding-top: .9rem;
  border-top: 1px solid var(--filet);
  opacity: .92;
}

/* ── P00 · ELLE ────────────────────────────────────────────────────────────
   Elle est le premier écran, en grand. La v1 la montrait à 104 px de large,
   à 6 400 px de défilement — c'est le grief n°2 du client. */
.elle { display: grid; gap: clamp(1.4rem, 3vw, 2.6rem); align-items: start; }
@media (min-width: 62rem) {
  .elle { grid-template-columns: minmax(0, 46fr) minmax(0, 54fr); gap: clamp(2rem, 3.4vw, 3.6rem); }
}

.portrait {
  position: relative;
  margin: 0;
  /* le portrait touche le bord haut et le bord gauche : il n'est pas « posé
     dans une carte », il entre dans la page */
  margin-left: calc(var(--marge) * -1);
  margin-top: calc(clamp(1rem, 3vw, 2.2rem) * -1);
  width: calc(100% + var(--marge));
}
@media (min-width: 62rem) { .portrait { margin-bottom: calc(clamp(3.6rem, 8vw, 7rem) * -1); } }

.portrait img {
  width: 100%;
  height: clamp(23rem, 66vh, 42rem);
  object-fit: cover;
  object-position: 50% 12%;
  background: var(--aluzinc);
}
@media (min-width: 62rem) { .portrait img { height: clamp(30rem, 82vh, 52rem); } }

/* Le seul objet autorisé à chevaucher la photo. Il est placé SOUS la garde de
   visage (--visage-bas), donc il ne peut pas entrer dans la boîte yeux-menton :
   la contrainte est géométrique, pas intentionnelle (garde-fou 7). */
/* Le poids chevauche TOUJOURS un bord de la photo : moitié sur l'image, moitié
   sur l'aplat, avec sa vraie ombre portée. Posé entièrement DANS la photo, il se
   lit comme une broche épinglée sur sa veste — un accessoire qu'elle ne porte
   pas — au lieu d'un objet posé sur la page.
   À 390 px la photo est pleine largeur : le seul bord disponible est le bord
   BAS. Au-delà de 62 rem elle devient une colonne : c'est le bord DROIT.
   Dans les deux cas il reste sous la garde de visage. */
.poids-epaule {
  position: absolute;
  bottom: calc(var(--taille-poids) / -2.4);
  right: clamp(8%, 12vw, 18%);
  --taille-poids: clamp(74px, 13vw, 132px);
  width: var(--taille-poids);
  transform: rotate(-8deg);
  filter: drop-shadow(6px 9px 0 rgba(20, 13, 10, .34));
  transition: transform 520ms cubic-bezier(.19, 1, .22, 1);
}
@media (min-width: 62rem) {
  .poids-epaule {
    /* jamais au-dessus de la garde de visage — la borne basse du clamp() la rend
       inatteignable même si --visage-bas était mal réglée */
    top: clamp(60%, var(--visage-bas), 78%);
    bottom: auto;
    right: calc(var(--taille-poids) / -2.2);
  }
}

.elle__nom {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.9rem, 12.5vw, 8.5rem);
  line-height: .88;
  letter-spacing: -.035em;
  margin: 0 0 .5rem;
  text-wrap: balance;
}
.elle__role {
  font-size: clamp(1.14rem, 1rem + .8vw, 1.5rem);
  font-weight: 500;
  margin: 0 0 .35rem;
}
.elle__employeur {
  font-family: var(--font-mono);
  font-size: .8rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  margin: 0 0 clamp(1.5rem, 3vw, 2.4rem);
  color: var(--cuir);            /* 8,77 sur attiéké — mesuré */
}
.elle__accroche {
  font-size: clamp(1.12rem, 1.02rem + .6vw, 1.42rem);
  line-height: 1.55;
  max-width: 42ch;
  margin: 0 0 clamp(1.6rem, 3vw, 2.4rem);
}
.elle__mode-emploi {
  font-family: var(--font-mono);
  font-size: .74rem;
  line-height: 1.6;
  max-width: 46ch;
  padding-left: .9rem;
  border-left: 2px solid var(--laiton);
  margin: 0 0 clamp(1.6rem, 3vw, 2.2rem);
}

/* ── Le bouton WhatsApp — un seul CTA sur toute la page ────────────────────
   --gbaka porte le CTA (charte). --attieke dessus = 5,60 mesuré. */
.cta-wa {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  min-height: 52px;                       /* > 44 px : cible tactile */
  padding: .85rem 1.5rem;
  background: var(--gbaka);
  color: var(--attieke);
  font-weight: 600;
  font-size: 1.06rem;
  text-decoration: none;
  border: 0;
  box-shadow: .28rem .32rem 0 var(--wenge);   /* posé */
  transition:
    box-shadow 300ms cubic-bezier(.23, 1, .32, 1),
    transform 300ms cubic-bezier(1, .33, .11, 1.34),
    padding 300ms cubic-bezier(1, .33, .11, 1.34),
    min-height 300ms cubic-bezier(1, .33, .11, 1.34),
    background-color 300ms cubic-bezier(.23, 1, .32, 1);
}
.cta-wa svg { flex: 0 0 auto; }
.planche--contact .cta-wa { box-shadow: .28rem .32rem 0 var(--wenge); }

/* ── P01 · SIX GESTES ──────────────────────────────────────────────────────
   Semé, pas grille : chaque objet porte ses propres --dx/--dy/--rot/--ech.
   Aucune rangée régulière, aucune carte. */
.seme { position: relative; display: grid; gap: clamp(2rem, 4vw, 3.4rem); }
@media (min-width: 46rem) { .seme { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 74rem) { .seme { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.objet {
  position: relative;
  transform: translate(var(--dx, 0), var(--dy, 0));
  padding-top: .4rem;
}
.objet__forme {
  width: calc(clamp(96px, 15vw, 168px) * var(--ech, 1));
  height: auto;
  margin-bottom: .9rem;
  transform: rotate(var(--rot, 0deg));
  transition: transform 520ms cubic-bezier(.19, 1, .22, 1);
}
.objet__nom {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 3.4vw, 2.15rem);
  line-height: 1.05;
  margin: 0 0 .1rem;
}
.objet__filet {
  display: block;
  height: 2px;
  width: 1.6rem;
  background: currentColor;
  opacity: .55;
  margin: .55rem 0 .7rem;
  transition: width 520ms cubic-bezier(.19, 1, .22, 1),
              opacity 520ms cubic-bezier(.19, 1, .22, 1);
}
.objet__texte { margin: 0; max-width: 40ch; font-size: .99rem; line-height: 1.6; }

/* ── P02 · CINQ DOMAINES ───────────────────────────────────────────────────
   Rangées larges. Le quartier conique est la seule géométrie régulière du
   site — et c'est un SECTEUR, pas une colonne ni une bande. Stops JUMEAUX :
   zéro fondu, c'est un aplat en quartier, pas un dégradé (garde-fou 14). */
.domaines { display: grid; gap: 0; border-top: 1px solid var(--filet); }

.domaine {
  position: relative;
  display: grid;
  gap: .55rem .1rem;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  padding: clamp(1.5rem, 3.2vw, 2.5rem) 0 clamp(1.6rem, 3.2vw, 2.6rem);
  border-bottom: 1px solid var(--filet);
  transition:
    padding-left 450ms cubic-bezier(.19, 1, .22, 1),
    padding-top 450ms cubic-bezier(.19, 1, .22, 1),
    padding-bottom 450ms cubic-bezier(.19, 1, .22, 1),
    column-gap 450ms cubic-bezier(.19, 1, .22, 1),
    transform 450ms cubic-bezier(.19, 1, .22, 1),
    background-color 450ms cubic-bezier(.19, 1, .22, 1);
}
/* le quartier : conic-gradient à ARRÊTS DURS (stops jumeaux, zéro fondu — ce
   n'est pas un dégradé, c'est un aplat en quartier). Il tourne au défilement.
   C'est un vrai élément et non un ::before, pour que la sonde d'audit le voie
   dans document.getAnimations() : une animation qu'aucun instrument ne peut
   lire ne sert pas de preuve. */
.quartier {
  position: absolute;
  top: 50%; left: -20vw;
  width: 30vw; aspect-ratio: 1;
  translate: 0 -50%;
  background: conic-gradient(
    var(--laiton) 0deg, var(--laiton) 62deg,
    transparent 62deg, transparent 360deg);
  opacity: .5;
  pointer-events: none;
  transform: rotate(0deg);
}

/* ── Animations scrubées ───────────────────────────────────────────────────
   Attachées EN PAUSE par site.js, jouées par délai négatif au défilement.
   Aucune n'est infinie : une boucle décorative se lit comme une barre de
   chargement, et ce dépôt l'a déjà payé. Chaque propriété VARIE d'un palier à
   l'autre — un `rotate()` identique de bout en bout serait une inclinaison
   statique transportée par une animation, pas un geste. */
@keyframes pose-epaule {
  from { transform: rotate(-8deg) translate(0, 0) scale(1); }
  to   { transform: rotate(9deg) translate(-14px, 26px) scale(1.06); }
}
@keyframes tourne-quartier {
  from { transform: rotate(0deg); }
  to   { transform: rotate(128deg); }
}
@keyframes redresse-piece-a {
  from { transform: rotate(var(--rot, 0deg)) scale(1); }
  to   { transform: rotate(0deg) scale(1.14); }
}
@keyframes redresse-piece-b {
  from { transform: rotate(var(--rot, 0deg)) scale(1); }
  to   { transform: rotate(calc(var(--rot, 0deg) * -1.4)) scale(.9); }
}
/* Un objet par rangée, sur la moitié droite. La colonne de texte est bornée à
   56ch pour rester lisible : sans ces objets, l'aplat sombre est vide sur près
   de la moitié de sa largeur, et c'est le grief « ça paraît vide » qui revient.
   Ce ne sont pas des ornements de remplissage — c'est le vocabulaire même de la
   direction, un objet posé et légendé par la rangée qu'il accompagne.
   Fill laiton sur fond wengé = 2,80 : NON TEXTUEL par construction (aria-hidden,
   aucun nœud texte, ≥48 px), cerné d'un filet aluzinc à 8,17 qui porte la
   lisibilité de forme. */
.domaine__piece {
  position: absolute;
  top: var(--haut, 50%);
  right: clamp(1%, 3vw, 4%);
  width: calc(clamp(46px, 6vw, 74px) * var(--ech, 1));
  translate: 0 -50%;
  margin-bottom: 0;
  opacity: .62;
  pointer-events: none;
}
@media (min-width: 62rem) {
  .domaine__piece {
    right: clamp(4%, 9vw, 16%);
    width: calc(clamp(64px, 8vw, 122px) * var(--ech, 1));
    opacity: 1;
  }
}

.domaine__indice {
  grid-row: span 3;
  font-family: var(--font-mono);
  font-size: .82rem;
  letter-spacing: .1em;
  padding-right: clamp(.9rem, 2.4vw, 2rem);
  padding-top: .55rem;
  opacity: .78;
}
.domaine__nom {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.75rem, 5vw, 3.15rem);
  line-height: 1;
  letter-spacing: -.02em;
  margin: 0;
}
.domaine__methode { margin: 0; max-width: 56ch; }
.domaine__mur {
  margin: 0;
  max-width: 56ch;
  font-family: var(--font-mono);
  font-size: .8rem;
  line-height: 1.62;
  color: var(--jaune-cocody);       /* 11,52 sur --wenge — mesuré */
  padding-left: .85rem;
  border-left: 2px solid var(--jaune-cocody);
}
.domaine__mur b { font-weight: 700; letter-spacing: .04em; }

/* ── P03 · LE POIDS ET LA MESURE ───────────────────────────────────────────
   Les objets de bronze sur la planche sombre : --laiton sur --wenge vaut 2,80,
   sous AA. Ils sont donc STRICTEMENT non textuels (aria-hidden, aucun nœud
   texte), ≥48 px, et détourés d'un filet --aluzinc (8,17 sur wenge) qui porte
   la lisibilité de forme. Garde-fou 4. */
.tiroir { display: flex; flex-wrap: wrap; gap: clamp(1rem, 2.6vw, 2.2rem); align-items: flex-end; margin-bottom: clamp(2rem, 4vw, 3rem); }
.tiroir__piece {
  width: calc(clamp(52px, 7vw, 88px) * var(--ech, 1));
  height: auto;
  /* --pose décale chaque pièce verticalement : posées sur une même ligne de
     base, douze objets de tailles voisines redeviennent une RANGÉE D'ICÔNES
     (banni n°9), quelles que soient leurs rotations. */
  margin-bottom: var(--pose, 0);
  transform: rotate(var(--rot, 0deg));
  transition: transform 460ms cubic-bezier(.19, 1, .22, 1);
}
/* Sur la planche laiton, une pièce remplie de laiton est INVISIBLE : il ne
   restait que le filet, et douze contours alignés lisent comme un jeu d'icônes.
   Les pièces y passent donc en wengé plein, cerné d'attiéké (6,04 mesuré sur
   laiton — le filet porte la lisibilité de forme ; la pièce n'est jamais du
   texte, elle reste aria-hidden et sans nœud texte). Recoloration par JETONS et
   non par sélecteur d'attribut : un hex hors :root est refusé par le lint L3,
   et à raison — une couleur écrite deux fois finit par diverger. */
.planche--terrain { --piece-corps: var(--wenge); --piece-filet: var(--attieke); --piece-detail: var(--jaune-cocody); }
.terrain__texte { max-width: 62ch; }
.terrain__texte p { margin: 0 0 1.05rem; }

/* la note en ligne : elle se déploie DANS le paragraphe (réf. A — six
   propriétés d'un coup, l'objet se recompose au lieu de glisser) */
.note {
  /* static, et c'est voulu : le bloc de contenu doit se caler sur le
     paragraphe (bloc conteneur positionné), pas sur ce marqueur */
  position: static;
  display: inline-block;
  font-family: var(--font-mono);
  font-size: .7em;
  line-height: 1;
  vertical-align: super;
  padding: .18em .34em;
  margin-left: .12em;
  border: 1px solid currentColor;
  cursor: help;
  transition:
    padding 340ms cubic-bezier(1, .33, .11, 1.34),
    letter-spacing 340ms cubic-bezier(1, .33, .11, 1.34),
    background-color 340ms cubic-bezier(.23, 1, .32, 1),
    color 340ms cubic-bezier(.23, 1, .32, 1),
    transform 340ms cubic-bezier(1, .33, .11, 1.34),
    border-color 340ms cubic-bezier(.23, 1, .32, 1);
}
/* Le corps de note s'ancre sur le PARAGRAPHE, pas sur le marqueur : ancré au
   marqueur, il partait de la position du mot et débordait à droite (mesuré à
   390 px : 285 → 574 px, scrollWidth 574 pour un viewport de 390). Ancré au
   paragraphe, sa largeur est bornée par la colonne de lecture par construction. */
.terrain__texte p, .refus li, .objet { position: relative; }
.note__corps {
  position: absolute;
  left: 0; right: 0; top: calc(100% + .5rem);
  z-index: 5;
  width: auto;
  padding: .75rem .9rem;
  background: var(--wenge);
  color: var(--attieke);
  border: 1px solid var(--aluzinc);
  font-size: 1.5em;
  line-height: 1.5;
  vertical-align: baseline;
  text-align: left;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 340ms cubic-bezier(.23, 1, .32, 1);
}
.planche--terrain .note__corps { background: var(--wenge); color: var(--attieke); }

/* ── P04 · CE QUE CE SITE NE FERA PAS ──────────────────────────────────────
   Pas une grille de cartes : une liste de déclarations de longueurs inégales. */
/* Le contre-champ tient la moitié droite de la planche : sans lui, l'aplat
   magenta est vide sur 45 % de sa largeur — c'est le grief « ça paraît vide »
   qui revient par la fenêtre. Ce n'est pas du remplissage : c'est le relevé
   des quatre pages de contact concurrentes, qui donne son sens à la planche. */
.refus-grille { display: grid; gap: clamp(2rem, 4vw, 3.4rem); align-items: start; }
@media (min-width: 62rem) { .refus-grille { grid-template-columns: minmax(0, 58fr) minmax(0, 42fr); } }

.contre-champ { border-left: 2px solid var(--attieke); padding-left: clamp(1rem, 2.2vw, 1.8rem); }
.contre-champ__titre {
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .16em;
  text-transform: uppercase; margin: 0 0 .9rem; font-weight: 600;
}
.contre-champ__intro { margin: 0 0 1.2rem; font-size: .97rem; }
.contre-champ__liste { margin: 0 0 1.3rem; }
.contre-champ__liste dt {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.05rem, 2vw, 1.28rem); margin-top: .95rem;
}
.contre-champ__liste dd { margin: .12rem 0 0; font-size: .95rem; line-height: 1.5; }
.contre-champ__note {
  font-family: var(--font-mono); font-size: .76rem; line-height: 1.7;
  margin: 0; padding-top: .9rem; border-top: 1px solid var(--filet);
}

.refus { list-style: none; margin: 0; padding: 0; max-width: 68ch; }
.refus li {
  padding: clamp(.9rem, 2vw, 1.35rem) 0;
  border-bottom: 1px solid var(--filet);
  font-size: clamp(1.04rem, 1rem + .35vw, 1.22rem);
}
.refus li:first-child { border-top: 1px solid var(--filet); }
/* :not(.poids) est OBLIGATOIRE — sans lui, `display:block` s'applique aussi aux
   mots du dispositif, qui s'étalent sur toute la largeur de la ligne et perdent
   leur creux : box-shadow:inset n'a aucun sens sur une boîte de bloc pleine
   largeur. C'est exactement le mode de panne décrit par le garde-fou 1, et il
   s'est produit ici au premier rendu. */
.refus li > strong { font-family: var(--font-display); font-weight: 700; font-size: 1.16em; display: block; margin-bottom: .18rem; }

/* ── P05 · CONTACT ─────────────────────────────────────────────────────────*/
.contact__numero {
  font-family: var(--font-mono);
  font-size: clamp(1.3rem, 5.2vw, 2.4rem);
  letter-spacing: .02em;
  margin: 0 0 1.6rem;
  font-weight: 600;
}
.contact__reserve { max-width: 54ch; font-size: .97rem; margin: clamp(1.8rem, 3vw, 2.6rem) 0 0; }

/* ── Pied de page ──────────────────────────────────────────────────────────*/
.pied {
  background: var(--wenge);
  color: var(--attieke);
  padding: clamp(2.4rem, 5vw, 4rem) var(--marge);
  font-size: .9rem;
}
.pied p { margin: 0 0 .8rem; max-width: 68ch; }
.pied__mention { font-family: var(--font-mono); font-size: .78rem; line-height: 1.7; opacity: .95; }
.pied a { color: var(--jaune-cocody); text-decoration-thickness: 1px; text-underline-offset: .22em; }

/* ══════════════════════════════════════════════════════════════════════════
   MICRO-INTERACTIONS — six sélecteurs :hover DISTINCTS, chacun avec son
   jumeau tactile. La version précédente est partie avec 8 :hover, 0 :active
   et 0 écouteur tactile : au doigt, elle n'avait AUCUNE interaction, et c'est
   l'utilisateur qui l'a signalé, pas les gates. Ici la parité est posée dès le
   premier build (règle L11).
   ══════════════════════════════════════════════════════════════════════════ */

/* 1 · le poids : il coule */
.poids:hover, .poids.est-pressee { color: var(--sur-metal); }
.poids:hover::before, .poids.est-pressee::before { clip-path: inset(0 0 0 0); }
.poids:hover, .poids.est-pressee {
  box-shadow:
    .09em .1em 0 color-mix(in srgb, var(--encre) 46%, transparent),
    inset 0 0 0 1px color-mix(in srgb, var(--sur-metal) 22%, transparent);
  transform: scaleY(1.035) scaleX(.992) translateY(2px);
}

/* 2 · la rangée de domaine : elle se RECOMPOSE (six propriétés, même durée) */
.domaine:hover, .domaine.est-pressee {
  padding-left: clamp(.8rem, 2.2vw, 2rem);
  padding-top: clamp(1.8rem, 3.6vw, 2.9rem);
  padding-bottom: clamp(1.9rem, 3.6vw, 3rem);
  column-gap: clamp(.4rem, 1.2vw, 1rem);
  transform: translateX(2px);
  background-color: color-mix(in srgb, var(--attieke) 7%, transparent);
}

/* 3 · le CTA WhatsApp : il se CREUSE réellement (posé → enfoncé) */
.cta-wa:hover, .cta-wa:focus-visible, .cta-wa.est-pressee {
  box-shadow: inset .2rem .22rem 0 rgba(20, 13, 10, .5), inset -.14rem -.16rem 0 rgba(242, 240, 238, .18);
  transform: translate(.2rem, .24rem);
  padding: .95rem 1.62rem;
  min-height: 54px;
  background-color: var(--cuir);
}

/* 4 · l'objet de planche : il corrige son angle de pose, son filet grandit */
.objet:hover .objet__forme, .objet.est-pressee .objet__forme { transform: rotate(0deg) scaleY(1.04) scaleX(.985); }
.objet:hover .objet__filet, .objet.est-pressee .objet__filet { width: 5.4rem; opacity: 1; }

/* 5 · la note : elle se déploie en ligne */
.note:hover, .note:focus-visible, .note.est-pressee {
  padding: .3em .5em;
  letter-spacing: .06em;
  background-color: var(--attieke);
  color: var(--wenge);
  border-color: var(--attieke);
  transform: translateY(-2px);
}
.note:hover .note__corps, .note:focus-visible .note__corps, .note.est-pressee .note__corps { clip-path: inset(0 0 0 0); }

/* 6 · l'indice de planche : il bascule d'aplat */
.planche__index:hover, .planche__index.est-pressee { background-color: var(--encre); color: var(--fond); }

/* La pièce de bronze de la planche sombre : elle se redresse */
.tiroir__piece:hover, .tiroir__piece.est-pressee { transform: rotate(0deg) scale(1.06); }

/* la note ouverte au doigt ou au clavier — un survol n'existe pas au doigt */
.note.est-ouverte { padding: .3em .5em; background-color: var(--attieke); color: var(--wenge); border-color: var(--attieke); }
.note.est-ouverte .note__corps { clip-path: inset(0 0 0 0); }

/* Sur un écran sans survol, l'état pressé fait tout le travail — et les états
   au repos restent des états FINIS, jamais des états d'attente. */
@media (hover: none) {
  .poids { transition-duration: 240ms, 240ms, 100ms; }
  .note { cursor: pointer; }
}

/* ── Mode ?audit : la page est FIGÉE mais pas VIDE ─────────────────────────
   Les captures pleine page sont prises sans JS. Si tous les mots y restaient
   creux, le juge verrait un seul des deux états du dispositif et le lirait
   comme un défaut. On peint donc le même mélange qu'en mouvement réduit :
   le creux ET le plein, côte à côte, lisibles à l'arrêt. */
.en-audit .poids:nth-of-type(odd) {
  color: var(--sur-metal);
  box-shadow: .09em .1em 0 color-mix(in srgb, var(--encre) 46%, transparent);
  transform: scaleY(1.035) scaleX(.992) translateY(2px);
}
.en-audit .poids:nth-of-type(odd)::before { clip-path: inset(0 0 0 0); }

/* ══════════════════════════════════════════════════════════════════════════
   MOUVEMENT RÉDUIT — le dispositif doit rester LISIBLE, pas disparaître.
   On ne peint pas tout coulé : un mélange de creux et de pleins conserve
   « le creux et le plein qui s'échangent ». Une page uniformément remplie a
   perdu son dispositif (garde-fou 11).
   ══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .poids:nth-of-type(odd) { color: var(--sur-metal); }
  .poids:nth-of-type(odd)::before { clip-path: inset(0 0 0 0); }
  .poids:nth-of-type(odd) {
    box-shadow: .09em .1em 0 color-mix(in srgb, var(--encre) 46%, transparent);
    transform: scaleY(1.035) scaleX(.992) translateY(2px);
  }
  .note__corps { clip-path: inset(0 0 0 0); position: static; display: block; width: auto; margin-top: .4rem; font-size: 1em; }
  .note { vertical-align: baseline; }
}
