/* ═══════════════════════════════════════════════════════════════════
   NOALA — le détail d'une étape : tiroir, rangées, pastilles d'état.
   Chargé par index.html ET patient.html AVANT app.css/patient.css :
   les surcharges contextuelles restent dans ces fichiers.
   Dépend des tokens :root d'app.css (--phase-*, --accent…).

   ⚠️ LA FRISE ELLE-MÊME EST PARTIE LE 2026-10-10 (décision de Pierre).
   Ni l'horizontale ni la verticale n'étaient plus rendues par une page
   depuis la refonte du cabinet et celle du portail. Leurs règles, la
   fonction `paintTimeline` d'ui.js et leurs tests sont partis ensemble.
   Le fichier garde son nom : sept pages le chargent sous ce nom.
   ═══════════════════════════════════════════════════════════════════ */

/* P3 (révisé, audit Pierre 2026-07-07) — en-tête de SUIVI au-dessus de la frise
   praticien : état des questionnaires (remplis / à remplir) + prochaine étape.
   PAS de compteur de jalons ni d'anneau de complétion : un parcours de soin
   n'est pas un objectif à compléter (les jalons incluent RDV et intervention). */
.noala-frise-progress { display: flex; align-items: center; justify-content: flex-start;
  gap: 12px; flex-wrap: wrap; margin-bottom: var(--s-2); }
.noala-frise-progress-txt { font-size: 13.5px; color: var(--text-2); }
.noala-frise-progress-txt strong { color: var(--ink); font-family: var(--font-serif); }

@keyframes noala-tl-deploy {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* ───── 3.B — Frise héros (nœuds = jalons) ───── */
.noala-jalon-skel { padding: var(--s-4) 0; }
/* 3.B — détail jalon */
.noala-jalon-detail { margin-top: 10px; border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow-md); overflow: hidden;
  animation: noala-tl-deploy .18s ease-out; }
.noala-jalon-detail-head { display: flex; align-items: baseline; gap: 10px; padding: 11px 16px; border-bottom: 1px solid var(--border-2); }
.noala-jalon-detail-head strong { font-family: var(--font-display); font-size: 15px; color: var(--ink); }
.noala-jalon-detail-meta { font-size: 12px; color: var(--text-2); }
/* ── EN-TETE DU TIROIR + BARRE D'ACTIONS DE L'ENVOI (2026-08-28) ─────────────
   La maquette pose l'ordre de lecture : le jalon se nomme, son etat se lit, ce
   qu'on peut en faire s'offre — PUIS le contenu. Les actions vivaient sous la
   liste, en carte pleine largeur de cinq boutons empiles, repetee par envoi. */
.noala-jalon-head { gap: 11px; align-items: center; border: 0; padding: 0 28px 10px 0; }
.noala-jalon-head-tag {
  flex: none; font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
  padding: 3px 11px; border-radius: var(--radius-pill);
  background: var(--accent-soft); color: var(--accent-text);
}
.noala-jalon-head-txt { min-width: 0; display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }

.noala-jalon-envoi {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px; margin-bottom: 8px;
  background: var(--surface-2); border-radius: 13px;
}
.noala-jalon-envoi-date { font-size: 12px; color: var(--text-2); }
/* `margin-left:auto` sur le GROUPE, pas sur un bouton : sinon le premier bouton
   visible porte la poussee, et il change avec le statut de l'envoi. */
