/* P250.10 — polices libres (SIL OFL, dist/fonts/OFL-*.txt), servies en local, font-display: swap.
   Aucune requête vers Google Fonts. Remplace Archivo et Bodoni Moda (périmées, 30/09/2026). */
@font-face{font-family:'Newsreader';font-style:normal;font-weight:200 800;font-display:swap;src:url(/fonts/newsreader-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Geist';font-style:normal;font-weight:100 900;font-display:swap;src:url(/fonts/geist-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:100 900;font-display:swap;src:url(/fonts/geist-mono-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* page.css — gabarit des 266 pages portées (P167).
   Mêmes jetons que l'accueil : une seule identité, peinte, jamais héritée du
   thème de l'OS du visiteur. Aucune dépendance externe, aucune requête tierce. */
/* ⚠️ R1 — P167.11, 24/09/2026 : thème SOMBRE périmé (--ink:#0F110E fond,
   --ivory:#F2EFE7 texte) ; FAIT FOI thème CLAIR « direction A » (Louis, QCM
   09/09/2026) — --ink reste le jeton de FOND (rôle inchangé, valeur
   inversée), --ivory reste le jeton de TEXTE PRINCIPAL (rôle inchangé,
   valeur inversée). Palette calculée pour WCAG 2.2 AA (texte ≥ 4.5:1 sur
   --ink ET --ink-2) : --ivory 15,6:1 · --ivory-2 12,4:1/11,4:1 ·
   --ivory-3 6,15:1/5,63:1 · --brass 5,67:1/5,18:1.
   ⚠️ R1 — --ivory-2 CORRIGÉ #4a4a44→#35352f (banc test_contraste_charte.py,
   24/09/2026) : #4a4a44 tenait 4,5:1 en PLEIN mais rendait 4,21:1 sous
   `opacity:.75` (svg .tr-axe, .intro) — la couleur composée avec le fond,
   pas la couleur déclarée seule, est ce qu'un lecteur voit.
   ⚠️ P167.13, 24/09/2026 — dette (a) du lot 1 : les noms `--ink`/`--ivory`
   restaient ceux du thème SOMBRE périmé (où `--ink` était l'encre foncée et
   `--ivory` le papier clair), donc inversés par rapport à leur RÔLE actuel
   depuis le 09/09. Noms propres posés ci-dessous (`--fond*`/`--encre*`) ;
   `--ink`/`--ivory`/`--ivory-2`/`--ivory-3` restent définis comme ALIAS DE
   TRANSITION — les lots 2 (réalisations, lieux) et 3a (annexes) tournent en
   parallèle dans leurs propres worktrees et y lisent encore ces noms : les
   retirer avant leur fusion casserait leurs pages sans qu'aucun signal ne le
   dise. Migrer les ~40 usages internes à ce fichier vers les noms propres
   reste à faire une fois les trois lots fusionnés (suivi : PORT-SITE-V2.md).
   ⚠️ L'ALIAS DUPLIQUE LA VALEUR HEXA, IL NE PASSE PAS PAR `var()` : un essai
   `--ink:var(--fond)` a fait échouer `test_contraste_charte.py` (son lecteur
   `_VAR` n'attend qu'un `#rrggbb` juste après `:`, jamais un renvoi indirect)
   — corrigé le 24/09/2026 en écrivant la même couleur deux fois. Conséquence
   assumée : les deux jeux de noms doivent être changés ENSEMBLE tant que
   l'alias vit. */
:root{--fond:#f4f2ee;--fond-2:#ece8e0;--encre:#191a1a;--encre-2:#35352f;
      --encre-3:#585b58;--brass:#7a5a24;--sage:#93AC8E;--line:rgba(25,26,26,.11);
      --disp:"Newsreader","Iowan Old Style",Georgia,serif;
      --ink:#f4f2ee;--ink-2:#ece8e0;
      --ivory:#191a1a;--ivory-2:#35352f;--ivory-3:#585b58}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--ink);color:var(--ivory-2);
     font-family:'Geist',-apple-system,'Helvetica Neue',Arial,sans-serif;
     font-size:1rem;line-height:1.65}
.wrap{max-width:min(74ch,92vw);margin:0 auto;padding:0 20px}
/* ⚠️ R1 — P167.11 puis P167.15, 25/09/2026. DEUX versions périmées, écrites :
   ① « border-bottom:1px solid var(--line);background:var(--ink-2);padding:14px 0 »
      — une barre pleine posée sur la page (Louis : « on enlève le bandeau haut
      juste les textes »).
   ② « .bandeau{background:none;border:0;padding:30px 0 14px} », sans aucun
      `position` — j'y avais écrit qu'un header collant « passerait sur les
      images et deviendrait illisible ». C'était vrai d'un header RESTÉ
      transparent ; ça ne l'est plus de celui-ci.
   FAIT FOI : le header est COLLÉ, et il change d'état au défilement — sa
   deuxième moitié de phrase, « éventuellement un effet header transparent ».

   COMMENT IL TIENT SANS UNE LIGNE DE JAVASCRIPT : `position:sticky` avec
   `top:-1px` fait franchir au bloc son propre seuil, ce que `:stuck` seul ne
   permet pas encore partout ; le fond n'apparaît donc pas d'un coup, il se
   pose pendant les ~30 premiers px de défilement. Aucune classe à ajouter,
   aucun écouteur de scroll, rien à désynchroniser.

   ⚠️ LE FOND N'EST PAS UNE DÉCORATION, C'EST CE QUI REND LE TEXTE LISIBLE :
   le logo et la nav sont SOMBRES sur les pages intérieures [mesuré le
   25/09/2026 : #191A1A sur /atelier/, /realisations/, /faq/]. Sans voile, ils
   passeraient sur les photos de plafond, claires et chargées. Le voile est
   donc à 82 % d'opacité — assez pour porter le texte, assez peu pour qu'on
   voie l'image défiler dessous. `backdrop-filter` n'est qu'un CONFORT : là où
   il manque (Firefox ancien), le voile seul suffit déjà.
   ⛔ Ne pas descendre sous 0.78 sans remesurer le contraste. */
.bandeau{background:none;border:0;padding:30px 0 14px;
         position:sticky;top:-1px;z-index:40;
         transition:background-color .28s ease,box-shadow .28s ease,padding .28s ease}
@supports (position:sticky){
  .bandeau{background-color:color-mix(in srgb,var(--ink) 82%,transparent);
           -webkit-backdrop-filter:saturate(1.4) blur(14px);
           backdrop-filter:saturate(1.4) blur(14px)}
}
/* ⚠️ En HAUT de page il ne doit RIEN y avoir : le voile ne se justifie que
   sur une image. `animation-timeline:scroll()` le fait apparaître avec le
   défilement, et là où il n'existe pas, le voile reste posé — jamais
   l'inverse, un texte illisible coûte plus cher qu'un voile de trop. */
@supports (animation-timeline:scroll()){
  .bandeau{animation:voile-au-defilement linear both;
           animation-timeline:scroll();animation-range:0 90px}
  @keyframes voile-au-defilement{
    from{background-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none}
    to{background-color:color-mix(in srgb,var(--ink) 82%,transparent);
       -webkit-backdrop-filter:saturate(1.4) blur(14px);
       backdrop-filter:saturate(1.4) blur(14px);
       box-shadow:0 1px 0 color-mix(in srgb,var(--ivory) 10%,transparent)}
  }
}
@media (prefers-reduced-motion:reduce){.bandeau{transition:none;animation:none}}
.bandeau .wrap{max-width:1180px;display:flex;align-items:center;
               justify-content:space-between;gap:16px;flex-wrap:wrap}
/* ⚠️ R1 — P167.11, 25/09/2026 (Louis : « La typo de mon logo n'est pas la
   bonne non plus ») : PÉRIMÉ `font-family:'Bodoni Moda'` — une police de
   substitution, pas la sienne. FAIT FOI : le mot est un TRACÉ, vectorisé
   depuis son fichier d'impression (logo_costaud.py), donc plus aucune police
   n'entre ici. La hauteur pilote tout : le mot se cale sur elle. */
.logo{display:inline-flex;align-items:center;gap:11px;color:var(--ivory);
      text-decoration:none;line-height:1}
.logo .rosace{width:32px;height:32px;flex:none}
.logo .mot{height:19px;width:auto;display:block}
.logo small{display:block;font-family:'Geist Mono',ui-monospace,Menlo,monospace;font-size:.58rem;
            letter-spacing:.22em;color:var(--ivory-3);margin-top:3px}
nav{display:flex;gap:8px 20px;align-items:center;flex-wrap:wrap}
nav a{color:var(--ivory-2);text-decoration:none;font-size:.92rem;
      padding:11px 4px;min-height:44px;display:inline-flex;align-items:center}
nav a:hover,nav a:focus-visible{color:var(--ivory)}
/* ⚠️ R1 — P167.11, 24/09/2026 : périmé color:var(--ink) (texte dark
   VALIDE en thème sombre, où --ink=#0F110E EST le texte le plus foncé) ;
   FAIT FOI color:var(--ivory) — en thème clair --ink devient le FOND
   (#f4f2ee) et ne peut plus servir de texte sur --sage. --ivory est le
   jeton de texte principal, inchangé de rôle. Test à jour :
   test_contraste_charte.py::test_un_BOUTON_a_son_PROPRE_fond_et_il_est_mesure. */
nav .btn{background:none;color:var(--ivory);border:1px solid var(--ivory);padding:10px 17px;border-radius:2px;font-weight:500}/* filet — Louis 24/09 (QCM « Demander un chiffrage · filet ») ; périmé : background:var(--sage) plein. ⚠️ --ivory est le jeton TEXTE, --ink le FOND (thème clair, l.119) — ma 1re écriture color:var(--ink) rendait 1,00:1, attrapée par test_contraste_charte */
main{padding:44px 0 64px}
h1{font-family:var(--disp);font-weight:400;color:var(--ivory);
   font-size:clamp(1.9rem,5vw,2.9rem);line-height:1.15;margin:0 0 26px;max-width:22ch}
h2{font-family:var(--disp);font-weight:400;color:var(--ivory);
   font-size:clamp(1.25rem,3vw,1.6rem);line-height:1.25;margin:38px 0 12px}
h3{font-family:var(--disp);font-weight:400;color:var(--ivory);
   font-size:clamp(1.05rem,2.2vw,1.22rem);line-height:1.3;margin:26px 0 10px}
p{margin:0 0 15px;max-width:68ch}
a{color:var(--brass)}
a:focus-visible,nav a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
footer{border-top:1px solid var(--line);background:var(--ink-2);
       padding:30px 0;font-size:.9rem;color:var(--ivory-3)}
@media (max-width:700px){ footer{font-size:.95rem} }
footer p{margin:0 0 7px}
footer a{color:var(--ivory-2)}
@media (prefers-reduced-motion: reduce){*{animation:none!important;transition:none!important}}

/* Images des pages portées (P167, 09/09/2026).
   ⚠️ width/height sont sur le <img> pour réserver la place AVANT le
   téléchargement : sans eux le texte saute quand l'image arrive, et le CLS
   passe de 0,001 à visible. `aspect-ratio` laisse la vraie proportion
   reprendre la main une fois l'image connue. */
figure{margin:0 0 22px}
figure.lead{margin:0 0 30px}
.planche{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));margin:34px 0 8px}
.planche figure{margin:0}
img{max-width:100%;height:auto;display:block;border-radius:2px;background:var(--ink-2)}
figure.lead img{width:100%;aspect-ratio:4/3;object-fit:cover}
.planche img{width:100%;aspect-ratio:4/3;object-fit:cover}

