/* ---------------------------------------------------------------------------
   FOVEA — feuille commune. Grille et typographie de la charte de collection.
   Toutes les mesures dérivent de la maquette 406,4 x 228,6 mm (16 x 9).
   1 mm = var(--mm). Aucune valeur en pixels en dur.
   --------------------------------------------------------------------------- */

/* --- LA FONTE EST EMBARQUÉE, ET CE N'EST PAS UN CONFORT ---------------------

   Ce fichier déclarait `font-family:"Noto Sans", system-ui` sans aucun
   `@font-face`. Noto Sans est installée sur le poste de Benoit ; elle n'est PAS
   une fonte système de macOS. Chez un lecteur, le numéro retombait donc sur
   `system-ui` — SF Pro sur Mac, Segoe UI sur Windows — avec d'autres métriques.

   Or tout ici est calibré sur des métriques : les budgets de caractères, les
   trois colonnes de l'écran de contexte, la rangée des portes qui doit tenir
   sur une ligne, l'allocation des colonnes du sommaire, la chasse aux veuves.
   Tout ce qui a été vérifié au rendu était vrai sur un seul poste au monde.

   Quatre faces, pas trois : sans le gras italique, un navigateur en SYNTHÉTISE
   un en penchant le gras, à des métriques que personne n'a mesurées. Le seul
   endroit du numéro où les deux se rencontrent est le panneau du pourquoi, et
   c'est déjà un endroit de trop.

   Et pas de sous-ensemble. Le numéro pèse 688 Mo d'images ; ces quatre faces en
   font 0,65. Découper des glyphes pour gagner 0,4 Mo, c'est prendre le risque
   qu'un jour un « ‹ », un « · » ou un « ↓ » manque dans une page qu'on ne
   regardera pas. On livre les fontes entières.

   Licence : SIL Open Font License 1.1, texte complet dans `fontes/OFL.txt`,
   qui doit accompagner le numéro partout où il est distribué. */
@font-face{
  font-family:"Noto Sans"; font-style:normal; font-weight:400;
  src:url("fontes/noto-sans-400.woff2") format("woff2");
  font-display:block;   /* jamais de rendu dans une fonte de secours, même bref */
}
@font-face{
  font-family:"Noto Sans"; font-style:italic; font-weight:400;
  src:url("fontes/noto-sans-400i.woff2") format("woff2");
  font-display:block;
}
@font-face{
  font-family:"Noto Sans"; font-style:normal; font-weight:700;
  src:url("fontes/noto-sans-700.woff2") format("woff2");
  font-display:block;
}
@font-face{
  font-family:"Noto Sans"; font-style:italic; font-weight:700;
  src:url("fontes/noto-sans-700i.woff2") format("woff2");
  font-display:block;
}

:root{
  --W: min(100vw, 177.7778vh);
  --mm: calc(var(--W) / 406.4);
  --pt: calc(var(--mm) * 0.3527778);

  --marge: 18;  --gout: 6;  --col: 69.28;  --rang: 43.65;

  --creme:     #f5f0e8;
  --encre:     #1a1a1a;
  --signature: #1f3a5f;
  --gris:      #6d6355;

  /* --- le registre MCM — une teinte par rubrique, jamais deux au même écran
     Quatre couleurs relevées sur une planche mid-century. Rams ne pose jamais
     quatre couleurs ensemble : il pose du neutre et UN accent. On les traite
     donc comme un registre — celle de l'écran courant, et rien d'autre.

     Chaque teinte tient DEUX rôles : mobilier typographique sur le crème, et
     fond plein sous du crème. C'est le second qui commande la valeur, et c'est
     pour ça que les trois premières sont plus sombres que la planche d'origine :
     aux valeurs relevées, un texte secondaire sur fond plein tombait sous le
     seuil AA de 4,5:1 que la charte §4 impose. Mesuré sur #f5f0e8, pas déduit. */
  --ardoise:  #3f5772;   /* rubrique I   · 6,57:1 — relevé #46617f, 5,65:1 */
  --olive:    #3f5c23;   /* rubrique II  · 6,69:1 — relevé #4e7a22, 4,48:1 */
  --brique:   #9a2d15;   /* rubrique III · 6,71:1 — relevé #c0391b, 4,82:1 */
  /* L'olive porte une désaturation de 20 % que les deux autres n'ont pas, et
     c'est une correction de RENDU, pas de système : à la valeur relevée, le
     fond plein de l'ouverture II se confondait avec l'herbe du panneau central
     — la page cessait de se distinguer de ce qu'elle commente. Constaté sur
     capture, arbitré par Benoit. Le jour où un numéro n'a pas de vert dans son
     œuvre, cette désaturation n'aura plus de raison d'être. */

  /* ⚠ LA MOUTARDE N'A AUCUN EMPLOI, et c'est un constat, pas un oubli.
     Elle ne peut pas porter de texte sur le crème — 2,38:1, très en dessous du
     seuil, exactement le cas déjà tranché pour le gris maison #b0a898 (charte
     §4, écart n° 2). Elle n'existe donc qu'en aplat, et le numéro n'a pas
     d'écran pour elle : le contexte est resté crème (mille mots justifiés sur
     un aplat saturé), et l'ouverture montre l'œuvre entière, pas une page.
     Elle reste déclarée parce que le registre a été relevé à quatre et que le
     jour où un écran d'aplat sans rubrique existera, c'est elle qu'il prendra.
     Tant qu'il n'existe pas, on ne lui fabrique pas de place. */
  --moutarde: #c8951c;

  --duree: 900ms;
  --courbe: cubic-bezier(.45,.02,.15,1);
}

