/* =========================================================================
   UST — jetons du système
   Direction retenue au banc : « Adaptation » (_design/ARBITRAGE.md).

   La page s'adresse à une rétine ouverte depuis vingt minutes. Toute
   l'interface tient entre L 5 % et L 22 % ; les photographies de l'auteur
   sont la seule source de lumière. Les neutres ne sont pas choisis : ils
   sont RECOPIÉS du k-means sur 219 029 pixels de signal des 136 astrophotos.

   Trois lois de palette (ARBITRAGE §5), qui expliquent chaque jeton :
     1. Loi d'accent — l'accent d'interface dérive de la teinte des NEUTRES
        mesurés (H 352). La bande H 9-20, la braise des nébulosités, reste la
        propriété exclusive des photographies : aucun chrome ne s'y aventure.
     2. La lampe n'éclaire que ce que la main touche — liens, bouton,
        soulignement de nav, index de graduation. Rien d'autre.
     3. Aucune surface claire, nulle part.

   CONTRASTES RECALCULÉS À LA FORMULE WCAG 2.x SUR CES HEXADÉCIMAUX EXACTS,
   et confrontés au tableau §5 de l'arbitrage. Dix d'entre eux tombent au
   centième près. UN SEUL DIVERGE, et il n'est pas arrondi :

     --gradue #867678 sur --nuit  =  4,58:1   (le §5 annonce 4,63:1)

   4,63:1 est la valeur de #877778, soit un point de rouge et de bleu de plus.
   Le §5 impose l'hexadécimal, pas le ratio : l'hexadécimal est donc conservé
   et le chiffre corrigé. Sans conséquence fonctionnelle — 4,58:1 passe l'AA
   du texte (4,5) sur le fond, et 3,74:1 sur carte tient le plancher de
   WCAG 1.4.11 (3,0) pour un objet graphique porteur, qui est son emploi.
   ========================================================================= */