.preuves{list-style:none;margin:0 0 26px;padding:0;display:grid;gap:10px}
.preuves li a{display:block;padding:14px 16px;border:1px solid var(--line);
  border-radius:2px;text-decoration:none;color:var(--ivory-2);min-height:44px}
/* 🛑 LE `span` N'EST PAS UN LIEN — IL NE PORTE DONC PLUS LA BORDURE DE CARTE.
   Séparé de la règle du lien le 13/09/2026 : une entrée de presse sans URL
   (1 occurrence, /presse/ [compté]) habillée comme un lien promet un clic
   qui n'existe pas. Et 1.4.11 ne porte que sur les composants d'INTERFACE :
   un texte non cliquable n'a pas d'indicateur à contraster. */
.preuves li span{display:block;padding:14px 16px;border-radius:2px;
  text-decoration:none;color:var(--ivory-2);min-height:44px}
.preuves li a:hover,.preuves li a:focus-visible{border-color:var(--brass)}
/* 🛑 WCAG 1.4.11 — LE SOULIGNEMENT EST UN INDICATEUR NON COLORIMÉTRIQUE.
   Posé le 13/09/2026 : la bordure `--line` valait 1,386:1 sur `--ink`
   [compté], loin des 3:1 exigés — elle était le SEUL indicateur du
   composant. Souligner le titre supprime la classe de défaut au lieu de
   la déplacer d'un jeton à l'autre : le lien reste identifiable même si
   la bordure devient invisible, et aucun ratio n'en dépend plus. */
