/* ============================================================================
   ROBUR — composants
   Dépend de tokens.css. Aucune valeur en dur ici : que des jetons.

   Le système tient en une phrase : un carnet d'entraînement réglé, où ce qui
   est fait est encré. D'où les trois règles de dessin :
     · des FILETS, pas des ombres (une ombre = un vrai survol, feuille ou menu)
     · le PLEIN veut dire fait, le CONTOUR veut dire à faire
     · un seul ornement dans tout le système : le filet de section (--regle)
   ============================================================================ */

/* ── Socle ─────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--font-texte);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  font-feature-settings: 'tnum' 0;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-titre);
  font-variation-settings: var(--fv-titre);
  font-optical-sizing: none;
  font-weight: var(--poids-gras);
  line-height: var(--leading-titre);
  letter-spacing: var(--tracking-titre);
  margin: 0;
}

p { margin: 0 0 var(--space-3); max-width: var(--largeur-lecture); }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: var(--c-accent); text-underline-offset: .18em; }
button { font: inherit; color: inherit; }

/* Anneau de focus : visible sur TOUS les fonds, y compris sur un bouton plein. */
:focus-visible {
  outline: 3px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
.btn--principal:focus-visible,
.tuile-encre:focus-visible { outline-color: var(--c-text); }

/* Réservé aux lecteurs d'écran. Tout pictogramme du système en porte un. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Chiffres : tabulaires partout où ils s'empilent ou se mettent à jour. */
.chiffre, .valeur, td, .jauge__valeur, .serie__valeur {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ── Coquille d'application ────────────────────────────────────────────────── */
.app {
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

.entete {
  position: sticky; top: 0; z-index: var(--z-barre);
  display: flex; align-items: center; gap: var(--space-3);
  padding: calc(var(--inset-haut) + var(--space-3)) var(--gouttiere) var(--space-3);
  background: color-mix(in oklab, var(--c-bg) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: var(--trait);
}
.entete__marque { display: flex; align-items: center; gap: var(--space-2); color: var(--c-accent); }
.entete__marque svg { width: 26px; height: 26px; display: block; }
.entete__mot {
  font-family: var(--font-titre); font-variation-settings: var(--fv-titre);
  font-optical-sizing: none; font-weight: var(--poids-gras);
  font-size: var(--text-lg); letter-spacing: var(--tracking-marque);
  color: var(--c-text);
}
.entete__droite { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }

/* Pastille de profil — l'application sait TOUJOURS à qui elle parle, et le
   montre. C'est un produit qui sert un ado nageur et un retraité qui reprend :
   ne jamais laisser l'utilisateur deviner pour qui l'écran a été calculé. */
.profil {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: var(--cible-min); padding: var(--space-1) var(--space-3) var(--space-1) var(--space-1);
  background: var(--c-surface); border: var(--trait); border-radius: var(--radius-full);
  text-decoration: none; color: inherit; cursor: pointer;
}
.profil__initiales {
  width: 32px; height: 32px; flex: none; border-radius: var(--radius-full);
  display: grid; place-items: center;
  background: var(--c-accent); color: var(--c-on-accent);
  font-size: var(--text-xs); font-weight: var(--poids-gras); letter-spacing: .02em;
}
.profil__texte { display: flex; flex-direction: column; line-height: 1.15; }
.profil__nom { font-size: var(--text-sm); font-weight: var(--poids-demi); }
.profil__meta { font-size: var(--text-xs); color: var(--c-text-muted); }

.contenu {
  padding: var(--space-5) var(--gouttiere) calc(var(--h-barre-onglets) + var(--inset-bas) + var(--space-8));
  width: 100%;
}

/* ── Titre d'écran ─────────────────────────────────────────────────────────── */
.titre-ecran { font-size: var(--text-2xl); margin-bottom: var(--space-1); }
.sous-titre { color: var(--c-text-muted); font-size: var(--text-sm); margin-bottom: var(--space-5); }

/* Étiquette de section : petites capitales + numéro en marge + filet.
   C'est l'unique ornement du système, et il porte une information (l'ordre). */
.section { margin-top: var(--space-6); }
.section:first-of-type { margin-top: 0; }
.section__tete {
  display: flex; align-items: baseline; gap: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: var(--regle) solid var(--c-text);
  margin-bottom: var(--space-4);
}
.section__num {
  font-family: var(--font-titre); font-variation-settings: var(--fv-titre);
  font-optical-sizing: none; font-weight: var(--poids-gras);
  font-size: var(--text-sm); color: var(--c-text-subtle); font-variant-numeric: tabular-nums;
}
.section__titre {
  font-family: var(--font-texte); font-size: var(--text-sm); font-weight: var(--poids-demi);
  text-transform: uppercase; letter-spacing: var(--tracking-etiquette);
}
.section__note { margin-left: auto; font-size: var(--text-sm); color: var(--c-text-muted); }

/* ── Carte ─────────────────────────────────────────────────────────────────── */
.carte {
  background: var(--c-surface);
  border: var(--trait);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.carte + .carte { margin-top: var(--space-3); }
.carte--tendue { padding: var(--space-3) var(--space-4); }

/* La carte du jour : un filet épais en tête, pas une ombre ni un dégradé. */
.carte--jour {
  border-top: var(--space-1) solid var(--c-accent);
  border-radius: var(--radius-xs) var(--radius-xs) var(--radius-md) var(--radius-md);
  padding: var(--space-5) var(--space-4);
}
/* Carte en pointillé — « rien de prévu » (écran du jour) et « bloc pas encore
   fait » (saisie de séance). Le contour passe de --c-border (1,39:1) à
   --c-border-strong (3,63:1) : c'était le MÊME défaut « ton sur ton » que sur
   l'onglet Semaine, sur un fond transparent, donc plus rien à l'écran. Un
   contour qui dit « ceci est un état » doit tenir le seuil 3:1 de la 1.4.11.

   Volontairement NEUTRE et pas en --c-repos : cette classe porte deux sens
   selon l'écran (repos / à faire). Lui donner l'ardoise du repos mentirait sur
   l'un des deux. Le découpage en deux classes est à faire côté vues. */
.carte--repos { background: transparent; border: var(--trait-fort); border-style: dashed; }
.carte--defaut { border-left: var(--filet-statut) solid var(--c-alerte); }

.carte__tete { display: flex; align-items: flex-start; gap: var(--space-3); margin-bottom: var(--space-3); }
.carte__titre { font-size: var(--text-xl); }
.carte__meta { font-size: var(--text-sm); color: var(--c-text-muted); }

/* ── Boutons ───────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--cible-min); padding: var(--space-2) var(--space-4);
  border: var(--trait-fort); border-radius: var(--radius-sm);
  background: transparent; color: var(--c-text);
  font-size: var(--text-base); font-weight: var(--poids-demi);
  cursor: pointer; text-decoration: none;
  transition: background var(--dur-court) var(--ease), border-color var(--dur-court) var(--ease);
}
.btn:hover { background: var(--c-surface-2); }
.btn:active { transform: translateY(1px); }

.btn--principal {
  background: var(--c-accent); color: var(--c-on-accent); border-color: var(--c-accent);
  min-height: var(--cible-gant); padding-inline: var(--space-5);
  font-size: var(--text-lg); font-weight: var(--poids-demi);
}
.btn--principal:hover { background: var(--c-accent-strong); border-color: var(--c-accent-strong); }
.btn--bloc { width: 100%; }
.btn--discret { border-color: transparent; color: var(--c-text-muted); }
.btn--discret:hover { color: var(--c-text); }
.btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }

/* ── Statuts ───────────────────────────────────────────────────────────────────
   Règle absolue : la forme dit l'état, la couleur ne fait que confirmer.
   plein = fait · contour = à faire · filet + terracotta = manqué · pointillé = repos
   Chaque puce porte un texte : jamais un point de couleur muet.              */
.statut {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-xs); font-weight: var(--poids-demi);
  text-transform: uppercase; letter-spacing: var(--tracking-etiquette);
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-full);
  white-space: nowrap;
}
.statut::before {
  content: ''; width: 10px; height: 10px; border-radius: var(--radius-full); flex: none;
}
.statut--fait      { color: var(--c-text); background: var(--c-surface-2); }
.statut--fait::before { background: var(--c-encre); }
.statut--a-faire   { color: var(--c-text-muted); }
.statut--a-faire::before { border: 2px solid var(--c-border-strong); }
.statut--manque    { color: var(--c-alerte); background: var(--c-alerte-soft); }
.statut--manque::before { background: var(--c-alerte); }
/* Repos : ardoise + pointillé + le mot. Trois porteurs pour une information,
   jamais la teinte seule (1.4.1). 5,56:1 clair · 9,07:1 sombre — au-dessus du
   seuil de texte, pas seulement de celui des composants. */
.statut--repos     { color: var(--c-repos); }
.statut--repos::before { border: 2px dashed var(--c-repos); }
/* Aujourd'hui : l'accent marque une POSITION DANS LE TEMPS, pas une réussite.
   C'est le seul emploi de l'accent en statut, et il ne juge rien — la règle
   « le vert n'est jamais un statut » vise le couple gagné/perdu, pas la date. */
.statut--aujourdhui { color: var(--c-accent); }
.statut--aujourdhui::before { background: var(--c-accent); }

/* ── Frise des cernes ──────────────────────────────────────────────────────────
   Une barre par semaine depuis le début, hauteur = volume de la semaine.
   Encré = semaine faite, contour = semaine à venir. C'est la marque devenue
   graphique : la progression se lit comme les cernes d'un tronc.
   Toujours accompagnée d'un tableau .sr-only — un graphique n'est pas un texte. */
.frise {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 3px;
  height: 84px; padding-top: var(--space-2);
}
.frise__barre {
  /* plafonnée : sur un écran large, douze barres étirées ne ressemblent plus
     à des cernes mais à un histogramme de tableur. */
  flex: 1 1 0; min-width: 4px; max-width: 26px;
  height: calc(var(--h) * 1%);
  border-radius: var(--radius-xs) var(--radius-xs) 0 0;
  background: var(--c-encre);
}
.frise__barre--avenir { background: transparent; border: 1px solid var(--c-border-strong); }
.frise__barre--courante { background: var(--c-accent); }
.frise__barre--vide { background: var(--c-alerte-soft); border: 1px solid var(--c-alerte); }
.frise__legende {
  display: flex; justify-content: space-between;
  font-size: var(--text-xs); color: var(--c-text-muted);
  border-top: var(--trait); padding-top: var(--space-1); margin-top: var(--space-1);
}

/* ── Jauge (macros, volume, charge) ───────────────────────────────────────────
   On affiche le RESTE, pas seulement le consommé : c'est la question que se
   pose quelqu'un devant son frigo à 19 h. Un dépassement se voit par une
   hachure, pas seulement par une couleur.                                    */
.jauge { margin-bottom: var(--space-4); }
.jauge__tete { display: flex; align-items: baseline; gap: var(--space-2); margin-bottom: var(--space-2); }
.jauge__nom { font-size: var(--text-sm); font-weight: var(--poids-demi); }
.jauge__valeur { margin-left: auto; font-size: var(--text-sm); }
.jauge__reste { display: block; font-size: var(--text-sm); color: var(--c-text-muted); }
.jauge__piste {
  position: relative; height: 14px; border-radius: var(--radius-xs);
  background: var(--c-surface-2); border: var(--trait);
}
.jauge__part {
  position: absolute; inset: 0 auto 0 0; width: calc(var(--p) * 1%);
  background: var(--c-teinte, var(--c-accent));
  border-radius: var(--radius-xs) 0 0 var(--radius-xs);
}
.jauge__depassement {
  position: absolute; inset: 0 auto 0 var(--depart, 100%); width: calc(var(--d) * 1%);
  background: repeating-linear-gradient(135deg,
    var(--c-alerte) 0 4px, transparent 4px 8px);
  border-left: 2px solid var(--c-alerte);
}
.jauge--proteines { --c-teinte: var(--c-macro-proteines); }
.jauge--glucides  { --c-teinte: var(--c-macro-glucides); }
.jauge--lipides   { --c-teinte: var(--c-macro-lipides); }
/* Repère de la cible : un trait qui DÉPASSE de la piste (d'où l'absence
   d'overflow:hidden au-dessus). On ne le pose que si la cible tombe ailleurs
   qu'au bout de la piste — sinon il ne dit rien. */
.jauge__cible {
  position: absolute; top: -2px; bottom: -2px; left: calc(var(--c) * 1%);
  width: 2px; background: var(--c-text);
}

/* ── Chiffre ───────────────────────────────────────────────────────────────── */
.chiffre {
  font-family: var(--font-texte);
  font-size: var(--text-chiffre); font-weight: var(--poids-demi);
  line-height: var(--leading-serre); letter-spacing: -0.02em;
}
.chiffre--xl { font-size: var(--text-chiffre-xl); }
.chiffre__unite { font-size: var(--text-lg); font-weight: var(--poids-normal); color: var(--c-text-muted); }
.bloc-stat { display: flex; flex-direction: column; gap: var(--space-1); }
.bloc-stat__nom {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-etiquette); color: var(--c-text-muted);
}
.bloc-stat__note { font-size: var(--text-sm); color: var(--c-text-muted); }
.grille-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-4);
}