:root {
  /* --- Les dix jetons de la palette (+ le fond) — ARBITRAGE §5 ----------
     Ratio /nuit et /ciel recalculés à la formule WCAG 2.x, sRGB.           */
  --nuit:        #0D0A0C;  /* fond global, sous le seuil du signal          */
  --ciel:        #242022;  /* cartes et panneaux · cluster 39 %  1,22 / —   */
  --filet:       #353032;  /* bordures au seuil       · 21 %     1,52 /1,24 */
  --filet-haut:  #534648;  /* piste, filets réveillés · 10 %     2,19 /1,79 */
  --gradue:      #867678;  /* graduations, seuils, index vide    4,58 /3,74 */
  --texte:       #EFE7E9;  /* encre principale                  16,21/13,24 */
  --champ:       #A6ACBA;  /* corps, chapôs, liens de nav        8,66 /7,08 */
  --label:       #B0A1A2;  /* labels et notes en chasse fixe     7,94 /6,49 */
  --lampe:       #F9435B;  /* L'ACCENT, H 352                    5,61 /4,58 */
  --lampe-haute: #FFB3BF;  /* on monte la lampe : survol, focus 11,68 /9,54 */
  --lampe-nuit:  #4E1020;  /* palier sombre, DÉCOR SEUL          1,33 / —   */

  /* --- LE FOND DU BOUTON PRINCIPAL, ET LUI SEUL -------------------------
     Le bouton portait --nuit sur --lampe : 5,61:1, conforme. Le donneur
     d'ordre le veut en blanc. Or son libellé fait 14 à 15 px en graisse 600 :
     ce n'est PAS du grand texte au sens WCAG (qui commence à 18,66 px en gras
     ou 24 px), le seuil applicable reste donc 4,5:1, et blanc sur --lampe ne
     donne que 3,51:1. Échec.
     La lampe ne bouge pas d'un point : elle reste l'accent des liens, des
     graduations, du soulignement de nav et des index. C'est le FOND DU BOUTON
     qui descend, et lui seul. Ratios recalculés à la formule WCAG 2.x sur ces
     hexadécimaux exacts :
       #FFFFFF sur --lampe-bouton        5,60:1  (l'ancien état valait 5,61:1)
       #FFFFFF sur --lampe-bouton-haute  4,86:1  (survol, seuil 4,5 tenu)
     Teinte mesurée du fond : H 350,8, à 1,3° de la teinte des neutres (H 352)
     dont la loi n° 1 fait dériver l'accent. L'écart est invisible et l'aplat
     reste hors de la bande braise H 9-20 réservée aux photographies ; c'est
     l'hexadécimal du donneur d'ordre qui est conservé, comme --gradue plus
     haut, et l'écart qui est écrit.
     LE SURVOL EST DÉRIVÉ, JAMAIS RETAPÉ : un pas du fond vers la lampe. La
     direction du système — « on monte la lampe » — est tenue, mais bornée,
     parce qu'au-delà de ce pas le blanc repasse sous 4,5:1.                 */
  --lampe-bouton:       #C9203A;
  --lampe-bouton-haute: color-mix(in srgb, var(--lampe-bouton) 70%, var(--lampe));
  --encre-bouton:       #FFFFFF;

  /* --- La rampe de l'accent : dérivée, jamais retapée à la main ---------
     Un seul accent, une seule rampe. Toute transparence de la lampe se
     calcule ici et nulle part ailleurs.                                    */
  --halo:       color-mix(in srgb, var(--lampe) 30%, transparent);
  --halo-fort:  color-mix(in srgb, var(--lampe) 46%, transparent);
  --lampe-bord: color-mix(in srgb, var(--lampe) 45%, transparent);
  /* C7 : l'en-tête prend un fond tokenisé, jamais un backdrop-filter. */
  /* LES CHAMPS DE SAISIE SE VOIENT, ET C'EST UNE CORRECTION DU 15/09/2026.
     Ils n'étaient qu'un filet bas en --filet-haut : rien ne disait où écrire,
     et le donneur d'ordre l'a dit avec ses mots. Un champ est maintenant une
     boîte, et la boîte doit tenir le seuil de 3:1 de la 1.4.11 CONTRE SES DEUX
     SUPPORTS, parce qu'un formulaire vit tantôt sur --nuit, tantôt sur --ciel.
     Mesuré à la formule WCAG sur les hexadécimaux exacts :
       --filet       1,52:1 sur nuit   1,24:1 sur ciel   échec
       --filet-haut  2,19:1            1,79:1            échec, c'était l'état
       --gradue      4,58:1            3,74:1            tenu des deux côtés
     C'est donc --gradue qui porte le contour, et lui seul le porte : aucun
     remplissage ne tient 3:1 sans devenir un aplat clair qui écraserait la
     nuit. Le fond n'a pas à le tenir, il n'est là que pour l'affordance, la
     tache plus claire qui dit « on écrit ici » ; à 8 % il vaut 1,16:1 sur nuit
     et 1,24:1 sur ciel, et l'encre --texte y garde 13,93:1 et 10,70:1. */
  --saisie-fond:       color-mix(in srgb, var(--texte) 8%, transparent);
  --saisie-bord:       var(--gradue);
  --saisie-bord-actif: var(--lampe);

  --voile-entete: color-mix(in srgb, var(--nuit) 92%, transparent);
  --selection:    color-mix(in srgb, var(--lampe) 88%, var(--nuit));

  /* --- LE VOILE DU HÉROS, ET SES DEUX VALEURS SONT MESURÉES -------------
     L'accueil pose son titre, son chapô et ses appels SUR une photographie
     du ciel. Tous les rapports de contraste de cette feuille sont calculés
     sur --nuit : sans voile, ils ne veulent plus rien dire là où le texte
     est posé, et le chapô en --champ tombe sous le seuil dès qu'un amas
     d'étoiles passe dessous.
     La mesure a été faite sur le rendu, pas au jugé : la photographie a été
     servie sans voile, les pixels sous la boîte du titre et sous celle du
     chapô ont été relevés aux deux points de rupture, et le voile composé
     par-dessus jusqu'à ce que le pixel LE PLUS CLAIR de la zone de texte
     tienne son seuil. Relevé, aux deux points de rupture :
       sans voile ........................ 1,00:1 partout. Le voile n'est pas
                                           un effet, c'est la condition.
       opacité minimale, titre (3:1) ..... 0,495
       opacité minimale, chapô (4,5:1) ... 0,78
       opacité minimale, surtitre ........ 0,80
       opacité minimale, crédit .......... 0,805  <- c'est elle qui commande
     --voile-hero vaut 0,97, au-dessus de ce minimum : la marge tient une
     autre photographie du catalogue, le jour où l'objet le plus travaillé
     change. Rendu obtenu, contre la valeur du jeton sur --nuit pur :
       titre 15,31 / 15,56  (16,21)   chapô 8,18 / 8,31  (8,66)
       surtitre et crédit 7,50 / 7,68  (7,94)
       --voile-hero         sous le texte : le fond y redevient --nuit à la
                            mesure, et les ratios du tableau tiennent tels
                            quels.
       --voile-hero-ouvert  sur la photographie, où aucun texte n'est posé.
                            Il ne l'éteint pas, il la tient sous le seuil du
                            signal (loi n° 3). */
  --voile-hero:        color-mix(in srgb, var(--nuit) 97%, transparent);
  --voile-hero-ouvert: color-mix(in srgb, var(--nuit) 28%, transparent);

  /* --- Les trois familles — ARBITRAGE §6, toutes auto-hébergées (C6) ----
     Display Spectral · Corps Epilogue · Donnée Martian Mono.
     Règle dure : tout nombre mesuré est en Martian Mono, y compris dans le
     h1 ; l'unité reste dans la famille de la prose.                        */
  --f-display: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif;
  --f-corps:   Epilogue, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-data:    "Martian Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* Graisses employées, et elles seules : les woff2 sont instanciés dessus. */
  --g-display:      300;   /* §6 : remontée de 200 à 300, les déliés tiennent */
  --g-display-forte:400;
  --g-corps:        400;
  --g-corps-moyen:  500;
  --g-corps-fort:   600;
  --g-mono:         300;
  --g-mono-fort:    500;

  /* --- Échelle fluide, une seule voie : clamp 320 -> 1440 ---------------
     Display plafonné à 96 px (§6) : à 128 px le h1 perçait la loi n° 3.
     Mono planchée à 12 px (C8) : la donnée est le contenu, pas une note.   */
  --d-display: clamp(2.75rem, 1.25rem + 6.2vw, 6rem);      /* 44 -> 96 px   */
  /* LE H1 DE L'ACCUEIL AU PLANCHER DE L'ÉCHELLE, ET POURQUOI IL LUI FAUT
     SON PROPRE PALIER. --d-display est plat à 44 px sous 387 px de large :
     c'est le plancher voulu. Or le h1 de l'accueil porte « photographie pas. »
     soudé par une espace insécable — un bloc de 17 signes qui, mesuré au
     rendu, réclame 326 px à 44 px de corps. La colonne en offre 280 à 320 px
     de large et 317 à 360 : le titre débordait, et le héros, qui recadre sa
     photographie, le coupait. Mesuré sur l'état d'origine, sans recadrage :
     la page entière défilait de 26 px à l'horizontale à 320.
     Ce jeton descend le titre à 37 px au plancher et rejoint --d-display à
     390, où le bloc entre. Il ne sert QU'À CE TITRE et qu'en dessous de
     24,5rem : au-delà, l'échelle commune reprend, et l'insécable retrouve son
     office, qui est d'empêcher « pas. » de rester seul en fin de ligne.     */
  --d-hero-etroit: clamp(2.3125rem, .05rem + 11.2vw, 2.75rem);  /* 37 -> 44 px */
  --d-h2:      clamp(1.875rem, 1.41rem + 2.32vw, 3.5rem);  /* 30 -> 56 px   */
  --d-h3:      clamp(1.25rem, 1.107rem + .71vw, 1.75rem);  /* 20 -> 28 px   */
  --d-h4:      clamp(1.0625rem, 1.027rem + .18vw, 1.1875rem); /* 17 -> 19   */
  --d-lead:    clamp(1.125rem, 1.054rem + .36vw, 1.375rem);/* 18 -> 22 px   */
  --d-corps:   clamp(1rem, .964rem + .18vw, 1.125rem);     /* 16 -> 18 px   */
  --d-petit:   clamp(.875rem, .857rem + .09vw, .9375rem);  /* 14 -> 15 px   */
  --d-mono:    clamp(.75rem, .72rem + .13vw, .8125rem);    /* 12 -> 13 px   */

  --i-serre:  1.02;   /* titrage display          */
  --i-titre:  1.18;   /* h3, h4                   */
  --i-corps:  1.6;    /* prose                    */
  --i-mono:   1.5;
  --l-display: -.022em;
  --l-mono:     .01em;
  --l-brow:     .14em;

  /* --- Espacement ------------------------------------------------------- */
  --e-1: .5rem;  --e-2: .75rem; --e-3: 1rem;   --e-4: 1.5rem;
  --e-5: 2rem;   --e-6: 2.5rem; --e-7: 3rem;   --e-8: 4rem;

  --section:       clamp(4.5rem, 3.11rem + 6.96vw, 9.375rem);  /* 72 -> 150 */
  --section-large: clamp(5.5rem, 3.61rem + 9.45vw, 12rem);     /* 88 -> 192 */
  --marge:     clamp(1.25rem, .55rem + 3.5vw, 2.5rem);

  /* --- L'EN-TÊTE : SA HAUTEUR EST UN JETON, PLUS UN NOMBRE RECOPIÉ ------
     Le sceau est servi à 64 px (sceau(64), inc/entete.php) dans une barre à
     min-height 4,5rem et padding 0 : il restait 4 px au-dessus et 4 en
     dessous. « Le logo absolument collé ». --air-entete pose cet air, et
     --h-entete en découle au lieu d'être écrit à la main.
     Le jeton n'est pas un confort : TROIS RÈGLES se calaient sur 4,5rem sans
     le savoir — le panneau du menu mobile, la barre alphabétique du lexique
     et les scroll-margin des ancres. Elles lisent maintenant le jeton, et la
     première retouche de hauteur ne les désalignera plus.
     La barre garde la même hauteur au repos et collée : la bascule
     data-collee ne change qu'un fond et la couleur d'un filet déjà posé,
     transparent au repos. Aucun saut au moment du basculement.             */
  /* POURQUOI LE SCEAU RESTE À 64 px, MAINTENANT QU'IL PORTE LE LOGO DU CLIENT.
     La question a été posée : monter la barre à 96 px pour que la marque se
     lise. Elle est refusée sur mesure, et voici la mesure. Le troisième glyphe
     du logo validé est le pied de la lunette, sans barre horizontale : la
     marque se lit « USI » à 48, 64, 80, 96 ET 132 px. Aucune hauteur de barre
     ne fait revenir un T qui n'est pas dessiné.
     Ce qui se lit vraiment, en pixels d'appareil, tiré du maître de 1254 px :
                              48     64     80     96    132
       anneau or,  densité 1   0,57   0,77   0,96   1,15   1,58
       anneau or,  densité 2   1,15   1,53   1,91   2,30   3,16
       jambage du U            2,60   3,47   4,34   5,21   7,16
       fût du 3e glyphe        2,37   3,16   3,96   4,75   6,53
       « by Gus »              0,15   0,20   0,26   0,31   0,42
     « by Gus » reste sous le pixel PARTOUT, jusqu'à 132 px en densité 2
     (0,84) : ce n'est pas 96 px qui le sauve, rien ne le sauve à ces tailles.
     Le sigle, lui, tient déjà largement à 64 px. L'ANNEAU RENDU, REMESURÉ À LA
     RECETTE sur les pixels composés par le navigateur (médiane du pic radial,
     1 440 angles, tube blanc écarté), vaut 4,40:1 sur --nuit à 64 px en densité
     1 et 9,34:1 en densité 2, contre un seuil de 3:1 pour un objet graphique.
     La pose annonçait 8,10:1 et 13,68:1 : c'était le haut de la distribution,
     pas sa médiane. Le sens ne change pas, le chiffre oui. Le tableau complet
     est au-dessus de .marque dans composants.css. Passer à 6rem coûterait 32 px de
     hauteur à --h-entete, donc au héros qui tombe au pixel sur la fenêtre à
     1440x900, 1366x768, 1280x800 et 1024x768, pour ne rien rendre lisible de
     plus. On ne les dépense pas.
     Le sceau n'est d'ailleurs pas seul à porter la marque en en-tête : il est
     décoratif (alt vide, aria-hidden), et le nom est écrit à côté de lui.     */
  --sceau-entete: 4rem;                 /* 64 px, la taille servie par sceau(64) */
  --air-entete:   var(--e-2);           /* 12 px au-dessus et sous le bloc de marque */
  --h-entete:     calc(var(--sceau-entete) + 2 * var(--air-entete));  /* 88 px */
  /* LA BARRE PLUS SON FILET. --h-entete est la hauteur de la BOÎTE de la
     barre ; .nav pose en plus un filet de 1 px sous elle, et .nav est en
     `sticky`, donc dans le flux : elle mange 89 px du premier écran. Le héros
     pleine page les retranche pour tomber exactement sur la fenêtre. Sans ce
     jeton, le héros dépasserait d'un pixel et la page défilerait au premier
     écran. Le panneau du menu mobile, lui, se cale sur --h-entete : il
     recouvre le filet, il ne se pose pas dessous. */
  --h-nav:        calc(var(--h-entete) + 1px);                        /* 89 px */

  /* --- LA HAUTEUR UTILE, ET ELLE A SA MESURE ---------------------------
     LOT DU 21/09/2026, SECONDE PASSE. L'entête est `sticky` et haute de
     --h-nav : elle est POSÉE SUR le premier écran, du haut, et elle ne s'en
     va pas au défilement. La hauteur qu'un bloc peut occuper sans qu'une
     partie reste cachée n'est donc pas 100svh, c'est 100svh moins la barre.
     Le héros de l'accueil retranchait déjà cette barre à la main
     (pages.css) ; la ronde ne le faisait pas, et son premier calage l'a
     payé : 12vh mesurés sur la fenêtre ENTIÈRE lui donnaient une emprise de
     929 px sur un écran de 900, dont 86 px restaient sous l'entête à la
     meilleure position de défilement. Le jeton existe pour que la faute ne
     se refasse pas : ce qui doit tenir dans l'écran se mesure sur lui.
     100svh et non 100vh, pour la même raison que le héros : sur un mobile à
     barre d'adresse rétractable, 100vh vaut la fenêtre DÉPLIÉE.           */
  --h-utile:      calc(100svh - var(--h-nav));   /* 811 px sur un écran de 900 */

  /* --- LA CIBLE MINIMALE, 21/09/2026 -----------------------------------
     24 px, le minimum de WCAG 2.5.8 (Target Size, Minimum). base.css pose
     déjà cette hauteur sur les liens seuls de liste ; le jeton la nomme
     pour les composants qui doivent la tenir sans padding, comme le lien
     de marque de la ronde, dont chaque pixel de hauteur coûte 1,7 px
     d'emprise de cercle.                                                  */
  --cible-min:    1.5rem;                                             /* 24 px */

  /* --- LE PLANCHER DE L'OUVERTURE EN BANDEAU ---------------------------
     La doctrine de cohérence (_design/COHERENCE.md) donne quatre crans
     d'ouverture, et un seul demande une hauteur écrite : le BANDEAU, qui
     pose la même photographie voilée que le héros de l'accueil sur une
     fraction de sa hauteur. Les deux autres crans se mesurent sur leur
     contenu, et le quatrième — la pleine fenêtre — est celui de l'accueil,
     qui a déjà --h-nav pour se retrancher de la fenêtre.

     CE JETON EST UN PLANCHER, JAMAIS UN PLAFOND. Un bandeau dont le chapô
     tient quatre lignes est plus haut que le jeton, et c'est normal : on ne
     coupe pas un texte pour tenir une hauteur. La dose se règle sur la
     longueur du chapô, qui est une décision d'écriture, pas sur un
     `max-height`, qui serait un rognage.

     LE RAPPORT AU HÉROS EST LA RAISON DES DEUX BORNES. L'ouverture d'une
     page de rang inférieur doit se lire d'emblée comme MOINS que l'accueil,
     sans quoi les deux se confondent et la hiérarchie du site disparaît.
     Le héros vaut la fenêtre moins la barre : 811 px sur un écran de 900,
     679 px sur un portable de 768. Le bandeau plafonne à 416 px, soit un
     peu plus de la moitié du premier et moins des deux tiers du second :
     l'écart se voit sans qu'on ait à comparer deux onglets.
     Au plancher, 272 px tiennent le surtitre, deux lignes de titre à 44 px
     et une ligne de crédit sans que la photographie devienne un liseré.  */
  --h-ouv-bandeau: clamp(17rem, 9.8rem + 18vw, 26rem);   /* 272 -> 416 px */

  /* --- LA COLONNE DE DROITE DU GABARIT DE MESSAGE ----------------------
     Le carnet du client (§2.7) dessine un message en deux colonnes : à
     gauche le message, à droite la FICHE MEMBRE, avec le nom d'utilisateur,
     la photo, le rang, le nombre de messages, la date et l'heure
     d'inscription, le matériel utilisé et la localisation.

     C'EST LE SEUL JETON QUE LE LOT DU FORUM AJOUTE, et il est mesuré, pas
     choisi. Ce qui commande sa largeur est la LIGNE LA PLUS LONGUE que la
     fiche doit tenir sans se couper, et il y en a deux candidates :

       « 02/09/2026 à 18 h 03 », en Martian Mono à --d-mono ... MESURE
       « Unistellar eQuinox 2 », le plus long des neuf noms d'appareils,
       en Epilogue à --d-petit ................................. MESURE

     RELEVÉ AU RENDU, au binaire chrome-headless-shell, à 1440x900 et à
     1024x768, sur le contenu de la fiche, ligne par ligne :

       « 02/09/2026 à 20 h 03 »  date et heure, Martian Mono ...... 175 px
       « Saint-Girons, Occitanie FR »  la localisation ............ 193 px
       « Matériel utilisé »  le surtitre du bloc ................... 174 px
       « Unistellar eQuinox 2 »  le plus long des neuf noms ....... 147 px
       « Administrateur »  le rang ............................... 152 px
       « Localisation »  le plus long des libellés ................ 130 px

     C'EST LA DATE QUI COMMANDE, et elle commande seule : c'est la seule de
     ces lignes qui ne peut PAS se couper sans devenir fausse, et sa largeur
     est invariante, puisque Martian Mono est à chasse fixe et que la donnée
     est en tabular-nums. Toutes les dates du site font 175 px à cet endroit.
     Le minimum est donc 175 + 32 de retrait + 1 de filet = 208 px.

     15rem en donne 240, soit 207 px de contenu. Les 32 px au-dessus du
     minimum ne sont pas du confort : ce sont eux qui tiennent la
     localisation (193 px) sur UNE ligne au lieu de deux, à côté de chaque
     message. Qui descend ce jeton sous 13,5rem coupe la date en deux.

     LE POINT DE REPLI EST MESURÉ AVEC : à 62rem, la colonne de gauche garde
     590 px, tout près des 608 px de --lecture. Un cran plus bas, à 768, elle
     tomberait à 352 px, soit 58 % de la mesure de lecture, et le carnet
     n'aurait plus deux colonnes mais une colonne et une gouttière. Sous
     62rem la fiche passe donc SOUS le corps, et ce jeton ne sert plus. */
  --forum-fiche: 15rem;   /* 240 px */

  /* --- LA TAILLE SERVIE DES ICÔNES 3D ----------------------------------
     Les cinq objets sont des carrés de même poids optique : une seule
     taille les tient tous, il n'y a rien à rattraper objet par objet. Deux
     emplois, donc deux jetons, et pas un nombre écrit dans une règle :
       --orne       l'ornement d'une section, à côté de sa tête. Il plafonne
                    à 176 px : au-delà il ferait concurrence au titre, et le
                    contour de la nébuleuse commence à se voir vers 220 px.
       --orne-hero  l'icône du héros, à droite du descriptif d'ouverture.
                    Elle est seule sur sa colonne et peut monter à 288 px.
     Le plancher (96 px, 128 px) est la taille de repli, quand la rangée se
     plie et que l'icône passe sur sa propre ligne. Les dérivés servis sont
     de 160, 320 et 480 : la plus grande valeur de ces clamps reste sous le
     320, donc aucune icône n'est jamais agrandie. */
  --orne:      clamp(6rem, 4rem + 5vw, 11rem);      /*  96 -> 176 px */
  --orne-hero: clamp(8rem, 4rem + 10vw, 18rem);     /* 128 -> 288 px */

  /* --portrait-bio  LE PORTRAIT DE GUS, ET IL N'EST PLUS UN ORNEMENT. Demande
     du donneur d'ordre le 22/09/2026 : « pas de fond, transparent, avec Gus en
     grand ». Il quitte donc --orne-hero, qui dimensionne les icônes 3D du
     héros, et prend son propre jeton, plus du double. Mesuré à 1440 : le texte
     de la lettre occupe --lecture (608 px), l'écart vaut --e-6 (40 px), le
     portrait 384 px, total 1 032 px dans 1 240 px de contenu. À 28rem il
     plafonne à 448 px, atteints à partir de 1 760 px de fenêtre.
     LE PLANCHER EST 12rem ET NON 8 : détouré sur fond transparent, sans cadre
     ni filet pour le porter, un buste de 128 px ne se lit plus comme un
     visage. */
  --portrait-bio: clamp(12rem, 6rem + 20vw, 28rem);  /* 192 -> 448 px */

  --gouttiere: var(--e-4);
  --contenu:   77.5rem;   /* 1240 px */
  /* La colonne de texte du héros. Elle sert DEUX fois — la grille et la
     largeur du crédit — et c'est la raison du jeton : la géométrie du
     voile est calée sur elle, un texte qui déborderait de cette largeur
     sortirait de la partie pleine du voile et perdrait son contraste. */
  --hero-colonne: 34rem;  /* 544 px */
  --etroit:    45rem;     /* 720 px  */
  --lecture:   38rem;     /* 608 px  */

  /* --- Rayons ----------------------------------------------------------- */
  --r:       1rem;      /* cartes, panneaux */
  --r-s:     .5rem;
  --r-pill:  100vw;
  --r-media: var(--r);
  --r-pied:  0;         /* le pied est un filet, plus une capsule */

  /* --- Ombres : jamais dures, jamais une teinte hors rampe -------------- */
  --ombre-carte: 0 0 46px -12px var(--halo);
  --ombre-index: 0 0 8px 0 var(--halo-fort);
  --ombre-bouton:0 0 26px 0 var(--halo);
  --ombre-bouton-haute: 0 0 34px 0 var(--halo-fort);
  --anneau: 0 0 0 1px var(--filet);

  /* --- La graduation, élément signature — ARBITRAGE §7 ------------------
     Deux instruments, deux axes, jamais confondus : l'épaisseur de piste
     est le premier signe visible qui les sépare.                           */
  --grad-piste-objet:    3px;
  --grad-piste-appareil: 6px;
  --grad-index:          2px;
  --grad-boite-objet:    14px;
  --grad-boite-appareil: 20px;
  --grad-ligne: calc(var(--d-mono) * var(--i-mono));

  /* --- Barème de motion — ARBITRAGE §8 ----------------------------------
     Cinq durées, une courbe, trois cadences. Aucune durée hors ce tableau
     ne doit apparaître dans un composant.                                  */
  --t-micro:   100ms;  /* survol de lien de nav                            */
  --t-ui:      200ms;  /* couleurs, bordures, halos, opacité d'index       */
  --t-panneau: 300ms;  /* bascule d'en-tête à 80 px de défilement          */
  --t-pose:    400ms;  /* tracé de graduation, scaleX 0 -> 1               */
  --t-revele:  560ms;  /* entrée de bloc, jouée une fois                   */
  --courbe:    cubic-bezier(.22, .61, .36, 1);

  --t-retard-pose:  120ms;  /* retard du tracé                                  */
  --t-retard-index: 420ms;  /* retard de l'allumage de l'index                  */
  --t-cadence:       80ms;  /* décalage entre frères, via --i                   */

  /* --- LA RONDE DES CONSTRUCTEURS, demande client du 14/09/2026 ------------
     --t-ronde  DÉROGATION NOMMÉE AU BARÈME, ET LA SEULE. Les cinq durées
                ci-dessus plafonnent à 560 ms parce qu'elles se jouent une
                fois ; la ronde de l'accueil est la seule animation INFINIE
                du site, et une durée qui se répète n'est pas de la même
                famille. Elle est hors barème parce qu'infinie, sur demande
                du client (14/09/2026 : les constructeurs « en cercle, en
                mouvement »). 60 s par tour, soit 6° par seconde : la vitesse
                angulaire d'une trotteuse, qu'on voit tourner sans la fixer,
                et un logo met 12 s à passer de son poste au poste voisin, ce
                qui laisse le lire. Entre 40 et 60 s l'œil suit ; sous 30 s
                ça tourne pour tourner. Coupée sous prefers-reduced-motion,
                et mise en pause par un bouton visible (WCAG 2.2.2).
     LE LOT DU 21/09/2026 SÉPARE CE QUI ÉTAIT CONFONDU. Jusqu'ici --r-ronde
     était à la fois le rayon de l'orbite ET la largeur de référence des
     logos : la ronde ne portait que cinq logos, les deux mesures pouvaient
     être la même. Le donneur d'ordre a demandé que la ronde « prenne à peu
     près l'écran » et que chaque poste porte un ou deux appareils : le rayon
     a doublé, la largeur des logos n'avait aucune raison de suivre.

     ET LE RAYON NE SE CHOISIT PLUS, IL SE DÉDUIT. Une seule mesure est
     libre, la tuile d'appareil ; le rayon en descend par la géométrie des
     cinq postes, et c'est ce qui rend la ronde juste à toutes les tailles au
     lieu de l'être aux quatre qu'on a regardées.

     SECONDE PASSE DU 21/09/2026, ET C'EST UN REFUS QUI L'A IMPOSÉE. La
     première passe mesurait la ronde contre 100vh, c'est-à-dire contre une
     fenêtre dont l'entête collante occupe déjà --h-nav. Mesurée contre la
     hauteur RÉELLEMENT disponible, --h-utile, l'emprise valait 929 px pour
     811, et 86 px de la ronde restaient sous l'entête à la meilleure
     position de défilement : le visiteur ne la voyait jamais entière.
     Ce qui a changé ici : la tuile descend de --h-utile ; la boîte de carte
     a maigri de 40 px de haut (voir composants.css §12, chaque pixel de
     carte coûtant 1,70 px de cercle) ; le rayon majore la diagonale au plus
     juste au lieu de la majorer par racine(2) ; --logo-ronde devient une
     constante ; et l'orbite demande désormais une HAUTEUR minimale en plus
     de sa largeur minimale, faute de quoi la ronde est une grille.

     TROISIÈME PASSE DU 21/09/2026, ET C'EST LE DONNEUR D'ORDRE QUI L'OUVRE :
     « ça doit tourner comme le premier ». La première ronde, celle des cinq
     logos seuls, tournait partout ; celle qui porte les appareils ne tournait
     qu'au-dessus de 56rem de HAUTEUR de fenêtre, soit 896 px, et AUCUNE
     définition de portable courante n'est au-dessus : 1536x864, 1366x768,
     1280x800 et 1024x768 recevaient une grille immobile. Mesure d'ouverture,
     refaite sur le conteneur avant toute retouche (emprise verticale de la
     ronde, forme, nombre d'animations en cours) :
       1920x1080 orbite 6 animations 972,0 px   1536x864 grille 0 anim 639,3 px
       1680x1050 orbite 6 animations 942,6 px   1366x768 grille 0 anim 639,0 px
       1440x900  orbite 6 animations 797,0 px   1280x800 grille 0 anim 633,5 px
                                                1024x768 grille 0 anim 633,1 px

     CE QUE LA MESURE A TROUVÉ, ET QUI N'ÉTAIT PAS DANS LE DOSSIER. Rapetisser
     la tuile ne suffisait pas, et pris seul c'était DANGEREUX. Deux murs que
     la passe précédente n'avait pas vus :
       1. LA CARTE NE SUIT PLUS SES TUILES SOUS 102 px DE TUILE. Sa largeur
          rendue se bloque à 239,34 px et n'en bouge plus, parce que c'est la
          RANGÉE DE MARQUE qui la tient : logo Unistellar 122,34 px (facteur
          strict 1,0547 sur --logo-ronde) + 12 px d'écart + libellé 71 px +
          2 x 8 px de retrait + 2 px de filets. Le jeton --carte-ronde-l, lui,
          continuait de descendre en 2 x tuile + 36 : à une tuile de 77 px il
          aurait annoncé 190 px pour une carte qui en mesure 239. Le rayon se
          déduit de ce jeton ; un jeton trop petit donne un cercle trop serré,
          et un cercle trop serré fait se TOUCHER les cartes. La largeur de la
          carte a donc maintenant son majorant de rangée, --marque-ronde, et
          --carte-ronde-l prend le max des deux.
       2. LE PLANCHER DE LA TUILE N'EST PAS CELUI QU'ON CROYAIT. Il était
          justifié par « sous 6,5rem, Seestar S30 Pro ne tient plus en deux
          lignes ». MESURÉ, ET C'EST FAUX : le nom reste sur deux lignes
          jusqu'à 56 px de tuile, son mot le plus long étant « Seestar ». Ce
          qui casse le premier, c'est LE PRIX : le plus large des neuf mesure
          81,17 px en Martian Mono à --d-mono = 13 px, et dès que la largeur
          utile de la tuile passe dessous il se replie sur deux lignes et la
          carte prend 19,5 px de haut d'un coup (constaté à 96 px de tuile,
          quand la tuile portait encore ses deux retraits de 8 px). Le
          plancher vrai est la largeur du prix, et le donneur d'ordre a
          demandé les prix.

     CE QUI EST FAIT. Le retrait intérieur du lien d'appareil passe à zéro en
     orbite : la vitre vaut alors la tuile entière, le plancher de tuile tombe
     de 97,2 px à la largeur nue du prix, ET la photographie grandit au lieu de
     maigrir (88 px de vitre à 1440x900 avant, 109,8 après). L'air de la carte
     passe à --air-carte-ronde. La hauteur de carte ne se majore plus par un
     7,5rem forfaitaire, elle s'ÉCRIT : filets, air, rangée de marque, tuile,
     nom sur deux lignes et prix, chacun par son jeton. Et la diagonale n'est
     plus majorée à la main quand le navigateur sait la calculer : hypot() la
     donne exacte, le majorant linéaire restant en repli (voir le @supports en
     bas de fichier). Gain mesuré de l'exactitude : 2,9 % de rayon.

     --air-carte-ronde  L'AIR INTÉRIEUR D'UNE CARTE EN ORBITE, 4 px, ET IL EST
                MESURÉ, PAS CHOISI. Le barème est relevé en grossissant la
                boîte de jeton de 10 px et en lisant l'emprise : un pixel de
                HAUTEUR de carte coûte 2,12 px d'emprise à 1024x768 (2,06 à
                2,13 aux trois tailles relevées) et un pixel de LARGEUR 1,30
                (1,29 à 1,35). L'air d'une carte qui tourne ne se paie donc pas
                comme celui d'une carte posée. À --e-1 (8 px) partout, l'emprise
                à la tuile plancher vaut 714,4 px pour 679 px de hauteur utile
                à 1024x768 : la ronde ne tient pas. À 4 px elle vaut 660,6 px,
                soit 97,3 %, et il reste 18,4 px. La grille, elle, garde
                --e-3 : elle n'a rien à payer. Quatre emplois, tous dans composants.css §12 : les
                deux retraits de la carte, l'écart entre la rangée de marque et
                les tuiles, et l'écart entre la photographie et son nom.
     --marque-ronde  LA LARGEUR DE LA PLUS LARGE DES CINQ RANGÉES DE MARQUE, et
                c'est elle qui tient la carte quand les tuiles sont petites.
                Relevée à --logo-ronde = 7,25rem et --d-petit = 15 px : logo
                Unistellar 122,34 + écart 8 + libellé « Unistellar » 71,00 =
                201,34 px ; Celestron, dont le libellé est le plus long (74 px)
                mais le logo au facteur 1 (116 px), n'en fait que 198,00. Le
                jeton majore la première : la part de logo suit --logo-ronde
                par le facteur strict d'Unistellar (1,055 majore 1,0547) et la
                part de libellé suit --d-petit, 71,00 px à 15 px valant 4,733
                em, majorés à 4,8. Rendu du jeton à 15 px : 202,38 px pour
                201,34 mesurés. Le libellé ne s'exprime pas autrement : aucune
                unité CSS ne mesure une chaîne.
     --logo-ronde  LA LARGEUR DE RÉFÉRENCE D'UN LOGO, ET C'EST UNE CONSTANTE.
                Un logo de facteur 1 (Celestron) fait exactement cette
                largeur, les quatre autres suivent facteurStrict de
                donnees/logos-constructeurs.json, qui égalise leurs hauteurs
                de lettre. À une largeur l, la capitale de chacun vaut
                0,098 x l (Celestron : 49 px de lettre pour 500 d'encre).
                7,25rem = 116 px : capitales à 11,4 px, pour un seuil de 11.
                À 7rem elles tomberaient à 10,98 px.
                POURQUOI UNE CONSTANTE ET PLUS UN clamp. Sous 64rem, la
                borne basse du clamp précédent gagnait TOUJOURS : 11vw vaut
                112,5 px à 1023 de large et 43 px à 390. La valeur fluide
                n'était donc jamais servie en grille. En orbite, elle l'était
                et elle coûtait cher : à 1440, un logo de 158 px poussait la
                rangée de marque à 266 px, plus large que les deux tuiles
                qu'elle surmonte, et c'est ELLE qui fixait alors la largeur
                de la carte (300 px mesurés) donc le rayon. Le logo est
                revenu à la largeur qui était déjà la sienne partout
                ailleurs, et la carte est redevenue commandée par ses tuiles.
                Gain mesuré à 1440 x 900 : 54 px de largeur de carte, 46 px
                de rayon, 88 px d'emprise.
     --tuile-ronde  LA LARGEUR D'UNE TUILE D'APPAREIL, la seule mesure libre
                de la ronde. La photo y est carrée ; la tuile est donc aussi
                haute que large, plus le nom du modèle et son prix.
                DEUX VALEURS, PARCE QUE LA RONDE A DEUX FORMES, et c'est la
                seule requête de média de ce fichier (elle est en bas) :
                  en grille elle suit la LARGEUR : 38vw donne 148 px à 390,
                    et deux tuiles plus leur gouttière font 308 px dans les
                    311 px utiles d'une carte de groupe.
                  en orbite elle DESCEND DE --h-utile, et la pente est
                    relevée sur la géométrie ci-dessous, pas choisie :
                    t = 0,234 x --h-utile - 5rem. Mesuré, hypot() servi :
                    660,6 px d'emprise pour 679 px utiles à 1024x768 (97,3 %)
                    et 950,4 px pour 991 à 1920x1080 (95,9 %). La pente est
                    BRIDÉE par le repli sans hypot(), qui grossit le rayon de
                    2,9 % : au repli, les sept tailles tiennent encore, de
                    92,1 % (1536x864) à 98,5 % (1366x768) de la hauteur utile.
                    Une pente plus raide remplissait mieux les grands écrans
                    et débordait sur ce repli.
                    Le min(10,5vw) est la garde de LARGEUR : sans lui, une
                    fenêtre de 1024 x 1366 donnerait une tuile de 192 px (le
                    plafond) et une emprise horizontale de 1 244 px pour
                    1 024 de fenêtre ; avec lui, 760 px.
                Plancher 6,5rem en grille (104 px) et 5,25rem en orbite,
                ET LES DEUX PLANCHERS NE DISENT PAS LA MÊME CHOSE. En grille
                la tuile porte ses deux retraits de --e-1 ; en orbite elle
                n'en a plus, et 5,25rem = 84 px de largeur utile pour un prix
                qui en mesure 81,17 au plus large (Martian Mono, --d-mono à
                son plafond de 13 px). Sous ce plancher le prix se replie sur
                deux lignes et la carte prend 19,5 px d'un coup. Le nom de
                modèle, lui, n'y est pour rien : mesuré, il tient sur deux
                lignes jusqu'à 56 px de tuile.
                Plafond 9,5rem en grille (152 px, deux tuiles dans la colonne
                d'un téléphone) et 12rem en orbite (192 px). Le plafond haut
                ne sert que sur un grand écran HAUT : à 2560 x 1440 la formule
                demanderait 236 px. 192 px est la limite des dérivés servis,
                qui sont taillés à 480 px : la vitre y fait 192 px moins ses
                deux --e-1 d'encart, soit 176, donc 352 px à la densité 2.
     --carte-ronde-l et --carte-ronde-h  LA BOÎTE D'UNE CARTE DE MARQUE, en
                jetons, pour que le rayon puisse s'en déduire. Elles ne sont
                plus forfaitaires : chaque pièce de la carte y est nommée par
                son jeton, et la seule mesure que CSS ne sait pas prendre, la
                largeur d'un libellé, est isolée dans --marque-ronde.
                  la largeur : LE MAX DE DEUX RANGÉES, et c'est la correction
                    de la troisième passe. Soit les deux tuiles et leur écart
                    --e-1 commandent, soit c'est la rangée de marque,
                    --marque-ronde, qui ne rétrécit pas avec les tuiles. Elles
                    s'égalent à 97,2 px de tuile ; sous cette valeur la carte
                    ne maigrit plus, et un jeton qui aurait continué de
                    descendre aurait donné un cercle trop serré. Plus les deux
                    retraits --air-carte-ronde et les 2 px de filets.
                  la hauteur : ÉCRITE PIÈCE À PIÈCE, plus majorée. 2 px de
                    filets, deux retraits et deux écarts --air-carte-ronde,
                    --cible-min pour la rangée de marque (elle n'a plus de
                    retrait vertical et vaut la cible de 24 px pour les cinq),
                    la tuile (qui EST la vitre, le lien d'appareil n'ayant plus
                    de retrait en orbite), deux lignes de --d-petit en
                    --i-titre pour le nom de modèle, et une ligne de --d-mono
                    en --i-mono pour le prix.
                  LE RELEVÉ, REFAIT FONTES CHARGÉES : celui de la troisième
                    passe (« jeton 180,90 px, carte rendue 180,89 ») ne se
                    reproduisait à aucune des sept tailles. À 1024x768 le
                    jeton mesure 210,609 x 179,797 px et la plus large des
                    cinq cartes rendues 208,344 x 179,797 : la hauteur tombe
                    juste, la largeur majore de 2,27 px. À 1366x768 : jeton
                    212,094 x 180,750, carte 211,344 x 180,750. Le jeton
                    majore, jamais l'inverse, et c'est ce qu'exige le rayon.
     --r-ronde  LE RAYON DE L'ORBITE, ET IL SE CALCULE.
                LA CONTRAINTE QUI COMMANDE N'EST PAS CELLE QU'ON CROIT. Les
                cartes se contre-tournent : elles restent DROITES pendant que
                l'orbite tourne. Deux cartes voisines gardent donc un écart de
                centre à centre constant, d = 2 r sin 36°, mais l'orientation
                de cet écart balaie tout le tour : à un moment il est
                horizontal, à un autre vertical. Deux rectangles droits
                distants de d se chevauchent dès que d est plus court que leur
                DIAGONALE. Le rayon doit donc vérifier
                  2 r sin 36° >= racine(L² + H²)
                soit r >= 0,8507 x racine(L² + H²).
                CE N'EST PAS DE LA THÉORIE : avec un rayon calé sur la seule
                largeur des cartes, la mesure a trouvé des chevauchements de
                10 à 21 px à cinq tailles de fenêtre sur cinq, à des angles de
                rotation qu'une capture ne montre pas.
                LA DIAGONALE SE PREND, ELLE NE SE MAJORE PLUS, --diag-ronde.
                Les deux premières passes la majoraient faute de racine
                carrée : racine(2) x max, qui coûte jusqu'à 41 % quand la
                carte est loin du carré, puis max + 0,4142 x min, qui est
                exacte au carré comme au plat et majore entre les deux.
                CSS SAIT LA CALCULER : hypot() est servi par Chrome 113,
                Safari 15.4 et Firefox 118, soit une base plus récente de
                trois versions de Firefox que le 100svh dont --h-utile dépend
                déjà. Mesuré à 1024x768, à jeu égal : rayon 247,34 px par le
                majorant linéaire contre 240,38 par hypot(), soit 2,9 %, et
                674,5 px d'emprise contre 660,6, soit 13,9 px repris. Le
                majorant reste écrit ici et hypot() le remplace par le
                @supports du bas de fichier ; --jeu-ronde y passe de 0 à
                --air-carte-ronde, le majorant linéaire portant déjà le sien
                (voir --jeu-ronde). Un navigateur sans hypot() garde donc
                l'ancienne géométrie et les sept tailles tiennent encore.
     --jeu-ronde  L'AIR ENTRE DEUX CARTES VOISINES, ET IL EST NÉ D'UNE
                MESURE DE CE LOT. Le rayon se déduit de la diagonale de la
                carte ; tant que la boîte de jeton MAJORAIT la carte rendue,
                l'écart entre deux cartes au pire angle était ce que cette
                majoration laissait traîner, c'est-à-dire rien de garanti.
                --carte-ronde-h s'écrivant maintenant au pixel, le balayage de
                144 angles a trouvé un jeu minimal de 0,12 px à 1440x900 :
                aucun chevauchement, mais rien non plus. Le jeu est donc
                DEMANDÉ, et il vaut l'air d'une carte. La condition de
                non-croisement se pose alors sur la carte grossie du jeu de
                chaque côté : 2 r sin 36° >= racine((L + jeu)² + (H + jeu)²).
                Relevé après : jeu minimal de 4,07 à 6,60 px aux sept tailles,
                pour 9,6 px d'emprise verticale payés.
                IL VAUT ZÉRO SUR LE REPLI SANS hypot(), ET C'EST MESURÉ : le
                majorant linéaire grossit déjà le cercle de 2,9 %, ce qui laisse
                de 4,40 à 13,72 px entre cartes aux sept tailles sans qu'on
                demande rien. Le lui ajouter portait 1366x768 à 99,9 % de la
                hauteur utile pour un jeu de 11 px dont personne n'a besoin.
     --debord-ronde  DE COMBIEN UN POSTE DÉBORDE DU CERCLE, ET C'EST LA MOITIÉ
                D'UNE CARTE, EN HAUT COMME EN BAS. La première passe
                retranchait 0,191 r en bas, au motif que les deux postes bas
                sont à sin 54° du centre : c'est vrai d'une ronde ARRÊTÉE,
                faux d'une ronde qui tourne, où chaque poste passe par le bas
                du cercle une fois par tour. La réserve vaut donc une
                demi-carte des deux côtés, et la ronde ne monte jamais dans
                la tête de section ni ne descend sur l'appel.              */
  --t-ronde: 60s;
  --logo-ronde: 7.25rem;
  --air-carte-ronde: .25rem;                                          /* 4 px */
  --marque-ronde: calc(1.055 * var(--logo-ronde) + var(--e-1) + 4.8 * var(--d-petit));
  --tuile-ronde: clamp(6.5rem, 38vw, 9.5rem);
  --carte-ronde-l: calc(2px + 2 * var(--air-carte-ronde)
                        + max(calc(2 * var(--tuile-ronde) + var(--e-1)),
                              var(--marque-ronde)));
  --carte-ronde-h: calc(var(--tuile-ronde) + 2px + 4 * var(--air-carte-ronde)
                        + var(--cible-min)
                        + 2 * var(--i-titre) * var(--d-petit)
                        + var(--i-mono) * var(--d-mono));
  --jeu-ronde: 0px;
  --diag-ronde: calc(max(calc(var(--carte-ronde-l) + var(--jeu-ronde)),
                         calc(var(--carte-ronde-h) + var(--jeu-ronde)))
                     + 0.4142 * min(calc(var(--carte-ronde-l) + var(--jeu-ronde)),
                                    calc(var(--carte-ronde-h) + var(--jeu-ronde))));
  --r-ronde: calc(0.8507 * var(--diag-ronde));
  --debord-ronde: calc(var(--carte-ronde-h) / 2);

  /* --- L'ENTRÉE EN TROIS TEMPS : DÉROGATION NOMMÉE AU BARÈME, 14/09/2026 ---
     Demande client du 14/09/2026, carnet §2.1, piste 1 : « le logo est frappé
     par des étoiles qui s'accélèrent de plus en plus, et finit sur l'éclipse
     totale ». Une séquence de 3 000 ms, jouée UNE FOIS PAR SESSION, et rien
     sous prefers-reduced-motion. Le barème plafonne à 560 ms parce qu'il
     décrit des transitions d'interface ; ceci est une partition, jouée une
     fois, et ses durées sont écrites ICI, toutes, pour que composants.css §9
     et le script de scène (inc/pied.php) n'en portent aucune : le script les
     lit par getComputedStyle, il ne recopie pas 3000.

     LES TROIS TEMPS, ET LEURS BORNES (la partition du lot d'images) :
       temps 1  l'approche et le choc     0 -> --entree-t1-fin      (1 600)
       temps 2  les éclats                --entree-t2-debut -> -fin (1 450 -> 2 350)
       temps 3  le passage du disque      --entree-t3-debut -> fin  (2 250 -> 3 000)
                (il passe, freine, s'arrête sur le sceau, tient, puis s'efface)
     Les temps se recouvrent, c'est voulu : les éclats naissent pendant que
     les dernières étoiles frappent, le disque part pendant que les éclats
     s'éteignent.

     LA CADENCE DU TEMPS 1, ET L'ARITHMÉTIQUE QUI LA TIENT. Quatorze étoiles
     partent à --entree-cadence l'une de l'autre (le brief donne 60 à 90 ms ;
     70 est retenu), et les trois dernières à --entree-rafale : départs 0, 70,
     ... 700, puis 740, 780, 820. Chacune vole --entree-vol = 750 ms en ease-in
     pur : la onzième (index 10, etoile-quatre) touche à 10 x 70 + 750 = 1 450,
     qui EST --entree-t2-debut, la première gerbe naît de ce choc ; la dernière
     touche à 820 + 750 = 1 570, sous --entree-t1-fin. Les trois chocs que le
     sceau encaisse (index 7, 10, 13) tombent à 1 240, 1 450 et 1 570 : espacés
     de plus de --entree-choc, les trois animations ne se chevauchent pas.
     --entree-mort est la disparition au contact, sur les 60 derniers ms du vol.

     LE TEMPS 2 : la gerbe pousse en --entree-gerbe-pousse puis s'éteint en
     --entree-gerbe-eteint ; brisures et étincelles volent --entree-eclat-vol
     en décélérant. Le dernier choc est à 1 570 : 1 570 + 700 = 2 270, sous
     --entree-t2-fin.

     LE TEMPS 3, RÉÉCRIT LE 15/09/2026, ET POURQUOI. Les trois nombres du brief
     du 14/09 sont incompatibles, c'est mesuré : un disque qui traverse de
     -85vw à +38vw en 750 ms passe sur le sceau à 1,6 px par milliseconde, et
     la couverture totale n'a duré que 12 ms (fuite du sceau hors disque :
     100 % à 2 700, 57,5 % à 2 750, 0,089 % à 2 795, 0 à 2 805, 11,5 % à
     2 820, 64,1 % à 2 850), pendant que le fondu du calque, lui, courait sur
     200 ms : l'éclipse totale, l'image que le client demande en dernier, se
     voyait à 13 % d'opacité. Arbitrage du 15/09 : LE DISQUE FREINE ET
     S'ARRÊTE SUR LE SCEAU. Il part à --entree-t3-debut, court
     --entree-t3-course en --entree-courbe-eclat (la même décélération que les
     éclats : l'énergie se dépense) et s'arrête centré sur le sceau à
     --entree-t3-arret. Il y TIENT --entree-t3-tenue, à pleine opacité : c'est
     pendant cette tenue que le FOND du calque et le SCEAU s'effacent, et pas
     le disque, donc la page se découvre AUTOUR d'un disque noir qui ne bouge
     plus. Le disque seul s'efface ensuite en --entree-eclipse-fin, et le
     calque est retiré à --entree-duree.
       2 250 départ | 2 550 arrêt centré | 2 850 fin de tenue | 3 000 retrait
     L'arithmétique est tenue par calc() et non par des nombres recopiés :
     --entree-t3-course est l'écart départ/arrêt, --entree-eclipse-fin est ce
     qui reste de --entree-duree après l'arrêt et la tenue. Trois jetons du
     14/09 sont morts avec l'ancien temps 3 et ont été retirés :
     --entree-retrait (le fondu du calque entier n'existe plus),
     --entree-eclipse-a (le disque ne sort plus à droite, il s'arrête au
     centre) et --entree-courbe-disque (la courbe calculée pour une traversée
     à vitesse presque constante, sans objet pour un freinage).
     COUVERTURE AVANT EFFACEMENT, mesurée à la reprise : la fuite du sceau
     hors du disque tombe à 0 AVANT --entree-t3-arret, c'est-à-dire avant que
     le sceau ne commence à s'effacer ; avant cela le disque mord le sceau,
     qui est encore à opacité 1 : c'est le passage du cercle noir sur le logo.

     LES DEUX COURBES DE LA PHRASE DU CLIENT :
       --entree-courbe-choc   ease-in PUR : la vitesse monte jusqu'au contact,
                              « des étoiles qui s'accélèrent de plus en plus ».
       --entree-courbe-eclat  l'inverse, les éclats DÉCÉLÈRENT : l'énergie est
                              dépensée.

     LA TAILLE DU DISQUE, MESURÉE (inc/donnees/entree.json) : le disque
     lunaire opaque n'occupe que 77 % du sprite, donc --entree-eclipse vaut
     1,30 pour que le DISQUE NOIR fasse 200 px, la taille du logo. C'est la
     demande du 15/09/2026, qui remplace le 1,55 d'avant : un disque de 238 px,
     un cinquième plus large que le logo.
     IL NE COUVRE PLUS TOUT LE SCEAU, et ce n'est plus nécessaire depuis que le
     sceau s'efface de lui-même pendant la tenue. Le tube du télescope déborde
     l'anneau or jusqu'à 57,9 % de la largeur du médaillon : son objectif
     dépasse du disque à deux heures, 1,627 % des pixels du sceau, à pleine
     opacité de l'arrivée (2 550 ms) au début du fondu, 0,127 à 2 700, nul à
     2 850. Fuite mesurée aux autres échelles : 135 % 1,147 % ; 140 % 0,691 % ;
     145 % 0,289 % ; 150 % 0,014 % ; 155 % 0,000 %.
     Le sprite de 640 px, rendu à la densité 2,46, couvre au plus un
     médaillon de 246 px : --entree-medaillon
     plafonne à 200 px, et son plancher de 132 px est la taille de l'ancien
     rideau, sceau(132). Les huit sprites (48 800 octets) sont rendus à la
     moitié de leur taille native, jamais plus.                                */
  --entree-duree:         3000ms;
  --entree-t1-fin:        1600ms;
  --entree-t2-debut:      1450ms;
  --entree-t2-fin:        2350ms;
  --entree-t3-debut:      2250ms;  /* le disque part hors champ, à gauche           */
  --entree-t3-arret:      2550ms;  /* il s'arrête, centré sur le sceau               */
  --entree-t3-course:     calc(var(--entree-t3-arret) - var(--entree-t3-debut));  /* 300 ms */
  --entree-t3-tenue:      300ms;   /* il tient, opaque ; fond et sceau s'effacent    */
  --entree-eclipse-fin:   calc(var(--entree-duree) - var(--entree-t3-arret) - var(--entree-t3-tenue));  /* 150 ms */
  --entree-cadence:       70ms;    /* entre deux départs d'étoile (brief : 60 à 90) */
  --entree-rafale:        40ms;    /* les trois derniers départs                    */
  --entree-vol:           750ms;   /* le vol d'une étoile, du bord au centre        */
  --entree-choc:          90ms;    /* le sceau encaisse : 1 -> .985 -> 1.008 -> 1   */
  --entree-mort:          60ms;    /* l'étoile s'éteint au contact                  */
  --entree-gerbe-pousse:  120ms;   /* la gerbe pousse, scaleX .2 -> 1               */
  --entree-gerbe-eteint:  180ms;   /* puis s'éteint                                  */
  --entree-eclat-vol:     700ms;   /* brisures et étincelles, 40 à 140 px           */
  --entree-courbe-choc:   cubic-bezier(.55, 0, 1, 1);
  --entree-courbe-eclat:  cubic-bezier(.1, .7, .3, 1);
  --entree-medaillon:     clamp(132px, 24vw, 200px);
  --entree-eclipse:       1.30;    /* 130 % : le disque noir fait la taille du logo  */
  --entree-eclipse-de:    -85vw;   /* d'où part le disque : hors champ, à gauche     */

  /* --- Focus ------------------------------------------------------------ */
  --focus-couleur: var(--lampe-haute);
  --focus-l: 2px;
  --focus-o: 3px;

  color-scheme: dark;
}