.preuves li a strong{text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px}
.preuves strong{color:var(--ivory);font-family:var(--disp);font-weight:400}

/* ————————————————————————————————————————————————————————————————
   P167-UX-TELEPHONE — trois défauts MESURÉS à 390×844 le 09/09/2026,
   pas trois intuitions de design :
   ① 2 cibles sous 24×24 px au pied de page (« Demander un chiffrage »
      138×15, « Mentions légales » 103×15) — WCAG 2.2 critère 2.5.8, AA ;
   ② la photo de tête d'une page de réalisation n'était PAS visible sans
      défiler : le prescripteur ouvre le lien et voit un menu, pas l'ouvrage.
      Or il juge sur le DÉTAIL (retour de Louis, 08/09) ;
   ③ 4 textes sous 14 px, illisibles au bras tendu.
   ———————————————————————————————————————————————————————————————— */
footer a{display:inline-block;padding:14px 4px;min-height:44px;line-height:1.2}
footer p{margin-bottom:2px}
@media (max-width:700px){
  /* ② moins d'air avant l'ouvrage : la photo entre dans le premier écran */
  main{padding-top:22px}
  h1{font-size:clamp(1.6rem,7vw,2.1rem);margin-bottom:16px;max-width:none}
  figure.lead{margin-bottom:22px}
  figure.lead img{aspect-ratio:3/2}
  /* ③ plancher de lisibilité */
  body{font-size:1.02rem}
  .preuves li a,.preuves li span{font-size:.95rem}
  /* ① toute cible tactile tient les 24 px, y compris en pied de page */
  nav a,footer a,.preuves li a{min-height:44px;display:flex;align-items:center}
  footer a{display:inline-flex}
}