/* ── Le registre des tarifs — deux façons de payer une SEULE formule ───────────
   POURQUOI CE COMPOSANT EXISTE (12/08/2026)
   La carte « Ma formule » composait ses deux prix avec `.chiffre__unite` et une
   barre oblique : « 8,99 €<span> / mois</span> ». Sur un Pixel, la ligne cassait
   entre la barre et le mot : on lisait « 8,99 €/ » puis « mois » à la ligne
   suivante, barre pendante. Ce n'est pas un bogue de `.chiffre__unite` — c'est
   qu'on lui a fait porter un séparateur qu'il n'a jamais eu vocation à porter.

   TROIS DÉCISIONS, ET ELLES SONT LIÉES
   1. LA BARRE OBLIQUE DISPARAÎT, ELLE N'EST PAS RÉPARÉE. Une insécable aurait
      soigné le symptôme. Mais « / » est un raccourci de tableur entre deux
      grandeurs ; ici il n'y a pas deux grandeurs, il y a un prix et sa cadence.
      Et une oblique posée entre un corps 36 et un corps 14 ne s'accorde à aucun
      des deux : elle est trop maigre pour le chiffre, trop haute pour le mot.
      Aucun séparateur ne peut rester orphelin s'il n'y a pas de séparateur.
   2. LA CADENCE EST DITE UNE SEULE FOIS, EN TÊTE DE COLONNE. Les deux montants
      sont comparables PARCE QU'ils sont tous deux ramenés au mois : c'est
      l'étalon du registre, pas une étiquette à recopier sous chaque chiffre.
      Écrire « par mois » deux fois, c'est écrire deux fois la même chose.
   3. DEUX LIGNES DE REGISTRE, JAMAIS DEUX COLONNES. Deux colonnes de prix, c'est
      la grille tarifaire de tout le monde, et elle raconte « deux produits,
      comparez-les ». Or c'est le MÊME produit. Deux lignes d'un même carnet
      disent « une chose, deux écritures » — et elles ont un effet de bord qui
      est tout l'objet de la demande : les deux montants, tabulaires et alignés
      à droite, forment une colonne où 8,99 tombe sur 5,75. L'économie se VOIT,
      verticalement, sans pastille ni prix barré. Un fait, pas un cri.

   Sur 360 px la mesure ne mord pas (le contenu d'une carte y fait 296 px) et la
   ligne se replie d'elle-même : étiquette et note à gauche, montant à droite.  */
