/* Direction esthetique : sombre, dense, les chiffres dominent la typographie.
   Contrat : docs/CONTRAT-2026-09-evolution.md, livrables L2.1 et L2.4.

   LE VERT EMERAUDE EST CONSERVE (#0e9f6e, deja pose dans `ui/app.py`) : c'est une continuite
   d'identite, pas une contrainte. Le rouge et le vert ne codent QUE le signe d'un montant ; ils ne
   servent jamais a hierarchiser, sinon un daltonien perd l'information.

   AUCUNE RESSOURCE EXTERNE : pas de @import, pas de police distante. La pile de polices systeme
   suffit et fonctionne reseau coupe. */

/* ------------------------------------------------------------------- les deux palettes

   TOUTE couleur du fichier passe par un jeton defini ici. Une couleur ecrite en dur ailleurs
   n'aurait pas d'equivalent clair : elle resterait sombre sur fond blanc, et le defaut ne se verrait
   qu'a l'usage, sur un ecran en plein soleil.

   CLAIR PAR DEFAUT dans la feuille, sombre sous `prefers-color-scheme` : c'est l'etat AVANT que le
   script ne se lance, et le meilleur pari est alors celui du systeme. Le choix retenu, lui, est
   estampille sur `<html data-theme>` des le premier octet de la page (script en tete de
   `index.html`), donc il n'y a pas de clignotement.

   Le vert emeraude reste la couleur possedee du projet dans les deux palettes ; seul le ton qui
   porte du TEXTE change, parce que #0e9f6e ne passe pas AA sur fond sombre, et #2ee6a8 ne le passe
   pas sur fond clair. Le rouge et le vert ne codent QUE le signe d'un montant. */
:root {
  --fond: #f4f6f8;
  --fond-carte: #ffffff;
  --fond-creux: #eaeef2;
  --fond-raye: #f0f3f6;
  --bord: #cfd8e0;
  --texte: #10171d;
  --texte-doux: #4d5c69;      /* 7,4:1 sur --fond */
  --emeraude: #0e9f6e;
  --emeraude-texte: #0a6f4d;  /* usage TEXTE : #2ee6a8 est illisible sur fond clair */
  --emeraude-bord: #8ad9bd;
  --emeraude-fond: #e7f7f0;
  --sur-emeraude: #ffffff;
  --rouge: #c0322f;
  --rouge-bord: #e6a6a4;
  --rouge-fond: #fdeceb;
  --ambre: #8a6100;
  --ambre-bord: #e3cd8f;
  --voile: rgba(24, 32, 40, .45);
  --chandelier-hausse: #0e9f6e;
  --chandelier-baisse: #d64545;
  --volume-hausse: #b7e6d3;
  --volume-baisse: #f2c4c4;
  --graphique-grille: #d8e0e7;
  --ma-courte: #0a6f4d;
  --graphique-nuage: #7d8f9c;
  /* LES DEUX COULEURS DE SENS DU REVELATEUR (L32.2), reprises du Pine : le teal du haussier peint
     le sommet de reference, l'orange du repli peint le creux retenu. Elles ne sont PAS celles des
     chandeliers ni des moyennes — un trait de structure doit se distinguer d'une bougie verte. */
  --graphique-revelateur-sommet: #0f8f7a;
  --graphique-revelateur-creux: #c9721a;
  /* Le calque du MOTIF DU JOUR (L35.1) : ses points et leurs noms. Une couleur qui n'est celle
     d'aucun autre trait, parce que c'est ce qu'on vient chercher en ouvrant le graphique. */
  --graphique-motif: #b0339a;
  --ma-moyenne: #8a6100;
  --ma-longue: #3d6f96;
  --ma-100: #6f4fa0;
  --ma-200: #55636f;

  /* LES COULEURS PROPRES AU GRAPHIQUE, et pourquoi elles ne sont pas celles de l'interface.
     Trois d'entre elles etaient empruntees : les droites au texte doux, le stop au rouge des
     montants negatifs, l'entree a la moyenne courte. Tant qu'elles n'etaient pas reglables, cela
     ne coutait rien. Des lors qu'on peut les changer (L12.2), changer le stop du graphique aurait
     repeint tous les montants negatifs de la page.

     Elles sont definies UNE SEULE FOIS, par reference : `var()` dans une propriete personnalisee
     se resout au moment du calcul, avec la valeur que le theme en vigueur donne au jeton pointe.
     Les recopier dans les trois blocs de theme aurait fait trois definitions a tenir d'accord. */
  --graphique-fond: var(--fond-carte);
  --graphique-texte: var(--texte-doux);
  --graphique-droite: var(--texte-doux);
  --graphique-stop: var(--rouge);
  --graphique-entree: var(--ma-courte);
  --graphique-nuage-fond: var(--graphique-nuage);
  /* LE FOND DE LA FENETRE SUIT LE SOMMET. Dans le Pine c'est la meme famille de teinte : la zone
     dit « la lecture qui vise ce pointille est encore valable ». Deux couleurs independantes
     laisseraient poser un fond orange sous un sommet vert, ce qui ne veut rien dire. */
  --graphique-revelateur-fond: var(--graphique-revelateur-sommet);
  --graphique-volume-moyenne: var(--texte-doux);
  /* Les trois lignes de seuil des oscillateurs. Elles suivent le Pine, qui est la reference de
     comparabilite : rouge pour le surachat, vert pour la survente, ambre pour l'ADX. */
  --graphique-seuil-haut: var(--chandelier-baisse);
  --graphique-seuil-bas: var(--chandelier-hausse);
  --graphique-seuil-neutre: var(--ambre);
  /* L'opacite du fond du nuage voyage comme une couleur : meme stockage, meme bouton
     « retablir », et une seule mecanique a comprendre. */
  --graphique-nuage-opacite: .14;
  /* Le Pine pose ses fonds a 92 % de transparence. On est un peu plus dense : sur un ecran de
     telephone tenu a bout de bras, 8 % ne se distingue pas du fond de la carte. */
  --graphique-revelateur-opacite: .11;

  /* CHAQUE TRAIT PORTE TROIS REGLAGES : sa couleur, son style et son epaisseur. Le style est le
     code de `LineStyle` de la bibliotheque — 0 plein, 1 pointille, 2 tirets — et non un mot a nous :
     traduire un vocabulaire qu'on n'a pas invente cree une table de correspondance de plus, qui
     finit par diverger. Les valeurs de depart sont exactement ce qui se tracait avant. */
  --ma-courte-style: 0;                     --ma-courte-epaisseur: 1;
  --ma-moyenne-style: 0;                    --ma-moyenne-epaisseur: 1;
  --ma-longue-style: 0;                     --ma-longue-epaisseur: 1;
  --ma-100-style: 0;                        --ma-100-epaisseur: 1;
  --ma-200-style: 0;                        --ma-200-epaisseur: 2;
  --graphique-volume-moyenne-style: 0;      --graphique-volume-moyenne-epaisseur: 1;
  --graphique-nuage-style: 0;               --graphique-nuage-epaisseur: 1;
  --graphique-droite-style: 2;              --graphique-droite-epaisseur: 1;
  /* Les deux traits du revelateur reprennent le Pine a la lettre : le sommet en pointille fin
     (`line.style_dashed`, width 1), le creux en trait plein epais (width 2). La difference de
     style est ce qui les distingue au premier coup d'oeil sans lire l'echelle. */
  --graphique-revelateur-sommet-style: 2;   --graphique-revelateur-sommet-epaisseur: 1;
  --graphique-revelateur-creux-style: 0;    --graphique-revelateur-creux-epaisseur: 2;
  --graphique-entree-style: 1;              --graphique-entree-epaisseur: 1;
  --graphique-stop-style: 1;                --graphique-stop-epaisseur: 1;
  --graphique-seuil-haut-style: 1;          --graphique-seuil-haut-epaisseur: 1;
  --graphique-seuil-bas-style: 1;           --graphique-seuil-bas-epaisseur: 1;
  --graphique-seuil-neutre-style: 1;        --graphique-seuil-neutre-epaisseur: 1;
  --graphique-oscillateur-1-style: 0;       --graphique-oscillateur-1-epaisseur: 1;
  --graphique-oscillateur-2-style: 0;       --graphique-oscillateur-2-epaisseur: 1;
  --graphique-oscillateur-3-style: 0;       --graphique-oscillateur-3-epaisseur: 1;
  --graphique-oscillateur-4-style: 0;       --graphique-oscillateur-4-epaisseur: 1;
  --graphique-oscillateur-5-style: 0;       --graphique-oscillateur-5-epaisseur: 1;
  --graphique-oscillateur-6-style: 0;       --graphique-oscillateur-6-epaisseur: 1;

  /* Les traces poses a la main, et ceux qu'on a adoptes d'un scanner. Ils etaient ecrits en dur
     dans `chart/dessins.js` — donc les seules couleurs du graphique qui ne suivaient ni le theme,
     ni les reglages. */
  --graphique-trace-manuel: var(--ma-courte);
  --graphique-trace-manuel-style: 0;         --graphique-trace-manuel-epaisseur: 2;
  --graphique-trace-adopte: var(--ma-moyenne);
  --graphique-trace-adopte-style: 2;         --graphique-trace-adopte-epaisseur: 2;
  --graphique-zone-opacite: .12;
  /* Les six teintes des oscillateurs, dans l'ordre ou le panneau les pose. Elles pointaient sur
     les moyennes et le rouge ; elles ont desormais leur propre nom, sans quoi changer la couleur
     du RSI aurait change celle de la moyenne courte. */
  --graphique-oscillateur-1: var(--ma-courte);
  --graphique-oscillateur-2: var(--ma-moyenne);
  --graphique-oscillateur-3: var(--ma-longue);
  --graphique-oscillateur-4: var(--rouge);
  --graphique-oscillateur-5: var(--texte-doux);
  --graphique-oscillateur-6: var(--chandelier-hausse);

  --rayon: 10px;
  --colonne: 1100px;
  color-scheme: light;
}