/* Lien « projet suivant » — l'état de l'art du 09/09/2026 le nomme comme un
   manque : sans lui, un prescripteur qui a aimé une page repart au menu. */
.suite{margin:44px 0 0;border-top:1px solid var(--line);padding-top:20px}
.suite a{display:block;text-decoration:none;padding:16px;border:1px solid var(--line);
  border-radius:2px;min-height:44px;color:inherit}
.suite a:hover,.suite a:focus-visible{border-color:var(--brass)}
.suite span{display:block;font-size:.875rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--brass);margin-bottom:6px}
.suite strong{font-family:var(--disp);font-weight:400;font-size:1.25rem;color:var(--ivory);
  text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px}   /* WCAG 1.4.11 — cf. .preuves li a strong */

/* ————————————————————————————————————————————————————————————————
   DIRECTION A — le défilement alterné. Choisie par Louis en QCM le
   09/09/2026, contre B et C que le panel préférait.
   Le rythme EST la direction : une colonne de lecture étroite, puis une
   image en fond perdu qui coupe la page sur toute sa largeur, puis la
   colonne à nouveau. L'image n'illustre pas le texte, elle l'interrompt.
   ⚠️ Sur téléphone, le fond perdu vaut la largeur d'écran entière : c'est
   là que l'alternance se sent. Sur bureau la colonne reste étroite et le
   fond perdu plafonne, sinon une macro s'étale sans rien montrer de plus.
   ———————————————————————————————————————————————————————————————— */