.tarifs {
  /* Mesure du registre. Au-delà, l'étiquette et son montant se perdent de vue :
     sur le rail de bureau la carte peut faire 900 px, et « AU MOIS » finirait à
     un demi-écran de « 8,99 € ». Valeur locale et non jeton global : c'est la
     mesure de CE bloc, elle ne sert nulle part ailleurs. */
  --tarifs-mesure: 24rem;
  max-width: var(--tarifs-mesure);
  /* Le registre et la liste de ce qui est inclus sont tous deux réglés au même
     filet. Sans un blanc franc entre les deux, l'œil enchaîne les traits et lit
     une seule table de sept lignes. C'est le blanc qui dit « ici on change de
     sujet », pas un filet plus épais. */
  margin-bottom: var(--space-5);
}

/* L'étalon, en tête de la colonne des montants et aligné sur elle. Masqué aux
   lecteurs d'écran (aria-hidden) : chaque montant porte sa propre cadence en
   .sr-only, sinon une ligne lue isolément dirait « 5,75 € » sans dire de quoi. */
.tarifs__unite {
  display: block; text-align: right;
  font-size: var(--text-xs); font-weight: var(--poids-moyen);
  text-transform: uppercase; letter-spacing: var(--tracking-etiquette);
  color: var(--c-text-muted);
  padding-bottom: var(--space-2);
}

