/* Écrit par inv_publie() à chaque publication, depuis les <style>
   de index.html. Ne pas modifier ici : la prochaine publication
   écrase. Les url() supposent ce fichier à la racine du site. */
/* Chemins RELATIFS et non absolus : index.html est à la racine du site, donc
     'outils/fonts/…' fonctionne en ligne ET en ouverture locale par file://.
     En absolu, l'aperçu local pointait la racine du disque et retombait sur les
     polices système — d'où un rendu différent du site. */
  @font-face{font-family:'Amieami';src:url('outils/fonts/Amieami.woff2') format('woff2'),url('outils/fonts/Amieami.woff') format('woff');font-weight:normal;font-style:normal;font-display:swap;}
  @font-face{font-family:'FluxischElse';src:url('outils/fonts/FluxischElse.woff2') format('woff2'),url('outils/fonts/FluxischElse.woff') format('woff');font-weight:normal;font-style:normal;font-display:swap;}

  /* ---- palette cartel : aucune teinte, la couleur vient des images ---- */
  :root{
    color-scheme:light dark;
    --fond:#ffffff; --fond-2:#f4f4f4;
    --encre:#141414; --encre-2:#4a4a4a; --encre-3:#6b6b6b;
    --filet:#dcdcdc; --focus:#141414;
    /* Display provisoire, en attendant le nom vivant. Bungee Shade est retiré :
       son faux relief contredisait le chantier 2, et sa requête vers Google Fonts
       faisait mentir la notice de vie privée. Le site n'appelle plus aucun tiers. */
    --f-display:'Amieami','Iowan Old Style',Georgia,serif;
    --f-body:'Amieami','Iowan Old Style','Palatino Linotype',Georgia,serif;
    --f-alt:'FluxischElse',ui-monospace,Menlo,monospace;
    --gout:clamp(20px,5vw,72px);
    --mesure:64ch;
    --n:12;                              /* colonnes de la grille commune */
    --gcol:clamp(12px,1.8vw,28px);       /* gouttière de colonne, partout la même */
    /* Hauteur de l'en-tête. Valeur de départ seulement : le script la remplace par
       la mesure réelle à chaque défilement. Devinée, elle était plus grande que
       l'en-tête, et du contenu défilait dans l'écart sous la barre de la pièce. */
    --h-entete:3.1rem;
  }
  @media (max-width:70em){:root{--n:8}}
  @media (max-width:44em){:root{--n:4}}
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="jour"]){
      --fond:#141414; --fond-2:#1c1c1c;
      --encre:#ededed; --encre-2:#b4b4b4; --encre-3:#8f8f8f;
      --filet:#333333; --focus:#ededed;
    }
  }
  :root[data-theme="jour"]{color-scheme:light}
  :root[data-theme="nuit"]{color-scheme:dark;
    --fond:#141414; --fond-2:#1c1c1c;
    --encre:#ededed; --encre-2:#b4b4b4; --encre-3:#8f8f8f;
    --filet:#333333; --focus:#ededed;
  }

  *{box-sizing:border-box;margin:0;padding:0}
  /* le seuil est collant : une ancre doit s'arrêter sous lui, pas dessous */
  html{scroll-padding-top:var(--h-entete)}
  main{flex:1}
  body{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;
    background:var(--fond);color:var(--encre);font-family:var(--f-body);line-height:1.55;
    -webkit-font-smoothing:antialiased}
  a{color:inherit}
  a:focus-visible,summary:focus-visible,button:focus-visible{outline:2px solid var(--focus);outline-offset:3px;border-radius:2px}

  /* ---- bandes : bord à bord, gouttières larges ----
     Un seul mur. L'alternance de fond est retirée : avec une bande centrale
     plusieurs fois plus haute que les autres, elle se lisait comme un accident de
     zèbre et coupait la lecture verticale qui révèle l'alignement bord à bord.
     Restent les filets et l'air — comme un accrochage réel.

     Le rythme se fait par la respiration, trois valeurs et pas une seule :
     ample à l'arrivée et avant la signature, moyenne pour l'offre, serrée pour
     l'archive — une archive a le droit d'être dense. Empiler n'est pas composer. */
  .bande{width:100%;padding:var(--souffle,clamp(2.6rem,6vh,5rem)) var(--gout);
    border-bottom:1px solid var(--filet)}
  .seuil,.contact{--souffle:clamp(4.2rem,11vh,8.5rem)}
  /* L'ouverture ne rajoute pas d'air en haut : le seuil vient d'en poser beaucoup,
     et les deux respirations empilées creusaient un trou de douze rem sous le nom. */
  .ouverture{--souffle:clamp(2.2rem,5vh,4rem);padding-top:clamp(.4rem,1vh,1rem)}
  .activites{--souffle:clamp(2.6rem,6vh,5rem)}
  .inventaire-bande{--souffle:clamp(1.8rem,3.5vh,3rem)}
  .dedans{max-width:1600px;margin:0 auto;width:100%;display:grid;
    grid-template-columns:repeat(var(--n),minmax(0,1fr));gap:0 var(--gcol)}
  .dedans>*{grid-column:1/-1;min-width:0}
  .mesure{max-width:var(--mesure)}
  .lbl{font-family:var(--f-alt);font-size:.74rem;letter-spacing:.18em;text-transform:uppercase;
    color:var(--encre-3);display:block;margin-bottom:1rem}

  /* ---- seuil : l'en-tête qui se contracte ----
     --c va de 0 (déployé) à 1 (contracté). Une seule variable, posée au défilement ;
     tout le reste en découle par calcul, rien n'est animé en boucle.
     La contraction n'endort pas le nom : il continue de permuter, de suivre le
     curseur et de se déformer, en petit. */
  /* Le seuil ne se colle que si le script tourne : c'est lui qui pose --c. Sans lui,
     une bande collante à pleine taille mangerait l'écran sans jamais se replier. */
  .nom-vif .seuil{position:sticky;top:0;z-index:20;background:var(--fond);
    padding-top:calc(.5rem + (1 - var(--c,0)) * var(--repli));
    padding-bottom:calc(.75rem + (1 - var(--c,0)) * var(--repli));
    border-bottom-color:transparent;
    --repli:clamp(3.7rem,10vh,7.8rem)}
  .seuil.contracte{border-bottom-color:var(--filet)}
  /* max-height, jamais height : une hauteur fixe coupait la seconde ligne dès qu'on
     agrandit la taille du texte — et rien ne le signalait. Là, le repli n'entame le
     texte qu'à la toute fin de la course, et jamais au repos. */
  .seuil .lbl{margin-bottom:calc((1 - var(--c,0)) * 1rem);
    max-height:calc((1 - var(--c,0)) * 3em);overflow:hidden;
    opacity:calc(.35 + (1 - var(--c,0)) * .65)}
  .seuil .role{font-size:clamp(1.05rem,2vw,1.4rem);color:var(--encre-2);
    margin-top:calc((1 - var(--c,0)) * .35rem);
    max-height:calc((1 - var(--c,0)) * 6em);overflow:hidden;
    opacity:calc(1 - var(--c,0))}
  .ouverture .intro{font-size:clamp(1rem,1.4vw,1.15rem);color:var(--encre-2)}

  /* ---- le nom vivant ----
     Tout s'aligne sur la grille suisse, sauf lui : il déborde d'une gouttière sur
     la gauche. C'est le seul écart autorisé, et c'est là que vit le paradoxe. */
  /* .045em d'approche au lieu de .01 : c'est la marge dans laquelle le pli travaille.
     Sans elle, les lettres dérivaient les unes dans les autres et finissaient par
     s'avaler — au bout d'une minute il manquait une lettre au nom. */
  .seuil h1{font-family:var(--f-display);font-weight:400;line-height:1.12;
    /* jamais deux lignes : la capture du 29/08 montre le nom plié en deux à 80 s,
       le seuil doublé de hauteur. Le nom échappe à la grille, il ne la casse pas. */
    white-space:nowrap;
    /* Aligné à gauche sur le contenu, en grand comme en réduit. L'écart d'une
       gouttière — « le nom est le seul élément autorisé à échapper à la grille » —
       est levé le 26/08/2026 : à l'œil ça ne racontait pas un écart, ça faisait un
       défaut de calage. Le paradoxe est porté par les lettres, pas par la marge. */
    letter-spacing:.045em;
    perspective:1100px;perspective-origin:50% 45%;
    --taille:clamp(2.2rem,8vw,5.5rem);
    font-size:calc(1.6rem + (var(--taille) - 1.6rem) * (1 - var(--c,0)))}
  .mot{display:inline-block;white-space:nowrap}

  /* une lettre : un span, pas un bouton — un bouton reste focusable au clic, et le
     focus atterrirait dans un sous-arbre aria-hidden, invisible et muet. */
  .de{display:inline-block;position:relative;vertical-align:baseline;line-height:0;
    cursor:pointer;transform-style:preserve-3d}
  /* le champ suit le curseur ; le geste vit en dessous : les deux se composent */
  .champ{display:block;transform-style:preserve-3d}
  /* le pli : la trace accumulée, jamais remise à zéro */
  .scene{display:block;position:relative;transform-style:preserve-3d;
    transform:translate(var(--dx,0),var(--dy,0)) rotate(var(--rot,0deg)) scale(var(--ech,1))}
  /* line-height 1.3 : la boîte doit contenir les jambages (g, p, y) et l'accent du É.
     Le découpage de repos est un polygone à quatre sommets, pas un inset : toutes les
     découpes du jeu parlent la même langue, donc elles s'interpolent. */
  .f{display:block;line-height:1.3;white-space:pre;
    clip-path:polygon(-40% -25%,140% -25%,140% 125%,-40% 125%);
    transition:transform var(--dur,.12s) var(--ease,steps(2,end)),
               opacity var(--dur,.12s) var(--ease,steps(2,end)),
               clip-path var(--dur,.12s) var(--ease,steps(3,end))}
  .f.dessous{position:absolute;inset:0}
  .f.pose{transform:none;opacity:1}
  /* Les deux faces restent visibles, l'une sur l'autre. C'est un choix d'Eric du
     26/08/2026, contre l'arrêté de la règle des plans, et il l'assume : un état en
     précède un autre, l'un transparaît sous l'autre. Plus fouillis, moins lisse,
     plus juste. La face du dessous n'est pas sélectionnable — sans quoi copier le
     nom donnait « ÉÉrriicc CChhaaggnnoonn ». */
  .f.dessous{-webkit-user-select:none;user-select:none}

  /* les gestes : quatorze manières de partir, quatorze d'arriver, tirées séparément.
     d- = le départ (la face qui sort) ; a- = l'arrivée (la face qui entre). */
  .d-flipy  .f.sort{transform:rotateY(90deg)}       .a-flipy  .f.entre{transform:rotateY(-90deg)}
  .d-flipx  .f.sort{transform:rotateX(90deg)}       .a-flipx  .f.entre{transform:rotateX(-90deg)}
  .d-toupie .f.sort{transform:rotate(200deg) scale(.2);opacity:0}
  .a-toupie .f.entre{transform:rotate(-160deg) scale(.2);opacity:0}
  .d-volet  .f.sort{transform:scaleY(.02)}          .a-volet  .f.entre{transform:scaleY(.02)}
  .d-chute  .f.sort{transform:translateY(.55em);opacity:0}
  .a-chute  .f.entre{transform:translateY(-.55em);opacity:0}
  .d-glisse .f.sort{transform:translateX(.5em) skewX(-12deg);opacity:0}
  .a-glisse .f.entre{transform:translateX(-.5em) skewX(12deg);opacity:0}
  .d-eclat  .f.sort{transform:scale(1.7);opacity:0} .a-eclat  .f.entre{transform:scale(.35);opacity:0}
  /* pivots décentrés — l'origine est posée en ligne par le script, pour qu'elle tienne
     pendant toute la course : une origine qui change en vol tordrait l'arc */
  .d-plomb  .f.sort{transform:rotateX(-84deg);opacity:.15}   /* le caractère qui tombe de la casse */
  .a-plomb  .f.entre{transform:rotateX(-84deg);opacity:.15}
  .d-feuillet .f.sort{transform:rotateY(-104deg)}            /* le feuillet sur sa couture */
  .a-feuillet .f.entre{transform:rotateY(-104deg)}
  .d-arrache .f.sort{transform:rotate3d(1,.62,.16,74deg) translate(.12em,-.09em);opacity:0}
  .a-arrache .f.entre{transform:rotate3d(1,.62,.16,-38deg) scale(1.05);opacity:0}
  /* balayages */
  .d-rideau .f.sort{clip-path:polygon(-40% -25%,140% -25%,140% -25%,-40% -25%)}
  .a-rideau .f.entre{clip-path:polygon(-40% 125%,140% 125%,140% 125%,-40% 125%)}
  .d-racle  .f.sort{clip-path:polygon(140% -25%,140% -25%,140% 125%,140% 125%)}
  .a-racle  .f.entre{clip-path:polygon(-40% -25%,-40% -25%,-40% 125%,-40% 125%)}
  .d-biffure .f.sort{clip-path:polygon(-220% -25%,-40% -25%,-80% 125%,-260% 125%)}
  .a-biffure .f.entre{clip-path:polygon(140% -25%,320% -25%,280% 125%,100% 125%)}
  /* la coupe : aucune transition. La durée nulle est posée en ligne, face par face. */
  .d-coupe .f.sort{opacity:0}                       .a-coupe .f.entre{opacity:0}

  /* matières d'écran : définitives */
  .m-encre  {color:var(--encre)}
  .m-contour{color:transparent;-webkit-text-stroke:2px var(--encre)}
  .m-fantome{color:transparent;-webkit-text-stroke:1px var(--encre-2)}
  .m-pixel  {color:var(--encre);
    text-shadow:.055em 0 0 var(--fond),0 .055em 0 var(--fond),.055em .055em 0 var(--encre-3)}
  .m-glitch {color:var(--encre);text-shadow:-.03em 0 0 var(--encre-3),.03em 0 0 var(--fond-2)}
  .m-source {color:var(--encre-2)}
  /* Les chevrons à mi-taille et en retrait : pleine taille, ils se lisaient comme
     des lettres (la lecture à froid du 29/08 a lu « Éki>c ») et, posés dans le
     flux, ils élargissaient la lettre au point de plier le nom en deux lignes.
     La borne consignée du pli — « pour que la lettre reste lisible » — vaut
     aussi pour ce que la matière ajoute autour. */
  .m-source::before{content:'<';color:var(--encre-3);font-size:.5em;opacity:.75}
  .m-source::after{content:'>';color:var(--encre-3);font-size:.5em;opacity:.75}
  /* Matières de matière — les tuiles photographiées, déposées le 01/09/2026.
     Photos d'Eric du matin même, sauf le carton (image de banque, provisoire,
     à remplacer par sa propre photo : voir le commentaire de .m-carton).
     Traitement identique pour toutes : éclairage aplani (division par le fond
     flou), valeur ramenée à L* 46 — la seule qui passe 3:1 à la fois sur le
     papier du jour (#f5f0e8, 4,5:1) et sur la nuit (#141414, 3,6:1) —, carré
     de 448 px, AVIF avec repli WebP. Ces sept-là pèsent 108 Ko en AVIF ;
     le dossier en compte dix-huit pour 122 Ko, papiers et nuit compris.
     La tuile n'est pas étirée sur la lettre (« cover » réduirait le grain de
     quatre fois) : taille fixe, et une position tirée par lettre en --mx/--my,
     pour que deux lettres de même matière ne montrent pas le même morceau. */
  .m-papier,.m-bois,.m-metal,.m-carton,.m-feutre,.m-verge,.m-plaque,
  .m-brique,.m-orange,.m-bleu,.m-moutarde,.m-vert,.m-rose,.m-pizza{
    color:transparent;-webkit-background-clip:text;background-clip:text;
    background-size:320px 320px;background-repeat:repeat;
    background-position:var(--mx,50%) var(--my,50%)}
  .m-papier{background-image:image-set(url('content/media/matieres/papier.avif') type('image/avif'),url('content/media/matieres/papier.webp') type('image/webp'))}
  .m-bois  {background-image:image-set(url('content/media/matieres/bois.avif') type('image/avif'),url('content/media/matieres/bois.webp') type('image/webp'))}
  .m-metal {background-image:image-set(url('content/media/matieres/metal.avif') type('image/avif'),url('content/media/matieres/metal.webp') type('image/webp'))}
  /* carton : image de banque (Freepik, licence gratuite avec attribution). Tenue
     ici en attendant la photo d'Eric — il a du carton plein l'atelier. À remplacer
     avant mise en ligne, ou à créditer visiblement. */
  .m-carton{background-image:image-set(url('content/media/matieres/carton.avif') type('image/avif'),url('content/media/matieres/carton.webp') type('image/webp'))}
  .m-feutre{background-image:image-set(url('content/media/matieres/feutre.avif') type('image/avif'),url('content/media/matieres/feutre.webp') type('image/webp'))}
  .m-verge {background-image:image-set(url('content/media/matieres/verge.avif') type('image/avif'),url('content/media/matieres/verge.webp') type('image/webp'))}
  .m-plaque{background-image:image-set(url('content/media/matieres/plaque.avif') type('image/avif'),url('content/media/matieres/plaque.webp') type('image/webp'))}
  /* Les papiers des marque-pages Holy Sheet, versés le 10/09/2026. Ce sont les
     vraies couleurs de la gamme, photographiées sur les cartes elles-mêmes :
     la couleur du nom vient donc d'un objet qu'Eric fabrique, comme le reste de
     la couleur du site vient des images. Six tuiles, 3,4 Ko en AVIF — un papier
     uni se comprime à presque rien. Trois d'entre elles ont une seconde version
     pour la nuit : voir plus bas. */
  .m-brique  {background-image:image-set(url('content/media/matieres/brique.avif') type('image/avif'),url('content/media/matieres/brique.webp') type('image/webp'))}
  .m-orange  {background-image:image-set(url('content/media/matieres/orange.avif') type('image/avif'),url('content/media/matieres/orange.webp') type('image/webp'))}
  .m-bleu    {background-image:image-set(url('content/media/matieres/bleu.avif') type('image/avif'),url('content/media/matieres/bleu.webp') type('image/webp'))}
  .m-moutarde{background-image:image-set(url('content/media/matieres/moutarde.avif') type('image/avif'),url('content/media/matieres/moutarde.webp') type('image/webp'))}
  .m-vert    {background-image:image-set(url('content/media/matieres/vert.avif') type('image/avif'),url('content/media/matieres/vert.webp') type('image/webp'))}
  .m-rose    {background-image:image-set(url('content/media/matieres/rose.avif') type('image/avif'),url('content/media/matieres/rose.webp') type('image/webp'))}
  /* Le marque-page pizza, de la série F##D P#RN. Quatre pizzas au catalogue ;
     celle-ci parce qu'elle se lit encore dans un fragment — la tuile est posée
     au hasard sous chaque lettre, et il faut qu'une tomate puisse y tomber. */
  .m-pizza   {background-image:image-set(url('content/media/matieres/pizza.avif') type('image/avif'),url('content/media/matieres/pizza.webp') type('image/webp'))}
  /* Quatre tuiles ont une seconde version pour la nuit. Les couleurs des
     marque-pages sont celles des cartes, pas des valeurs choisies pour un
     écran : posés sur le noir de la nuit (#141414), le brique (L* 24), le
     vert (28) et l'orange (39) tombent sous 3:1 sur toute leur surface — la
     lettre disparaît. La pizza y perd sa croûte, la moitié de la tuile.
     Plutôt que d'éclaircir partout et de perdre le jour, la nuit reçoit la
     même tuile remontée à L* 46 (48 pour la pizza, dont l'écart est aplani
     de moitié). Le jour garde exactement les couleurs photographiées.
     Mesuré, pas estimé : voir la note de fabrication du 10/09/2026.
     Les dix autres matières tiennent sur les deux fonds sans seconde tuile.
     :not(.og):not(.capture) — les deux modes de capture posent le papier du
     jour quel que soit le thème du système, et doivent donc garder les tuiles
     du jour ; sans ça, une vignette de partage prise sur une machine en mode
     sombre sortait avec les couleurs de la nuit. */
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="jour"]):not(.og):not(.capture) .m-brique {background-image:image-set(url('content/media/matieres/brique-nuit.avif') type('image/avif'),url('content/media/matieres/brique-nuit.webp') type('image/webp'))}
    :root:not([data-theme="jour"]):not(.og):not(.capture) .m-orange {background-image:image-set(url('content/media/matieres/orange-nuit.avif') type('image/avif'),url('content/media/matieres/orange-nuit.webp') type('image/webp'))}
    :root:not([data-theme="jour"]):not(.og):not(.capture) .m-vert   {background-image:image-set(url('content/media/matieres/vert-nuit.avif') type('image/avif'),url('content/media/matieres/vert-nuit.webp') type('image/webp'))}
    :root:not([data-theme="jour"]):not(.og):not(.capture) .m-pizza  {background-image:image-set(url('content/media/matieres/pizza-nuit.avif') type('image/avif'),url('content/media/matieres/pizza-nuit.webp') type('image/webp'))}
  }
  :root[data-theme="nuit"]:not(.og):not(.capture) .m-brique {background-image:image-set(url('content/media/matieres/brique-nuit.avif') type('image/avif'),url('content/media/matieres/brique-nuit.webp') type('image/webp'))}
  :root[data-theme="nuit"]:not(.og):not(.capture) .m-orange {background-image:image-set(url('content/media/matieres/orange-nuit.avif') type('image/avif'),url('content/media/matieres/orange-nuit.webp') type('image/webp'))}
  :root[data-theme="nuit"]:not(.og):not(.capture) .m-vert   {background-image:image-set(url('content/media/matieres/vert-nuit.avif') type('image/avif'),url('content/media/matieres/vert-nuit.webp') type('image/webp'))}
  :root[data-theme="nuit"]:not(.og):not(.capture) .m-pizza  {background-image:image-set(url('content/media/matieres/pizza-nuit.avif') type('image/avif'),url('content/media/matieres/pizza-nuit.webp') type('image/webp'))}
  /* repli pour les navigateurs sans image-set() : le WebP seul */
  @supports not (background-image:image-set(url('a.webp') type('image/webp'))){
    .m-papier{background-image:url('content/media/matieres/papier.webp')}
    .m-bois  {background-image:url('content/media/matieres/bois.webp')}
    .m-metal {background-image:url('content/media/matieres/metal.webp')}
    .m-carton{background-image:url('content/media/matieres/carton.webp')}
    .m-feutre{background-image:url('content/media/matieres/feutre.webp')}
    .m-verge {background-image:url('content/media/matieres/verge.webp')}
    .m-plaque{background-image:url('content/media/matieres/plaque.webp')}
    .m-brique  {background-image:url('content/media/matieres/brique.webp')}
    .m-orange  {background-image:url('content/media/matieres/orange.webp')}
    .m-bleu    {background-image:url('content/media/matieres/bleu.webp')}
    .m-moutarde{background-image:url('content/media/matieres/moutarde.webp')}
    .m-vert    {background-image:url('content/media/matieres/vert.webp')}
    .m-rose    {background-image:url('content/media/matieres/rose.webp')}
    .m-pizza   {background-image:url('content/media/matieres/pizza.webp')}
    @media (prefers-color-scheme:dark){
      :root:not([data-theme="jour"]):not(.og):not(.capture) .m-brique {background-image:url('content/media/matieres/brique-nuit.webp')}
      :root:not([data-theme="jour"]):not(.og):not(.capture) .m-orange {background-image:url('content/media/matieres/orange-nuit.webp')}
      :root:not([data-theme="jour"]):not(.og):not(.capture) .m-vert   {background-image:url('content/media/matieres/vert-nuit.webp')}
      :root:not([data-theme="jour"]):not(.og):not(.capture) .m-pizza  {background-image:url('content/media/matieres/pizza-nuit.webp')}
    }
    :root[data-theme="nuit"]:not(.og):not(.capture) .m-brique {background-image:url('content/media/matieres/brique-nuit.webp')}
    :root[data-theme="nuit"]:not(.og):not(.capture) .m-orange {background-image:url('content/media/matieres/orange-nuit.webp')}
    :root[data-theme="nuit"]:not(.og):not(.capture) .m-vert   {background-image:url('content/media/matieres/vert-nuit.webp')}
    :root[data-theme="nuit"]:not(.og):not(.capture) .m-pizza  {background-image:url('content/media/matieres/pizza-nuit.webp')}
  }

  /* les jeux de fontes du nom. Déposés le 31/08/2026. Une déclaration ne vit ici
     que si son fichier existe : déclarées à vide, elles coûtaient sept requêtes 404
     par visite froide pour finir sur les mêmes replis système (audit du 29/08/2026).
     Les trois premières sont des sous-ensembles aux vingt glyphes du nom
     — < > A C G H I N O R a c g h i n o r É é et l'espace — d'où leur poids.
     Karrik, Terminal Grotesque, Avara : Velvetyne, OFL 1.1. */
  @font-face{font-family:'Karrik';src:url('outils/fonts/karrik-nom.woff2') format('woff2');font-display:swap}
  @font-face{font-family:'Terminal Grotesque';src:url('outils/fonts/terminal-grotesque-nom.woff2') format('woff2');font-display:swap}
  /* le fichier envoyé est Avara-Bold : on le déclare à 700, sinon le navigateur
     le prendrait pour un romain et fabriquerait un gras par-dessus un gras. */
  @font-face{font-family:'Avara';src:url('outils/fonts/avara-nom.woff2') format('woff2');font-weight:700;font-display:swap}
  /* Faune fait exception : elle est en CC BY-ND, qui interdit de redistribuer un
     fichier modifié — et un sous-ensemble EST un fichier modifié. Elle est donc
     déposée entière et inchangée, octet pour octet (38 Ko au lieu de 5).
     Crédit obligatoire, y compris à l'imprimé : Faune, Alice Savoie / Cnap. */
  @font-face{font-family:'Faune';src:url('outils/fonts/faune-text.woff2') format('woff2');font-display:swap}
  /* le fichier envoyé est NotCourierSans-Bold : déclaré à 700, comme Avara, pour que
     .t-machine tombe sur le vrai gras au lieu d'en faire fabriquer un.
     OSP, GPL v2 + exception fonte. */
  @font-face{font-family:'NotCourierSans';src:url('outils/fonts/notcouriersans-nom.woff2') format('woff2');font-weight:700;font-display:swap}
  /* Anthony, Sun Young Oh, Velvetyne, OFL 1.1 — tirée des sculptures d'Anthony Caro
     qui s'appuient l'une sur l'autre. Elle n'occupe la place de personne : elle ajoute
     un dixième créneau, parce que le reproche fait au jeu était d'avoir trop peu de
     dessins distincts, pas d'avoir trop de créneaux.
     Le sous-ensemble garde ses fonctions OpenType — c'est tout son intérêt : treize
     des seize lettres du nom ont deux variantes en plus de leur dessin de base.
     calt est active par défaut, donc les lettres se redessinent d'elles-mêmes selon
     leur voisinage. ss01 et ss02 permettent en plus de choisir un état précis. */
  @font-face{font-family:'Anthony';src:url('outils/fonts/anthony-nom.woff2') format('woff2');font-display:swap}
  /* Crickx écartée volontairement : c'est la fonte du logo Holy Sheet, la réutiliser
     ici ferait tenir deux identités par le même dessin. Le créneau manuscrit reste
     donc sur ses replis système en attendant son remplaçant. */
  /* 800 demandé à Karrik Regular : le navigateur fabrique un faux gras. Karrik a un
     vrai Bold chez Velvetyne — le déposer et remonter à 700 rendrait le dessin réel.
     Laissé à 800 en attendant, l'OFL le permet, mais c'est un épaississement calculé. */
  .t-grot{font-family:'Karrik','Helvetica Neue',Arial,sans-serif;font-weight:800;letter-spacing:-.02em}
  /* 400 et non 700 : le fichier déposé est Faune Text Regular. Demander 700 ferait
     fabriquer un faux gras au navigateur — un épaississement mécanique du dessin,
     que la licence ND de Faune n'autorise pas plus que la fausse oblique.
     Repasser à 700 le jour où Faune-Text_Bold est déposée. */
  .t-serif{font-family:'Faune','Iowan Old Style',Palatino,Georgia,serif;font-weight:400}
  .t-mono{font-family:var(--f-alt);font-weight:700;font-size:.86em}
  .t-etroit{font-family:'Terminal Grotesque','Haettenschweiler','Arial Narrow Bold',Impact,sans-serif;letter-spacing:.02em}
  /* Faune retirée de cette pile-ci tant que son italique n'est pas déposée : avec le
     seul romain déclaré, le navigateur fabriquerait une fausse oblique — même dessin
     que .t-serif, simplement penché. Iowan Old Style a un vrai italique dessiné, donc
     un écart réel. Remettre 'Faune' en tête le jour où faune-text-italic.woff2 arrive. */
  .t-italique{font-family:'Iowan Old Style',Palatino,Georgia,serif;font-style:italic;font-weight:600}
  .t-legere{font-family:'Helvetica Neue',Arial,sans-serif;font-weight:200}
  /* Crickx retirée de la pile : elle est la fonte du logo Holy Sheet, et rien ne la
     déclare plus ici. Le créneau attend son remplaçant — voir FONTES-A-RECUPERER.md.
     Attention, les replis sont fragiles : Bradley Hand n'existe que sur macOS,
     Brush Script MT que sur Windows, et le 'cursive' générique ne donne souvent rien
     ailleurs. C'est le seul créneau du nom qui repose entièrement sur le système. */
  .t-manuscrit{font-family:'Bradley Hand','Segoe Script','Brush Script MT',cursive;font-weight:700;font-size:1.04em}
  .t-machine{font-family:'NotCourierSans','American Typewriter','Courier New',Courier,monospace;font-weight:700;font-size:.9em}
  .t-titre{font-family:'Avara',Didot,'Bodoni 72','Playfair Display',Georgia,serif;font-weight:700;letter-spacing:-.01em}
  /* le dixième créneau. Pas de repli utile : aucune fonte système ne ressemble à
     Anthony, mieux vaut retomber sur la grotesque neutre que sur un faux voisin. */
  .t-anguleuse{font-family:'Anthony','Helvetica Neue',Arial,sans-serif}

  /* Deux matières reposent sur des mécanismes qui peuvent manquer — -webkit-text-stroke
     est une propriété préfixée, jamais normalisée. Sans garde, la lettre disparaît
     (contour) ou devient un rectangle de couleur (matières). Horizon dix ans. */
  @supports not (-webkit-text-stroke:1px currentColor){
    .m-contour,.m-fantome{color:var(--encre);-webkit-text-stroke:0}
  }
  /* Sans background-clip:text, une matière laisse la lettre en color:transparent,
     donc invisible. Ce repli n'en nommait que quatre sur sept : feutre, vergé et
     plaque disparaissaient. Il les nomme toutes, les six papiers compris. */
  @supports not ((background-clip:text) or (-webkit-background-clip:text)){
    .m-papier,.m-bois,.m-metal,.m-carton,.m-feutre,.m-verge,.m-plaque,
    .m-brique,.m-orange,.m-bleu,.m-moutarde,.m-vert,.m-rose,.m-pizza{color:var(--encre);background:none}
  }

  /* ---- activités : grille de vignettes ---- */
  .grille{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(15rem,100%),1fr));gap:clamp(1.2rem,3vw,2.2rem)}
  .vign{display:flex;flex-direction:column;gap:.7rem;text-decoration:none;color:inherit}
  /* Carré : les marques le sont, et un cadre 4/3 leur coupait la tête. La photo
     qui reste s'y recadre sans dommage. */
  .vign .img{aspect-ratio:1;overflow:hidden;background:var(--fond-2)}
  /* Pas de filtre gris au repos : toute la couleur vient des images, c'est la
     décision-mère. Le gris mettait en sourdine le seul organe de couleur de la page,
     et seulement sur les appareils à souris. Le cartel se tait, il ne dessature pas. */
  .vign img{width:100%;height:100%;object-fit:cover;display:block}
  .vign .nom{font-size:1.15rem;font-weight:600;line-height:1.2}
  .vign .quoi{font-family:var(--f-alt);font-size:.76rem;letter-spacing:.05em;color:var(--encre-3)}

  /* ---- inventaire (bande écrite par inventaire/admin.php) ---- */
  .inv{position:relative}
  /* 1.6rem : la marge que portait autrefois une ligne d'intro sous le titre, et qui
     manquait depuis qu'elle a été retirée — « Inventaire » collait aux colonnes. */
  .inv h2{font-family:var(--f-alt);font-size:.74rem;font-weight:400;letter-spacing:.18em;
    text-transform:uppercase;color:var(--encre-3);margin-bottom:1.6rem}
  /* Une colonne peut porter plusieurs catégories : trois catégories d'une pièce
     ne font plus trois guérites d'une ligne à côté d'une tour de neuf. Le PHP
     répartit les catégories consécutives en colonnes de hauteurs voisines,
     sans jamais rompre l'ordre de lecture. */
  .inv-colonnes{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(16rem,100%),1fr));gap:2rem 2.6rem}
  .inv-col{align-content:start}
  .inv-groupe+.inv-groupe{margin-top:2.2rem}
  /* Deux niveaux, deux registres — pas deux tailles. « INVENTAIRE » est un titre de
     bande : capitales espacées, comme PROJETS et ÉCRIRE. Une catégorie est du
     contenu : bas-de-casse, fonte de labeur, encre plus présente. Au même registre,
     les deux se lisaient sur le même plan et le classement devenait illisible. */
  .inv-groupe h3{font-family:var(--f-body);font-size:1.02rem;font-weight:700;
    letter-spacing:0;text-transform:none;color:var(--encre);margin-bottom:.4rem}
  /* le remix : cinq icônes poussées à droite, sur la ligne du titre. Posé par le
     script et absent du HTML livré — sans JS, l'inventaire garde l'ordre publié.
     Le bloc-tête est construit en JS autour du h2 existant, pour ne rien changer
     à ce que le CMS écrit. */
  .inv-tete{display:flex;align-items:center;justify-content:space-between;
    gap:1rem;flex-wrap:wrap;margin-bottom:.9rem}
  /* la marge passe du h2 au bloc qui le contient : sinon elle s'appliquerait au
     titre seul et les icônes, alignées dessus, resteraient collées à la suite. */
  .inv-tete>h2{margin:0}
  .inv-remix{display:flex;align-items:center;gap:.15rem;margin:0}
  /* 2rem de cible : au-dessus des 24 px que réclame WCAG 2.2, sans peser autant
     que les 2.75rem de la barre flottante, qui est seule sur son bord. */
  .inv-remix button{display:inline-flex;align-items:center;justify-content:center;
    width:2rem;height:2rem;padding:0;border:0;border-radius:3px;background:none;
    color:var(--encre-3);cursor:pointer;transition:color .12s,background-color .12s}
  .inv-remix button:hover{color:var(--encre);background:var(--filet)}
  /* --accent n'a jamais été défini : le site n'a pas de couleur d'accent, toute
     la couleur vient des images — c'est la décision-mère, écrite plus haut.
     Une variable absente rend la déclaration invalide, et une déclaration
     invalide dans une règle PLUS SPÉCIFIQUE efface celle qui aurait dû
     s'appliquer. Conséquences, jusqu'au 10/09/2026 : le bouton actif ne changeait
     pas de couleur, et surtout les cinq boutons de remix n'avaient AUCUN contour
     de focus — la règle générale de la ligne 114 était annulée par celle-ci. */
  .inv-remix button[aria-pressed="true"]{color:var(--encre);background:var(--filet)}
  .inv-remix button:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
  .inv-remix svg{width:17px;height:17px;display:block}
  @media (prefers-reduced-motion:reduce){.inv-remix button{transition:none}}
  /* un groupe reconstruit par le remix n'a pas toujours de titre : le sans-titre
     ne doit pas laisser un blanc là où l'œil attend une ligne. */
  .inv-groupe.sans-titre>h3{display:none}
  .inv-liste{list-style:none;border-top:1px solid var(--filet)}
  .inv-liste>li{border-bottom:1px solid var(--filet)}
  /* la coche au crayon sur le catalogue : le temps de la session, une pièce déjà
     ouverte passe en encre secondaire. Rien n'est stocké, rien ne sort du navigateur. */
  .inv-piece[data-vu] .inv-titre{color:var(--encre-2)}
  .inv-piece>summary{display:flex;align-items:baseline;gap:.6rem;padding:.7rem .1rem;cursor:pointer;list-style:none}
  .inv-piece>summary::-webkit-details-marker{display:none}
  .inv-titre{font-size:.98rem;overflow-wrap:anywhere}
  .inv-annee{font-family:var(--f-alt);font-size:.72rem;color:var(--encre-3);margin-left:auto}
  .inv-piece>summary:hover .inv-titre{text-decoration:underline;text-underline-offset:3px}
  /* la pièce en cours : la même ligne, mais rien ne s'ouvre. Trois points après
     le titre, pas de main, pas de soulignement — elle ne promet rien encore. */
  .inv-encours{display:flex;align-items:baseline;gap:.6rem;padding:.7rem .1rem;
    cursor:default;color:var(--encre-2)}
  .inv-encours .ic{vertical-align:-.12em;margin-left:.34em;opacity:.45}
  .inv-vide{color:var(--encre-3)}
  /* fantôme : ces règles ne servent jamais dans index.html, où aucune pièce ne
     porte la classe — elles n'existent que pour index-local.html, écrit à côté
     et retenu par .gitignore. Les garder ici évite deux feuilles de style à
     tenir d'accord. La ligne s'estompe sans devenir illisible : c'est une pièce
     de travail, pas une pièce éteinte. */
  .inv-fantome{opacity:.55}
  .inv-fantome:hover,.inv-fantome[open]{opacity:.85}
  .inv-fantome .inv-titre .ic{vertical-align:-.12em;margin-left:.34em;opacity:.6}

  /* corps d'une pièce : replié sous la ligne sans JS, repris par le panneau avec JS */
  .inv-corps{padding:0 .1rem 1.2rem;max-width:var(--mesure)}
  .inv-texte{color:var(--encre-2);margin-bottom:.8rem}
  .inv-images{margin:.9rem 0}
  /* Un scénario : une démo interactive embarquée en cadre depuis
     inventaire/scenarios/ (01/09/2026). La hauteur vient du cadre lui-même par
     postMessage ; 560 px de repli si le script ne parle pas, et ça défile dedans.
     Le cadre prend toute la mesure : une démo à demi-largeur ne se lit pas. */
  .inv-scenario{margin:1.2rem 0 1.8rem;max-width:none}
  /* Aucune bordure : la démo dessine sa propre fenêtre (barre, coins, ombre).
     Deux cadres emboîtés font un cadre de trop. Et rien ne défile dedans : la
     hauteur annoncée est celle du contenu, au pixel. */
  /* Pas de transition sur la hauteur : le cadre s'anime, la démo remesure le
     cadre en train de bouger, réannonce, relance l'animation — le cadre n'arrive
     jamais et paraît « pas fixe ». La hauteur se pose d'un coup. */
  .inv-scenario iframe{display:block;width:100%;height:var(--h,560px);border:0;
    background:transparent;overflow:hidden}
  .inv-scenario figcaption{font-family:var(--f-alt);font-size:.78rem;color:var(--encre-3);margin-top:.5rem}
  .inv-scenario figcaption a{color:inherit}
  @media (prefers-reduced-motion:reduce){.inv-scenario iframe{transition:none}}
  @media print{.inv-scenario iframe{display:none}
    .inv-scenario figcaption::after{content:' (démonstration en ligne, non imprimée)'}}
  .inv-zoom{display:block;line-height:0;cursor:zoom-in}
  /* Une porte : un mot de la phrase qui mène ailleurs — une page, une source,
     quelqu'un, ou les images de la pièce par-dessus le texte. Le geste vient de
     l'ancien Pulse ; l'icône dit où l'on va avant qu'on y aille. */
  .inv-porte{display:inline;line-height:inherit;cursor:pointer;
    text-decoration:underline;text-underline-offset:3px;
    text-decoration-color:var(--encre-3);text-decoration-thickness:1px}
  .inv-porte:hover{text-decoration-color:currentColor}
  .inv-porte .ic{vertical-align:-.18em;margin-left:.24em;opacity:.5;transition:opacity .15s}
  .inv-porte:hover .ic,.inv-porte:focus-visible .ic{opacity:1}
  /* le point médian isolé : aucune ligature ne se forme à travers lui */
  .pm{font-feature-settings:'liga' 0,'dlig' 0,'calt' 0}
  /* La porte en attente : le mot est marqué, rien ne se clique. Soulignée en
     pointillé — des points de suspension sous le mot — et sans changement au
     survol : elle ne promet rien encore. C'est la réponse aux href="#" que
     l'ancien Pulse accumulait : l'attente se dit, elle ne se simule pas. */
  .inv-attente{cursor:default;color:var(--encre-2);
    text-decoration-style:dotted;text-decoration-color:var(--encre-3)}
  .inv-attente:hover{text-decoration-color:var(--encre-3)}
  .inv-attente .ic{opacity:.45}
  .inv-attente:hover .ic{opacity:.45}
  .inv-corps img{display:block;max-width:100%;height:auto;background:transparent}
  /* Les liens d'une pièce : un par ligne, chacun suivi de l'icône de son type.
     Le geste vient de l'ancien Pulse — savoir ce qu'on va trouver avant de cliquer.
     L'icône est décorative ; le type est aussi écrit, hors de vue, pour qui ne la
     voit pas. Le sprite est posé une fois dans la section, sans requête. */
  .inv-liens{list-style:none;display:flex;flex-direction:column;gap:.35rem;margin-top:.9rem}
  .inv-liens a{display:inline-flex;align-items:center;gap:.42rem;
    text-underline-offset:4px;width:fit-content}
  .inv-liens .ic{flex:none;opacity:.55;transition:opacity .15s}
  .inv-liens a:hover .ic,.inv-liens a:focus-visible .ic{opacity:1}
  .ic-sprite{position:absolute;width:0;height:0;overflow:hidden}
  .hors-vue{position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}

  /* ---- la fenêtre interne : par-dessus la bande inventaire ---- */
  /* La pièce ne recouvre rien : elle prend la place du contenu, entre l'en-tête et le
     pied. L'en-tête reste visible et collant, le pied se retrouve au bout, le
     défilement est celui de la page — pas un défilement dans une boîte. Et le contenu
     de la pièce tombe sur les mêmes colonnes que tout le reste : la grille tient à
     tout moment, y compris ici. */
  .piece[hidden]{display:none}
  main.piece-ouverte>.bande:not(.seuil):not(.piece){display:none}
  .piece .dedans{row-gap:0}
  /* la barre reste sous l'en-tête pendant qu'on lit : le bouton de fermeture ne
     s'échappe jamais en haut de page */
  .piece-barre{grid-column:1/-1;position:sticky;top:var(--h-entete);z-index:5;
    background:var(--fond);display:flex;align-items:baseline;gap:1rem;flex-wrap:wrap;
    padding:.9rem 0;border-bottom:1px solid var(--filet);margin-bottom:1.8rem}
  /* Seuil contracté : l'en-tête maigrit, --h-entete avec lui, et la barre collante
     vient se caler plus haut — le titre se retrouve serré sous le bord. On lui rend
     l'air que la contraction lui a pris. Le seuil est le premier enfant de main et
     le panneau le dernier : le combinateur de frères suffit, sans :has() ni classe
     supplémentaire posée par le script. */
  #seuil.contracte ~ #piece .piece-barre{padding-top:1.25rem}
  /* h1 autant que h2 : sur la fiche, le nom de la pièce est le titre de la page,
     et il se pose dans la même barre. Une seule règle pour un seul objet. */
  .piece-barre h1,.piece-barre h2{font-size:clamp(1.2rem,2.5vw,1.7rem);font-weight:600;line-height:1.2;
    margin:0;text-transform:none;letter-spacing:0;color:var(--encre);font-family:var(--f-body)}
  .piece-barre .an{font-family:var(--f-alt);font-size:.78rem;color:var(--encre-3)}
  .piece-fermer{margin-left:auto;font-family:var(--f-alt);font-size:.74rem;
    letter-spacing:.16em;text-transform:uppercase;
    display:inline-flex;align-items:center;gap:.5rem;
    min-height:2.75rem;padding:0 .9rem;cursor:pointer;
    background:transparent;border:1px solid var(--encre-3);color:var(--encre-2)}
  .piece-fermer:hover{border-color:var(--encre);color:var(--encre)}
  /* Le raccourci d'édition n'existe qu'en local : le JS ne le révèle que si
     l'hôte est localhost, file: ou .local. Il n'apparaît jamais en ligne. */
  .piece-editer{margin-left:.6rem;font-family:var(--f-alt);font-size:.74rem;
    letter-spacing:.06em;color:var(--encre-3);border:1px dashed var(--filet);
    border-radius:2px;padding:.28rem .55rem;text-decoration:none;white-space:nowrap}
  .piece-editer:hover{border-color:var(--encre);color:var(--encre)}
  @media print{.piece-editer{display:none}}
  .piece-fermer .x{font-size:1.1em;line-height:1}
  /* le corps de la pièce hérite de la grille commune */
  .panneau-corps{grid-column:1/-1}
  .panneau-corps .inv-corps{max-width:none;padding:0 0 3rem}
  .panneau-corps .inv-texte{font-size:1.05rem;margin-bottom:1.4rem}
  /* Les images se rendent en planches groupées par série : une fiche a plusieurs
     pages, un livre plusieurs doubles. Chaque planche prend la proportion de son
     image — rien n'est rogné, rien ne flotte au milieu d'une cellule trop haute.
     Elles coulent en colonnes plutôt qu'en rangées : deux images de formats
     différents ne laissent pas de trou sous la plus courte. */
  .inv-serie{margin:0 0 1.5rem}
  .inv-serie:last-child{margin-bottom:0}
  /* Le titre de série. La règle visait « .inv-serie>h4 » alors que le h4 vit dans
     un <header> : elle n'a jamais rien atteint, et le titre sortait sans mise en
     forme — d'où son air de texte égaré. Corrigé le 01/09/2026, les deux formes
     couvertes. Le nom seul : ni numéro, ni compte de planches. */
  .inv-serie>h4,.inv-serie-tete h4{font-family:var(--f-alt);font-size:.7rem;letter-spacing:.14em;
    text-transform:uppercase;color:var(--encre-3);margin:0;font-weight:400}
  .inv-serie-tete{margin:0 0 1.25rem}
  /* Grid, pas multicol. Les colonnes CSS peignaient l'anneau de focus en
     fragments et en résidus (WebKit, constat d'Eric du 29/08 : cadres noirs
     arrondis orphelins autour et à côté des vignettes). Et leur ordre de
     lecture était vertical, contredisant « image n sur N » et les portes
     img:2-5. Le grid lit à l'horizontale et ne fragmente rien. */
  .inv-planches{display:grid;grid-template-columns:1fr;gap:var(--gcol);
    align-items:start}
  .plaque{margin:0}
  /* Le vrac : deux empilements de hauteurs voisines, calculés par le PHP à la
     publication (partition contiguë — l'ordre du modèle tient). Les visuels
     remontent, sans multicol donc sans fantômes de peinture. */
  /* --plc : le nombre de colonnes choisi par pièce, émis en style en ligne.
     Repli à 2 si l'attribut manque (pièces d'avant le réglage). */
  .inv-planches.inv-fluide,
  .panneau-corps .inv-corps .inv-planches.inv-fluide{grid-template-columns:repeat(var(--plc,2),1fr)}
  /* Téléphone : la répartition calculée côté serveur ne peut pas se redistribuer.
     Les colonnes se dissolvent et les images coulent d'elles-mêmes sur deux rangs. */
  @media (max-width:44em){
    .inv-planches.inv-fluide,
    .panneau-corps .inv-corps .inv-planches.inv-fluide{grid-template-columns:repeat(2,1fr)}
    .inv-fluide>.pl-col{display:contents}
  }
  .pl-col{display:grid;gap:var(--gcol);align-content:start;min-width:0}
  .plaque .inv-zoom{display:block;aspect-ratio:var(--ar,4/5);background:var(--fond-2);
    box-shadow:inset 0 0 0 1px transparent;transition:box-shadow .15s}
  .plaque .inv-zoom:hover{box-shadow:inset 0 0 0 1px var(--filet)}
  .plaque picture{display:block;width:100%;height:100%}
  .plaque img{width:100%;height:100%;max-height:none;object-fit:contain}
  .plaque figcaption{font-family:var(--f-alt);font-size:.68rem;line-height:1.4;
    color:var(--encre-3);margin-top:.4rem}
  .panneau-corps .inv-images{margin:0}
  .panneau-corps .inv-planches{grid-template-columns:repeat(2,1fr)}

  /* Ce qu'Eric écrivait dans le Pulse : des paragraphes, des titres de section,
     un filet pour séparer, l'italique, et la citation attribuée. Rien de plus —
     il n'a jamais employé ni liste, ni gras, ni tableau. */
  .inv-texte>*+*{margin-top:.85em}
  .inv-texte h3{font-family:var(--f-body);font-size:1.05em;font-weight:700;
    letter-spacing:0;text-transform:none;margin-top:1.6em}
  .inv-texte h4{font-family:var(--f-alt);font-size:.74em;letter-spacing:.12em;
    text-transform:uppercase;color:var(--encre-3);margin-top:1.4em;font-weight:400}
  .inv-texte hr{border:0;border-top:1px solid var(--filet);margin:1.6em 0;width:100%}
  .inv-texte blockquote{margin-left:0;padding-left:1.1em;
    border-left:2px solid var(--filet);color:var(--encre-3)}
  .inv-texte blockquote footer{font-family:var(--f-alt);font-size:.74em;
    letter-spacing:.04em;margin-top:.5em}
  .inv-texte blockquote footer::before{content:'— '}

  /* Continuer la balade : les pièces qui prolongent celle-ci. La flèche précède
     le nom — elle pointe le chemin — et reste hors du soulignement et de la
     copie : décorative, posée en CSS. */
  .inv-voisins{margin-top:1.8rem;padding-top:.9rem;border-top:1px solid var(--filet)}
  .inv-voisins h4{font-family:var(--f-alt);font-size:.7rem;letter-spacing:.14em;
    text-transform:uppercase;color:var(--encre-3);margin:0 0 .5rem;font-weight:400}
  .inv-voisins ul{list-style:none;display:flex;flex-wrap:wrap;gap:.3rem 1.2rem}
  .inv-voisins li::before{content:'\2192\00A0';color:var(--encre-3)}
  .inv-voisins li{display:inline-flex;align-items:baseline}
  .inv-voisins a{text-decoration:underline;text-underline-offset:3px;
    text-decoration-color:var(--encre-3);text-decoration-thickness:1px}
  .inv-voisins a:hover{text-decoration-color:currentColor}
  /* Cibles tactiles : ces renvois font 25 px de haut — au-dessus du plancher
     WCAG 2.2 AA (24 px), sous les 44 px que recommandent iOS et Material.
     Sur écran tactile seulement, on les épaissit ; la souris ne perd rien. */
  @media (pointer:coarse){
    .inv-voisins li{align-items:center}
    .inv-voisins a{display:inline-block;padding-block:.6rem}
  }

  /* ---- contact ---- */
  .contact a{font-size:clamp(1.1rem,2.4vw,1.6rem);text-decoration:underline;text-underline-offset:6px;
    text-decoration-thickness:1px}
  .contact a:hover{text-decoration-thickness:2px}

  /* ---- pied ---- */
  footer{width:100%;padding:1.6rem var(--gout) 3rem;font-family:var(--f-alt);font-size:.72rem;
    letter-spacing:.05em;color:var(--encre-3)}
  footer .dedans{display:flex;justify-content:space-between;flex-wrap:wrap;gap:.8rem}
  footer a{text-decoration:underline;text-underline-offset:3px}
  /* Nues : ni cercle, ni fond, ni bordure — juste les signes. Les icônes se posent
     à 20 px du bord droit et du haut ; les zones cliquables, elles, font 44 px et
     débordent autour sans se voir. Chaque bouton est centré : (44 − 20) / 2 = 12.
     Deux commandes désormais : arrêter le nom, et changer le jour en nuit. */
  .commandes{position:fixed;z-index:30;--cible:2.75rem;--ico:20px;
    top:calc(20px - (var(--cible) - var(--ico)) / 2);
    right:calc(20px - (var(--cible) - var(--ico)) / 2);
    display:flex;align-items:center}
  .theme{display:grid;place-items:center;width:var(--cible);height:var(--cible);
    background:none;border:0;padding:0;color:var(--encre-3);cursor:pointer}
  .theme:hover{color:var(--encre)}
  #theme[aria-pressed="true"] svg{transform:rotate(180deg)}
  /* un seul des deux signes à la fois : carré quand ça tourne, triangle sinon */
  #vie[data-vie="on"] .i-play,#vie[data-vie="off"] .i-stop{display:none}
  #vie[data-vie="off"]{color:var(--encre)}
  .piece:focus-visible{outline:2px solid var(--focus);outline-offset:-4px}
  .mz-privacy{flex-basis:100%;margin-top:1rem;padding-top:1rem;border-top:1px solid var(--filet);
    font-family:var(--f-body);font-size:.8rem;letter-spacing:0;line-height:1.6;color:var(--encre-3)}
  .mz-privacy summary{cursor:pointer;list-style:none;display:inline-flex;gap:.5rem;align-items:baseline;
    font-family:var(--f-alt);font-size:.72rem;letter-spacing:.05em;padding:.55rem 0}
  .mz-privacy summary::-webkit-details-marker{display:none}
  .mz-privacy summary::before{content:'+';font-weight:700}
  .mz-privacy details[open] summary::before{content:'–'}
  .mz-privacy p{margin-top:.7rem;max-width:76ch}
  .mz-privacy a{color:var(--encre);text-decoration:underline;text-underline-offset:3px}

  /* ---- visionneuse plein écran ---- */
  .inv-vue{border:0;padding:0;background:transparent;max-width:100vw;width:100%;
    height:100vh;height:100dvh;max-height:100dvh}
  .inv-vue::backdrop{background:rgba(0,0,0,.93)}
  .inv-vue-corps{display:flex;flex-direction:column;height:100%;padding:1rem;gap:.6rem;cursor:zoom-out}
  .inv-vue img{flex:1;min-height:0;width:100%;object-fit:contain;background:transparent}
  .inv-vue-bas{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;cursor:auto;
    font-family:var(--f-alt);font-size:.76rem;color:#ededed}
  .inv-vue-bas .leg{flex:1;min-width:6rem}
  .inv-vue button{font-family:var(--f-alt);font-size:.9rem;min-width:2.75rem;min-height:2.75rem;
    border:1px solid rgba(237,237,237,.45);background:transparent;color:#ededed;cursor:pointer}
  .inv-vue button:hover{border-color:#ededed}
  .inv-vue button:focus-visible{outline:2px solid #ededed;outline-offset:2px}
  .inv-vue button[disabled]{opacity:.45;cursor:default}

  /* ---- grille suisse : un seul système de colonnes pour toutes les bandes.
     Vignettes et colonnes d'inventaire partagent les mêmes bords, d'une bande à
     l'autre. Le nom est le seul élément autorisé à échapper à la grille.
     Repli sans subgrid : les grilles auto-fill déclarées plus haut. ---- */
  @supports (grid-template-columns:subgrid){
    .grille{grid-template-columns:subgrid;column-gap:var(--gcol)}
    .vign{grid-column:span 3}
    .inv{display:grid;grid-template-columns:subgrid;column-gap:var(--gcol)}
    .inv>*{grid-column:1/-1}
    /* UN SEUL FLUX (chantier K, 29/08/2026) : les deux colonnes texte|images
       sont abandonnées — deux murs qui s'ignoraient. Le texte garde sa mesure,
       les chapitres prennent la largeur, et le texte reprend entre eux là où
       les marqueurs (planches:N-M) le décident. */
    .panneau-corps,.panneau-corps .inv-corps{display:grid;grid-template-columns:subgrid;
      column-gap:var(--gcol);grid-column:1/-1;row-gap:0}
    .panneau-corps .inv-corps>*{grid-column:1/-1}
    .panneau-corps .inv-texte,.panneau-corps .inv-liens{grid-column:1/span 7;max-width:var(--mesure)}
    .panneau-corps .inv-voisins{grid-column:1/span 7}
    .panneau-corps .inv-images{margin:1.4rem 0 2rem}
    .inv-colonnes{grid-template-columns:subgrid;column-gap:var(--gcol)}
    /* la largeur de colonne suit le nombre de colonnes que le PHP a retenu */
    .inv-col{grid-column:span var(--inv-span,3)}
    @media (max-width:70em){
      .vign{grid-column:span 4}
      .inv-col{grid-column:span 4}
      .panneau-corps .inv-texte,.panneau-corps .inv-liens,
      .panneau-corps .inv-voisins{grid-column:1/-1;max-width:var(--mesure)}
      .panneau-corps .inv-planches{grid-template-columns:repeat(3,1fr)}
    }
    @media (max-width:44em){
      /* une vignette par rangée : à span 2 sur quatre colonnes, l'image tombait
         à 160 px de large sur un téléphone — le repli sans subgrid, lui, en
         donnait une pleine largeur. Les deux chemins se rejoignent ici. */
      .vign{grid-column:span 4}
      .inv-col{grid-column:span 4}
      .panneau-corps .inv-texte,.panneau-corps .inv-liens,
      .panneau-corps .inv-voisins{grid-column:1/-1}
      /* téléphone : deux planches par colonne. Une seule obligeait à faire
         défiler dix écrans pour voir dix images. */
      .panneau-corps .inv-planches{grid-template-columns:repeat(2,1fr)}
    }
  }

  @media (prefers-reduced-motion:reduce){
    *{transition-duration:.01ms !important;animation-duration:.01ms !important}
    /* l'en-tête ne colle pas : la barre de la pièce n'a rien sous quoi se caler */
    :root{--h-entete:0px}
    /* le nom s'arrête : aucune mutation spontanée, ni geste, ni champ, ni pli.
       Il ne permute plus qu'au survol, et sans mouvement. Non négociable —
       une animation continue rend certaines personnes malades. */
    .f{transition:none}
    .champ{transform:none !important}
    .scene{transform:none !important}
  }
  /* en contraste forcé, un bouton sans bordure ni fond n'a plus de cible visible ;
     et les matières du nom (contour, ombre, dégradé découpé au texte) s'effondrent —
     on rend le nom à l'encre du système avant qu'il ne disparaisse. */
  @media (forced-colors:active){
    .piece-fermer,.inv-vue button{border:1px solid ButtonBorder}
    .f{color:CanvasText !important;-webkit-text-stroke:0 !important;
       text-shadow:none !important;background:none !important}
    .m-source::before,.m-source::after{content:none}
  }

  @media print{
    @page{margin:16mm}
    :root,:root:not([data-theme="jour"]),:root[data-theme="nuit"]{
      --fond:#fff;--fond-2:#fff;--encre:#000;--encre-2:#222;--encre-3:#555;--filet:#999;
      color-scheme:light}
    body{background:#fff;color:#000}
    .bande{padding:0 0 1.4rem;border-color:#999}
    .commandes,.theme,.mz-privacy,.inv-vue,.piece,.vign .img{display:none}
    main.piece-ouverte>.bande{display:block}   /* on imprime la page, pas la pièce ouverte */
    .inv-colonnes{display:block}
    .inv-piece{break-inside:avoid}
    .inv-piece:not([open])>:not(summary){display:block}
    .inv-piece::details-content{content-visibility:visible;display:block}
    .inv-corps img{break-inside:avoid;height:auto;width:auto;max-height:7cm;max-width:5.5cm}
    main a[href^="http"]::after{content:" (" attr(href) ")";font-size:.8em}
    /* Depuis le 09/09/2026 l'accueil ne porte que des résumés : ce qui s'imprime
       est un catalogue de notices, et le corps entier d'une pièce s'imprime
       depuis sa propre page. Les pièces déjà ouvertes ont reçu leur corps et
       l'impriment ; les autres donnent leur résumé et leur adresse — de quoi
       retrouver la pièce depuis la feuille. */
    .inv-suite a::after{content:" — eric-chagnon.be" attr(href);font-size:.8em;color:#555}
    /* le nom en encre pleine : le seuil ne colle plus, rien ne se contracte, aucune
       face cachée, aucune matière. Un cartel imprimé ne fait pas de relief. */
    /* --c est un style en ligne sur <html> : seul un !important d'auteur le bat.
       Sans ça, on imprimait l'en-tête dans l'état contracté où on avait laissé la page. */
    :root{--c:0 !important}
    .nom-vif .seuil,.seuil{position:static;padding:0 0 1.4rem;border-bottom-color:#999}
    .seuil .lbl,.seuil .role{max-height:none;opacity:1;overflow:visible;margin-top:0}
    /* hors mode capture seulement : la carte, elle, s'imprime telle qu'elle se voit */
    html:not(.capture) #nom{font-size:2.4rem;margin-left:0;perspective:none}
    html:not(.capture) .f.dessous{display:none}
    html:not(.capture) .f,html:not(.capture) .scene,html:not(.capture) .champ,html:not(.capture) .de{
      transform:none !important;clip-path:none !important;transition:none !important;opacity:1 !important}
    html:not(.capture) .f{font-family:var(--f-body) !important;color:#000 !important;
      -webkit-text-stroke:0 !important;text-shadow:none !important;background:none !important}
    html:not(.capture) .m-source::before,html:not(.capture) .m-source::after{content:none}
  }

  /* ---- mode capture : ?graine=N&capture -----------------------------------
     Le nom seul, figé, posé au format carte de visite. C'est ainsi que la
     planche se fabrique : le navigateur d'Eric imprime en PDF (Cmd-P) et rend un
     fichier VECTORIEL, fontes réelles incorporées, matières en images — ce
     qu'aucune capture d'écran ni aucun script hors navigateur n'égale.
     La page fait 91 × 61 mm : 85 × 55 plus 3 mm de fond perdu. Le numéro de
     graine est imprimé dans le fond perdu : c'est le colophon qui rejoue la
     carte. Sans le paramètre, rien de tout ceci n'existe. */
  html.capture{background:#f5f0e8}
  html.capture body{margin:0;background:#f5f0e8}
  html.capture body>*:not(main),html.capture main>*:not(#seuil),html.capture .commandes,
  html.capture #seuil .dedans>*:not(#nom):not(.capture-pied):not(.capture-num){display:none !important}
  html.capture #seuil{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;
    padding:0;margin:0;border:0;height:100vh;background:#f5f0e8}
  html.capture #seuil .dedans{display:block;width:91mm;height:61mm;position:relative;max-width:none;padding:0;margin:0}
  html.capture #nom{position:absolute;left:0;right:0;top:11mm;margin:0;text-align:center;
    font-size:12.5mm;line-height:1;white-space:nowrap;perspective:900px}
  html.capture .capture-pied{position:absolute;left:9mm;bottom:9mm;margin:0;font-family:var(--f-alt);
    font-size:2.3mm;color:#1a1712;letter-spacing:.02em}
  html.capture .capture-pied b{font-weight:400;color:#c84b00;display:block;margin-top:1mm}
  html.capture .capture-num{position:absolute;left:4mm;top:1.2mm;margin:0;font-family:var(--f-alt);font-size:1.6mm;color:#9a968e}
  @media print{
    html.capture{-webkit-print-color-adjust:exact;print-color-adjust:exact}
    html.capture #seuil{position:static;height:61mm}
  }

  /* ---- le sommaire d'une pièce, sur l'accueil ------------------------------
     Le résumé et son lien, en attendant le corps que le dépli va chercher.
     Rien de neuf à l'œil : le texte reprend .inv-texte, le lien se pose comme
     les liens typés de la fiche. Le seul ajout est l'attente — une pièce qui
     charge ne doit pas paraître vide. */
  /* Le titre d'une pièce dans son summary : un h4 depuis le 09/09/2026, pour
     que la hiérarchie tienne. Il ne doit rien changer à l'œil — d'où la remise
     à plat des marges et du poids que le navigateur donne aux titres.
     Restreint au summary : sans cette borne, la règle aplatissait aussi le h1
     des fiches, qui se rendait alors en corps de texte. */
  summary .inv-titre{margin:0;font-size:inherit;font-weight:inherit;line-height:inherit;display:inline;
    font-family:inherit;letter-spacing:inherit}
  .inv-suite{margin-top:.9rem;font-family:var(--f-alt);font-size:.82rem;letter-spacing:.04em}
  .inv-suite a{color:var(--encre-2);text-decoration:none;border-bottom:1px solid var(--filet)}
  .inv-suite a:hover{color:var(--encre);border-bottom-color:var(--encre)}
  .inv-sommaire[aria-busy="true"]{opacity:.55;transition:opacity .18s}
  /* Le bouton « vues » pendant que le compte collectif arrive. L'ordre local
     est déjà posé : ce n'est pas une attente qui bloque, c'est une précision
     qui vient. D'où un signe discret, et non un sablier.
     Ni aria-busy ni opacity : le premier fait ignorer le bouton par les
     lecteurs d'écran au moment même où on vient de le presser, le second
     tombait à 2:1 de contraste. Une couleur, qui reste lisible. */
  .inv-remix button[data-attente]{color:var(--filet)}
  /* Le corps arrive après coup, et il est haut. Sans cette ligne, le navigateur
     compense l'insertion en déplaçant le défilement (scroll anchoring) ; le
     déplacement déclenche contracte(), qui recalcule --c ; --c change la taille
     du nom ET la hauteur du seuil ; la page bouge ; il compense encore. Le nom
     pompait. Ici, rien à compenser : la pièce vient d'être ouverte, on est en
     haut, et ce qui s'ajoute s'ajoute dessous. */
  #piece,#piece .panneau-corps,#piece .inv-corps{overflow-anchor:none}
  /* ---- la fiche d'une pièce, à son adresse -------------------------------
     Il n'y a plus rien de propre à la fiche : /p/slug/ EST cette page, engendrée
     depuis elle à la publication, avec la pièce dépliée et son nom écrit sur le
     corps de page. Le seuil, le nom vivant, la bascule, les bandes, le pied, la
     barre de pièce et les planches sont les mêmes règles, appliquées au même
     balisage. La fiche a eu son habillage à elle pendant une demi-journée ; il
     avait déjà divergé le jour de sa naissance, et les planches y tombaient à un
     tiers de leur taille. Deux jeux de règles pour un seul objet ne tiennent
     jamais. Ce qui reste ici tient en deux lignes : la pièce désignée s'ouvre
     seule, donc l'inventaire est masqué avant même que le script s'exécute — et
     un <noscript> défait ce masque pour qui n'a pas de JavaScript, à qui la
     pièce est alors donnée dépliée, en place, dans l'inventaire. */
  main.piece-ouverte .inv-remix{display:none}   /* remixer un inventaire masqué n'a pas de sens */

  /* ---- mode og : ?graine=N&og ---------------------------------------------
     La même chose que la carte, à la taille d'une image de partage : 1200 × 630,
     en pixels et non en millimètres — ce n'est pas un objet imprimé, c'est une
     vignette qui traverse les messageries. Le nom y est celui du jour, tiré par
     la graine, et le numéro reste écrit : l'image de partage est une carte de
     visite de plus, elle se rejoue.
     Rien n'est écrit en dur : fond, encres, filet et fontes sortent des mêmes
     variables que la page. L'image ne peut donc pas dériver du site — c'est ce
     qui était arrivé à celle d'avant, restée sur un rôle qui avait changé.
     La capture se fait au navigateur — le serveur n'en a pas, et aucune
     bibliothèque PHP ne composerait ces onze lettres dans onze fontes et sept
     matières.
     Graine retenue le 09/09/2026 : n° 3. Choisie sur une seule règle — que le
     nom se lise d'un bout à l'autre. Les tirages voisins posaient des lettres
     en contour sur du blanc, ou faisaient se chevaucher les deux derniers n. */
  /* Le jour, toujours : une vignette de partage ne suit pas le réglage de
     celui qui la fabrique. Les valeurs sont celles de :root, reprises ici
     pour couvrir aussi le cas où data-theme dit « nuit ». */
  /* !important : le média sombre pose ses variables sur :root:not([data-theme]),
     plus spécifique que html.og — sans lui, la vignette sortait en nuit. */
  html.og{--fond:#ffffff !important;--fond-2:#f4f4f4 !important;--encre:#141414 !important;
    --encre-2:#4a4a4a !important;--encre-3:#6b6b6b !important;--filet:#dcdcdc !important;
    color-scheme:light;background:var(--fond)}
  html.og body{margin:0;background:var(--fond);overflow:hidden}
  /* Le dé montre une face à la fois. En marche, les deux se relaient et l'œil
     ne voit que celle du dessus ; à l'arrêt (&og, &capture, &fige) elles
     restent toutes deux posées, avec chacune sa fonte et sa matière — deux
     alphabets superposés sur la même lettre. À 132 px, « Chagnon » devenait
     illisible, comme un repérage raté. La vignette de partage ne garde donc
     que la face du dessus. Ajouté le 10/09/2026, en regardant la capture.
     La carte imprimée (html.capture) garde ses deux faces : elle est tenue en
     main, pas lue en vignette, et l'épaisseur y fait quelque chose. */
  html.og .f.dessous{display:none}
  html.og body>*:not(main),html.og main>*:not(#seuil),html.og .commandes,
  html.og #seuil .dedans>*:not(#nom):not(.og-sur):not(.og-role):not(.og-texte):not(.og-pied):not(.og-num){display:none !important}
  html.og #seuil{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;
    padding:0;margin:0;border:0;height:100vh;background:var(--fond)}
  html.og #seuil .dedans{display:block;width:1200px;height:630px;position:relative;max-width:none;padding:0;margin:0}
  /* 132 px : en dessous, les matières les plus fines — le contour, le vergé —
     se referment et le nom fait des trous. Mesuré à l'écran, pas au jugé. */
  html.og #nom{position:absolute;left:78px;right:78px;top:118px;margin:0;text-align:left;
    font-size:132px;line-height:1;white-space:nowrap;perspective:1100px;letter-spacing:.045em}
  html.og .og-sur{position:absolute;left:82px;top:86px;margin:0;font-family:var(--f-alt);
    font-size:19px;letter-spacing:.28em;color:var(--encre-3)}
  html.og .og-role{position:absolute;left:82px;top:310px;margin:0;font-family:var(--f-body);
    font-size:30px;color:var(--encre-2);letter-spacing:.01em}
  html.og .og-texte{position:absolute;left:82px;right:120px;top:374px;margin:0;
    font-family:var(--f-body);font-size:25px;line-height:1.5;color:var(--encre)}
  html.og .og-pied{position:absolute;left:82px;bottom:66px;margin:0;font-family:var(--f-alt);
    font-size:22px;letter-spacing:.06em;color:var(--encre);
    border-top:1px solid var(--filet);padding-top:22px;width:1036px;box-sizing:border-box}
  html.og .og-num{position:absolute;right:82px;bottom:70px;margin:0;font-family:var(--f-alt);
    font-size:17px;color:var(--encre-3)}