main > .wrap{max-width:min(68ch,92vw)}
figure.bleed{margin-inline:calc(50% - 50vw);width:100vw;max-width:100vw;margin-block:34px}
figure.bleed img{width:100%;height:auto;display:block;border-radius:0}
figure.bleed figcaption{max-width:min(68ch,92vw);margin:12px auto 0;padding:0 20px;
  font-size:.9rem;color:var(--ivory-3);line-height:1.5}
@media (min-width:1000px){
  figure.bleed{margin-inline:auto;width:auto;max-width:1120px}
  figure.bleed img{border-radius:2px}
  figure.bleed figcaption{padding:0}
}

/* ——— mise_en_forme.py — étapes et puces (11/09/2026) ——— */
ol.etapes{list-style:none;margin:18px 0;padding:0}
ol.etapes li{position:relative;padding:0 0 26px 52px}
ol.etapes li:last-child{padding-bottom:0}
ol.etapes .num{position:absolute;left:0;top:.1rem;width:38px;text-align:right;
  font-family:var(--disp);font-size:1.7rem;line-height:1;color:var(--brass)}
ol.etapes b{font-family:var(--disp);font-weight:400;font-size:1.06rem;
  color:var(--ivory)}
ul.points{list-style:none;margin:16px 0;padding:0}
ul.points li{position:relative;padding:9px 0 9px 22px;
  border-top:1px solid var(--line);color:var(--ivory-2)}
ul.points li::before{content:'';position:absolute;left:2px;top:19px;width:7px;
  height:1px;background:var(--brass)}

/* ——— icones.py — émojis-icônes en SVG (P235.3, 27/09/2026) ——— */
svg.ic{width:1em;height:1em;vertical-align:-.14em;margin-inline:0 .35em;
  fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;
  stroke-linejoin:round;color:var(--brass);flex:none}
ul.points li>svg.ic:first-child{position:absolute;left:0;top:13px;margin:0}
ul.points li:has(>svg.ic:first-child)::before{content:none}

/* ————— LE ZOOM TECHNIQUE (17/09/2026) — un gros plan sur un ouvrage que nous
   avons fabriqué et posé, et « du gros texte a côté » (Louis).
   ⚠️ R1 — PÉRIMÉ : « ni schéma dessiné ». FAIT FOI (Louis, même soir) : le
      croquis revient, en DESSIN D'ATELIER — « un peu plus dessin industrielle
      […] comme si on l'avait dessiné en CAO », « tu as supprimé le croquis
      c'est dommage je veux le garder ». Le tableau, lui, reste écarté. Le cadrage et l'échelle viennent du carnet
      `reecritures/zooms.json`, portés par --zt-cadrage / --zt-echelle. */
/* défauts du carnet — le style inline du bloc les surcharge page par page ;
   déclarés ici pour qu'aucune règle ne lise un jeton indéfini */
.zt,.zt-loupe,.zt-cao{--zt-cadrage:50% 10%;--zt-echelle:2.2}
.zt{display:grid;gap:22px;margin:44px 0}
@media(min-width:900px){
  .zt{grid-template-columns:minmax(0,1.35fr) minmax(280px,1fr);gap:44px;
    align-items:center;margin-inline:calc(50% - min(560px,46vw));
    width:min(1120px,92vw)}
}
.zt .cadre{position:relative;overflow:hidden;aspect-ratio:4/3;background:var(--ink-2)}
.zt .cadre img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:var(--zt-cadrage,50% 10%);
  transform:scale(var(--zt-echelle,2.2));
  transform-origin:var(--zt-cadrage,50% 10%);border-radius:0}