.tarifs__lignes { margin: 0; padding: 0; list-style: none; }

/* Une ligne = une façon de payer. Le montant occupe la rangée 1 de la colonne
   de droite, l'étiquette la rangée 1 à gauche (alignées sur la MÊME ligne de
   base : c'est ce qui fait le couple étiquette-chiffre d'un registre), la note
   la rangée 2 à gauche, sous l'étiquette qu'elle précise. */
.tarif {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--space-4); row-gap: var(--space-1);
  padding: var(--space-3) 0;
  border-top: var(--trait);   /* filet DÉCORATIF : l'information est portée par
                                 les étiquettes et l'alignement, pas par le trait */
}
.tarif__cadence {
  grid-column: 1; grid-row: 1;
  font-size: var(--t-etiquette); font-weight: var(--poids-demi);
  text-transform: uppercase; letter-spacing: var(--tracking-etiquette);
  color: var(--c-text);       /* à l'encre : c'est le SUJET de la ligne */
}
/* Tabulaire ET aligné à droite : les deux ensemble, pas l'un ou l'autre. Le
   tabulaire garantit que 8,99 et 5,75 ont la même chasse ; l'alignement à droite
   garantit que les unités restent l'une sous l'autre le jour où un prix passe à
   deux chiffres. `nowrap` est la ceinture qui va avec l'insécable du balisage :
   le montant et son symbole ne se séparent jamais, quoi qu'on écrive autour. */
.tarif__montant {
  grid-column: 2; grid-row: 1; justify-self: end;
  font-size: var(--text-3xl); font-weight: var(--poids-demi);
  line-height: var(--leading-serre); letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1;
  white-space: nowrap;
}
.tarif__detail {
  grid-column: 1; grid-row: 2;
  font-size: var(--text-sm); line-height: var(--leading-normal);
  color: var(--c-text-muted);
}

/* La ligne de bas de registre. Sa place fait sa force : dans un carnet, ce qui
   est écrit sous le dernier filet est le total. Le montant économisé passe à
   l'encre, le commentaire reste en estompe — l'économie est mise en évidence
   par la hiérarchie, jamais par une couleur d'alerte ni un « −36 % ! ». */