/* --- ce que l'écran courant lit -------------------------------------------
   Les sept jetons vivent sur `#stage`, PAS sur `:root`, et c'est la seule
   position qui marche. Une propriété personnalisée se substitue là où elle est
   DÉCLARÉE : `--rubrique:var(--teinte)` posée sur `:root` y lit la valeur de
   `--teinte` sur `:root`, puis descend déjà résolue. Redéfinir `--teinte` sur
   `#stage` ne rejouait alors rien — les trois rubriques calculaient le même
   bleu de signature, et le mobilier ne bougeait pas d'un écran à l'autre.
   Déclarées sur le même élément, elles se résolvent contre la valeur que cet
   élément a réellement. Constaté au rendu, pas déduit. */
#stage{
  --teinte:     var(--signature);
  --rubrique:   var(--teinte);   /* mobilier : rubriques, étiquettes, filets */
  --champ:      var(--creme);    /* le fond de l'écran */
  --sur-champ:  var(--encre);    /* le texte principal posé dessus */
  --second:     var(--gris);     /* crédits, notes, appuis */
  --bande:      #e2e0dc;         /* marquage du passage traçable, cran d'annonce */
  --bande-forte:#cacccd;         /* marquage, cran visé */
}

/* --- qui porte quelle teinte ---------------------------------------------- */
#stage[data-rub="I"]  {--teinte:var(--ardoise)}
#stage[data-rub="II"] {--teinte:var(--olive)}
#stage[data-rub="III"]{--teinte:var(--brique)}
/* « ap » — l'appareil du numéro, qui n'appartient à aucune rubrique. Il garde le
   bleu de signature, comme l'écran de l'œuvre entière : le registre MCM dit la
   RUBRIQUE, et hors rubrique il n'a rien à dire. */
#stage[data-rub="ap"] {--teinte:var(--signature)}

/* --- les écrans à fond plein : l'appareil ---------------------------------
   Sur l'ouverture, la clôture et la descendance d'une rubrique, la teinte cesse
   d'être un accent et devient le fond. C'est le seul signal de changement de
   rubrique qui se voie sans être lu, et il ne coûte pas un pixel de mobilier.

   Le mobilier typographique passe alors en crème avec le texte : garder la
   teinte sur son propre fond ferait deux couleurs au même écran, ce que le
   registre interdit. La teinte n'est plus dite, elle est vue.

   Les valeurs dérivées sont des OPAQUES — `color-mix` rend une couleur pleine,
   pas un alpha. Deux marquages qui se touchent additionneraient leur
   transparence et fabriqueraient un troisième ton que personne n'a choisi
   (charte §4, et c'est le défaut qui avait produit six collisions). */