.zt .dire,.zt-loupe .dire{margin:0}
.zt .dire .eti,.zt-loupe .dire .eti{display:block;font-size:.66rem;
  letter-spacing:.2em;text-transform:uppercase;color:var(--brass);margin-bottom:14px}
.zt .dire p,.zt-loupe .dire p{margin:0;font-family:var(--disp),Georgia,serif;
  font-weight:400;color:var(--ivory);font-size:clamp(1.5rem,3.2vw,2.1rem);
  line-height:1.22}
.zt .dire .sous,.zt-loupe .dire .sous{margin-top:16px;font-family:inherit;
  font-size:.95rem;line-height:1.55;color:var(--ivory-3);max-width:34ch}

.zt-loupe{display:grid;gap:18px;margin:44px 0}
@media(min-width:900px){
  .zt-loupe{grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:28px;
    align-items:start;margin-inline:calc(50% - min(560px,46vw));
    width:min(1120px,92vw)}
}
.zt-loupe .source{position:relative;line-height:0}
.zt-loupe .source img{width:100%;height:auto;border-radius:0}
/* le cadre de repérage assombrit tout SAUF la zone montrée */
.zt-loupe .repere{position:absolute;left:4%;top:1.5%;width:92%;height:21%;
  border:1px solid var(--brass);box-shadow:0 0 0 9999px rgba(15,17,14,.45)}
.zt-loupe .agrandi{position:relative;overflow:hidden;aspect-ratio:4/3;
  background:var(--ink-2)}
.zt-loupe .agrandi img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:var(--zt-cadrage,50% 10%);
  transform:scale(var(--zt-echelle,2.1));
  transform-origin:var(--zt-cadrage,50% 10%);border-radius:0}
.zt-loupe .dire{grid-column:1/-1}

/* ————— LE ZOOM « CAO » (17/09/2026) — la photo de l'ouvrage ET son croquis
   d'atelier côte à côte : la photo prouve, le dessin explique. Le SVG est
   produit par `croquis_cao.py` depuis le carnet ; ici, seulement son ENCRE.
   🛑 La hiérarchie des traits EST le sujet : un plan se lit parce que le
      contour porté est plus gras que la ligne de construction. Aplatir ces
      épaisseurs rendrait le « croquis simpliste » que Louis a refusé. */
.zt-cao{display:grid;gap:26px;margin:48px 0}
@media(min-width:900px){
  .zt-cao{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:34px 40px;
    align-items:start;margin-inline:calc(50% - min(560px,46vw));
    width:min(1120px,92vw)}
  .zt-cao .dire{grid-column:1/-1}
}
.zt-cao .cadre{position:relative;overflow:hidden;aspect-ratio:4/3;
  background:var(--ink-2)}
.zt-cao .cadre img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:var(--zt-cadrage,50% 10%);
  transform:scale(var(--zt-echelle,2.2));
  transform-origin:var(--zt-cadrage,50% 10%);border-radius:0}
.zt-cao .plan{background:var(--ink-2);padding:18px 16px;
  border:1px solid var(--line)}
.zt-cao .dire{margin:0}
.zt-cao .dire .eti{display:block;font-size:.66rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--brass);margin-bottom:14px}
.zt-cao .dire p{margin:0;font-family:var(--disp),Georgia,serif;font-weight:400;
  color:var(--ivory);font-size:clamp(1.5rem,3.2vw,2.1rem);line-height:1.22}
.zt-cao .dire .sous{margin-top:16px;font-family:inherit;font-size:.95rem;
  line-height:1.55;color:var(--ivory-3);max-width:52ch}

/* l'encre du dessin — quatre épaisseurs, comme au bureau d'études */
svg.cao{display:block;width:100%;height:auto}
svg.cao .tr-fort{fill:none;stroke:var(--ivory);stroke-width:5;
  stroke-linecap:square}
svg.cao .tr-fin{fill:none;stroke:var(--ivory-2);stroke-width:2.2}
svg.cao .tr-axe{fill:none;stroke:var(--brass);stroke-width:1.8;
  stroke-dasharray:30 7 5 7;opacity:.75}