.tarifs__bilan {
  margin: 0; padding-top: var(--space-3); border-top: var(--trait);
  font-size: var(--text-sm); line-height: var(--leading-normal);
  color: var(--c-text-muted);
}
.tarifs__bilan strong { color: var(--c-text); font-weight: var(--poids-demi); }

/* Variation chiffrée : signe TOUJOURS explicite, couleur en second.
   Pas de vert/rouge : un +2 kg est un fait, pas une victoire ou une faute. */
.delta { font-variant-numeric: tabular-nums; font-weight: var(--poids-demi); }
.delta--attention { color: var(--c-alerte); }

/* ── Exercices et séries ───────────────────────────────────────────────────── */
.exercice { border-bottom: var(--trait); padding: var(--space-4) 0; }
.exercice:last-child { border-bottom: 0; }
.exercice__tete { display: flex; align-items: baseline; gap: var(--space-3); margin-bottom: var(--space-1); }
.exercice__nom { font-size: var(--text-lg); font-weight: var(--poids-demi); }
.exercice__prescription { margin-left: auto; font-size: var(--text-sm); color: var(--c-text-muted); }
.exercice__consigne { font-size: var(--text-sm); color: var(--c-text-muted); margin: 0 0 var(--space-3); }

/* Les carrés de série : plein = série faite. Le même motif que la frise,
   à l'échelle de l'exercice. On ne compte pas, on VOIT. */
.series {
  display: grid; gap: var(--space-2);
  grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
}
.serie {
  min-width: 0; min-height: var(--cible-min);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  border: var(--trait-fort); border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  background: transparent; cursor: pointer;
}
.serie__valeur { font-size: var(--text-sm); font-weight: var(--poids-demi); font-variant-numeric: tabular-nums; }
.serie__rang { font-size: var(--text-xs); color: var(--c-text-muted); }
.serie--faite { background: var(--c-encre); border-color: var(--c-encre); color: var(--c-bg); }
.serie--faite .serie__rang { color: var(--c-bg); opacity: .75; }
.serie--courante { border-color: var(--c-accent); border-width: 2px; box-shadow: inset 0 0 0 1px var(--c-accent); }

/* ── Pas à pas (charge / répétitions) ──────────────────────────────────────────
   56 px : on l'utilise les mains moites, à bout de bras, entre deux séries. */
.pas { display: flex; align-items: stretch; gap: var(--space-2); }
.pas__btn {
  width: var(--cible-gant); height: var(--cible-gant); flex: none;
  border: var(--trait-fort); border-radius: var(--radius-sm);
  background: var(--c-surface); font-size: var(--text-xl); line-height: 1; cursor: pointer;
}
.pas__btn:hover { background: var(--c-surface-2); }
.pas__champ {
  flex: 1; min-width: 0; height: var(--cible-gant);
  border: var(--trait-fort); border-radius: var(--radius-sm);
  background: var(--c-surface); color: var(--c-text);
  text-align: center; font-size: var(--text-xl); font-weight: var(--poids-demi);
  font-variant-numeric: tabular-nums;
}
.pas__legende {
  display: block; font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-etiquette); color: var(--c-text-muted);
  margin-bottom: var(--space-2);
}

/* ── Effort perçu : une échelle nommée, pas une note sur 10 ────────────────────
   « RPE 8 » ne veut rien dire pour un débutant de 60 ans. Les mots, oui. */
.effort { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-1); }
.effort__cran {
  min-width: 0; min-height: var(--cible-min); padding: var(--space-2) var(--space-1);
  overflow-wrap: anywhere;
  border: var(--trait); border-radius: var(--radius-sm);
  background: transparent; cursor: pointer;
  font-size: var(--text-xs); line-height: 1.2; text-align: center; color: var(--c-text-muted);
}
.effort__cran[aria-pressed="true"] {
  background: var(--c-encre); border-color: var(--c-encre); color: var(--c-bg);
  font-weight: var(--poids-demi);
}

/* ── Listes ────────────────────────────────────────────────────────────────── */
.liste { border-top: var(--trait); }
.liste__ligne {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) 0; border-bottom: var(--trait); min-height: var(--cible-min);
}
.liste__principal { flex: 1; min-width: 0; }
.liste__nom  { display: block; font-weight: var(--poids-moyen); }
.liste__meta { display: block; font-size: var(--text-sm); color: var(--c-text-muted); }
.liste__valeur { flex: none; font-variant-numeric: tabular-nums; text-align: right; }