/* Le detail qui compte : `:not([data-theme="clair"])`. Sans lui, un telephone regle en sombre
   ignorerait un choix « clair » explicite — la preference du systeme gagnerait contre celle de
   l'utilisateur, ce qui est exactement l'inverse de ce qu'on veut. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="clair"]) {
    --fond: #0e1216;
    --fond-carte: #161c22;
    --fond-creux: #10161b;
    --fond-raye: #131a20;
    --bord: #253039;
    --texte: #e6edf3;
    --texte-doux: #9fb0bd;    /* 7,0:1 sur --fond */
    --emeraude-texte: #2ee6a8;
    --emeraude-bord: #1d5a45;
    --emeraude-fond: #04140d;
    --sur-emeraude: #04120c;
    --rouge: #ff6b6b;
    --rouge-bord: #5a2020;
    --rouge-fond: #24151a;
    --ambre: #f0b429;
    --ambre-bord: #5a4a1d;
    --voile: rgba(5, 8, 10, .72);
    --chandelier-baisse: #e05252;
    --volume-hausse: #14513c;
    --volume-baisse: #5a2626;
    --graphique-grille: #253039;
    --ma-courte: #2ee6a8;
    --graphique-nuage: #6b7d8a;
    --graphique-revelateur-sommet: #2bd4b4;
    --graphique-revelateur-creux: #f59e3f;
    --graphique-motif: #ff7ad9;
    --ma-moyenne: #f0b429;
    --ma-longue: #7aa2c2;
    --ma-100: #b39ddb;
    --ma-200: #96a4b2;
    color-scheme: dark;
  }
}

:root[data-theme="sombre"] {
  --fond: #0e1216;
  --fond-carte: #161c22;
  --fond-creux: #10161b;
  --fond-raye: #131a20;
  --bord: #253039;
  --texte: #e6edf3;
  --texte-doux: #9fb0bd;
  --emeraude-texte: #2ee6a8;
  --emeraude-bord: #1d5a45;
  --emeraude-fond: #04140d;
  --sur-emeraude: #04120c;
  --rouge: #ff6b6b;
  --rouge-bord: #5a2020;
  --rouge-fond: #24151a;
  --ambre: #f0b429;
  --ambre-bord: #5a4a1d;
  --voile: rgba(5, 8, 10, .72);
  --chandelier-baisse: #e05252;
  --volume-hausse: #14513c;
  --volume-baisse: #5a2626;
  --graphique-grille: #253039;
  --ma-courte: #2ee6a8;
  --graphique-nuage: #6b7d8a;
  --graphique-revelateur-sommet: #2bd4b4;
  --graphique-revelateur-creux: #f59e3f;
  --graphique-motif: #ff7ad9;
  --ma-moyenne: #f0b429;
  --ma-longue: #7aa2c2;
  --ma-100: #b39ddb;
  --ma-200: #96a4b2;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* L'ASCENSEUR NE DISPARAIT PLUS, et sa place est reservee. « Je pense que la barre de defilement
     doit rester visible car lorsque le graphique occupe tout l'ecran, j'ai du mal a scroller »
     (Jeremy, 2026-09-09). `scrollbar-gutter: stable` empeche la page de sauter de quelques pixels
     quand la barre apparait ; les regles `::-webkit-scrollbar` plus bas demandent une barre
     CLASSIQUE au lieu du recouvrement transitoire que Chrome dessine par defaut.

     CE QUI RESTE HORS DE PORTEE : sur Android, la barre du document est dessinee par le systeme et
     aucune regle CSS ne la fige ouverte. La vraie correction du defilement est ailleurs — c'est
     `touch-action` sur le cadre du graphique, plus bas. */
  scrollbar-gutter: stable;
  scrollbar-width: auto;
  scrollbar-color: var(--bord) transparent;
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--bord); border-radius: 999px;
  border: 3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--texte-doux); background-clip: content-box; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 15px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  padding-bottom: env(safe-area-inset-bottom);
}

/* ---------------------------------------------------- le bloc du haut, epingle d'un seul tenant
   TROIS `sticky` EMPILES SONT DEVENUS UN (L23.3). L'en-tete, les onglets et la rangee du ticker
   etaient cales les uns sous les autres par des hauteurs mesurees en JavaScript : trois occasions
   de se tromper, et une panne possible chaque fois qu'une mesure arrivait avant que la mise en
   page ne soit faite. « La partie avec le ticker et le champ de recherche ne s'affichent pas en
   permanence si je scrolle » (Jeremy, 2026-09-09). Un seul conteneur epingle supprime la classe
   entiere de defauts : il n'y a plus aucun decalage a calculer.

   LE FOND EST OPAQUE, sinon le contenu de la page defilerait dessous en transparence. */
.haut {
  position: sticky; top: 0; z-index: 5;
  background: var(--fond);
}

/* ------------------------------------------------------------------ en-tete */
.barre {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between;
  padding: 12px 16px;
  background: var(--fond-carte);
  border-bottom: 1px solid var(--bord);
}

.marque { display: flex; align-items: center; gap: 9px; font-weight: 650; letter-spacing: .2px; }

/* L'EN-TETE SE REPLIE (L21). Sur un ecran de telephone, la marque et les quatre tampons prenaient
   une centaine de pixels sur deux lignes, en permanence, au-dessus d'un graphique qu'on vient
   voir. Replie, il ne reste que la ligne qui sert : le nom, et le tampon qui dit si l'on est sur
   le poste ou en consultation.

   MEME MEMOIRE QUE LES BLOCS DU GRAPHIQUE (`momentum.blocs-ouverts`). Un second mecanisme aurait
   fini par contredire le premier. */
.entete { flex: 1 1 auto; min-width: 0; }

.entete > summary {
  /* PAS DE `display: flex` ICI — voir `.pli-titre` plus bas. La mise en page est portee par
     l'enfant, le `summary` garde l'affichage que le navigateur lui donne. */
  cursor: pointer; list-style: none;
  border-radius: var(--rayon); padding: 2px 4px; margin: -2px -4px;
}

.entete > summary > .pli-titre {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-height: 32px;
}
.entete > summary::-webkit-details-marker { display: none; }

/* La marque de pliage, dessinee a droite du sommaire : sans elle, rien ne dit que le bloc s'ouvre. */
.entete > summary > .pli-titre::after {
  content: ''; margin-left: auto;
  width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 6px solid var(--texte-doux);
  transition: transform .12s ease;
}
.entete[open] > summary > .pli-titre::after { transform: rotate(180deg); }
.entete > summary:focus-visible { outline: 2px solid var(--emeraude-texte); outline-offset: 2px; }

.entete-corps {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px; padding-top: 10px;
}

.fleche {
  width: 0; height: 0; display: inline-block;
  border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-bottom: 12px solid var(--emeraude);
}

.tampons { display: flex; flex-wrap: wrap; gap: 6px; }

.tampon {
  font: 600 12px/1 ui-monospace, "Cascadia Mono", Consolas, monospace;
  padding: 5px 8px; border-radius: 999px;
  background: var(--fond-creux); border: 1px solid var(--bord); color: var(--texte-doux);
}

.tampon.local { color: var(--emeraude-texte); border-color: var(--emeraude-bord); }
.tampon.distant { color: var(--ambre); border-color: var(--ambre-bord); }

/* ------------------------------------------------------------------ onglets */
.onglets {
  display: flex; gap: 4px; overflow-x: auto; padding: 8px 12px;
  border-bottom: 1px solid var(--bord); background: var(--fond);
  /* PLUS AUCUN DECALAGE : les onglets vivent dans `.haut`, qui est epingle pour eux. La valeur en
     dur de 53 px, puis la variable mesuree qui l'avait remplacee, ont disparu toutes les deux. */
  scrollbar-width: thin;
}

.onglets button {
  flex: 0 0 auto;
  background: transparent; color: var(--texte-doux);
  border: 1px solid transparent; border-radius: 999px;
  padding: 7px 13px; font: inherit; font-weight: 600; cursor: pointer;
  /* 44 px : cible tactile minimale, sinon l'onglet se rate au doigt sur telephone. */
  min-height: 40px;
}

.onglets button[aria-selected="true"] {
  color: var(--texte); background: var(--fond-carte); border-color: var(--bord);
}

.onglets button:focus-visible,
.gestes button:focus-visible { outline: 2px solid var(--emeraude-texte); outline-offset: 2px; }

/* ------------------------------------------------------------------ contenu */
main { max-width: var(--colonne); margin: 0 auto; padding: 16px 12px 8px; }

.attente, .note { color: var(--texte-doux); }
.note { font-size: 13px; }