svg.cao .tr-cache{fill:none;stroke:var(--ivory-3);stroke-width:2;
  stroke-dasharray:10 8}
/* ⚠️ PAS D'`opacity` ICI : le banc de contraste lit toute règle sous opacity
   comme du TEXTE (elle n'a pas de `color`, il applique le défaut du corps) et
   refusait la hachure à 3,48:1. C'est un faux positif — une hachure n'est pas
   du texte —, mais la teinte pleine donne le même gris sans tendre le garde.
   🛑 Le faux positif du banc reste à signaler : il est noté au fichier d'état. */
svg.cao .cao-defs pattern line{stroke:var(--ivory-3);stroke-width:1}
svg.cao .cao-defs marker path{fill:var(--brass)}
svg.cao .hach{stroke:none}
/* ⛔ AUCUNE TAILLE DE TEXTE ICI : elle est portée par `croquis_cao.py`, qui
   CALCULE des largeurs avec. Une règle CSS l'emporterait sur l'attribut du
   SVG et le calcul deviendrait faux en silence. La feuille garde l'encre. */
svg.cao text{font-family:ui-monospace,"SFMono-Regular",Menlo,Consolas,monospace;
  letter-spacing:.06em;fill:var(--ivory-2)}
svg.cao .cao-cote .ligne{fill:none;stroke:var(--brass);stroke-width:2}
svg.cao .cao-cote text{fill:var(--brass);text-anchor:middle}
svg.cao .attache{stroke:var(--brass);stroke-width:1.4;opacity:.7}
svg.cao .cao-repere .pt{fill:var(--brass);stroke:none}
svg.cao .cao-repere circle{r:5}
svg.cao .cao-cartouche .tr-fort{stroke-width:2}
svg.cao .cao-cartouche .ct-titre{fill:var(--ivory);letter-spacing:.12em}
svg.cao .cao-cartouche .ct-cle{fill:var(--ivory-3);letter-spacing:.2em}
svg.cao .cao-cartouche .ct-val{fill:var(--ivory-2);letter-spacing:.08em}


/* ── LOT 3a (P167.12) — pages annexes, ajouts en fin de fichier UNIQUEMENT ──
   Aucune classe existante n'est modifiée. Préfixe .annexe- réservé au lot 3a.
   Neutralise le .wrap interne qu'émet encart_avis.rendre() (il porte déjà son
   propre <div class="wrap">) : sans cette règle, /avis/ imbrique deux .wrap
   (celui du GABARIT + celui de la section avis), inoffensif visuellement mais
   redondant. */
.annexe-avis .wrap{max-width:none;padding:0}

/* ═══ P250.10 — DA « Craft discret » (Louis, 30/09/2026) — mêmes jetons que l'accueil.
   Les hex ci-dessus restent le repli (navigateur sans OKLCH, banc de contraste) ; ce bloc les surcharge.
   Titres Newsreader 300, texte Geist, légendes Geist Mono 12 px ; micro-effets <= 8 px et <= 700 ms,
   coupés sous prefers-reduced-motion. ═══ */
html[lang]{
 --da-bg:oklch(97% .006 80);--da-ink:oklch(24% .01 60);--da-mute:oklch(52% .012 60);
 --da-line:oklch(88% .008 70);--da-surface:oklch(94% .008 75);--da-accent:oklch(52% .06 55);
 --da-stone:oklch(84% .008 75);--da-stone-2:oklch(66% .01 70);
 --da-disp:'Newsreader','Iowan Old Style',Georgia,serif;--da-body:'Geist',-apple-system,'Helvetica Neue',Arial,sans-serif;--da-mono:'Geist Mono',ui-monospace,Menlo,monospace;
 --fond:var(--da-bg);--fond-2:var(--da-surface);--encre:var(--da-ink);--encre-2:oklch(34% .01 60);--encre-3:var(--da-mute);
 --brass:var(--da-accent);--line:var(--da-line);--disp:var(--da-disp);
 --ink:var(--da-bg);--ink-2:var(--da-surface);--ivory:var(--da-ink);--ivory-2:oklch(34% .01 60);--ivory-3:var(--da-mute);
 --da-card:oklch(99% .004 80 / .6);
}
@media (prefers-color-scheme:dark){html[lang]:not([data-theme="light"]){
 --da-bg:oklch(19% .008 60);--da-ink:oklch(93% .006 80);--da-mute:oklch(72% .01 70);--da-line:oklch(32% .008 60);
 --da-surface:oklch(23% .008 60);--da-accent:oklch(76% .07 65);--da-stone:oklch(38% .008 60);--da-stone-2:oklch(56% .01 60);
 --encre-2:oklch(84% .008 75);--ivory-2:oklch(84% .008 75);--da-card:oklch(26% .008 60 / .6)}}