/* ── Jours de la semaine ───────────────────────────────────────────────────────
   REFONTE DU 12/08/2026 — motif : « on ne distingue pas les jours du premier
   coup d'œil, les jours de repos sont ton sur ton » (Adam, sur son Pixel).
   La mesure lui donnait raison : le seul séparateur de deux jours valait 1,09:1
   et le pointillé d'un jour de repos 1,39:1, contre 3:1 exigés par la 1.4.11.

   Une ligne de jour porte maintenant TROIS marqueurs, jamais un seul :
     · un FILET DE NATURE à gauche, pleine hauteur (--filet-nature) : c'est lui
       le « code couleur » demandé, et c'est aussi lui qui borne la ligne ;
     · un PAVÉ DE DATE encadré à ≥ 3:1, toujours à la même place et à la même
       largeur — c'est cette colonne régulière qui rend le balayage possible.
       Sa FORME dit l'état : contour = à faire, plein = fait, pointillé = repos.
       (Règle n°2 du système. Elle survit au daltonisme et au plein soleil.)
     · un MOT, toujours : « Fait », « À faire », « Repos », « Aujourd'hui ».

   Ce que je n'ai PAS fait, et pourquoi : le filet du bas reste --c-border
   (1,39:1). Il aère, il ne délimite plus rien — la ligne est bornée par son
   filet de nature. Un séparateur renforcé EN PLUS des filets aurait fait sept
   traits noirs empilés : un tableau de comptable, pas un carnet.

   Typographie : les niveaux viennent de `hierarchie.css` (.t-repere, .t-titre,
   .t-meta). Les classes ci-dessous ne portent que la MISE EN PLACE et les
   ÉTATS — jamais une deuxième définition du même niveau. */
.jour {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  align-items: start;
  gap: var(--space-1) var(--space-3);
  padding: var(--space-4) 0 var(--space-4) var(--space-3);
  border-bottom: var(--trait);
  /* Posé sur tous les jours, y compris ceux sans nature connue : sans largeur
     constante, les pavés de date se décaleraient d'une ligne à l'autre et la
     colonne de repère — tout l'intérêt du dispositif — serait perdue. */
  border-left: var(--filet-nature) solid var(--c-border-strong);
}
.jour:last-child { border-bottom: 0; }

/* Le pavé de date : l'ancre du balayage. Encadré, donc identifiable seul. */
.jour__date {
  text-align: center;
  padding: var(--space-1) var(--space-1) var(--space-2);
  border: var(--trait-fort);            /* 3,63:1 clair · 3,76:1 sombre */
  border-radius: var(--radius-sm);
  background: transparent;              /* contour = à faire */
}
.jour__abbr {
  display: block; font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-etiquette); color: var(--c-text-muted);
}
/* Crochet d'état uniquement : la typographie du numéro vient de .t-repere,
   que le balisage pose à côté. Redéfinir la fonte ici ferait deux vérités. */
.jour__num { display: block; }

.jour__corps { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
/* Conservé pour les écrans qui ne sont pas encore passés à .t-meta. */
.jour__detail { display: block; font-size: var(--text-sm); color: var(--c-text-muted); }

/* ── Les quatre natures d'un jour ──────────────────────────────────────────────
   L'ordre de ces règles EST la règle de priorité : à faire < repos < fait <
   aujourd'hui. Un jour fait aujourd'hui garde son pavé plein (il est fait) et
   prend le filet d'accent (il est aujourd'hui) : les deux informations tiennent
   ensemble sans se recouvrir. */

/* À FAIRE — l'état par défaut, déjà porté par .jour ci-dessus. Rien à ajouter :
   le contour du pavé et le filet neutre le disent. */

/* REPOS — ardoise et pointillé. Il doit EXISTER sans crier : c'est du
   programme, pas un trou. D'où un titre plus petit et moins gras qu'une
   séance, mais un pavé aussi visible (5,56:1) que celui d'un jour chargé. */
.jour--repos { border-left-color: var(--c-repos); }
.jour--repos .jour__date { border-style: dashed; border-color: var(--c-repos); }
.jour--repos .jour__abbr,
.jour--repos .jour__num { color: var(--c-repos); }   /* 5,56:1 · 9,07:1 */
.jour--repos .jour__titre {
  font-size: var(--text-base); font-weight: var(--poids-moyen);
  color: var(--c-text-muted);                        /* 7,04:1 · 8,55:1 */
}

/* FAIT — encré. Le plein veut dire fait : c'est la règle n°2, elle ne se
   négocie pas et elle ne dépend d'aucune couleur. */
.jour--fait { border-left-color: var(--c-encre); }
.jour--fait .jour__date { background: var(--c-encre); border-color: var(--c-encre); }
.jour--fait .jour__abbr,
.jour--fait .jour__num { color: var(--c-bg); }       /* 15,10:1 · 16,15:1 */
.jour--fait .jour__abbr { opacity: .8; }

/* AUJOURD'HUI — l'accent, et RIEN QUE le filet + le contour. Le pavé n'est plus
   rempli comme il l'était avant : le remplissage appartient à « fait », et deux
   sens pour une même forme, c'est un système qui ment. */
.jour--aujourdhui { border-left-color: var(--c-accent); }
.jour--aujourdhui .jour__date { border-color: var(--c-accent); border-width: 2px; }

.jauge__reste { display: block; }

/* Le repli du détail d'un jour. <details> natif : l'état plié/déplié est
   annoncé par le lecteur d'écran sans une ligne de JavaScript, et il survit à
   une repeinture complète du DOM. Le triangle du navigateur est CONSERVÉ (d'où
   l'absence de `display:` ici : le changer supprime le marqueur dans Chromium,
   donc sur le WebView Android). */
.jour__plus { margin-top: var(--space-1); }
.jour__voir {
  padding: var(--space-3) 0;            /* ≥ 44 px de cible tactile */
  font-size: var(--text-sm); font-weight: var(--poids-moyen);
  color: var(--c-text-muted); cursor: pointer;
}
.jour__voir::marker { color: var(--c-text-muted); }
.jour__plus[open] > .jour__voir { color: var(--c-text); }
.jour__plus .liste { margin-bottom: var(--space-2); }

/* ── Segments (bascule à deux ou trois choix) ──────────────────────────────── */
.segments {
  display: inline-flex; padding: 3px; gap: 3px;
  background: var(--c-surface-2); border-radius: var(--radius-sm); border: var(--trait);
  /* Sur bureau, `.contenu` est une grille : un inline-flex s'y étire sur toute
     la colonne et le groupe devient une bande grise de 900 px pour trois mots.
     `width: max-content` + `justify-self: start` le ramènent à sa taille. */
  width: max-content; max-width: 100%; justify-self: start;
}
.segments__choix {
  min-height: 38px; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-xs);
  background: transparent; color: var(--c-text-muted);
  font-size: var(--text-sm); font-weight: var(--poids-moyen); cursor: pointer;
}
.segments__choix[aria-pressed="true"] {
  background: var(--c-surface); color: var(--c-text); box-shadow: var(--ombre-flottant);
}