h1 { font-size: 19px; margin: 0 0 4px; }
h2 { font-size: 15px; margin: 20px 0 8px; text-transform: uppercase; letter-spacing: .6px;
     color: var(--texte-doux); }

/* LE BANDEAU D'INFORMATION (L30.3). Il rend compte de ce qui est arrive sans qu'on le demande —
   des preferences reprises de l'autre appareil, ou remplacees. Il se distingue du bandeau d'erreur
   par la couleur ET par le fait qu'il s'efface : il raconte un evenement, pas un etat. */
.bandeau-info {
  margin: 0 0 10px; padding: 8px 12px;
  border: 1px solid var(--emeraude); border-radius: var(--rayon);
  background: var(--fond-carte); color: var(--texte); font-size: 13px;
}

.bandeau-erreur {
  border: 1px solid var(--rouge-bord); background: var(--rouge-fond); color: var(--rouge);
  padding: 10px 12px; border-radius: var(--rayon); margin: 0 0 14px;
}

/* Cartes d'etat : le chiffre d'abord, son libelle ensuite — on lit le montant avant de lire ce
   qu'il designe, ce qui est l'ordre dans lequel on consulte un tableau de bord. */
.cartes {
  display: grid; gap: 8px; margin-bottom: 14px;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
}

.carte {
  background: var(--fond-carte); border: 1px solid var(--bord); border-radius: var(--rayon);
  padding: 10px 12px;
}

.carte .valeur {
  font: 700 20px/1.15 ui-monospace, "Cascadia Mono", Consolas, monospace;
  display: block; margin-bottom: 3px;
}

.carte .libelle { font-size: 12px; color: var(--texte-doux); }

.positif { color: var(--emeraude-texte); }
.negatif { color: var(--rouge); }
.neutre  { color: var(--texte-doux); }

/* ------------------------------------------------------------------ tableaux */
.cadre-table {
  border: 1px solid var(--bord); border-radius: var(--rayon); overflow: hidden;
  background: var(--fond-carte);
}

/* Le defilement horizontal appartient au TABLEAU, jamais au corps de la page : sinon toute la mise
   en page glisse sous le doigt des qu'une colonne deborde. */
.defilement { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table { border-collapse: collapse; width: 100%; font-size: 13.5px; }

th, td {
  padding: 7px 10px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--bord);
}

th:first-child, td:first-child { text-align: left; position: sticky; left: 0;
                                 background: var(--fond-carte); }

thead th {
  position: sticky; top: 0; background: var(--fond-creux); color: var(--texte-doux);
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .5px; z-index: 1;
}

tbody tr:last-child td { border-bottom: 0; }
tbody tr:nth-child(even) td { background: var(--fond-raye); }
tbody tr:nth-child(even) td:first-child { background: var(--fond-raye); }

td.nombre { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; }

.vide { padding: 18px 12px; color: var(--texte-doux); }

.badge {
  display: inline-block; padding: 2px 7px; border-radius: 999px; font-size: 11.5px;
  font-weight: 600; border: 1px solid var(--bord); background: var(--fond-creux);
}
.badge.achetable { color: var(--emeraude-texte); border-color: var(--emeraude-bord); }
.badge.couper    { color: var(--rouge); border-color: var(--rouge-bord); }
.badge.courir    { color: var(--ambre); border-color: var(--ambre-bord); }

/* ------------------------------------------------------------------ fiches d'ordre */
/* Une fiche est faite pour etre RECOPIEE dans le courtier, au telephone : la ligne a saisir est en
   monospace et selectionnable, le bouton fait 44 px de haut. */
.fiches {
  display: grid; gap: 8px; margin-bottom: 6px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}

.fiche {
  background: var(--fond-carte); border: 1px solid var(--bord);
  border-left: 3px solid var(--texte-doux); border-radius: var(--rayon); padding: 10px 12px;
}
.fiche.achat { border-left-color: var(--emeraude); }
.fiche.vente { border-left-color: var(--rouge); }