html[lang][data-theme="dark"]{
 --da-bg:oklch(19% .008 60);--da-ink:oklch(93% .006 80);--da-mute:oklch(72% .01 70);--da-line:oklch(32% .008 60);
 --da-surface:oklch(23% .008 60);--da-accent:oklch(76% .07 65);--da-stone:oklch(38% .008 60);--da-stone-2:oklch(56% .01 60);
 --encre-2:oklch(84% .008 75);--ivory-2:oklch(84% .008 75);--da-card:oklch(26% .008 60 / .6)}
html,body{background:var(--da-bg);color:var(--da-ink);font-family:var(--da-body)}
h1,h2,h3,ol.etapes b,.preuves strong,.suite strong,.avis-mise blockquote p,.avis-liste strong,.presse-lire .titre{font-family:var(--da-disp);font-weight:300;letter-spacing:-.02em}
.logo small,figcaption,small,.lab,.legende,.cartel,.avis-note,.avis-qui a,.presse-lire .date,.presse-lire .source,.zt .dire .sous,footer{font-family:var(--da-mono);font-size:12px;font-weight:400}
.avis-liste a,.avis-ini,.suite a,.preuves li a{background:var(--da-card)}
a:focus-visible,:focus-visible{outline-color:var(--da-accent)}
@keyframes da-net{from{filter:blur(6px)}to{filter:none}}
h1{animation:da-net 700ms cubic-bezier(.2,.7,.2,1) both}
main a:not(.logo):not(.btn){background:linear-gradient(currentColor,currentColor) 0 100%/0 1px no-repeat;transition:background-size 320ms ease}
main a:not(.logo):not(.btn):hover,main a:not(.logo):not(.btn):focus-visible{background-size:100% 1px}
.avis-liste a,.suite a,.preuves li a{transition:border-color 320ms ease,box-shadow 320ms ease,transform 320ms ease}
.avis-liste a:hover,.avis-liste a:focus-visible,.suite a:hover,.suite a:focus-visible{box-shadow:0 0 0 1px var(--da-accent),0 0 8px oklch(52% .06 55 / .25);transform:translateY(-2px)}
button,.btn,[type=submit]{transition:transform 160ms ease,box-shadow 320ms ease}
button:active,.btn:active,[type=submit]:active{transform:scale(.98)}
footer a{transition:color 320ms ease}
@media (prefers-reduced-motion:reduce){
 h1{animation:none!important}
 main a:not(.logo),.avis-liste a,.suite a,.preuves li a,button,.btn,[type=submit],footer a{transition:none!important}
 .avis-liste a:hover,.suite a:hover{transform:none}}

/* P250.10-logo — logo final P250.12 (30/09/2026) : encre en clair, ivoire en sombre (picture). */
.logo .logo-img{height:40px;width:auto;display:block;object-fit:contain}
@media(max-width:700px){.logo .logo-img{height:30px}}
.logo .logo-img--ivoire{display:none}
@media (prefers-color-scheme:dark){html[lang]:not([data-theme="light"]) .logo .logo-img--encre{display:none}
 html[lang]:not([data-theme="light"]) .logo .logo-img--ivoire{display:block}}
html[lang][data-theme="dark"] .logo .logo-img--encre{display:none}
html[lang][data-theme="dark"] .logo .logo-img--ivoire{display:block}