/* ── Message du coach ─────────────────────────────────────────────────────────
   Un encadré sobre, cité en Fraunces. C'est une phrase d'un coach, pas une
   notification système : elle a le droit d'avoir une voix. Jamais plus de
   deux lignes, jamais d'exclamation.                                         */
.mot-coach {
  border-left: var(--regle) solid var(--c-accent);
  padding: var(--space-1) 0 var(--space-1) var(--space-4);
  margin: var(--space-4) 0;
}
.mot-coach p {
  font-family: var(--font-titre); font-variation-settings: var(--fv-titre);
  font-optical-sizing: none; font-size: var(--text-lg); font-weight: var(--poids-normal);
  line-height: var(--leading-titre); margin: 0;
}
.mot-coach__signature {
  display: block; margin-top: var(--space-2);
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-etiquette); color: var(--c-text-muted);
}

/* ── Barre d'onglets (mobile) ──────────────────────────────────────────────── */
.onglets {
  position: fixed; inset: auto 0 0 0; z-index: var(--z-barre);
  display: flex; align-items: stretch;
  height: calc(var(--h-barre-onglets) + var(--inset-bas));
  padding-bottom: var(--inset-bas);
  background: var(--c-surface); border-top: var(--trait);
}
.onglets__lien {
  position: relative;
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; text-decoration: none; color: var(--c-text-muted);
  font-size: var(--text-xs); font-weight: var(--poids-moyen);
  min-height: var(--cible-min);
  /* CE BLOC EST LA CORRECTION DE LA « BANDE GRISE » (constatée 11/08/2026).
     Diagnostic mesuré au pixel sur la capture : la bande valait exactement
     rgb(107,107,107) — un gris parfaitement NEUTRE, alors qu'aucune couleur de
     Robur ne l'est (toutes sont teintées vert ou chaud). #6B6B6B est la valeur
     de `ButtonFace` dans la feuille de style navigateur en `color-scheme: dark`.
     Les onglets sont des <button> dans l'application (des <a> dans les
     maquettes, d'où l'absence du défaut ici) : sans background déclaré, ils
     prenaient le fond de bouton par défaut. Les quatre boutons en `flex:1`
     collés = une bande continue, avec les coins arrondis du UA visibles aux
     deux extrémités seulement — exactement ce que montre la capture.
     Ce n'était donc NI la coquille Capacitor, NI la zone du geste.
     Règle générale : toute classe du système susceptible d'être posée sur un
     <button> neutralise elle-même l'apparence native (cf. .btn, .serie,
     .effort__cran, .segments__choix — tous le font déjà). */
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 0; margin: 0; padding: 0;
  font-family: inherit; cursor: pointer;
}
.onglets__lien svg { width: 22px; height: 22px; }
.onglets__lien[aria-current="page"] { color: var(--c-text); }
/* L'onglet courant est marqué par un filet, pas seulement par une couleur. */
.onglets__lien[aria-current="page"]::before {
  content: ''; position: absolute; top: 6px; left: 50%; transform: translateX(-50%);
  width: 26px; height: var(--regle); background: var(--c-accent);
}