/* =========================================================================
   ALIAS DE TRANSITION — À SUPPRIMER
   Les 61 pages ont été écrites sur le vocabulaire de la direction précédente
   (« le temps de pose », accent braise). Elles sont reprises page par page.
   D'ici là ces alias les branchent sur la palette arbitrée, pour qu'aucune
   page ne serve une couleur invalide ni une braise dans le chrome.
   Aucune règle NOUVELLE ne doit utiliser un nom de cette liste.
   ========================================================================= */
:root {
  --fond:         var(--nuit);
  --fond-2:       var(--ciel);
  --nuit-2:       var(--ciel);
  --surface:      var(--ciel);
  --carte:        var(--ciel);
  --carte-haute:  var(--filet);
  --texte-2:      var(--champ);
  --cendre:       var(--champ);
  --lait:         var(--texte);
  --filet-fort:   var(--filet-haut);
  --accent:       var(--lampe);
  --accent-texte: var(--lampe);
  --sur-accent:   var(--nuit);
  --braise:       var(--lampe);        /* loi n° 1 : plus de braise en chrome */
  --braise-clair: var(--lampe-haute);
  --braise-sombre:var(--lampe-nuit);
  --braise-o12:   color-mix(in srgb, var(--lampe) 12%, transparent);
  --braise-o20:   color-mix(in srgb, var(--lampe) 20%, transparent);
  --braise-o30:   var(--halo);
  --lait-o10:     var(--filet);
  --lait-o20:     var(--filet-haut);

  --t-hero:  var(--d-display);
  --t-h1:    var(--d-display);
  --t-h2:    var(--d-h2);
  --t-h3:    var(--d-h3);
  --t-h4:    var(--d-h4);
  --t-corps: var(--d-corps);
  --t-petit: var(--d-petit);
  --t-data:  var(--d-mono);
  --t-brow:  var(--d-mono);

  --d-1: var(--t-micro);   --d-2: var(--t-ui);    --d-3: var(--t-panneau);
  --d-4: var(--t-pose);    --d-5: var(--t-revele);
  --courbe-2: var(--courbe);
  --ombre-aura: var(--ombre-carte);
  --ombre-glow: var(--ombre-carte);
}