.fiche-tete { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.fiche-sens { font-size: 11.5px; font-weight: 700; letter-spacing: .6px; color: var(--texte-doux); }
.fiche-symbole { font-weight: 700; font-size: 16px; }

.a-copier {
  font: 600 14px/1.3 ui-monospace, "Cascadia Mono", Consolas, monospace;
  margin: 0 0 8px; padding: 7px 9px; border-radius: 8px;
  background: var(--fond-creux); border: 1px solid var(--bord);
  user-select: all; overflow-wrap: anywhere;
}

.fiche .copier {
  width: 100%; min-height: 44px; cursor: pointer; font: inherit; font-weight: 600;
  background: transparent; color: var(--texte);
  border: 1px solid var(--bord); border-radius: 8px;
}
.fiche .copier:hover { border-color: var(--emeraude); }
.fiche .copier:focus-visible { outline: 2px solid var(--emeraude-texte); outline-offset: 2px; }

/* ------------------------------------------------------------------ graphique */

/* LE PLEIN ECRAN (L27). Mesure en 360 x 800, le vrai viewport d'un A33 : le trace n'occupait que
   308 px des 800 du premier ecran, 39 %, parce que 289 px de bandeau colle et 200 px de titre et
   d'outils passent devant lui. La place etait le sujet.

   `position: fixed` PLUTOT QUE L'API `requestFullscreen` SEULE : elle marche partout, y compris
   la ou l'API refuse un element non-video, et elle laisse poser nos propres commandes par-dessus.
   L'API n'est plus demandee du tout depuis le 2026-10-08 : sa notification de sortie, affichee par
   le navigateur, se posait sur les outils (chart/commandes.js). La barre systeme d'Android reste.

   `!important` sur la hauteur, et ce n'est pas de la paresse : le cadre porte une hauteur INLINE
   des que le lecteur en a pose une a la poignee, et une declaration de feuille ne bat pas un style
   inline. L'alternative — retirer puis remettre le style — laisserait un etat a restaurer, donc un
   etat a perdre. */
.cadre-graphique.plein-ecran {
  /* `!important` : la couche de dessin ecrit `position: relative` en inline sur ce meme
     cadre, et un style inline bat une declaration de feuille. Sans cela, le plein ecran
     n'aurait aucun effet des qu'un trace manuel a ete attache — c'est-a-dire toujours. */
  position: fixed !important; inset: 0; z-index: 50;
  width: 100%; height: 100% !important; max-height: none;
  /* SANS MARGE (G1.a). Le cadre garde sinon la sienne (10 px en haut) : avec `inset: 0` et une
     hauteur de 100 %, la contrainte est trop forte et c'est le bas qui cede — le cadre glissait de
     10 px et sa bande basse sortait de l'ecran. Mesure au banc le 2026-10-06 dans une vue de
     800 px : cadre de 10 a 810. Personne ne le voyait tant que rien d'atteignable n'y vivait ; la
     barre d'outils du telephone y vit. */
  margin: 0;
  border-radius: 0; border: 0;
  /* La poignee de redimensionnement n'a plus de sens quand le cadre EST l'ecran. */
  resize: none;
  /* TOUT LE GESTE AU GRAPHIQUE (L31). `pan-y` sur le cadre laisse le vertical au navigateur ; en
     plein ecran, il n'y a rien derriere a faire defiler, et ce vertical ne fait donc que priver le
     graphique de son deplacement. `none` le lui rend — et la bibliotheque l'accepte parce que
     `arbitrerLesGestes` passe `vertTouchDrag` a vrai des que cette classe est posee. Les deux
     moities sont necessaires : le CSS seul laisserait la bibliotheque refuser le geste, la
     bibliotheque seule laisserait le navigateur defiler par-dessus. */
  touch-action: none;
}
/* Les commandes du plein ecran : posees sur le cadre, au-dessus de l'echelle des prix — la seule
   bande ou l'on ne trace jamais. Un bouton pose sur la zone de trace serait sous le doigt au
   moment ou l'on trace, ce que la barre d'outils du dessin evite deja pour la meme raison. */
.commandes-cadre {
  /* AU-DESSUS DE LA TOILE DE DESSIN (60), DANS TOUS LES MODES (G1.a, contrat § 0.3). A 51, la
     toile — sensible aux clics des qu'un outil est choisi — recouvrait les deux rangees : en mode
     « Niveau », ni « ✕ Quitter », ni les plages, ni la bascule n'etaient atteignables. Constate au
     banc le 2026-10-06, aux trois largeurs, avant cette correction. */
  position: absolute; z-index: 70;
  /* `env(...)` AVEC SON REPLI, ET IL VAUT SOUVENT ZERO. Android ne publie un encart de decoupe
     qu'a une application qui le reclame, ce qu'une page web ne peut pas faire. Il sert la ou il
     existe (iOS, certains navigateurs) ; ce qui repare le cas de Jeremy est ailleurs — voir
     `.plages-cadre`. */
  top: calc(6px + env(safe-area-inset-top, 0px)); right: 8px;
  display: flex; gap: 4px; align-items: center;
  /* DANS LA ZONE DU TRACE, PAS SUR LE CADRE ENTIER (G1.a). Un element absolu d'une grille qui nomme
     sa zone s'ancre a cette zone : sur le poste, la rangee des plages commence a droite de la barre
     d'outils ; au telephone, elle monte avec la barre quand on la deplie. Sans barre (autres
     graphiques, barre pliee), la zone est le cadre entier et rien ne change. */
  grid-area: trace;
}
.commandes-cadre button {
  /* Six boutons en surimpression sur 360 px de large : chaque pixel compte, et ils ne doivent pas
     couvrir plus que la bande haute de l echelle des prix.

     `min-height: 32px` MALGRE CE QUI PRECEDE (L30.2). Mesures du 2026-09-11 en 360 x 800 : les
     boutons faisaient 19 px de haut, soit une cible qu'on rate au pouce — et c'est en plein ecran,
     donc sous le pouce, qu'on a le plus besoin d'atteindre la sortie. La rangee entiere fait
     222 px de large : la contrainte etait la hauteur, jamais la largeur. 32 px est la valeur deja
     retenue pour les cases a cocher de cet ecran. */
  padding: 3px 8px; font-size: 11px; line-height: 1; min-height: 32px;
  background: var(--fond-carte); color: var(--texte);
  border: 1px solid var(--graphique-grille); border-radius: 6px;
  opacity: 0.85; cursor: pointer;
}
.commandes-cadre button:hover, .commandes-cadre button:focus-visible { opacity: 1; }
/* LES PLAGES, EN BAS A GAUCHE (L34.1). « 3 mois tombe pile sur l'appareil photo » (Jeremy,
   2026-09-23). La rangee unique mesurait 246 px collee a droite d'une vue de 360 : elle traversait
   le centre de l'ecran, ou vit le poincon d'un A33. Aucun placement fin ne pouvait l'eviter — il
   fallait sortir de la bande haute.

   LA MEME CLASSE PORTE LES DEUX RANGEES : `.commandes-cadre` donne l'apparence des boutons et leur
   cible de 32 px, `.plages-cadre` ne change que l'ancrage. Deux jeux de regles auraient diverge au
   premier bouton retouche.

   EN BAS A GAUCHE et non a droite : la frise du temps porte a gauche les dates les plus anciennes,
   a droite la seance du jour. On couvre ce qu'on lit le moins. */
.plages-cadre {
  top: auto; right: auto;
  bottom: calc(6px + env(safe-area-inset-bottom, 0px)); left: 8px;
}
/* Le titre regarde, rappele en plein ecran : sans lui, on perd le seul repere qui dit CE QU'ON
   REGARDE, puisque la rangee du ticker reste derriere. */
/* ---------------------------------------------- L33 : la ligne de la bougie pointee
   EN SURIMPRESSION, PAS DANS LE FLUX. Une rangee de plus au-dessus du graphique reprendrait la
   hauteur que L32.1 vient de rendre a la frise du temps. Elle se pose donc SUR le trace, comme
   TradingView pose la sienne, et elle est TRANSPARENTE AUX GESTES : sans `pointer-events: none`,
   elle intercepterait le doigt sur le coin haut gauche du graphique — celui qu'on touche pour
   deplacer les bougies les plus anciennes. */
.entete-bougie {
  /* SOUS LA RANGEE DE BOUTONS, ET C'EST UNE CAPTURE QUI L'Y MET. Posee a 5 px, la ligne partageait
     le haut du cadre avec `1M 3M 6M Tout » ⛶` : en 360 px de large, les deux demandent 400 px et
     les trois dernieres valeurs passaient DERRIERE les boutons (rendu du 2026-09-12). Le coin haut
     gauche n'est libre que sur un ecran large, et ce n'est pas celui qu'on vise. */
  position: absolute; top: 44px; left: 8px; z-index: 40;
  /* Ancree a la zone du trace (G1.a) : sur le poste, la barre d'outils occupe le bord gauche. */
  grid-area: trace;
  /* Elle ne deborde jamais du cadre : au pire elle passe a la ligne. */
  max-width: calc(100% - 16px);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px;
  pointer-events: none;
  font-size: 11px; line-height: 1.2; font-variant-numeric: tabular-nums;
  color: var(--texte-doux);
  /* Un voile, pas un bloc : les bougies derriere doivent rester perceptibles. */
  background: color-mix(in srgb, var(--graphique-fond) 82%, transparent);
  padding: 2px 6px; border-radius: 5px;
}
.entete-bougie .valeur-bougie { display: inline-flex; gap: 3px; }
/* La lettre est un REPERE, pas une donnee : elle s'efface devant le chiffre qu'elle annonce. */
.entete-bougie b { font-weight: 600; opacity: .65; }
.entete-bougie .valeur-bougie span { color: var(--texte); }
.variation-bougie { font-weight: 600; }
.variation-bougie[data-sens="positif"] { color: var(--chandelier-hausse); }
.variation-bougie[data-sens="negatif"] { color: var(--chandelier-baisse); }
.variation-bougie[data-sens="neutre"] { color: var(--texte-doux); }

/* Le titre rappele du plein ecran vit sur la MEME rangee que les boutons, a gauche : la ligne
   passe donc sous les deux d'un seul coup, et aucune regle particuliere n'est necessaire. */

.titre-plein-ecran {
  position: absolute; top: 6px; left: 10px; z-index: 70; grid-area: trace;
  font-size: 13px; font-weight: 600; color: var(--texte);
  background: var(--fond-carte); padding: 4px 8px; border-radius: 6px; opacity: 0.85;
}

.cadre-graphique {
  /* PLUS DE PLAFOND EN PIXELS. A 480 px, tout le graphique tenait dans la moitie d'un ecran de
     bureau : agrandir le panneau des oscillateurs ne pouvait se faire qu'en ecrasant les
     chandeliers, ce qui ne ressemble pas a « agrandir ». Le geste existait, la place manquait. */
  height: min(70vh, 900px); min-height: 260px;
  /* DEUX ZONES, LA BARRE D'OUTILS ET LE TRACE (G1.a). « On ne peut pas dessiner en plein ecran »
     (Jeremy, 2026-10-06) : la barre vit donc DANS le cadre, et le graphique se range a cote d'elle
     au lieu d'etre recouvert. Sur le poste, la barre est une colonne a gauche ; au telephone, une
     rangee en bas (regle plus bas). Une colonne `auto` sans barre vaut zero : un cadre qui n'en
     porte pas — erreur de trace, autres bancs — reste un trace plein cadre. */
  display: grid;
  grid-template-areas: "barre trace";
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  /* La poignee native du navigateur, en bas a droite. Elle demande `overflow` different de
     `visible` — c'est deja le cas. Sur telephone elle n'existe pas : la hauteur y reste
     proportionnelle a l'ecran, et c'est le bon comportement. */
  resize: vertical;
  border: 1px solid var(--bord); border-radius: var(--rayon); overflow: hidden;
  background: var(--fond-carte); margin: 10px 0 12px;
  /* LE GESTE VERTICAL APPARTIENT A LA PAGE, L'HORIZONTAL AU GRAPHIQUE (L21).
     `touch-action: none` donnait TOUT au graphique — y compris le defilement vertical. Le cadre
     occupant 70 % de la hauteur, les sept dixiemes de l'ecran d'un telephone ne defilaient donc
     pas : « lorsque le graphique occupe tout l'ecran, j'ai du mal a scroller » (2026-09-09). Ce
     n'etait pas un ascenseur qui manquait, c'etait un geste confisque.

     `pan-y` rend au navigateur le defilement vertical, et laisse au graphique le glissement
     horizontal — celui du temps, le seul qui compte au doigt — ET LE PINCEMENT.

     IL Y AVAIT `pinch-zoom` ICI JUSQU'AU 2026-09-10, ET C'ETAIT UNE ERREUR (L28.1). Le commentaire
     qui l'accompagnait pretendait que cette valeur « laisse au graphique le pincement ». C'est
     l'inverse : nommer un geste dans `touch-action`, c'est le DONNER au navigateur. Source — MDN,
     `touch-action`, consultee le 2026-09-10 : « pinch-zoom : Enable multi-finger panning and
     zooming of THE PAGE », et « By default, panning and pinching gestures are handled EXCLUSIVELY
     BY THE BROWSER ». Le pincement zoomait donc la page et le graphique ne le voyait jamais, alors
     que la bibliotheque sait le traiter (`handleScale.pinch` est actif par defaut) : ni zoomer ni
     dezoomer au doigt n'etait possible.

     Le prix a payer : le doigt pose sur le graphique ne zoome plus la PAGE. C'est le bon echange —
     sur un graphique, le pincement doit zoomer le graphique. */
  touch-action: pan-y;
  /* Repere des commandes posees dessus (L27). La couche de dessin pose deja un `position:
     relative` INLINE ; l'ecrire ici rend le cadre sur de lui meme, sans dependre d'elle. */
  position: relative;
}

/* L'ECHELLE DES PRIX REPREND TOUS LES GESTES (L23.2) — correction d'un defaut introduit la veille
   par la regle ci-dessus.

   `touch-action` d'un ancetre RESTREINT ses descendants : la valeur effective est l'INTERSECTION de
   l'element et de ses ancetres. `pan-y` sur le cadre a donc emporte le glissement vertical PARTOUT
   dedans, y compris sur l'echelle des prix — dont c'est exactement le geste : on y tire vers le
   haut ou le bas pour etaler ou resserrer l'echelle. « Je n'arrive pas a ajuster le graphique
   lorsque je fais glisser mon doigt sur les prix » (Jeremy, 2026-09-09).

   `none` etant PLUS restrictif que `pan-y`, l'intersection vaut `none` : la cellule reprend tout,
   pendant que le corps du graphique continue de laisser passer le defilement de la page.

   POURQUOI CE SELECTEUR. La bibliotheque dispose le graphique en tableau : chaque rangee porte
   [echelle gauche][panneau][echelle droite]. Mesure du 2026-09-09 en 430 px : le panneau fait
   328 px, l'echelle des prix 60 px, et c'est la DERNIERE cellule de sa rangee. Les deux rangees
   separatrices d'un pixel tombent aussi dans le selecteur — sans consequence, on ne pose pas le
   doigt sur un trait d'un pixel.

   L'ECHELLE DES TEMPS, en bas, n'a pas besoin de la meme chose : on l'etale HORIZONTALEMENT, et
   `pan-y` laisse deja passer l'horizontal au graphique. */
.cadre-graphique .tv-lightweight-charts tr > td:last-child {
  touch-action: none;
}

/* LA RANGEE DU TICKER (L21, refaite en L23.3). Elle n'est plus epinglee POUR ELLE-MEME : elle
   vit dans `#barre-ecran`, a l'interieur du bloc `.haut` qui est epingle d'un seul tenant. Elle
   n'a donc plus ni `position`, ni `top`, ni `z-index` a tenir a jour. */
.barre-graphique {
  padding: 8px 12px; margin: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px;
  border-bottom: 1px solid var(--bord);
  max-width: var(--colonne); margin-inline: auto;
}

.choix-ticker, .champ-ticker {
  font: inherit; font-weight: 700; min-height: 44px; padding: 8px 12px;
  background: var(--fond-carte); color: var(--texte);
  border: 1px solid var(--bord); border-radius: var(--rayon);
}
/* 44 px de haut, comme le selecteur : c'est la cible tactile minimale, et cette barre se manipule
   au doigt sur le telephone comme a la souris sur le poste. */
/* LA LARGEUR TIENT L'EXEMPLE DU PLACEHOLDER. A 9.5em, « autre titre (ex. KO)... » s'affichait
   « autre titre (ex. K » : la phrase s'arretait au milieu du mot qui devait l'expliquer. */
.champ-ticker { font-weight: 600; min-width: 8em; text-transform: uppercase; }
/* L'etiquette et le champ font un seul objet : le clic sur le texte donne le focus au champ. */
.boite-ticker { display: flex; align-items: center; gap: 8px; flex: 1 1 190px; min-width: 0; }
.boite-ticker .champ-ticker { min-width: 0; }
.boite-ticker .note { white-space: nowrap; }
.champ-ticker::placeholder { font-weight: 400; text-transform: none; color: var(--texte-doux); }
.choix-ticker:focus-visible, .champ-ticker:focus-visible {
  outline: 2px solid var(--emeraude-texte); outline-offset: 2px;
}

.absences ul { margin: 4px 0 0; padding-left: 18px; }
.absences li { margin: 2px 0; }

/* ------------------------------------------------------------------ gestes */
.gestes { max-width: var(--colonne); margin: 8px auto 0; padding: 0 12px 16px; }
.rangee { display: flex; flex-wrap: wrap; gap: 8px; }

.gestes button {
  background: var(--fond-carte); color: var(--texte);
  border: 1px solid var(--bord); border-radius: var(--rayon);
  padding: 10px 14px; font: inherit; font-weight: 600; cursor: pointer; min-height: 44px;
}

.gestes button:hover:not(:disabled) { border-color: var(--emeraude); }
.gestes button:disabled { opacity: .5; cursor: progress; }

/* ------------------------------------------------------------------ dialogue */
dialog {
  border: 1px solid var(--bord); border-radius: var(--rayon);
  background: var(--fond-carte); color: var(--texte); max-width: 380px; width: calc(100% - 32px);
}
dialog::backdrop { background: var(--voile); }
dialog h2 { margin-top: 0; }
dialog input {
  width: 100%; padding: 10px; margin: 10px 0 6px; font: inherit; min-height: 44px;
  background: var(--fond-creux); color: var(--texte);
  border: 1px solid var(--bord); border-radius: 8px;
}
dialog menu { display: flex; justify-content: flex-end; padding: 0; margin: 10px 0 0; }
dialog button {
  background: var(--emeraude); color: var(--sur-emeraude); border: 0; border-radius: 8px;
  padding: 10px 16px; font: inherit; font-weight: 700; cursor: pointer; min-height: 44px;
}
.erreur { color: var(--rouge); font-size: 13px; margin: 4px 0 0; }

/* ------------------------------------------------------------------ pied */
.pied {
  max-width: var(--colonne); margin: 0 auto; padding: 18px 12px 28px;
  color: var(--texte-doux); font-size: 12px; border-top: 1px solid var(--bord);
}
.pied p { margin: 4px 0; }


@media (max-width: 560px) {

  /* ------------------------------------------------- L32.1 : rendre la place au graphique
   Budget mesure le 2026-09-11 en 360 x 800, avant correction : 523 px consommes avant le
   graphique, soit 65 % de la vue — 57 px d'en-tete, 67 px d'onglets, 196 px pour la rangee du
   ticker, 28 px de titre, 75 px de resume, 52 px d'outils. Le cadre, haut de 496 px, finissait
   donc a 1019 px dans une vue de 800 : la frise du temps tombait 221 px sous le pli.

   On ne rogne QUE sur un ecran etroit. Sur un poste, ces 523 px ne genent personne et le resume
   sert a qui decouvre un ecran. */
  /* Le titre est deja dans l'onglet actif, juste au-dessus, en plus gros. */
  main h1 { font-size: 1.05rem; margin: 6px 0 2px; }

  /* LE RESUME SORT DE L'ECRAN, PAS DU DOCUMENT. Il decrit ce que l'ecran montre — a qui le
     regarde, l'ecran le dit mieux que lui. Mais il reste lu par un lecteur d'ecran : le retirer
     vraiment priverait de la seule description disponible qui ne soit pas graphique. */
  main > p.note {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }

  /* La rangee du ticker tenait sur quatre lignes. Les champs rendent leur largeur fixe et les
     boutons se serrent : la cible tactile de 44 px est conservee, c'est l'air qui part. */
  .barre-graphique { padding: 6px 10px; gap: 6px; }
  .choix-ticker, .champ-ticker { min-height: 40px; padding: 6px 10px; }
  .boite-ticker .note { display: none; }
  .barre-graphique .outil { min-height: 40px; padding: 6px 10px; }

  main { padding-top: 12px; }
  .carte .valeur { font-size: 18px; }
  /* 62vh AU LIEU DE 70 : il reste de la page au-dessus et au-dessous du cadre, donc un endroit ou
     le doigt fait defiler a coup sur. Le geste passe desormais aussi par-dessus le graphique
     (`touch-action` ci-dessus) ; cette marge est la ceinture en plus des bretelles. */
  .cadre-graphique { height: min(62vh, 900px); }
}

/* ----------------------------------------------------------------- ecran Simulateur
   Contrat : livrable L6.3. Le formulaire passe d'une grille a une colonne sous 640 px : sur un
   telephone, deux champs cote a cote reduisent chacun a une largeur ou le clavier numerique masque
   ce qu'on saisit. Cibles tactiles a 44 px, comme le reste du paquet. */
.simulateur {
  display: grid; gap: 12px; margin: 16px 0;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.simulateur .champ { display: flex; flex-direction: column; gap: 4px; }

.simulateur .champ .libelle { font-size: 12px; color: var(--texte-doux); }

.simulateur .champ .aide { font-size: 11px; color: var(--texte-doux); }

.simulateur input, .simulateur select {
  min-height: 44px; padding: 8px 10px; border-radius: var(--rayon);
  background: var(--fond-creux); border: 1px solid var(--bord); color: var(--texte);
  font: 600 15px/1 ui-monospace, "Cascadia Mono", Consolas, monospace;
}

.simulateur input:focus-visible, .simulateur select:focus-visible {
  outline: 2px solid var(--emeraude-texte); outline-offset: 1px;
}

.courbe-payoff {
  width: 100%; height: auto; margin: 8px 0;
  background: var(--fond-carte); border: 1px solid var(--bord); border-radius: var(--rayon);
}

/* Le zero est la seule ligne que l'oeil cherche sur un profil de gain : il est plus visible que
   les reperes verticaux, qui ne sont la que pour situer. */
.axe-zero { stroke: var(--texte-doux); stroke-width: 1; }
.repere-strike { stroke: var(--bord); stroke-width: 1; stroke-dasharray: 4 4; }
.repere-seuil { stroke: var(--ambre); stroke-width: 1; stroke-dasharray: 2 4; }
.etiquette-repere { fill: var(--texte-doux); font-size: 11px; }
.graduation { fill: var(--texte-doux); font-size: 11px; }

/* Deux courbes, deux traitements : la ligne brisee de l'echeance est le fait, la courbe d'avant
   echeance est l'etat present. La seconde est plus claire et plus fine — elle bougera demain. */
.courbe-echeance { stroke: var(--emeraude-texte); stroke-width: 2.5; }
.courbe-avant { stroke: var(--texte-doux); stroke-width: 1.5; stroke-dasharray: 5 3; }

.carte .note { font-size: 11px; color: var(--texte-doux); margin-top: 2px; }

/* Une perte de 100 % ne se lit pas comme une perte de 98 % : elle est definitive. */
.perte-totale { color: var(--rouge); font-weight: 700; }

.avertissement {
  margin-top: 20px; padding: 10px 12px; border-radius: var(--rayon);
  border: 1px solid var(--bord); background: var(--fond-creux);
  color: var(--texte-doux); font-size: 13px;
}

/* ------------------------------------------------------- traces manuels du graphique (L7.1)
   La toile se pose SUR le graphique. En mode « naviguer » elle est transparente aux evenements :
   sans cela, poser une couche au-dessus figerait le pincement et le glissement de la bibliotheque,
   et le graphique cesserait de se manipuler au doigt sans qu'on comprenne pourquoi. */
/* AU-DESSUS DES CANEVAS DE LA BIBLIOTHEQUE, et c'est ce qui manquait. Lightweight Charts empile
   ses propres couches avec des `z-index` explicites — 1 et 2 pour les canevas de chaque panneau,
   49 et 50 pour les separateurs. Sans z-index a nous, la toile de dessin restait en dessous : les
   clics allaient au canevas de la bibliotheque et les traces poses etaient peints SOUS le
   graphique. Rien ne se dessinait, et rien ne pouvait le dire.

   Constate le 2026-09-08 en scriptant la vraie page : `elementFromPoint` au milieu du graphique
   rendait un CANVAS sans classe, celui de la bibliotheque. Le controle manuel des outils de dessin
   (contrat J7) n'avait jamais ete fait — il aurait trouve ce defaut le premier jour.

   En mode « Naviguer », la toile est transparente aux evenements : les separateurs de panneaux
   restent saisissables. Dans un mode de dessin, elle les couvre — c'est le prix a payer, et il se
   paie en revenant a « Naviguer ». */
.toile-dessins {
  /* SON RECTANGLE EST CELUI DU GRAPHIQUE, pose par la couche de dessin (`dessins.js`) : depuis G1.a
     le cadre porte aussi la barre d'outils, et une toile sur tout le cadre decalerait chaque geste
     de la largeur de la barre. */
  position: absolute; top: 0; left: 0; z-index: 60; pointer-events: none; touch-action: auto;
}

/* ------------------------------------------------------- la selection directe (G2.3)
   LES POIGNEES DU TRACE SELECTIONNE. Une cible de 28 px pour le doigt, dont seul le point central se
   voit. AU-DESSUS DE LA TOILE (60), sous les rangees du cadre (70).

   `touch-action: none` EST CE QUI REND LA POIGNEE AU DOIGT. Le cadre porte `pan-y` (L21) : un doigt
   pose sur le graphique fait defiler la page des qu'il glisse verticalement. La valeur effective est
   l'INTERSECTION de l'element et de ses ancetres ; `none` ici donne `none`, et la poignee glissee vers
   le haut deplace son point au lieu de faire defiler la page. */
.poignee-trace {
  position: absolute; z-index: 65; width: 28px; height: 28px; border-radius: 50%;
  touch-action: none; cursor: grab; background: transparent;
}
.poignee-trace::after {
  content: ""; position: absolute; left: 8px; top: 8px; width: 12px; height: 12px;
  box-sizing: border-box; border-radius: 50%;
  background: var(--fond-carte); border: 2px solid var(--texte);
}
/* LA BANDE D'ACTIONS DU TRACE SELECTIONNE : Supprimer, Prolonger. Dans le cadre, plein ecran compris ;
   sa place (au-dessus du trace, sinon au-dessous, sans couvrir une poignee) est calculee par la couche
   de dessin. */
.bande-actions {
  position: absolute; z-index: 68; display: flex; gap: 4px; padding: 4px;
  background: var(--fond-carte); border: 1px solid var(--graphique-grille); border-radius: 8px;
}
.bande-actions .outil {
  /* La cible du cadre, 32 px (L30.2), et un mot sur chaque bouton. */
  min-height: 32px; height: 32px; padding: 3px 8px; font-size: 11px; line-height: 1;
  border-radius: 6px; white-space: nowrap;
}
/* `hidden` doit gagner sur le `display` ci-dessus : la regle de l'agent utilisateur est plus faible. */
.poignee-trace[hidden], .bande-actions[hidden], .bande-actions .outil[hidden] { display: none; }

/* LE PANNEAU DE STYLE (G2.9) : dans le cadre, plein ecran compris, ouvert par « Style » de la bande. Au-dessus
   de la bande (68), sous la barre (70) et ses listes (71). Une cible de 32 px par choix. */
.panneau-style {
  position: absolute; z-index: 69; box-sizing: border-box; width: 320px; max-width: calc(100% - 16px);
  display: flex; flex-direction: column; gap: 4px; padding: 6px;
  background: var(--fond-carte); border: 1px solid var(--graphique-grille); border-radius: 8px;
}
.panneau-style[hidden] { display: none; }
.panneau-style .rangee-style { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.panneau-style .mot-style { flex: 0 0 62px; font-size: 11px; color: var(--texte-doux); }
.panneau-style .outil {
  min-width: 32px; min-height: 32px; height: 32px; padding: 3px 8px; font-size: 11px; line-height: 1;
  border-radius: 6px; white-space: nowrap;
}
.panneau-style .jeton { width: 32px; padding: 0; background: var(--jeton); border: 2px solid var(--graphique-grille); }
/* Le fond est REDIT ici : sinon `.outil[aria-pressed="true"]`, plus bas, peint le jeton choisi en emeraude
   et l'on ne voit plus quelle couleur est prise (audit G2.9). */
.panneau-style .jeton[aria-pressed="true"] { background: var(--jeton); border-color: var(--texte); }

/* LE CHAMP DE SAISIE DU TEXTE (G2.8) : dans le cadre, plein ecran compris, en haut de la zone — le clavier du
   telephone occupe le bas. Au-dessus de la barre (70), des listes (71) et de la bande d'actions (68). 16 px :
   en dessous, certains telephones zooment la page a la prise de focus. */
.saisie-texte {
  position: absolute; z-index: 72; display: flex; gap: 4px; padding: 4px; box-sizing: border-box;
  background: var(--fond-carte); border: 1px solid var(--graphique-grille); border-radius: 8px;
}
.saisie-texte[hidden] { display: none; }
.saisie-texte input { flex: 1 1 auto; min-width: 0; height: 32px; box-sizing: border-box; font-size: 16px; }
.saisie-texte .outil {
  min-height: 32px; height: 32px; padding: 3px 8px; font-size: 11px; line-height: 1;
  border-radius: 6px; white-space: nowrap;
}

/* ------------------------------------------------------- la barre d'outils DANS le cadre (G1.a)
   La zone du graphique, puis la barre. La zone est une case de la grille : sa boite change quand
   la barre change, et c'est ce que la bibliotheque sait suivre (`graphique.js`). */
.zone-graphique { grid-area: trace; min-width: 0; min-height: 0; }

.barre-outils {
  grid-area: barre;
  /* AU-DESSUS DE LA TOILE dans tous les modes, comme les rangees du cadre. */
  position: relative; z-index: 70;
  /* SUR LE POSTE : une colonne le long du bord gauche, qui PASSE SUR UNE SECONDE COLONNE quand la
     hauteur ne suffit pas (contrat, § 0.10) — jamais de defilement, jamais de bouton rogne. Un cadre
     reduit a son minimum garde 258 px interieurs ; huit boutons de 32 px et leurs intervalles en
     demandent 284. */
  display: flex; flex-direction: column; flex-wrap: wrap; align-content: flex-start; gap: 4px;
  padding: 4px;
  background: var(--fond-carte); border-right: 1px solid var(--graphique-grille);
}
.barre-outils .outil {
  /* La cible du cadre, 32 px (L30.2), et un MOT sur chaque bouton : une infobulle au survol
     n'existe pas au doigt. */
  min-height: 32px; height: 32px; padding: 3px 8px; font-size: 11px; line-height: 1;
  border-radius: 6px; white-space: nowrap;
}

/* LA LISTE D'UN GROUPE (G2.5) : dans le CADRE, plein ecran compris, posee contre la barre par
   `barre_outils.js` (a droite d'elle sur le poste, au-dessus d'elle au telephone) et ramenee dans le
   cadre. Chaque entree porte un mot, sur 32 px au moins (L30.2). Au-dessus de la barre (70) et de la
   bande d'actions (68). */
.liste-outils {
  position: absolute; z-index: 71; display: flex; flex-direction: column; gap: 4px; padding: 4px;
  background: var(--fond-carte); border: 1px solid var(--graphique-grille); border-radius: 8px;
}
.liste-outils[hidden] { display: none; }
.liste-outils .outil {
  min-height: 32px; height: 32px; padding: 3px 10px; font-size: 11px; line-height: 1;
  border-radius: 6px; white-space: nowrap; text-align: left;
}

/* La bascule n'existe que sur ecran etroit : sur le poste, la barre est toujours depliee. */
.bascule-barre { display: none; }

@media (max-width: 560px) {
  /* AU TELEPHONE : une rangee le long du bord bas, au-dessus de l'encart de securite, PLIEE PAR
     DEFAUT — regarder est le geste ordinaire, dessiner l'exception (L21). Pliee, elle n'occupe aucun
     pixel ; depliee, ses boutons passent sur deux rangees plutot que de defiler. */
  .cadre-graphique {
    grid-template-areas: "trace" "barre";
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
  }
  .barre-outils {
    flex-direction: row;
    padding: 4px 4px calc(4px + env(safe-area-inset-bottom, 0px));
    border-right: 0; border-top: 1px solid var(--graphique-grille);
  }
  .cadre-graphique:not(.barre-depliee) > .barre-outils { display: none; }
  .commandes-cadre .bascule-barre { display: block; }
}

.outils-dessin { margin: 8px 0; display: flex; flex-direction: column; gap: 6px; }

.outil {
  min-height: 44px; padding: 8px 12px; border-radius: var(--rayon);
  background: var(--fond-carte); border: 1px solid var(--bord); color: var(--texte);
  font: 600 13px/1 system-ui, -apple-system, "Segoe UI", sans-serif; cursor: pointer;
}

/* L'outil actif se voit au fond ET au contour : la couleur seule laisserait un daltonien sans
   repere sur la barre la plus utilisee de l'ecran. */
.outil[aria-pressed="true"] {
  background: var(--emeraude); border-color: var(--emeraude-texte);
  color: var(--sur-emeraude);
}

.outil:disabled { opacity: 0.45; cursor: default; }

.outils-dessin select {
  min-height: 44px; padding: 8px 10px; border-radius: var(--rayon);
  background: var(--fond-creux); border: 1px solid var(--bord); color: var(--texte);
}

/* ------------------------------------------------------- selecteur de theme (clair/sombre/systeme)
   Trois boutons plutot qu'une liste deroulante : sur un telephone, l'etat courant se lit d'un coup
   d'oeil au lieu de se deplier. */
.theme { display: flex; gap: 4px; }

.theme .outil {
  font-size: 12px; padding: 5px 9px;
}

@media (max-width: 480px) {
  /* Sur un ecran etroit, l'en-tete porte deja quatre tampons : le selecteur passe a la ligne
     entiere plutot que de compresser les libelles jusqu'a l'illisible. */
  .theme { width: 100%; justify-content: flex-end; }
}

/* ------------------------------------------------------- cases d'affichage des traces (L8.4)
   Sous le graphique, pas au-dessus : treize cases en haut d'un ecran de telephone repousseraient
   le trace hors de vue, et c'est le trace qu'on vient voir. */
.barre-cases { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0 4px; }

/* LE BLOC DES OUTILS N'EST PAS UNE CASE PARMI D'AUTRES (L23.4). Il reutilise le dessin de `.cases`
   mais vit dans `.outils-dessin`, qui est une colonne — et non dans `.barre-cases`, qui est une
   rangee. Or `flex: 1 1 260px` fixe une base sur l'AXE PRINCIPAL : une largeur en rangee, une
   HAUTEUR en colonne. Replie, le bloc gardait donc 260 px pour un titre de 32 : une boite blanche
   vide de 228 px. « Quand je collapse dessiner sur le graphique, les boutons masques mais le fond
   du cadre reste en blanc en grande dimension » (Jeremy, 2026-09-09), mesure au navigateur.

   `auto` : il prend la hauteur de ce qu'il contient, et rien de plus.

   LE SELECTEUR PORTE LES DEUX CLASSES, et ce n'est pas du zele : `.outils-pli` seul a la meme
   specificite que `.cases`, donc c'est l'ordre du fichier qui aurait tranche — et il tranchait en
   faveur de `.cases`. Mesure du 2026-09-09 apres la premiere tentative : `flex` valait encore
   `1 1 260px`. `.cases.outils-pli` gagne quel que soit l'ordre, et dit ce qu'il est : une
   exception a `.cases`, pas une regle a cote. */
.cases.outils-pli { flex: 0 0 auto; }

.cases {
  flex: 1 1 260px; min-width: 0;
  border: 1px solid var(--bord); border-radius: var(--rayon);
  background: var(--fond-carte); padding: 8px 12px 10px; margin: 0;
}

/* Le titre d'un bloc repliable. Meme dessin que la legende qu'il remplace, plus la marque de
   pliage du navigateur : ce qui se replie doit se voir repliable sans qu'on l'essaie. */
.cases > summary {
  font: 600 11px/1 system-ui, -apple-system, "Segoe UI", sans-serif;
  text-transform: uppercase; letter-spacing: .6px; color: var(--texte-doux);
  cursor: pointer; list-style-position: inside;
}

/* LA MISE EN PAGE DU TITRE EST PORTEE PAR UN ENFANT, jamais par le `summary` lui-meme (L23.3).
   WebKit traite mal un `<summary>` en `display: flex` : marqueur de pliage perdu, largeurs des
   enfants mal calculees, et le pliage cesse d'etre fiable. Un `<span>` interieur rend exactement
   la meme chose sans toucher a l'element que le navigateur doit savoir plier.

   `min-height` a 32 px : cible tactile. `display: inline-flex` et non `flex`, pour que le
   marqueur de pliage du navigateur reste sur la meme ligne que le titre. */
.cases > summary > .pli-titre,
.reglages-couleurs > summary > .pli-titre {
  display: inline-flex; align-items: center; min-height: 32px;
}

.cases > summary:focus-visible,
.reglages-couleurs > summary:focus-visible {
  outline: 2px solid var(--emeraude); outline-offset: 2px;
}

/* Le panneau des couleurs prend sa propre ligne : pose a cote des cases, ses vingt-deux lignes
   auraient ecrase la colonne des traces sur un ecran etroit. Replie par defaut — c'est un reglage
   qu'on fait une fois, pas une commande qu'on cherche tous les jours. */
.reglages-couleurs {
  flex: 1 1 100%;
  border: 1px solid var(--bord); border-radius: var(--rayon);
  background: var(--fond-carte); padding: 8px 12px 10px;
}

.reglages-couleurs summary {
  font: 600 11px/1 system-ui, -apple-system, "Segoe UI", sans-serif;
  text-transform: uppercase; letter-spacing: .6px; color: var(--texte-doux);
  cursor: pointer; list-style-position: inside;
}

/* `min(100%, 420px)` ET NON `420px` : une colonne plus large que son conteneur deborde par la
   droite, ce que la grille ne rattrape pas. A 360 px — le viewport reel d'un A33 — la colonne vaut
   donc 100 %, et 420 px des que la place existe. 420, parce que la ligne porte desormais un champ
   de valeur en plus du nuancier. */
.grille-couleurs {
  display: grid; gap: 6px 16px; margin: 8px 0 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 420px), 1fr));
}