/* ── Rail (desktop) ────────────────────────────────────────────────────────── */
.rail { display: none; }

@media (min-width: 60rem) {
  :root { --gouttiere: var(--space-6); }

  .app {
    grid-template-columns: 15rem 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas: "rail entete" "rail contenu";
    max-width: var(--largeur-app); margin-inline: auto;
    border-inline: var(--trait); min-height: 100dvh;
  }
  .entete { grid-area: entete; }
  .contenu {
    grid-area: contenu; padding-bottom: var(--space-10);
    display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6);
  }
  .contenu--deux { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); align-items: start; }

  .onglets { display: none; }

  /* Le rail porte déjà la marque : l'en-tête ne la répète pas. Un logo affiché
     deux fois sur le même écran n'ajoute rien et vole une ligne au contenu. */
  .entete__marque, .entete__mot { display: none; }
  .rail__pied .profil { display: none; }
  .rail {
    grid-area: rail; display: flex; flex-direction: column; gap: var(--space-1);
    padding: var(--space-5) var(--space-3); border-right: var(--trait);
    background: var(--c-surface);
    position: sticky; top: 0; align-self: start; height: 100dvh;
  }
  .rail__marque {
    display: flex; align-items: center; gap: var(--space-2);
    color: var(--c-accent); padding: 0 var(--space-2) var(--space-5);
  }
  .rail__marque svg { width: 30px; height: 30px; }
  .rail__mot {
    font-family: var(--font-titre); font-variation-settings: var(--fv-titre);
    font-optical-sizing: none; font-weight: var(--poids-gras); font-size: var(--text-xl);
    letter-spacing: var(--tracking-marque); color: var(--c-text);
  }
  .rail__lien {
    display: flex; align-items: center; gap: var(--space-3);
    min-height: var(--cible-min); padding: 0 var(--space-3);
    border-radius: var(--radius-sm); text-decoration: none;
    color: var(--c-text-muted); font-weight: var(--poids-moyen);
    /* même garde que .onglets__lien : cette classe se pose aussi sur un <button> */
    appearance: none; -webkit-appearance: none;
    background: transparent; border: 0; width: 100%; font-family: inherit;
    font-size: var(--text-base); text-align: left; cursor: pointer;
  }
  .rail__lien:hover { background: var(--c-surface-2); color: var(--c-text); }
  .rail__lien[aria-current="page"] {
    background: var(--c-surface-2); color: var(--c-text); font-weight: var(--poids-demi);
    box-shadow: inset var(--regle) 0 0 var(--c-accent);
  }
  .rail__lien svg { width: 22px; height: 22px; flex: none; }
  .rail__pied { margin-top: auto; }

  .titre-ecran { font-size: var(--text-3xl); }
  .frise { height: 120px; }
}

/* ── Courbe (progression) ──────────────────────────────────────────────────────
   Tracé en SVG dans le flux, pas une image : il suit le thème et le zoom.
   Toujours doublé d'un tableau lisible (visible ou .sr-only).                */
.courbe { width: 100%; height: auto; display: block; }
.courbe__grille { stroke: var(--c-border); stroke-width: 1; }
.courbe__ligne { fill: none; stroke: var(--c-accent); stroke-width: 2.5; stroke-linejoin: round; }
.courbe__tendance { fill: none; stroke: var(--c-text-subtle); stroke-width: 1.5; stroke-dasharray: 5 4; }
.courbe__point { fill: var(--c-accent); }
.courbe__axe { fill: var(--c-text-muted); font-size: 11px; font-family: var(--font-texte); }

/* ── Tableau ───────────────────────────────────────────────────────────────── */
.tableau { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.tableau th {
  text-align: left; font-weight: var(--poids-demi); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: var(--tracking-etiquette);
  color: var(--c-text-muted); padding: var(--space-2) var(--space-2) var(--space-2) 0;
  border-bottom: var(--regle) solid var(--c-text);
}
.tableau td { padding: var(--space-3) var(--space-2) var(--space-3) 0; border-bottom: var(--trait); }
.tableau td:last-child, .tableau th:last-child { text-align: right; padding-right: 0; }

/* Garde-fou : sur un écran de 360 px, aucun enfant ne doit imposer sa largeur
   minimale au document. Un débordement horizontal dans une salle de sport, ça
   veut dire un bouton qu'on n'atteint pas. */
.contenu > *, .carte > *, .grille-stats > *, .duo > * { min-width: 0; }

/* ── Divers ────────────────────────────────────────────────────────────────── */
.pile > * + * { margin-top: var(--space-4); }
.rangee { display: flex; align-items: center; gap: var(--space-3); }
.rangee--fin { justify-content: flex-end; }
.pousse { margin-left: auto; }
.muet { color: var(--c-text-muted); }
.tenu { font-size: var(--text-sm); }
.hr { border: 0; border-top: var(--trait); margin: var(--space-5) 0; }