/* Loi n° 3 : aucune surface claire, nulle part. Les enveloppes de thème
   clair de la direction précédente sont neutralisées, pas supprimées :
   une page qui porte encore .t-clair reste lisible, en nuit.              */
.t-clair, .t-braise { color-scheme: dark; }
.t-braise { --fond: var(--lampe-nuit); --fond-2: var(--lampe-nuit); }

/* LES DEUX SEULES CONDITIONS DE CE FICHIER, ET ELLES ONT LEUR RAISON.
   --tuile-ronde mesure la tuile d'appareil de la ronde de l'accueil. La ronde
   a DEUX FORMES et non deux tailles : une grille au serré, une orbite au
   large ET AU HAUT (composants.css §12, où les deux mesures qui imposent la
   bascule sont écrites). En grille, la tuile suit la LARGEUR disponible ; en
   orbite, elle suit la HAUTEUR UTILE, parce que c'est la hauteur d'écran que
   la ronde doit occuper sans qu'un morceau reste sous l'entête collante.
   Une seule expression ne peut pas dire les deux : min(38vw, 14vh) donnerait
   118 px à 390 x 844 au lieu des 148 px que la carte offre. Le jeton est donc
   écrit deux fois, sous la forme qui le lit. --r-ronde et --debord-ronde, eux,
   se calculent depuis elle et suivent tout seuls.
   LA CONDITION DE HAUTEUR DESCEND À 48rem, ET C'EST LE CHANTIER DU JOUR.
   Elle valait 56rem, soit 896 px de fenêtre : toutes les définitions de
   portable courantes passaient dessous et recevaient une grille immobile,
   alors que le donneur d'ordre demandait que « ça tourne comme le premier ».
   Le plancher se mesure ainsi : à la tuile plancher de l'orbite (5,25rem,
   84 px, la largeur du prix), l'emprise verticale vaut 660,6 px, et il faut
   donc 660,6 + 89 = 749,6 px de fenêtre. 48rem (768 px) est le premier cran
   rond au-dessus, et c'est la hauteur d'écran des portables que le dossier
   nomme : 1366x768 tient avec 14,5 px de reste, 1024x768 avec 18,4.
   CE QUI RESTE EN GRILLE, ET C'EST MESURÉ, PAS SUPPOSÉ : les 768 px se lisent
   sur la FENÊTRE, c'est à dire la hauteur d'écran moins l'habillage du
   navigateur, divisée par le zoom. Formes relevées : 1366x668 (écran de 768
   moins 100 px de barres) GRILLE, 1366x698 (moins 70 px) GRILLE, 1242x698
   (plein écran, zoom 110 %) GRILLE, 1093x614 (zoom 125 %) GRILLE, 931x698
   (1024x768 au zoom 110 %) GRILLE, 1536x764 (écran de 864 moins 100 px)
   GRILLE ; et de l'autre côté 1440x800 ORBITE, 1309x818 (1440x900 au zoom
   110 %) ORBITE, 1396x785 (1536x864 au zoom 110 %) ORBITE, 1920x980 ORBITE.
   SUR UN ÉCRAN DE 768 px L'ORBITE DEMANDE DONC LE PLEIN ÉCRAN ET LE ZOOM À
   100 %. Sous ce plancher la grille reprend la main, et il n'y a rien à
   sauver en rétrécissant, la tuile étant déjà sur le prix.                   */
@media (min-width: 64rem) and (min-height: 48rem) {
  :root {
    --tuile-ronde: clamp(5.25rem, min(calc(0.234 * var(--h-utile) - 5rem), 10.5vw), 12rem);
  }
}

/* LA DIAGONALE EXACTE QUAND LE NAVIGATEUR SAIT LA PRENDRE. Le majorant
   linéaire écrit plus haut reste la valeur de base ; hypot() le remplace ici,
   et --jeu-ronde avec lui : le majorant linéaire porte déjà son propre jeu,
   mesuré de 4,40 px (1536x864) à 13,02 px (1920x1080). Les deux chemins
   tiennent aux sept tailles du dossier, l'exact avec 2,9 % de rayon en
   moins. Voir --r-ronde.                                                    */
@supports (width: hypot(1px, 1px)) {
  :root {
    --jeu-ronde: var(--air-carte-ronde);
    --diag-ronde: hypot(calc(var(--carte-ronde-l) + var(--jeu-ronde)),
                        calc(var(--carte-ronde-h) + var(--jeu-ronde)));
  }
}