/* `flex-wrap` PLUTOT QU'UN POINT DE RUPTURE : la ligne porte un selecteur, une valeur ecrite,
   parfois un style et une epaisseur, puis le nom du jeton. En 360 px — le viewport reel d'un A33 —
   tout cela ne tient pas sur un rang. Laisser le nom passer a la ligne quand la place manque
   dispense d'une media query qui aurait fige une largeur devinee. */
.ligne-couleur {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  min-height: 32px; font-size: 13px; cursor: pointer;
  /* UN TRAIT SOUS CHAQUE LIGNE, parce que le nom passe au rang suivant quand la place manque :
     sans separateur, « Moyenne courte » se lit aussi bien comme le titre du bloc d'en dessous que
     comme le nom du sien. Le trait tranche, et ne coute rien la ou tout tient sur un rang. */
  padding-bottom: 5px; border-bottom: 1px solid var(--fond-creux);
}

/* La valeur ecrite a la main (L29.1). Chasse fixe : sept caracteres qui ne bougent pas d'un champ
   a l'autre se comparent d'un coup d'oeil, ce qui est tout l'interet d'afficher la valeur. */
.ligne-couleur .champ-hexa {
  font: 12px/1 ui-monospace, "Cascadia Mono", Consolas, monospace;
  width: 78px; padding: 4px 6px;
  background: var(--fond-carte); color: var(--texte);
  border: 1px solid var(--bord); border-radius: 4px;
}
/* Une saisie refusee se voit, et ne pose rien. Le rouge seul ne suffirait pas a qui le distingue
   mal : le champ garde aussi son `aria-invalid`, que le lecteur d'ecran annonce. */