.noala-jalon-envoi-act { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.noala-jalon-act {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
  font-size: 12px; font-weight: 600; white-space: nowrap;
  padding: 5px 11px; border-radius: var(--radius-pill); cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.noala-jalon-act > .noala-ic { width: 14px; height: 14px; }
.noala-jalon-act:hover { border-color: var(--accent); color: var(--accent-text); }
/* Une seule action primaire : saisir en consultation. */
/* ⚠️ Le PRIMAIRE ne peut pas etre un aplat accent : il portait 2,75:1 au repos
   et 5,54:1 au SURVOL, donc il n etait lisible que la souris dessus. Le couple
   `--cta-bg` / `--cta-bg-hover` rend 11,97:1 puis 8,33:1, et il est deja apparie
   — `--ink` porte la meme valeur mais n a aucun jumeau de survol. */
.noala-jalon-act.is-primary { background: var(--cta-bg); border-color: var(--cta-bg); color: #fff; }
.noala-jalon-act.is-primary:hover { background: var(--cta-bg-hover); border-color: var(--cta-bg-hover); color: #fff; }
/* Destructif : lisible, jamais attirant. Il ne prend sa couleur d'alerte qu'au
   survol — la barre ne doit pas etre ponctuee de rouge au repos. */
.noala-jalon-act.is-danger { color: var(--text-2); }
.noala-jalon-act.is-danger:hover { border-color: var(--alert); color: var(--alert); background: var(--alert-soft); }

.noala-jalon-items { list-style: none; margin: 0; padding: 6px; display: flex; flex-direction: column; gap: 2px; }
.noala-jalon-item { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border-radius: 12px; transition: background .12s; }
/* ⚠️ Garde POSÉE D'AVANCE. Aucun item de tiroir ne porte `data-sev` aujourd'hui —
   leur branchement est différé au lot 1f, dont la frise dépend. Le sélecteur nu
   pesait (0,2,0) et battait donc `.noala-sev--*` (0,1,0) : il aurait effacé la
   gravité au moment précis où l'utilisateur désigne la rangée. La poser
   maintenant ne change rien au rendu (le `:not` matche tout tant qu'aucun
   `data-sev` n'existe) et évite de la redécouvrir dans six mois. */
.noala-jalon-item:not([data-sev]):hover { background: var(--surface-2); }
/* L'AFFORDANCE de la rangee (2026-08-28). Le lot C.2 a efface le bouton au repos
   en ecrivant que la rangee restait cliquable — elle ne l'etait pas : ni @click
   ni curseur. Le curseur suit `data-cliquable`, pose par le markup PRATICIEN
   seulement : cette feuille est partagee avec la frise verticale du portail
   patient, dont les rangees n'ont pas d'action. Un `cursor` pose sur la classe
   nue promettrait au patient un clic qui ne fait rien. */
.noala-jalon-item[data-cliquable="1"],
.noala-jalon-qsrow[data-cliquable="1"] { cursor: pointer; }
.noala-jalon-qsrow[data-cliquable="1"]:hover .noala-jalon-item-lab { color: var(--accent-text); }
/* Pastille d'icone plutot qu'un glyphe pose a nu : c'est le vocabulaire de
   toutes les autres rangees du produit, et sur 14 items alignes le glyphe nu
   ne donnait aucun point d'ancrage a l'oeil.

   ⚠️ LA DEFINITION VIT DANS app.css (2026-08-28). Ce que le lot C.2 a ecrit ici
   — 32px, rayon 10, --accent-soft sur --accent-text, glyphe 17px — etait le
   sosie exact de `.noala-ico-tile--sm` du socle. `.noala-jalon-item-ic` y est
   donc devenue un ALIAS, selon le motif du lot A : une definition, plusieurs
   noms, zero markup touche, zero test casse (app.css:944-949). Les 32px sont
   CONSERVES : le tiroir empile jusqu'a 14 rangees, ou la pastille de 36px du
   socle prend trop de place — d'ou l'alias sur --sm et non sur la taille de base. */
.noala-jalon-item-lab { flex: 1; font-size: 13.5px; color: var(--ink); min-width: 0; }

/* ═══ LE TIROIR PRATICIEN — ecarts 3.43, 3.45, 3.46 ═══════════════════════
   ⚠️ SCOPE `.noala-parcours-pop`, ancetre EXCLUSIF du tiroir praticien (une
   occurrence dans index.html, zero dans patient.html). Sans ce scope, ces trois
   regles changeraient surtout le PORTAIL, qui porte douze rangees contre onze
   ici — et aucun ecart du rapport portail ne le demande. Meme discipline que
   `data-cliquable` ci-dessus.

   3.46 en particulier BAISSERAIT la lisibilite cote patient : de 13,5px/`--ink`
   (11,46:1 sur `--bg`) a 12,5px/`--text` (9,01:1). Les deux tiennent AA, mais
   c'est une reduction non demandee sur le public le plus fragile du produit.

   3.45 — HONNETETE SUR CE QUE LE FOND APPORTE : `--bg` #FAFAF8 sur la carte
   `--surface` blanche rend **1,045:1**. Il est quasi invisible. Le gain de
   separation entre quatorze rangees vient du `gap` porte a 7px, PAS du
   remplissage. On pose quand meme le fond — c'est la maquette — mais qui lira
   « la liste se lit comme un bloc unique » ne doit pas croire que ce fond y
   repond : c'est l'ecart qui y repond. */
.noala-parcours-pop .noala-jalon-items { gap: 7px; }
.noala-parcours-pop .noala-jalon-item {
  background: var(--bg);
  padding: 10px 12px;
  border-radius: 11px;
}
.noala-parcours-pop .noala-jalon-item-lab {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text);
}

/* Pastille d'OBJECTIF (ecart 3.43). La bande {min, max} vit sur `Envoi.objectifs`
   depuis la migration 104 et n'etait rendue que dans la popup Scores.

   ⚠️ FOND OPAQUE, ET C'EST LA TOUTE LA QUESTION. La maquette pose
   `--accent-tint`, qui est TRANSLUCIDE : son contraste depend alors du fond de
   la rangee, lequel change au survol — mesure, la recette de la maquette tombe a
   4,06:1 quand la rangee est survolee, sous AA, et rien ne le montre sur une
   capture statique. Pire, elle depend AUSSI de l'ecart 3.45 ci-dessus : trois
   regles du meme lot se composent sur le meme pixel.
   `color-mix(in srgb, var(--accent) 7%, var(--surface))` resout exactement au
   #F0F9F8 de la maquette, mais OPAQUE : le ratio ne depend plus de rien.
   Mesure : `--accent-text` dessus = 5,1766:1, au repos comme au survol.

   ⚠️ CETTE CLASSE NE DOIT JAMAIS ETRE EMISE PAR patient.html (regle 2.11,
   hors dispositif medical). La vue patient recoit la BANDE seule, jamais le
   libelle, et le mot « atteint » de la maquette a deja ete retire par le
   proprietaire produit parce que c'est un jugement derive sur un score clinique.
   Coller « Objectif 35-48 » a cote de « 78/100 » sur la meme rangee ferait faire
   la soustraction au patient. La forme conforme existe deja, detachee du score,
   dans l'accordeon « Mes objectifs » du portail. */
/* ⚠️ `.noala-jalon-obj` A DÉMÉNAGÉ DANS app.css le 2026-08-31, et ce n'est pas
   du rangement : `admin.html` ne charge PAS cette feuille, et la table des étapes
   de son builder de protocole emploie cette pastille depuis la vague A du lot 5.
   Elle y serait sortie NUE — une classe absente ne lève rien.
   Le nom reste trompeur (la classe n'a rien de propre à la frise, c'est LA
   pastille d'objectif du produit) ; le renommer est un geste séparé, il touche
   cinq sites d'appel et un e2e. */
/* Lot C (audit V2 §3c) — une ligne par questionnaire dans le détail de jalon.
   Classes ADDITIVES (le rendu praticien historique n'utilise pas .is-multi). */
.noala-jalon-item.is-multi { align-items: flex-start; }
.noala-jalon-item.is-multi .noala-jalon-item-go { margin-top: 2px; }
.noala-jalon-item-rows { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
/* ⚠️ SECONDE EXCEPTION NOMMEE au gel de la frise (passation §3), et le second
   defaut de RENDU du lot — mesure, pas suppose.
   Sur 375 px, le `<li>` pose les rangees et le bouton « Remplir → » COTE A COTE.
   Mesure : li = 279 px, moins 24 px de padding = 255 ; le bouton en prend 118,
   il reste 137 pour les rangees, et le libelle recoit **15 px**. « APAIS » — cinq
   caracteres — s'y enroule sur quatre lignes.
   L'audit attribuait cet enroulement au libelle trop long (ecart 5.28, « sans
   libelle patient court, le titre continuera de s'enrouler dans une colonne de
   ~110 px »). C'est INSUFFISANT comme diagnostic : `nom_court` (migration 127)
   donne bien « APAIS », et la colonne casse quand meme. La cause est la
   largeur, pas le texte.
   Sous 768 px — la ou vit la frise VERTICALE du patient — l'action passe donc
   SOUS son contenu, ce que fait toute mise en page mobile. Aucune interaction
   avec les trois defauts de 1f, qui portent sur `.noala-tl-seg`, la coupure
   apres J0 et `--tl-avenir-ring`. */
@media (max-width: 767px) {
  .noala-jalon-item, .noala-jalon-item.is-multi { flex-direction: column; align-items: stretch; gap: 8px; }
  .noala-jalon-item.is-multi .noala-jalon-item-go { margin-top: 0; }
  .noala-jalon-item-go { align-self: flex-start; }
}
.noala-jalon-qsrow { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* Écart 5.27 — le filet de la maquette (`.vrow + .vrow`, patient.html:57). Sans
   lui, un jalon à quatre entrées empile des rangées que rien ne sépare, et un
   libellé qui s'enroule sur deux lignes devient indiscernable de son voisin. */
.noala-jalon-qsrow + .noala-jalon-qsrow {
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--border-2); }
/* RETIREE le 2026-08-28 : `[data-done="1"] .noala-jalon-item-ic { color: var(--accent) }`.
   Deux raisons, dont une qui la rendait nuisible la ou elle s'appliquait.
   1. Elle etait INERTE cote praticien : la pastille y vit au niveau du <li>
      (index.html:1055 ; l'ancre « 1002 » de ce commentaire etait morte), pas
      dans la ligne (index.html:1002) — elle n'a jamais rien peint de ce cote.
   2. La ou elle s'appliquait (portail patient, patient.html:1784 et 1837 ;
      l'ancre « 1772 » etait morte elle aussi), elle DEGRADAIT
      la lisibilite : elle remplacait --accent-text par --accent SUR un fond
      --accent-soft, faisant tomber le glyphe sous le seuil 3:1 des elements
      graphiques porteurs d'information. Le glyphe « accompli » devenait le moins
      lisible des trois.
   Le signal « fait » reste porte deux fois, sans rien perdre : par
   `.noala-jalon-qsrow-state[data-done="1"]` (fond accent-soft, texte accent-text)
   et par la pastille de score. Meme raisonnement que le lot A retirant
   l'`opacity:.7` d'un libelle annule : un troisieme signal qui coute en lisibilite
   n'ajoute pas d'information. */
/* ⚠️ EXCEPTION NOMMEE au gel de la frise (passation §3). C'est le seul defaut
   de RENDU du lot : sans `flex: none`, la pastille d'etat passe SOUS le libelle
   des qu'il s'enroule, et les deux se chevauchent. Sa classe soeur
   `.noala-consent-state` porte deja `flex-shrink: 0` (app.css) — c'est un oubli,
   pas une intention. Un mot, aucune interaction avec les trois defauts de 1f,
   qui portent sur `.noala-vtl-*` et sur les segments. */
/* ⚠️ `--text` et NON `--text-2`, et ce n'est pas un detail de gout : sur
   `--surface-2` le gris moyen ne rend que 4,28:1 (recalcule) pour une pastille
   de 10,5px, donc SOUS le 4,5:1 du texte normal. `--text` y rend 8,00:1.
   La pastille SOEUR `.noala-vtl-chip` avait deja corrige exactement cela, avec
   sa mesure ecrite (cf plus bas) ; celle-ci ne l'avait pas suivie.
   ⚠️ Et l'action de l'audit demandait `--text-2` : l'appliquer a la lettre
   aurait GRAVE le defaut dans deux regles explicites au lieu de l'heriter d'une.
   Meme piege que le point 4 du bloc LOT 1f, qui ecrit deja « NE PAS appliquer la
   cible que propose l'audit ». */
.noala-jalon-qsrow-state { flex: none; font-size: 10.5px; font-weight: 700; padding: 1px 8px; border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--text); white-space: nowrap; }
/* Ecart 3.7 — SIX etats sortaient dans le meme gris : « expire », « annule »,
   « planifie », « a remplir », « a faire », « rempli · sans score ». Seul l'etat
   qui ATTEND UNE ACTION prend une teinte ; le reste garde le neutre, parce que
   tout teindre revient a ne rien signaler.
   Le vocabulaire vient du serveur : `state` ∈ {complete, expire, annule, open,
   planifie} (`reponses.py`). */
.noala-jalon-qsrow-state[data-state="open"],
.noala-jalon-qsrow-state[data-state="complete"] { background: var(--warn-soft); color: var(--warn-text); }
/* Un etat annule se barre ; il ne s'appuie pas. Meme parti que la pastille
   soeur : un annule n'est pas plus grave qu'un neutre, il est HORS JEU. */
.noala-jalon-qsrow-state[data-state="annule"] { text-decoration: line-through; }
/* ⚠️ DERNIERE DECLARATION DU BLOC, et delibere : `[data-done="1"]` et
   `[data-state="open"]` ont la MEME specificite (0,2,0), et une ligne
   « rempli · sans score » peut porter `it.state === 'open'`. Le texte donne deja
   la priorite a `done` ; la couleur doit la donner aussi.
   ⚠️ ET ELLE GARDE SON TEAL. La reconnaissance proposait `--status-good-soft` /
   `--status-good`, la recette de la maquette : recalcule, ce couple rend 4,38:1
   contre 4,76:1 pour celui-ci. Le « correctif » aurait fait BAISSER le contraste
   sous AA, sur les deux fronts. Le vert reste reserve aux surfaces jugees a
   3:1 — les pastilles d'icone, pas le texte. */
.noala-jalon-qsrow-state[data-done="1"] { background: var(--accent-soft); color: var(--accent-text); }
.noala-jalon-pill { font-size: 10.5px; padding: 2px 9px; border-radius: var(--radius-pill); font-weight: 600; }
/* Le violet #7c5cd6 est hors charte NOALA — il ne code aucune gravite, juste
   la nature « media ». Il rejoint la teinte de phase, qui est dans la palette. */
.noala-jalon-pill.media { background: var(--phase-avant-soft); color: var(--phase-avant-text); }
/* L'action ne se REPETE plus a l'identique sur chaque ligne. Sur un dossier
   reel le tiroir porte 14 items, dont 12 affichaient le meme bouton
   « Voir le detail → » : douze fois la meme commande, c'est douze fois rien.
   Le bouton s'efface au repos et revient au survol ou au focus clavier.
   ⚠️ SA JUSTIFICATION A CHANGE LE 2026-09-01. Elle disait « la rangee entiere
   reste cliquable » — ce n'est PLUS vrai : le clic sur toute la ligne basculait
   le cadre vers la vue Scores par surprise, et la revue du proprietaire produit
   l'a fait retirer (point 4). Le fondu tient toujours, mais pour une autre
   raison : la couverture reste complete sans lui — survol a la souris,
   `:focus-visible` au clavier, `@media (hover: none)` au tactile — et la seule
   perte est qu'une souris doit viser le bouton plutot que la ligne. C'est un
   plus petit geste, mais un geste PREVISIBLE, ce qui etait tout l'objet de la
   correction. */
.noala-jalon-item-go { background: transparent; border: 1px solid var(--border); color: var(--accent-text); font-size: 12px;
  padding: 4px 11px; border-radius: var(--radius-pill); cursor: pointer; white-space: nowrap; font-weight: 600;
  opacity: 0; transition: opacity .12s, background .12s, color .12s, border-color .12s; }
.noala-jalon-item:hover .noala-jalon-item-go,
.noala-jalon-item-go:focus-visible { opacity: 1; }
@media (hover: none) { .noala-jalon-item-go { opacity: 1; } }
.noala-jalon-item-go:hover { background: var(--cta-bg); color: #fff; border-color: var(--cta-bg); }
.noala-jalon-item-go.ghost { color: var(--text-2); }
.noala-jalon-item-go.ghost:hover { background: var(--surface-2); color: var(--ink); border-color: var(--border); }