#stage.appareil, #stage.descendance{
  --champ:     var(--teinte);
  --rubrique:  var(--creme);
  --sur-champ: var(--creme);
  --second:     color-mix(in srgb, var(--creme) 82%, var(--teinte));
  --bande:      color-mix(in srgb, var(--creme) 16%, var(--teinte));
  --bande-forte:color-mix(in srgb, var(--creme) 32%, var(--teinte));
}
/* Le contexte reste CRÈME, et c'est le seul écran du numéro pour lequel la
   question s'est posée. Il ne montre aucune reproduction, donc une teinte
   saturée n'y concurrencerait rien — mais il porte aussi la plus grosse masse
   de texte du numéro, mille mots justifiés en trois colonnes. Un aplat sous
   cette masse-là est lisible au contraste et fatigant à la lecture, ce qui
   n'est pas la même mesure. Arbitrage de Benoit, sur capture. */
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%}
body{
  background:#141210;
  display:flex; align-items:center; justify-content:center;
  font-family:"Noto Sans", system-ui, sans-serif;
  font-size:calc(11 * var(--pt));
  line-height:calc(14 * var(--pt));
  color:var(--encre);
  cursor:default; overflow:hidden;
}
#stage{
  position:relative; width:var(--W); aspect-ratio:16/9;
  background:var(--champ);          /* le fond est toujours à fond perdu — charte §5 */
  color:var(--sur-champ);
  overflow:hidden;
}

/* --- typographie : trois corps, 9 · 11 · 16 — charte §3 ------------------- */
.rubrique, .locateur, .etiquette{
  font-weight:700; font-size:calc(9 * var(--pt)); line-height:calc(12 * var(--pt));
  color:var(--rubrique);
}
.rubrique, .etiquette{text-transform:uppercase; letter-spacing:.06em}
h1{
  font-weight:700; font-size:calc(16 * var(--pt)); line-height:calc(20 * var(--pt));
  color:var(--sur-champ); text-wrap:balance;
  margin:calc(5 * var(--pt)) 0 calc(3 * var(--pt));
}
/* la citation est à 16 : dans un écran de rapprochement, elle EST le titre */
.citation{
  font-style:italic; font-size:calc(16 * var(--pt)); line-height:calc(20 * var(--pt));
  color:var(--sur-champ); text-wrap:balance;
}
/* seul le corps d'analyse est justifié ; tout le reste au fer à gauche */
.corps{text-align:justify; hyphens:auto; -webkit-hyphens:auto}
.credit{font-size:calc(9 * var(--pt)); line-height:calc(12 * var(--pt)); color:var(--second)}
.nom{font-weight:700; font-size:calc(9 * var(--pt)); line-height:calc(12 * var(--pt))}

/* --- le tracé, dispositif central — charte §5 ----------------------------
   `pointer-events:all` rend chaque forme survolable bien qu'elle n'ait pas de
   fond : c'est ce qui rend la peinture interrogeable, et pas seulement
   annotable. Une forme peut porter plusieurs clés (voir traces.js). */
.traces{position:absolute; left:0; top:0; width:100%; height:100%;
  pointer-events:none; overflow:visible}
/* --- LE TRACÉ : aucun trait ---------------------------------------------
   Un rectangle n'est pas une forme de Bosch, c'est une structure de données,
   et un filet posé sur la peinture est exactement l'ajout que la charte §6
   interdit. On ne cerne donc pas le sujet : **on fait reculer le reste.**

   C'est le nom de la collection appliqué au dispositif. La fovéa ne trace pas
   de contour autour de ce qu'elle voit — elle est le seul endroit net d'un
   champ qui s'estompe partout ailleurs. Ici : la peinture reste INTACTE à
   l'intérieur du tracé, et l'alentour s'efface vers le crème de la page. On
   n'ajoute rien sur l'œuvre ; on retire de l'attention autour.

   Les formes du SVG ne servent plus qu'à la détection du pointeur. Le travail
   visuel est fait par un calque voilé, percé au masque à l'endroit exact. */
.traces > *[data-t]{
  fill:transparent; stroke:none; pointer-events:all;
}

/* le voile : une copie de l'image, désaturée et remontée vers le crème */
.traces .voile{
  opacity:0; pointer-events:none;
  transition:opacity 240ms cubic-bezier(.4,0,.2,1);
}
.traces.actif .voile{
  /* jamais 1 : l'original transparaît toujours un peu sous le lavis */
  opacity:.9;
  /* l'attention vient lentement et se relâche vite : 560 à l'aller, 240 au retour */
  transition-duration:560ms;
}