.ligne-couleur .champ-hexa.invalide {
  border-color: var(--rouge);
  outline: 1px solid var(--rouge);
}

.actions-couleurs { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* Inerte tant qu'il n'y a rien a valider : un bouton toujours actif ne dirait plus rien de l'etat
   du panneau. */
.actions-couleurs .appliquer-couleurs:disabled {
  opacity: 0.45; cursor: default;
}

/* 44 px de large : c'est la cible tactile minimale, et un selecteur de couleur trop petit se rate
   au doigt comme a la souris. */
.ligne-couleur input[type="color"] {
  width: 44px; height: 26px; padding: 0; cursor: pointer;
  border: 1px solid var(--bord); border-radius: 4px; background: none;
}

.ligne-couleur input[type="range"] { width: 44px; cursor: pointer; }

.case {
  display: flex; align-items: center; gap: 6px;
  min-height: 32px;                 /* la case elle-meme fait 24 px : c'est la LIGNE qu'on vise */
  font-size: 13px; cursor: pointer;
}

.case input { width: 20px; height: 20px; accent-color: var(--emeraude); flex: none; }

/* Un trace indisponible garde sa case et porte sa raison. Une case disparue se lirait comme un
   trace qu'on a choisi de ne pas offrir. */
.case.indisponible { color: var(--texte-doux); cursor: not-allowed; }
.case .raison { font-size: 11px; font-style: italic; }

.cartes-indicateurs { margin-top: 8px; }
.cartes-indicateurs .valeur { font-variant-numeric: tabular-nums; }

/* Tri et filtre des tableaux (parité PyQt6, retrouvée le 2026-09-07). L'en-tête devient un bouton :
   il doit se voir cliquable sans devenir un ornement, d'où la flèche qui n'apparaît qu'au tri
   actif. Le troisième état d'un clic rend l'ordre métier, il n'est pas un « sans tri » neutre. */
.barre-table { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; flex-wrap: wrap; }

.filtre-table {
  flex: 0 1 240px; min-width: 140px;
  padding: 6px 10px; border-radius: var(--rayon);
  border: 1px solid var(--bord); background: var(--fond-creux); color: var(--texte);
  font: inherit; font-size: .9em;
}

.filtre-table:focus-visible { outline: 2px solid var(--emeraude); outline-offset: 1px; }

.compte-lignes { white-space: nowrap; }

th button.tri {
  all: unset; cursor: pointer; display: inline-flex; gap: 4px; align-items: baseline;
  width: 100%; font: inherit; color: inherit;
}

th button.tri:focus-visible { outline: 2px solid var(--emeraude); outline-offset: 2px; }

th[data-tri="asc"] button.tri::after { content: "\2191"; color: var(--emeraude); }
th[data-tri="desc"] button.tri::after { content: "\2193"; color: var(--emeraude); }

/* Origine du titre affiche, et aide des outils de dessin (2026-09-07). Tout etait sur le meme
   plan : rien ne distinguait un titre possede d'un titre qu'un scanner venait de detecter. */
.badge.origine {
  background: var(--fond-creux); color: var(--texte-doux);
  border: 1px solid var(--bord); white-space: nowrap;
  /* `.rangee` est un conteneur flex sans `align-items` : par defaut ses enfants s'ETIRENT. La
     pastille prenait donc les 44 px du selecteur voisin, texte colle en haut avec ses 2 px de
     marge. Ce n'etait pas un texte mal centre dans sa pastille, c'etait une pastille de la
     mauvaise hauteur. */
  align-self: center;
}

.aide-outil { margin: 6px 0; }

.aide-outil summary {
  cursor: pointer; color: var(--texte-doux); font-size: .9em;
  padding: 2px 0; list-style-position: inside;
}

.aide-outil summary:focus-visible { outline: 2px solid var(--emeraude); outline-offset: 2px; }

.aide-outil p { margin: 4px 0 0; }

/* Le cours d'options, sous le simulateur (2026-09-07). Replie par defaut sauf le premier : six
   documents deplies feraient de l'outil de calcul une page de lecture. */
.lecons { margin-top: 28px; border-top: 1px solid var(--bord); padding-top: 16px; }

.lecon {
  border: 1px solid var(--bord); border-radius: var(--rayon);
  background: var(--fond-carte); margin: 8px 0; padding: 0 14px;
}

.lecon > summary {
  cursor: pointer; padding: 10px 0; font-weight: 600;
  list-style-position: inside;
}

.lecon > summary:focus-visible { outline: 2px solid var(--emeraude); outline-offset: 2px; }

.lecon-corps { padding-bottom: 12px; max-width: 68ch; }

.lecon-corps > :first-child { margin-top: 0; }

.lecon-titre { margin: 18px 0 6px; font-size: 1em; color: var(--emeraude-texte); }

.lecon-corps blockquote {
  margin: 12px 0; padding: 8px 14px;
  border-left: 3px solid var(--emeraude-bord); background: var(--fond-creux);
}

.lecon-corps code {
  background: var(--fond-creux); border-radius: 4px; padding: 1px 5px; font-size: .92em;
}

.lecon-corps ul { padding-left: 20px; }

.lecon-corps li { margin: 4px 0; }

/* Changer la poche d'un titre, depuis le graphique (2026-09-07). Le geste vit dans la barre du
   titre parce que c'est la qu'on se dit « celle-ci, je la garde a la main ». */
.poche-geste { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.poche-geste .note { font-size: .85em; }

/* « Pourquoi ce titre est ici » (2026-09-07). Le bloc est LARGE MAIS BORNE a 72 caracteres : une
   ligne de prose qui traverse un ecran de PC ne se lit pas, elle se survole. */
.justification {
  margin-top: 20px; padding: 14px 16px; max-width: 72ch;
  border: 1px solid var(--bord); border-left: 3px solid var(--emeraude);
  border-radius: var(--rayon); background: var(--fond-carte);
}

.justification h3 { margin: 0 0 10px; font-size: 1em; }

/* LE MOTIF DU JOUR (L35.1), sous le graphique. Le filet a la couleur des points du calque : on
   relie l'encadre a ce qu'on vient de voir sans avoir a le chercher. */
.motif-du-jour {
  margin-top: 12px; padding: 12px 14px; max-width: 72ch;
  border: 1px solid var(--bord); border-left: 3px solid var(--graphique-motif);
  border-radius: var(--rayon); background: var(--fond-carte);
}
.motif-du-jour p { margin: 0 0 8px; }
.motif-du-jour .motif-tete strong { color: var(--graphique-motif); }

.justification p { margin: 8px 0; line-height: 1.5; }

.justification .origine { display: inline-block; margin-bottom: 4px; }

/* La mesure ressort du reste : c'est la seule phrase du bloc qui parle d'un resultat mesure, et
   c'est celle qu'on a le plus envie de sauter quand elle est defavorable. */
.justification .mesure {
  padding: 8px 12px; border-radius: var(--rayon); background: var(--fond-creux);
}

/* --- les trois seuils du scanner (L10.3) -------------------------------------
   REPLIE PAR DEFAUT (`<details>`) : ce panneau se consulte quand on se demande « pourquoi si
   peu ? », pas a chaque ouverture de l'ecran. Deploye d'office, il repousserait le plan de trade
   hors de vue sur un telephone — et c'est le plan qu'on vient voir. */
.panneau-univers { margin-top: 24px; }
.panneau-univers > details {
  border: 1px solid var(--bord); border-radius: var(--rayon); background: var(--fond-carte);
}
.panneau-univers summary {
  padding: 12px 14px; font-weight: 700; cursor: pointer; min-height: 44px;
  list-style-position: inside;
}
.panneau-univers summary:focus-visible { outline: 2px solid var(--emeraude-texte); }
.univers-corps { padding: 0 14px 14px; display: grid; gap: 18px; }
.univers-etage h3 { margin: 0 0 8px; font-size: 1rem; }

/* L'ENTONNOIR SE LIT DE HAUT EN BAS : un depart, des retraits, un reste. Les valeurs sont
   alignees a droite en chiffres tabulaires, sinon l'oeil ne peut pas comparer deux lignes. */
.entonnoir { list-style: none; margin: 0; padding: 0; }
.entonnoir li {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; align-items: baseline;
  padding: 4px 0; border-bottom: 1px solid var(--fond-creux);
}
.entonnoir li.note { grid-template-columns: 1fr; border-bottom: 0; padding-top: 8px; }
.entonnoir-valeur { font-variant-numeric: tabular-nums; font-weight: 700; text-align: right; }
.entonnoir .note { grid-column: 1 / -1; }

.univers-places { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.univers-place { display: flex; align-items: center; gap: 6px; min-height: 44px; }

.univers-champs { display: grid; gap: 12px; margin-top: 12px; }
.univers-champ { display: grid; gap: 4px; }
.univers-champ > span:first-child { font-weight: 600; }
.univers-champ input {
  font: inherit; min-height: 44px; padding: 8px 12px; max-width: 16em;
  background: var(--fond); color: var(--texte);
  border: 1px solid var(--bord); border-radius: var(--rayon);
  font-variant-numeric: tabular-nums;
}
.univers-champ input:disabled { opacity: .6; }
.univers-pied { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }

/* La liste qui explique les six outils de dessin. Une puce par bouton, le nom en gras : c'est ce
   qu'on relit une fois, pas une prose qu'on lit en entier. */
.aide-liste { margin: 6px 0 0; padding-left: 20px; }
.aide-liste li { margin: 3px 0; }

/* Une ligne de reglage : la couleur, le style, l'epaisseur, puis le nom. Les trois commandes en
   tete et alignees — c'est la colonne qu'on parcourt quand on cherche « la ligne trop fine ». */
.ligne-couleur .choix-style {
  font: inherit; font-size: 12px; padding: 2px 4px; max-width: 110px;
  background: var(--fond-carte); color: var(--texte);
  border: 1px solid var(--bord); border-radius: 4px;
}

.ligne-couleur .choix-epaisseur {
  font: inherit; font-size: 12px; width: 48px; padding: 2px 4px;
  background: var(--fond-carte); color: var(--texte);
  border: 1px solid var(--bord); border-radius: 4px;
}

.ligne-couleur .nom-jeton { flex: 1 1 auto; min-width: 9em; }

/* Le ticker mene a son graphique. Souligne au survol seulement : dans une colonne de soixante
   lignes, soixante soulignements permanents feraient un tableau illisible. */
.lien-ticker { color: inherit; text-decoration: none; font-weight: 700; }
.lien-ticker:hover, .lien-ticker:focus-visible { text-decoration: underline; }

/* Un tampon dont les prix sont plus vieux que la publication. Ce n'est pas une panne — le marche
   ferme le week-end — mais c'est un fait qui doit se voir plutot que se deduire. */
.tampon.perime { border-color: var(--ambre-bord); color: var(--ambre); }
