/* 10-toile.css — l'accueil : le cadre de la toile, et les arêtes qui la traversent.
 *
 * Les NŒUDS sont dans `11-noeuds.css`. La coupe suit la frontière que le dessin trace déjà —
 * arêtes en SVG ici, nœuds en HTML là-bas — et non un compte de lignes.
 *
 * ── L'ORDRE COMPTE ─────────────────────────────────────────────────────────────────
 * Onzième tranche, donc la dernière de la cascade. Le chiffre en tête du nom est son rang,
 * et `server/feuilles.py` trie NUMÉRIQUEMENT — c'est ce qui empêche « 10- » de se ranger
 * avant « 9- ». Ce fichier est le premier à exercer réellement ce chemin.
 *
 * ── DEUX BOÎTES, UN SEUL REPÈRE ────────────────────────────────────────────────────
 * Les arêtes sont en SVG, les nœuds en HTML, superposés sur le même carré. Ce n'est pas un
 * compromis : un `<g>` reçoit bien les clics, mais il n'est ni focusable, ni un bouton, ni
 * annonçable — or le geste numéro un de cet écran est « je tape sur mon produit pour y
 * entrer ». Les nœuds sont donc de vrais `<a href="#slug">`, ce qui rend la tabulation,
 * l'appui long et le titre au survol gratuits.
 *
 * Le SVG porte `viewBox="0 0 100 100"`, le HTML `left: calc(var(--x) * 1%)` : les deux
 * lisent les MÊMES centièmes, sans une ligne de conversion. Ce qui les tient d'accord n'est
 * PAS que la boîte soit carrée, c'est `preserveAspectRatio="none"` sur le SVG — sans lui, il
 * se centrerait en gardant ses proportions pendant que les nœuds suivent la boîte, et les
 * traits décrocheraient des cercles d'autant plus que l'écran est allongé.
 *
 * La boîte peut donc être un rectangle, et sur un téléphone elle doit l'être : voir plus bas.
 *
 * ── CE QUE LES COULEURS ONT LE DROIT DE PEINDRE ────────────────────────────────────
 * Les cinq `--pilier-*` ne sont QUE des traits (`--pil` → `stroke`) ; les trois couleurs
 * d'état ne sont QUE des aplats. C'est cette séparation qui permet huit couleurs sans
 * arc-en-ciel ; `tests/test_charte.py` la tient, et `web/tokens.css` dit pourquoi elle ne
 * pouvait pas être chromatique.
 */

/* La largeur maximale, écrite une fois : la toile, sa phrase et sa légende doivent partager
 * la même colonne, et trois copies d'un nombre finissent par en devenir deux. */
:root { --toile-max: 680px; }

.toile {
  position: relative;
  width: 100%;
  max-width: var(--toile-max);   /* une toile de 1 200 px à neuf nœuds n'est pas plus lisible :
                                  * elle est plus vide. Elle se centre, elle ne s'étire pas.
                                  * 680 et non 560 : sur un grand écran la boîte redevient
                                  * carrée, donc l'étiquette d'un produit retombe vers la
                                  * machine posée derrière lui — le dégagement ne se gagne
                                  * plus en hauteur, il se gagne en taille. */
  margin: var(--s3) auto 0;
  aspect-ratio: 1;
}

/* — la hauteur, sur un téléphone —
 * Un carré laissait trois cent quatre-vingts pixels de vide sous la légende : sur un écran
 * de 430 × 930, la largeur est la ressource rare et la hauteur la ressource abondante, et
 * une toile carrée se règle sur la rare. L'anneau devient donc une ELLIPSE — les nœuds
 * restent des cercles, seule leur disposition s'étire.
 *
 * Ce que ça achète n'est pas de la place perdue : c'est le dégagement VERTICAL entre un
 * produit et la machine posée derrière lui, qui est la collision qui a fixé tous les rayons.
 * Étirer en hauteur la desserre sans rien resserrer ailleurs.
 *
 * `dvh` et non `vh` : sur mobile, `vh` ignore la barre d'adresse qui se rétracte, donc la
 * toile dépassait au chargement puis « sautait » au premier défilement.
 * Le second terme est un garde-fou : sur un écran très allongé, une ellipse trop étirée
 * cesse de se lire comme une toile. */
@media (max-width: 680px) {
  .toile {
    aspect-ratio: auto;
    /* 190 px : l'en-tête, la phrase, la légende et les marges. Approché volontairement —
     * un calcul exact demanderait de mesurer, donc du JavaScript, pour gagner dix pixels. */
    height: min(calc(100dvh - 190px), 135vw);
    min-height: 105vw;
  }
}

/* — les arêtes — */

.toile-fils {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;     /* un trait qui touche le bord ne doit pas être rogné à la moitié
                          * de son épaisseur : le SVG est le carré, les traits vivent dessus. */
}

/* `vector-effect: non-scaling-stroke` est posé dans le balisage, et il n'est pas décoratif :
 * sans lui, `stroke-width` s'exprime en unités de `viewBox`, donc une unité vaut 3,3 px sur
 * un téléphone et 5,6 px sur un carré de 560. Le même trait paraîtrait deux fois plus épais
 * sur grand écran — et on chercherait la cause dans le CSS, où elle n'est pas. */
.lien {
  fill: none;
  stroke-linecap: round;
}

/* Le squelette. Toujours dessiné, même à trois heures du matin : c'est lui qui fait qu'un
 * écran sans activité se lit « rien à signaler » et non « panne ». Sans lui, l'accueil est
 * une constellation de points isolés. */
.lien.struct {
  stroke: var(--line);
  stroke-width: 1px;
  opacity: .9;
}

/* Le travail des agents. Le trait existe TOUJOURS dans le document, éteint par défaut : le
 * nombre d'éléments ne doit jamais changer, sinon le composant doit rebâtir son squelette et
 * toutes les animations en cours repartent de zéro. Allumer un fil est un changement de
 * classe, donc une transition — pas une reconstruction. */
.lien.agent {
  stroke: var(--pil, var(--accent));
  stroke-width: 1px;
  opacity: 0;
  transition: opacity .2s ease, stroke-width .2s ease;
}

.lien.agent.passe  { opacity: .22; }
.lien.agent.recent { opacity: .6;  stroke-width: 2px; }

.lien.agent.vif {
  opacity: 1;
  stroke-width: 2.5px;
  stroke-dasharray: 6 6;
  animation: toile-defile 1.2s linear infinite;
}

/* Des tirets qui défilent, et pas un paquet qui voyage le long du trait : `offset-path`
 * n'existe pas sur iOS < 16, et le paquet Capacitor descend jusqu'à iOS 13. Le message est
 * le même, le repli n'a pas à être écrit. */
@keyframes toile-defile { to { stroke-dashoffset: -24; } }

/* — les cinq piliers —
 * Le serveur envoie `pillar: "produit"`, le composant écrit `pil-produit`, et c'est ICI que
 * la teinte est connue. Aucun nom de pilier n'entre dans `web/el/` : exactement la même
 * répartition que `.lv-*` pour les niveaux. */
.pil-taches    { --pil: var(--pilier-taches); }
.pil-strategie { --pil: var(--pilier-strategie); }
.pil-produit   { --pil: var(--pilier-produit); }
.pil-diffusion { --pil: var(--pilier-diffusion); }
.pil-sante     { --pil: var(--pilier-sante); }