/* le trou dans le voile — noir = la peinture reste telle quelle */
.traces mask .forme{
  fill:#000; stroke:none; fill-opacity:0;
  transition:fill-opacity 220ms cubic-bezier(.4,0,.2,1);
}
.traces mask .forme.on{ fill-opacity:1; transition-duration:520ms }

/* Le passage traçable. La règle §6 dit : rien n'apparaît avant que le lecteur
   n'agisse. Elle était appliquée à la lettre — soulignement transparent tant
   qu'on n'était pas DESSUS — et elle se retournait contre elle-même : la marque
   n'apparaissait qu'une fois trouvée, donc elle n'annonçait rien. Un lecteur
   pouvait traverser les 80 plans sans soupçonner qu'une phrase se touche, et le
   dispositif central du numéro restait lettre morte.

   Le geste qui déclenche est désormais d'entrer dans le BLOC de texte, pas de
   viser une phrase. §6 tient — il faut toujours agir — mais l'action demandée
   est celle qu'on fait de toute façon en s'approchant pour lire. Deux crans, le
   plus franc réservé au passage visé. */
.t{cursor:pointer;
   background-color:transparent;
   box-decoration-break:clone; -webkit-box-decoration-break:clone;
   padding:0 calc(.8 * var(--mm)); margin:0 calc(-.8 * var(--mm));
   border-radius:calc(.8 * var(--mm));
   /* La bande est PEINTE, pas dimensionnée par la boîte. La boîte de fond d'un
      élément en ligne se calcule sur les métriques de la fonte — 25 px pour un
      corps de 18,33 — et ni `line-height` ni `padding` ne la réduisent. Avec
      23,33 px d'interligne, deux ancres sur deux lignes voisines se
      chevauchaient de 2,67 px : six collisions dans un seul paragraphe.
      Un dégradé plat de hauteur fixe, centré, laisse 3,3 px d'air entre les
      bandes et ne touche pas d'un pixel à la mise en page. */
   background-repeat:no-repeat;
   background-position:center;
   background-size:100% 0;
   transition:background-size 180ms ease}
/* Teintes OPAQUES, pré-mélangées sur le crème (#f5f0e8) — signature à 9 % et à
   20 %. Une couleur semi-transparente s'additionne partout où deux bandes se
   touchent et fabrique un second gris que personne n'a choisi. Une opaque ne le
   peut pas, jamais, quelle que soit la géométrie. Contrepartie assumée : ces
   deux valeurs ne valent que sur le fond crème de la charte. */
.t{background-image:linear-gradient(var(--bande), var(--bande))}
.bloc:hover .t{background-size:100% calc(12 * var(--pt))}
/* le cran fort reste plus spécifique que le cran d'annonce, sinon
   `.bloc:hover .t` (0,3,0) écrase `.t:hover` (0,2,0) */
.t:hover, .t.on,
.bloc:hover .t:hover, .bloc:hover .t.on{
   background-image:linear-gradient(var(--bande-forte), var(--bande-forte));
   background-size:100% calc(12 * var(--pt))}
/* Le clavier, c'est aussi « toucher » — la règle §6 est respectée : rien
   n'apparaît avant que le lecteur n'agisse. Mais sans souris on ne sait pas où
   l'on est, alors la marque est plus franche qu'au survol. `:focus-visible` et
   non `:focus` : un clic à la souris ne doit rien allumer de plus que le
   survol. */
.t:focus-visible{outline:calc(.3 * var(--mm)) solid var(--rubrique);
   outline-offset:calc(.6 * var(--mm)); border-bottom-color:var(--second)}

/* --- le rail : invisible jusqu'à ce qu'on bouge — charte §6 --------------- */
#rail{position:absolute; display:flex; gap:calc(2 * var(--mm)); align-items:center;
  opacity:0; transition:opacity 500ms ease}
#rail.vu{opacity:1}
#rail button{appearance:none; border:0; background:none; padding:0; cursor:pointer;
  width:calc(6 * var(--mm)); height:calc(1.6 * var(--mm)); display:block}
#rail button::after{content:""; display:block; height:calc(.4 * var(--mm));
  background:var(--second); opacity:.45; transition:opacity 200ms ease}
#rail button[aria-current="true"]::after{opacity:1; background:var(--sur-champ)}

@media (prefers-reduced-motion: reduce){
  :root{--duree:1ms}
  .traces .voile, .traces mask .forme{transition-duration:1ms}
}
