/* ============================================================
   Direction visuelle : affiche de salle de sport / brutalisme
   sombre. Anton condensé pour les titres, Chivo pour le corps,
   JetBrains Mono pour les quantités et métadonnées.
   Parti pris assumé : une seule ambiance, sombre, quel que soit
   le thème du navigateur — toutes les couleurs sont donc peintes
   explicitement.
   ============================================================ */
:root{
  color-scheme:dark;
  --bg:#0c0b09;
  --bg-2:#141310;
  --line:#2a2822;
  --line-hi:#3c392f;
  --ink:#f2efe6;
  --ink-dim:#8d897b;
  --acid:#d9ff3d;          /* alimentaire, et accent d'action generique */
  --fire:#ff5c1f;          /* sport */
  --cool:#5ec8ff;          /* recettes */
  --danger:#ff3b4e;
  --grain:.035;
  /* Détachement d'une carte sans trait : une ombre basse et large, qui se
     voit à peine mais qui décolle le bloc du fond. */
  --ombre:0 1px 2px rgba(0,0,0,.35), 0 4px 14px rgba(0,0,0,.22);

  /* Échelle typographique. Huit échelons de rapport ~1,22 : t3 est le
     corps courant, t2 l'étiquette, t1 la mention. Au-delà de t5, ce sont
     des titres. Toute taille nouvelle doit rejoindre un échelon — sans
     quoi on retombe à dix-neuf tailles qui se ressemblent sans s'accorder. */
  --t1:9px;  --t2:11px;  --t3:13px;  --t4:15px;
  --t5:18px;  --t6:22px;  --t7:28px;  --t8:40px;
  /* Trois rayons, proportionnés à ce qu'ils arrondissent : le petit pour
     ce qu'on touche, le courant pour les cartes, le grand pour les
     fenêtres. Les pastilles gardent leur 99px. */
  --r-sm:6px;
  --r:10px;
  --r-lg:16px;

  /* Ce qui dépend du sens du thème. En sombre, un voile clair éclaircit ;
     en clair, il devra assombrir — d'où le jeton plutôt que la valeur.
     Le thème clair les redéfinit tous, et rien d'autre. */
  --saisie:#000;
  --ink-2:#cfcbbe;
  --voile-1:rgba(255,255,255,.03);
  --voile-2:rgba(255,255,255,.06);
  --voile-3:rgba(255,255,255,.09);
  --bouton-knob:#fff;
  --voile-fenetre:rgba(12,11,9,.78);
  --ombre:0 1px 2px rgba(0,0,0,.35), 0 4px 14px rgba(0,0,0,.22);
  --ombre-haute:0 2px 4px rgba(0,0,0,.35), 0 10px 26px rgba(0,0,0,.3);
  --ombre-fenetre:0 30px 80px rgba(0,0,0,.65)}
/* ---------- Thème clair ----------
   Seuls les jetons changent ; aucune règle de composant n'est dupliquée.
   C'est ce qui rend le thème tenable : une couleur oubliée ici se voit
   tout de suite, alors qu'une règle dupliquée se désynchronise en
   silence.

   L'acide et l'orange ne bougent pas — ce sont les couleurs de
   l'application, pas du thème. Seules leurs déclinaisons « texte »
   s'assombrissent : du vert acide sur du blanc ne se lit pas. */
@media (prefers-color-scheme:light){
  :root:not([data-theme="sombre"]){
    color-scheme:light;
    --bg:#faf8f3;
    --bg-2:#ffffff;
    --line:#e3ded2;
    --line-hi:#cdc6b6;
    --ink:#1a1814;
    --ink-dim:#6b6558;
    --ink-2:#403a30;
    --acid:#5c7a00;          /* l'acide, assombri pour rester lisible */
    --fire:#d4400a;
    --cool:#0a72a8;
    --danger:#c81230;
    --grain:.02;
    --saisie:#ffffff;
    --voile-1:rgba(0,0,0,.025);
    --voile-2:rgba(0,0,0,.05);
    --voile-3:rgba(0,0,0,.08);
    --bouton-knob:#ffffff;
    --voile-fenetre:rgba(40,36,30,.42);
    --ombre:0 1px 2px rgba(60,52,38,.10), 0 4px 14px rgba(60,52,38,.07);
    --ombre-haute:0 2px 4px rgba(60,52,38,.12), 0 10px 26px rgba(60,52,38,.12);
    --ombre-fenetre:0 30px 80px rgba(40,36,30,.30);
  }
}

/* Le choix explicite l'emporte sur le réglage de l'appareil, dans les
   deux sens : c'est pour cela que la même palette est écrite deux fois
   plutôt que placée dans la seule requête de média. */
:root[data-theme="clair"]{
  color-scheme:light;
  --bg:#faf8f3;
  --bg-2:#ffffff;
  --line:#e3ded2;
  --line-hi:#cdc6b6;
  --ink:#1a1814;
  --ink-dim:#6b6558;
  --ink-2:#403a30;
  --acid:#5c7a00;
  --fire:#d4400a;
  --cool:#0a72a8;
  --danger:#c81230;
  --grain:.02;
  --saisie:#ffffff;
  --voile-1:rgba(0,0,0,.025);
  --voile-2:rgba(0,0,0,.05);
  --voile-3:rgba(0,0,0,.08);
  --bouton-knob:#ffffff;
  --voile-fenetre:rgba(40,36,30,.42);
  --ombre:0 1px 2px rgba(60,52,38,.10), 0 4px 14px rgba(60,52,38,.07);
  --ombre-haute:0 2px 4px rgba(60,52,38,.12), 0 10px 26px rgba(60,52,38,.12);
  --ombre-fenetre:0 30px 80px rgba(40,36,30,.30);
}

/* En clair, le texte posé SUR un accent doit s'inverser : l'acide
   assombri porte du blanc, là où l'acide vif portait du noir. */
:root[data-theme="clair"] ::selection,
:root[data-theme="clair"] .toast,
:root[data-theme="clair"] .chip-filtre.on,
:root[data-theme="clair"] .mini.on,
:root[data-theme="clair"] .mini.retour:hover,
:root[data-theme="clair"] .mini.valider:hover,
:root[data-theme="clair"] .mini.faite:hover,
:root[data-theme="clair"] .tbtn.faite:hover,
:root[data-theme="clair"] .li.done .ck,
:root[data-theme="clair"] .jour-sport:hover,
:root[data-theme="clair"] .focus-jour.on,
:root[data-theme="clair"] .tabs-groupe.sport .tab.on,
:root[data-theme="clair"] .chip-filtre.regime.on,
:root[data-theme="clair"] .stats-profil[open] .stats-modifier,
:root[data-theme="clair"] .focus.mode-jour .focus-jour.on{color:#fff}
@media (prefers-color-scheme:light){
  :root:not([data-theme="sombre"]) ::selection,
  :root:not([data-theme="sombre"]) .toast,
  :root:not([data-theme="sombre"]) .chip-filtre.on,
  :root:not([data-theme="sombre"]) .mini.on,
  :root:not([data-theme="sombre"]) .mini.retour:hover,
  :root:not([data-theme="sombre"]) .mini.valider:hover,
  :root:not([data-theme="sombre"]) .mini.faite:hover,
  :root:not([data-theme="sombre"]) .tbtn.faite:hover,
  :root:not([data-theme="sombre"]) .li.done .ck,
  :root:not([data-theme="sombre"]) .jour-sport:hover,
  :root:not([data-theme="sombre"]) .focus-jour.on,
  :root:not([data-theme="sombre"]) .tabs-groupe.sport .tab.on,
  :root:not([data-theme="sombre"]) .chip-filtre.regime.on,
  :root:not([data-theme="sombre"]) .stats-profil[open] .stats-modifier,
  :root:not([data-theme="sombre"]) .focus.mode-jour .focus-jour.on{color:#fff}
}

/* L'interrupteur lui-même : deux pictogrammes au trait, celui qui montre
   le thème vers lequel on va. */
.theme-btn{
  display:inline-grid;place-items:center;width:30px;height:30px;flex:none;
  border:1px solid var(--line-hi);border-radius:99px;background:none;
  color:var(--ink-dim);cursor:pointer;transition:color .15s,border-color .15s;
}
.theme-btn:hover{color:var(--ink);border-color:var(--ink-dim)}
.theme-btn svg{width:15px;height:15px}
.theme-btn .vers-clair{display:none}
:root[data-theme="clair"] .theme-btn .vers-clair{display:block}
:root[data-theme="clair"] .theme-btn .vers-sombre{display:none}
@media (prefers-color-scheme:light){
  :root:not([data-theme="sombre"]) .theme-btn .vers-clair{display:block}
  :root:not([data-theme="sombre"]) .theme-btn .vers-sombre{display:none}
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:'Chivo',ui-sans-serif,system-ui,sans-serif;
  font-size:var(--t4);line-height:1.5;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden}
/* Texture : grain très discret */
body::before{
  content:'';position:fixed;inset:0;pointer-events:none;z-index:999;
  opacity:var(--grain);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E")}
button,input,textarea,select{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:none}
::selection{background:var(--acid);color:#000}
:focus-visible{outline:2px solid var(--acid);outline-offset:2px}
/* L'attribut hidden doit gagner contre nos propres display:flex, sinon un
   contrôle masqué selon le profil resterait affiché. */
[hidden]{display:none!important}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* ---------- HEADER ---------- */
header{
  border-bottom:1px solid var(--line);
  padding:10px 24px 0;
  position:relative;
  background:
    radial-gradient(900px 300px at 10% -40%, rgba(217,255,61,.10), transparent 70%),
    radial-gradient(600px 260px at 90% -60%, rgba(255,92,31,.10), transparent 70%)}
.wrap{max-width:1400px;margin:0 auto}
.brand{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px}
h1{
  font-family:'Anton',Impact,'Arial Narrow',sans-serif;font-weight:400;
  font-size:clamp(19px,2.1vw,26px);line-height:1;letter-spacing:.01em;
  margin:0;text-transform:uppercase;white-space:nowrap}
h1 em{font-style:normal;color:var(--acid)}
h1 em + em{color:var(--fire)}
h1 .ghost{color:transparent;-webkit-text-stroke:1px var(--line-hi)}
.sub{
  display:flex;flex-direction:column;align-items:flex-start;gap:4px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);letter-spacing:.12em;
  color:var(--ink-dim)}
.sub-sport{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.sub-label{white-space:nowrap}
.sub-stat{color:var(--ink-dim)}
.sub b{color:var(--fire);font-weight:600}
.toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-left:auto}
.tbtn{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  border:1px solid var(--line-hi);padding:6px 11px;border-radius:var(--r-sm);color:var(--ink-dim);
  transition:.15s}
.tbtn:hover{color:var(--bg);background:var(--acid);border-color:var(--acid)}
.tbtn.warn:hover{background:var(--danger);border-color:var(--danger);color:#fff}

/* ---------- TABS ---------- */
nav.tabs{display:flex;align-items:flex-end;gap:30px;margin-top:12px;overflow-x:auto;scrollbar-width:none}
nav.tabs::-webkit-scrollbar{display:none}
.tab{
  font-family:'Anton',Impact,sans-serif;font-size:var(--t3);
  padding:8px 14px;border:1px solid var(--line);border-bottom:none;color:var(--ink-dim);
  background:var(--bg-2);white-space:nowrap;position:relative;top:1px;
  display:inline-flex;align-items:center;gap:7px}
.tab+.tab{border-left:none}

/* Le pictogramme de l'onglet. Il n'apprend rien à qui lit l'étiquette —
   son rôle est le repérage périphérique : retrouver « Courses » du coin
   de l'œil, sans lire. D'où le retrait : présent, jamais premier. Il
   hérite de la couleur, donc prend l'accent du domaine sans qu'on ait à
   le lui dire, et devient net sur l'onglet actif. */
.tab-picto{width:15px;height:15px;flex:none;opacity:.5;transition:opacity .15s}
.tab:hover .tab-picto{opacity:.85}
.tab.on .tab-picto{opacity:1}

/* Sous 700 px, la place manque : l'étiquette prime, le signe s'efface. */
@media (max-width:700px){
  .tab-picto{display:none}
}
.tab:hover{color:var(--ink)}
.tab.on{color:var(--bg);background:var(--acid);border-color:var(--acid)}
.tab .n{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);opacity:.6;margin-left:7px}

main{max-width:1400px;margin:0 auto;padding:16px 24px 40px}
section[hidden]{display:none}
.sec-head{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 12px;padding-bottom:8px;border-bottom:1px dashed var(--line)}
.sec-head h2{font-family:'Anton',Impact,sans-serif;font-weight:400;font-size:var(--t6);margin:0}
.sec-head p{margin:0;color:var(--ink-dim);font-size:var(--t3);max-width:70ch}
/* Le bouton d'aide part à droite ; le reste se serre à gauche. */
.sec-head .aide-btn{margin-left:auto}

/* ---------- SEMAINE ---------- */
.week{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}
/* Les angles arrondis découpent ce qu'ils contiennent : sans cela, le
   filet du dernier repas dépasserait du coin de la carte. */
.day{overflow:hidden;
  border-radius:var(--r);background:var(--bg-2);
  display:flex;flex-direction:column;
  animation:rise .45s cubic-bezier(.2,.7,.3,1) both;box-shadow:var(--ombre)}
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.day-head{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:12px 14px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,var(--voile-1),transparent)}
.day-head h3{font-family:'Anton',Impact,sans-serif;font-weight:400;font-size:var(--t6);margin:0}
.day.sport .day-head h3{color:var(--fire)}
.badge{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);letter-spacing:.12em;text-transform:uppercase;
  border:1px solid currentColor;padding:3px 7px;border-radius:99px;color:var(--ink-dim);transition:.15s}
.badge.sport{color:var(--fire);background:rgba(255,92,31,.10)}
.badge:hover{filter:brightness(1.4)}
.meal{padding:11px 14px;border-bottom:1px solid var(--line)}
.meal:last-child{border-bottom:none}
.meal-t{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-dim);display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:8px}
.add{color:var(--acid);font-size:var(--t4);line-height:1;padding:2px 5px;border:1px solid transparent;border-radius:var(--r-sm)}
.add:hover{border-color:var(--acid)}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{
  display:inline-flex;align-items:center;gap:7px;max-width:100%;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:4px 4px 4px 9px;font-size:var(--t3);background:var(--voile-1);
  transition:.15s}
.chip:hover{border-color:var(--ink-dim);background:var(--voile-2)}
.chip.recipe{border-color:rgba(94,200,255,.45);color:var(--cool)}
.chip.recipe .chip-txt{cursor:pointer}
.chip.excluded{opacity:.45;border-color:var(--danger);text-decoration:line-through}
.chip.excluded::before{content:'\26A0';color:var(--danger);font-size:var(--t2);text-decoration:none}
.chip .x{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);line-height:1;color:var(--ink-dim);
  padding:2px 5px;border-radius:var(--r-sm)}
.chip .x:hover{background:var(--danger);color:#fff}
.chip-in{
  background:var(--saisie);border:1px solid var(--acid);border-radius:var(--r-sm);
  padding:5px 8px;font-size:var(--t3);width:100%;outline:none;margin-top:6px}

/* ---------- ALIMENTS ---------- */
.food-tools{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:16px}
.field{
  display:flex;align-items:center;gap:8px;border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:8px 12px;background:var(--bg-2)}
.field input,.field select{background:none;border:none;outline:none;width:230px;font-size:var(--t4)}
.field select{width:auto;color:var(--ink)}
.field select option{background:var(--bg-2)}
.field span{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim);white-space:nowrap}
.table-scroll{overflow-x:auto}
table.foods{width:100%;border-collapse:collapse;font-size:var(--t4);min-width:640px}
table.foods th{
  font-size:var(--t3);font-weight:600;
  color:var(--ink-dim);text-align:left;padding:10px;border-bottom:1px solid var(--line-hi)}
/* Précision d'unité dans un en-tête : plus discrète que l'intitulé, et
   sans capitales espacées, pour ne pas peser autant que lui. */
table.foods th .th-note{margin-left:6px;letter-spacing:.04em;text-transform:none;opacity:.7}
table.foods td{padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
table.foods tr:hover td{background:var(--voile-1)}
.food-name{font-weight:600}
tr.ex .food-name{text-decoration:line-through;color:var(--ink-dim)}
.count{font-family:'JetBrains Mono',ui-monospace,monospace;color:var(--acid);font-size:var(--t3);font-variant-numeric:tabular-nums}
.count.zero{color:var(--ink-dim)}
/* Usage hors de la semaine affichée : le badge tient toute la colonne et
   ne se coupe pas, c'est un avertissement avant renommage ou suppression. */
/* ---------- Barres des catalogues ----------
   Chercher et ajouter sont deux gestes différents : ils partageaient une
   rangée de champs identiques, si bien qu'on ne savait pas lequel on
   était en train de faire. La recherche a sa forme propre, l'ajout est un
   formulaire encadré avec son bouton. */
.cat-barre{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:10px}
.recherche{position:relative;flex:1 1 260px;min-width:0;display:flex;align-items:center}
.recherche input{
  width:100%;background:var(--bg-2);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:9px 32px 9px 30px;font-size:var(--t4);color:var(--ink);outline:none}
.recherche input:focus{border-color:var(--acid)}
.recherche input::placeholder{color:var(--ink-dim)}
/* La loupe est dessinée en fond : pas d'icône à charger, pas de nœud en plus. */
.recherche::before{
  content:'';position:absolute;left:11px;width:10px;height:10px;
  border:1.5px solid var(--ink-dim);border-radius:50%;pointer-events:none}
.recherche::after{
  content:'';position:absolute;left:20px;top:calc(50% + 2px);width:5px;height:1.5px;
  background:var(--ink-dim);transform:rotate(45deg);pointer-events:none}
.recherche-x{
  position:absolute;right:6px;width:20px;height:20px;line-height:1;
  border:none;background:none;color:var(--ink-dim);font-size:var(--t5);cursor:pointer;
  border-radius:var(--r-sm)}
.recherche-x:hover{background:var(--line);color:var(--ink)}

.chip-filtre{
  border:1px solid var(--fire);border-radius:var(--r);background:none;
  color:var(--fire);padding:7px 11px;cursor:pointer;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  transition:.15s}
.chip-filtre:hover{background:rgba(255,92,31,.10)}
.chip-filtre.on{background:var(--fire);color:#000;font-weight:600}
.cat-compte{
  margin-left:auto;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}
.cat-compte.filtre-actif{color:var(--acid)}

.cat-ajout{
  display:flex;flex-wrap:wrap;align-items:flex-end;gap:10px;margin-bottom:14px;
  border-radius:var(--r);background:var(--bg-2);padding:12px 14px;box-shadow:var(--ombre)}
.cat-ajout-t{
  font-size:var(--t3);font-weight:600;
  color:var(--ink-dim);
  align-self:center}
.cat-ajout .field{flex:1 1 170px}
/* min-width:0 : sans lui, un champ flex refuse de descendre sous la largeur
   de son contenu et déborde de la rangée. */
.cat-ajout .field input,.cat-ajout .field select{width:100%;min-width:0}
/* Le champ des calories en porte deux, le nombre et le libellé de portion. */
.cat-ajout .champ-kcal{flex:1 1 240px}
.cat-ajout .field input[type=number]{flex:0 0 62px;width:62px}

/* Proposition en attente : même famille que « ailleurs », autre message. */
.tag-attente{color:var(--fire);border-color:var(--fire);background:rgba(255,92,31,.08)}
.mini.valider{border-color:var(--acid);color:var(--acid)}
/* Retour en arrière : même famille que « valider », même accent. */
.mini.retour{border-color:var(--acid);color:var(--acid);margin-left:6px}
.mini.retour:hover{background:var(--acid);color:#000}
.mini.valider:hover{background:var(--acid);color:#000}

/* Popularité : une information, pas un avertissement — donc ni l'orange
   des propositions ni le rouge du danger. Le nombre porte la lecture ; à
   partir de trois comptes, il prend l'accent du domaine. */
.popularite{white-space:nowrap}
.popularite-vide{color:var(--ink-dim);opacity:.45}
.tag-pop{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-dim)}
.tag-pop b{font-size:var(--t4);color:var(--ink);font-weight:600;letter-spacing:0;margin-right:3px}
.tag-pop.forte b{color:var(--acid)}
.domaine-sport .tag-pop.forte b{color:var(--fire)}

/* Catalogues en lecture seule : renommer, exclure et supprimer sont
   réservés à l'admin. Pour un utilisateur, la colonne d'actions n'aurait
   plus rien à montrer — elle disparaît en entier, en-tête compris, et sa
   largeur revient aux colonnes qui portent de l'information. */
table.foods.sans-actions td:last-child,
table.foods.sans-actions th:last-child{display:none}
.slots{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim);letter-spacing:.06em}
.tag-shop{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);letter-spacing:.1em;text-transform:uppercase;
  border:1px solid var(--line-hi);color:var(--ink-dim);padding:2px 5px;border-radius:99px;margin-left:8px}
.acts{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap}
.mini{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  border:1px solid var(--line-hi);padding:5px 9px;border-radius:var(--r-sm);color:var(--ink-dim);transition:.15s}
.mini:hover{color:var(--bg);background:var(--ink)}
.mini.dngr:hover{background:var(--danger);color:#fff;border-color:var(--danger)}
.mini.on{background:var(--fire);color:#000;border-color:var(--fire)}
.rename-in{background:var(--saisie);border:1px solid var(--acid);border-radius:var(--r-sm);padding:5px 8px;font-size:var(--t4);outline:none;width:100%}

/* ---------- RECETTES ---------- */
.recipes{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(330px,1fr))}
.rec{border-radius:var(--r);background:var(--bg-2);padding:16px 18px;position:relative;box-shadow:var(--ombre)}
.rec.flash{border-color:var(--cool);box-shadow:0 0 0 1px var(--cool) inset}
.rec h3{font-family:'Anton',Impact,sans-serif;font-weight:400;font-size:var(--t6);margin:0 70px 2px 0;color:var(--cool)}
.rec .tag{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim);display:block;margin-bottom:10px}
.rec p{margin:0;font-size:var(--t4);color:var(--ink-2);white-space:pre-wrap;max-width:60ch}
.rec .acts{position:absolute;top:14px;right:14px}
[contenteditable]:focus{outline:1px solid var(--acid);outline-offset:3px;border-radius:var(--r)}

/* ---------- COURSES ---------- */
.shop{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}
.cat{overflow:hidden;border-radius:var(--r);background:var(--bg-2);display:flex;flex-direction:column;box-shadow:var(--ombre)}
.cat h3{
  font-family:'Anton',Impact,sans-serif;font-weight:400;font-size:var(--t5);
  margin:0;padding:12px 14px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;gap:10px}
.cat h3 .n{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim);letter-spacing:0;font-variant-numeric:tabular-nums}
.li{display:flex;align-items:center;gap:10px;padding:8px 14px;border-bottom:1px solid var(--line)}
.li:last-of-type{border-bottom:none}
.ck{
  width:16px;height:16px;flex:0 0 16px;border:1px solid var(--line-hi);border-radius:var(--r-sm);
  display:grid;place-items:center;font-size:var(--t2);color:transparent;cursor:pointer}
.li.done .ck{background:var(--acid);border-color:var(--acid);color:#000}
.li.done .li-n{color:var(--ink-dim);text-decoration:line-through}
.li-n{flex:1;font-size:var(--t4);text-align:left;cursor:pointer}
.li-q{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);color:var(--acid);font-variant-numeric:tabular-nums}
.li.done .li-q{color:var(--ink-dim)}
.cat form{display:flex;gap:6px;padding:10px 14px;border-top:1px dashed var(--line);margin-top:auto}
.cat form input{background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);padding:6px 8px;font-size:var(--t3);outline:none;min-width:0}
.cat form input:focus{border-color:var(--acid)}
.cat form input.n{flex:1}
.cat form input.q{width:78px;font-family:'JetBrains Mono',ui-monospace,monospace}

.foot{
  margin-top:34px;padding:14px 16px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--bg-2);
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim);
  display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap}
.foot .conseil{color:var(--ink-dim);max-width:70ch}
.foot .conseil::before{content:'Conseil du jour · ';color:var(--acid);font-size:var(--t1)}
.foot #saveState{color:var(--acid);opacity:.75}
.foot #saveState:empty{display:none}
/* Client et API désaccordés : ce n'est pas une information de plus, c'est
   un avertissement — il prend la couleur des alertes. */
.foot #saveState.desync{color:var(--danger);opacity:1;font-weight:600}
/* Masquage par visibility, pas par un décalage en pourcentage : vide, la
   pastille ne mesure que ses marges intérieures, et translateY(160%) la
   descendait de 32 px depuis bottom:26px — laissant 14 px d'acide visibles
   en permanence au bas de la page. */
.toast{
  position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(10px);
  background:var(--acid);color:#000;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);
  padding:10px 18px;border-radius:var(--r);z-index:1300;
  max-width:90vw;text-align:center;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:transform .3s cubic-bezier(.2,.8,.3,1), opacity .2s linear, visibility .3s}
.toast.show{transform:translateX(-50%) translateY(0);opacity:1;visibility:visible}
.toast.err{background:var(--danger);color:#fff}
.empty{color:var(--ink-dim);font-size:var(--t3);font-style:italic}

/* Les marges latérales valent à toute largeur : en paysage sur un
   téléphone à encoche, elle mord sur le côté et la fenêtre dépasse
   620 px — le bloc mobile plus bas ne s'appliquerait pas. */
header,main{
  padding-left:max(24px, env(safe-area-inset-left));
  padding-right:max(24px, env(safe-area-inset-right));
}

/* ---------- Zone sûre ----------
   En application posée sur l'écran d'accueil, la page occupe tout
   l'écran : sans ces marges, le pied passe sous la barre d'accueil de
   l'iPhone et les bords se glissent sous l'encoche en paysage.

   max() plutôt que la seule variable : sur un appareil sans encoche,
   env() vaut zéro et c'est la marge d'origine qui s'applique. */
@media (max-width:620px){
  header{
    padding-top:max(9px, env(safe-area-inset-top));
    padding-left:max(12px, env(safe-area-inset-left));
    padding-right:max(12px, env(safe-area-inset-right));
  }
  main{
    padding-left:max(12px, env(safe-area-inset-left));
    padding-right:max(12px, env(safe-area-inset-right));
    /* De quoi défiler jusqu'au bout sans que la barre du bas recouvre la
       dernière carte : sa hauteur, plus la zone sûre. */
    padding-bottom:calc(76px + env(safe-area-inset-bottom));
  }
  .gate{
    padding-top:max(10px, env(safe-area-inset-top));
    padding-bottom:max(10px, env(safe-area-inset-bottom));
  }
  .focus.mode-jour{padding-bottom:max(14px, env(safe-area-inset-bottom))}
  .focus-corps{padding-bottom:calc(16px + env(safe-area-inset-bottom))}
  .toast{bottom:calc(84px + env(safe-area-inset-bottom))}
}

/* ---------- Navigation du pouce ----------
   Toute la navigation vivait en haut de l'écran, hors d'atteinte du
   pouce sur un téléphone moderne. Elle descend, et l'en-tête s'allège
   d'autant : plus de sur-titres de groupes, plus de défilement
   horizontal à dix onglets. */
.barre-bas{display:none}

@media (max-width:620px){
  .barre-bas:not([hidden]){
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:900;
    background:var(--bg-2);border-top:1px solid var(--line);
    padding:6px max(4px, env(safe-area-inset-left)) calc(6px + env(safe-area-inset-bottom)) max(4px, env(safe-area-inset-right));
    box-shadow:0 -2px 14px rgba(0,0,0,.18);
  }
  .barre-item{
    flex:1 1 0;min-width:0;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    /* 48 px : une cible qu'on atteint sans viser. */
    min-height:48px;padding:4px 2px;border:none;background:none;
    color:var(--ink-dim);cursor:pointer;border-radius:var(--r-sm);
    transition:color .15s;
  }
  .barre-picto{width:21px;height:21px;flex:none}
  .barre-plus-signe{
    display:grid;place-items:center;font-size:var(--t5);line-height:1;
  }
  .barre-txt{
    font-size:var(--t1);letter-spacing:.02em;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;
  }
  .barre-item.on{color:var(--acid)}
  /* L'onglet ouvert porte un trait au-dessus : la couleur seule se
     distingue mal d'un simple survol. */
  .barre-item.on::before{
    content:'';position:absolute;top:0;width:26px;height:2px;
    background:var(--acid);border-radius:0 0 2px 2px;
  }
  .barre-item{position:relative}
  .barre-item:active{background:var(--voile-2)}

  /* La vue sans distraction prend tout l'écran : la barre s'efface. */
  body.focus-ouvert .barre-bas:not([hidden]){display:none}

  /* La navigation du haut a perdu sa raison d'être. */
  nav.tabs{display:none}

  /* La ligne « Sport » doublait l'onglet Séances, à cinquante pixels par
     écran. Les jours s'ouvrent depuis le planning, à un geste d'ici. */
  .sub{display:none}
}

/* Les onglets qui ne tiennent pas dans la barre. Une feuille qui monte du
   bas, là d'où vient le doigt qui l'a demandée. */
.feuille-voile{
  position:fixed;inset:0;z-index:1100;
  background:var(--voile-fenetre);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  display:flex;align-items:flex-end;
}
.feuille-voile[hidden]{display:none}
.feuille{
  width:100%;background:var(--bg-2);
  border-radius:var(--r-lg) var(--r-lg) 0 0;
  padding:10px 14px calc(18px + env(safe-area-inset-bottom));
  box-shadow:var(--ombre-fenetre);
  animation:monte .22s cubic-bezier(.2,.8,.3,1) both;
  max-height:80vh;overflow-y:auto;
}
@keyframes monte{from{transform:translateY(100%)}to{transform:none}}
.feuille-poignee{
  width:38px;height:4px;border-radius:99px;background:var(--line-hi);
  margin:0 auto 14px;
}
.feuille-liste{display:flex;flex-direction:column;gap:2px}
.feuille-item{
  display:flex;align-items:center;gap:14px;
  padding:14px 10px;border:none;background:none;border-radius:var(--r-sm);
  color:var(--ink);font-size:var(--t4);text-align:left;cursor:pointer;width:100%;
}
.feuille-item:active{background:var(--voile-2)}
.feuille-picto{width:20px;height:20px;flex:none;color:var(--ink-dim)}
.feuille-item.on{color:var(--acid)}
.feuille-item.on .feuille-picto{color:var(--acid)}
.feuille-nom{flex:1 1 auto}
.feuille-n{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);
}

@media (prefers-reduced-motion:reduce){
  .feuille{animation:none}
}

/* ---------- Réglages de notification ---------- */
.notif-bloc{margin-bottom:18px;padding-bottom:16px;border-bottom:1px dashed var(--line)}
.notif-bloc .meal-t{margin-bottom:8px}
.notif-etat{margin:0 0 10px;font-size:var(--t3);color:var(--ink-dim);line-height:1.5}
.notif-cases{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}
.notif-cases .regime-case{align-items:flex-start;text-align:left}

/* ---------- États vides ----------
   Un écran vide est le moment où l'on ne sait pas quoi faire. Il dit donc
   ce qu'il n'y a pas, pourquoi, et le geste qui y remédie — centré, avec
   de l'air, pour qu'on comprenne que le vide est voulu et non une panne. */
.vide{
  display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:34px 20px;text-align:center;color:var(--ink-dim);
}
.vide-signe{width:40px;height:40px;color:var(--line-hi);margin-bottom:2px}
.vide-alim  .vide-signe{color:rgba(217,255,61,.45)}
.vide-sport .vide-signe{color:rgba(255,92,31,.45)}
.vide-titre{margin:0;font-size:var(--t4);font-weight:600;color:var(--ink)}
.vide-texte{margin:0;font-size:var(--t3);max-width:46ch;line-height:1.5}
.vide .tbtn{margin-top:6px}

@media (max-width:620px){
  .vide{padding:26px 14px}
}

/* ---------- La réponse au geste ----------
   Épuré au repos, ludique à l'action : rien ne bouge tant qu'on ne touche
   à rien. Sept réponses, sur les gestes qu'on répète le plus. */

/* 1. Ce qui vient d'apparaître. Marqué par le script, qui compare le
      rendu au précédent — sans quoi les soixante puces de la semaine
      s'animeraient à chaque clic. */
@keyframes surgit{
  from{opacity:0;transform:scale(.88)}
  60%{transform:scale(1.03)}
  to{opacity:1;transform:none}
}
.neuf{animation:surgit .26s cubic-bezier(.2,.8,.3,1) both}

/* 2. L'enfoncement. Un bouton qui ne bouge pas sous le doigt laisse
      douter que le clic ait porté — surtout sur un écran tactile. */
.tbtn:active,.mini:active,.tab:active,.add:active,.ck:active,
.chip-filtre:active,.aide-btn:active,.actualiser:active,.menu-item:active,
.jour-sport:active,.focus-jour:active,.plat-btn:active,.x:active{
  transform:scale(.96);
}
.tbtn,.mini,.tab,.add,.ck,.chip-filtre,.aide-btn,.menu-item,
.jour-sport,.focus-jour,.plat-btn,.x{transition:transform .08s ease-out,background .15s,color .15s,border-color .15s}

/* 3. Les cartes se soulèvent au survol. Ce sont des objets qu'on
      manipule — la carte le dit avant qu'on clique. */
.rec,.modele,.modele-admin{
  transition:transform .18s cubic-bezier(.2,.8,.3,1), box-shadow .18s;
}
.rec:hover,.modele:hover,.modele-admin:hover{
  transform:translateY(-2px);
  box-shadow:var(--ombre-haute);
}

/* 4. La section entre au changement d'onglet : on voit que le clic a
      porté, même quand les deux onglets se ressemblent. */
@keyframes entreDoux{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.entre{animation:entreDoux .2s ease-out both}
/* Au balayage, la section vient du côté vers lequel on a poussé. */
@keyframes entreDroite{from{opacity:0;transform:translateX(26px)}to{opacity:1;transform:none}}
@keyframes entreGauche{from{opacity:0;transform:translateX(-26px)}to{opacity:1;transform:none}}
.entre-droite{animation:entreDroite .22s cubic-bezier(.2,.8,.3,1) both}
.entre-gauche{animation:entreGauche .22s cubic-bezier(.2,.8,.3,1) both}

/* La sortie. Plus brève que l'entrée — ce qui s'en va n'a pas besoin
   d'être regardé — et dans le même sens que le geste : au balayage vers
   la gauche, l'ancienne section sort par la gauche pendant que la
   nouvelle arrive par la droite.
   .12s doit rester d'accord avec DUREE_SORTIE dans le script. */
@keyframes sortGauche{from{opacity:1;transform:none}to{opacity:0;transform:translateX(-22px)}}
@keyframes sortDroite{from{opacity:1;transform:none}to{opacity:0;transform:translateX(22px)}}
@keyframes sortDoux{from{opacity:1;transform:none}to{opacity:0;transform:translateY(-5px)}}
.sort-gauche{animation:sortGauche .12s ease-in both}
.sort-droite{animation:sortDroite .12s ease-in both}
.sort{animation:sortDoux .12s ease-in both}

/* 5. Une course cochée. La case marque le coup, la ligne s'efface
      doucement au lieu de changer d'état d'un bloc. */
@keyframes coche{0%{transform:scale(1)}45%{transform:scale(1.28)}100%{transform:scale(1)}}
.li.done .ck{animation:coche .3s cubic-bezier(.2,.8,.3,1)}
.li{transition:opacity .2s}

/* 6. Un plat armé attend qu'on lui désigne un repas : il respire, pour
      qu'on n'oublie pas qu'un geste est en cours. */
@keyframes respire{0%,100%{opacity:1}50%{opacity:.55}}
.plat.arme{animation:respire 1.6s ease-in-out infinite}

/* Rien de tout cela ne s'impose : le système a le dernier mot. */
@media (prefers-reduced-motion:reduce){
  .neuf,.entre,.entre-droite,.entre-gauche,
  .sort,.sort-gauche,.sort-droite,.li.done .ck,.plat.arme{animation:none}
  .tbtn:active,.mini:active,.tab:active,.add:active,.ck:active,
  .chip-filtre:active,.aide-btn:active,.actualiser:active,.menu-item:active,
  .jour-sport:active,.focus-jour:active,.plat-btn:active,.x:active{transform:none}
  .rec:hover,.modele:hover,.modele-admin:hover{transform:none}
  .day{animation:none}
}

/* ---------- ÉTATS GLOBAUX ---------- */
/* Écran de saisie du mot de passe et écran d'erreur de connexion. */
/* Une fenêtre se pose sur un voile sombre et flouté, à travers lequel la
   page reste devinable : on n'a pas changé d'écran, on a ouvert quelque
   chose par-dessus — et cliquer le voile le referme. La connexion fait
   exception : rien à deviner derrière, rien à congédier. */
.gate{
  position:fixed;inset:0;z-index:1200;background:var(--voile-fenetre);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  display:grid;place-items:center;padding:24px}
.gate#gate{background:var(--bg);backdrop-filter:none;-webkit-backdrop-filter:none}
.gate[hidden]{display:none}
.gate-box{
  width:min(420px,100%);border:1px solid var(--line-hi);border-radius:var(--r-lg);
  background:var(--bg-2);padding:26px 24px}
.gate-box h2{font-family:'Anton',Impact,sans-serif;font-weight:400;font-size:var(--t7);margin:0 0 6px}
.gate-box p{margin:0 0 18px;font-size:var(--t3);color:var(--ink-dim);white-space:pre-wrap}
/* Pas de règle générique sur « .gate-box form » ni sur ses champs : elle
   datait de la fenêtre de connexion, où le champ et le bouton sont côte à
   côte, et imposait cette rangée à tout formulaire modal. C'est .gate-stack
   qui pose la mise en page des fenêtres empilées, et #modeleForm la sienne. */
.gate-err{color:var(--danger);font-size:var(--t3);margin-top:12px;min-height:1em}

.busy{position:fixed;top:0;left:0;right:0;height:2px;z-index:1250;background:transparent;overflow:hidden}
.busy.on::after{
  content:'';position:absolute;inset:0;width:40%;background:var(--acid);
  animation:slide 1s linear infinite}
@keyframes slide{from{transform:translateX(-100%)}to{transform:translateX(350%)}}

@media print{
  body{background:#fff;color:#000}
  body::before,.toolbar,nav.tabs,.add,.chip .x,.acts,.cat form,.food-tools,.toast,.busy,.gate{display:none!important}
  section[hidden]{display:block!important}
  .day,.rec,.cat{break-inside:avoid;border-color:#999;background:#fff}
  .chip{border-color:#bbb}
  .rec p{color:#222}
  h1,.rec h3,.day.sport .day-head h3{color:#000!important;-webkit-text-stroke:0}
}

/* ---------- PROFILS ---------- */
.whoami{
  display:inline-flex;align-items:center;gap:8px;margin-right:6px;
  padding:6px 10px;border-radius:var(--r);background:var(--bg-2);box-shadow:var(--ombre)}
.whoami[hidden]{display:none}
.whoami-nom{font-size:var(--t3);color:var(--ink)}
.role-pill{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);letter-spacing:.14em;
  text-transform:uppercase;padding:3px 7px;border-radius:99px;border:1px solid currentColor;
  white-space:nowrap}


/* Groupe compteur + action dans l'en-tête d'un rayon. */
.cat-actions{display:inline-flex;align-items:center;gap:10px}

/* ---------- FORMULAIRE DE COMPTES ---------- */
.user-form{
  display:flex;flex-wrap:wrap;gap:10px;align-items:center;
  padding:16px;margin-bottom:20px;
  border-radius:var(--r);background:var(--bg-2);box-shadow:var(--ombre)}
.user-form .field input{width:190px}
.user-form .field select{color:var(--ink)}

/* ---------- ÉCRANS MODAUX ---------- */
.gate-stack{display:flex;flex-direction:column;gap:8px}
.gate-stack input{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:9px 11px;font-size:var(--t4);outline:none}
.gate-stack input:focus{border-color:var(--acid)}
.gate-row{display:flex;gap:8px}

/* Carte de création d'un rayon : bordure pointillée pour la distinguer
   des rayons réels sans en faire une carte de plus.

   La largeur et la couleur sont dites ici. Sans elles, « border-style »
   seul prenait les valeurs initiales du navigateur — 3 px, couleur du
   texte — et donnait un cadre bien plus lourd que celui qu'on voulait
   depuis que .cat n'a plus de bordure à lui. */
.cat-new{border:1px dashed var(--line-hi);background:transparent}
.cat-new h3{border-bottom-style:dashed;color:var(--ink-dim)}
.cat-new form{border-top:none}

/* ---------- PORTÉE DES DONNÉES ---------- */
/* Deux étages : ce qui est commun à tous les comptes, et ce qui
   appartient au compte affiché. La distinction doit se lire sans
   avoir à cliquer. */
.portee{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);
  margin:0;padding:3px 8px;border:1px solid var(--line-hi);border-radius:99px}

.compte-switch{padding:4px 10px}
.compte-switch select{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  letter-spacing:.06em;color:var(--ink)}
.compte-switch[hidden]{display:none}

/* Travailler dans le plan d'un autre compte doit rester impossible à
   oublier : accent orange, le même que les jours de sport. */
.autre-compte{
  border:1px solid var(--fire);border-left-width:3px;border-radius:var(--r);
  background:rgba(255,92,31,.08);
  padding:9px 14px;margin-bottom:14px;font-size:var(--t3);color:var(--ink);max-width:80ch}

.tag-autres{color:var(--fire);border-color:rgba(255,92,31,.5)}

/* ---------- DEUX PROFILS ---------- */
/* utilisateur : neutre, c'est le cas courant. admin : orange, comme les
   jours de sport, parce que ses gestes portent sur le commun. */
.role-utilisateur{color:var(--ink-dim)}
/* Le coach tient la bibliothèque de séances : il parle la couleur du
   sport, comme l'admin, mais sans son fond — son domaine est plus étroit. */
.role-coach{color:var(--fire)}
.role-admin{color:var(--fire);background:rgba(255,92,31,.10)}
/* Un rôle créé dans la grille : ni la couleur du quotidien, ni celle du
   commun — on voit qu'il est d'ici, pas ce qu'il permet. */
.role-perso{color:var(--ink-2)}

/* Signature d'une recette : dit qui l'a écrite, donc pourquoi elle est
   modifiable ou non. */
.rec-auteur{
  display:block;margin-top:12px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}
/* Une recette qu'on ne peut pas modifier se reconnaît à son titre
   éteint et à sa signature — « écrite par Untel » — juste en dessous.
   Elle portait en plus un cadre pointillé, hérité du temps où les cartes
   avaient une bordure : depuis qu'elles n'en ont plus, « border-style »
   seul reprenait les valeurs initiales du navigateur et dessinait un
   trait de 3 px couleur du texte. Trois signaux pour une même chose, et
   le plus voyant était le moins voulu. */
.rec-lecture h3{color:var(--ink-dim)}

/* ---------- SEMAINES ENREGISTRÉES ---------- */
/* Une rangée d'onglets secondaires, volontairement plus discrète que la
   navigation principale : on change de semaine, pas de section. */
.semaines{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.semaines-onglets{display:flex;flex-wrap:wrap;gap:6px}
.sem{
  display:inline-flex;align-items:center;gap:8px;
  border:1px solid var(--line-hi);border-radius:var(--r);
  padding:5px 10px;background:var(--bg-2);color:var(--ink-dim);transition:.15s}
.sem:hover{color:var(--ink);border-color:var(--ink-dim)}
.sem.on{
  background:var(--acid);border-color:var(--acid);color:var(--bg);
  cursor:default}
.sem-nom{
  font-family:'Anton',Impact,sans-serif;
  font-size:var(--t3);letter-spacing:.04em}
.sem-n{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  opacity:.65;font-variant-numeric:tabular-nums}
.semaines-outils{display:flex;flex-wrap:wrap;gap:6px;margin-left:auto}
.semaine-desc{
  flex:1 1 100%;margin:0;font-size:var(--t3);color:var(--ink-dim);max-width:80ch}

/* La description se saisit dans la même fenêtre que le nom. */
.gate-stack textarea{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:9px 11px;font-size:var(--t4);outline:none;resize:vertical;
  font-family:'Chivo',ui-sans-serif,system-ui,sans-serif}
.gate-stack textarea:focus{border-color:var(--acid)}

@media print{
  .semaines-outils{display:none!important}
  .sem:not(.on){display:none!important}
}

/* ---------- SÉANCES ---------- */
/* Une séance s'imbrique dans la carte du jour, comme un repas, mais
   descend d'un cran de plus : séance → exercice → séries. Le liseré
   gauche marque cette profondeur sans multiplier les cadres. */
.seance{
  padding:12px 14px;border-bottom:1px solid var(--line)}
.seance:last-of-type{border-bottom:none}
.seance-tete{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  flex-wrap:wrap;margin-bottom:8px}
.seance-tete h4{
  font-family:'Anton',Impact,sans-serif;font-weight:400;
  font-size:var(--t4);letter-spacing:.03em;margin:0;color:var(--fire)}
.seance-note{
  margin:0 0 10px;font-size:var(--t3);color:var(--ink-dim);font-style:italic}

.exo{
  border-left:2px solid var(--line-hi);padding:8px 0 8px 12px;margin-bottom:10px}
.exo:last-of-type{margin-bottom:0}
.exo-tete{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.exo-nom{font-weight:600;font-size:var(--t4)}
.exo-groupe{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-dim);
  border:1px solid var(--line-hi);border-radius:99px;padding:2px 6px}

/* Une série par ligne : numéro, répétitions, charge, repos. */
.series{display:flex;flex-direction:column;gap:4px;margin-top:8px;align-items:flex-start}
.serie{display:flex;align-items:center;gap:6px}
.serie-n{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);width:14px;text-align:right;font-variant-numeric:tabular-nums}
.serie-in{
  background:var(--saisie);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:3px 6px;font-size:var(--t3);width:72px;outline:none;
  font-family:'JetBrains Mono',ui-monospace,monospace}
.serie-in:focus{border-color:var(--acid)}
.serie-val{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);
  color:var(--ink-dim);width:72px}

/* ---------- MENU DES ACTIONS SECONDAIRES ---------- */
/* Export, import, impression et compte quittent la barre pour un menu :
   l'en-tête tient alors sur une seule rangée, même avec le sélecteur de
   compte affiché. */
.menu-wrap{position:relative}
.menu-btn{font-size:var(--t4);line-height:1;padding:5px 12px;letter-spacing:0}
.menu-btn[aria-expanded="true"]{background:var(--acid);border-color:var(--acid);color:var(--bg)}
.menu{
  position:absolute;right:0;top:calc(100% + 6px);z-index:1050;
  display:flex;flex-direction:column;min-width:190px;
  border:1px solid var(--line-hi);border-radius:var(--r-lg);
  background:var(--bg-2);box-shadow:0 12px 32px rgba(0,0,0,.55);
  padding:5px}
.menu-item{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);
  text-align:left;padding:8px 10px;border-radius:var(--r-sm);transition:.12s}
.menu-item:hover{background:var(--acid);color:var(--bg)}
.menu-item.dngr:hover{background:var(--danger);color:#fff}
.menu-sep{height:1px;background:var(--line);margin:5px 8px}

/* ---------- AIDE REPLIÉE ---------- */
/* Les explications ne servent qu'une fois : elles vivent derrière un « ? »
   plutôt que d'occuper trois lignes à chaque chargement. */
.aide-btn{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  width:22px;height:22px;flex:0 0 22px;border-radius:99px;
  border:1px solid var(--line-hi);color:var(--ink-dim);
  display:grid;place-items:center;transition:.15s}
.aide-btn:hover,.aide-btn.on{background:var(--acid);border-color:var(--acid);color:var(--bg)}

/* Actualiser un catalogue commun : une pastille dans la famille des
   « mini » — même police, même hauteur — avec une flèche circulaire tracée
   au trait et le mot à côté, pour qu'on ne la confonde pas avec l'aide.
   Pendant la requête, seule la flèche tourne ; la pastille reste stable
   sous le pointeur. Sur téléphone, le mot s'efface, la flèche suffit. */
.actualiser{
  display:inline-flex;align-items:center;gap:6px;
  height:26px;padding:0 10px 0 8px;border-radius:99px;
  border:1px solid var(--line-hi);background:var(--voile-1);color:var(--ink-dim);
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  cursor:pointer;
  transition:color .15s, border-color .15s, background .15s}
.actualiser svg{width:13px;height:13px;flex:none;transition:transform .35s ease}
.actualiser:hover{color:var(--ink);border-color:var(--ink-dim);background:var(--voile-3)}
.actualiser:hover svg{transform:rotate(60deg)}
.actualiser:focus-visible{outline:none;border-color:var(--acid);color:var(--ink)}
.actualiser:disabled{cursor:progress}
.actualiser.en-cours{color:var(--acid);border-color:var(--acid);background:rgba(217,255,61,.06)}
.actualiser.en-cours svg{animation:tourne .8s linear infinite;transition:none}
/* Côté sport, la pastille parle orange comme le reste du domaine. */
.domaine-sport .actualiser:focus-visible{border-color:var(--fire)}
.domaine-sport .actualiser.en-cours{color:var(--fire);border-color:var(--fire);background:rgba(255,92,31,.06)}
@keyframes tourne{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .actualiser svg,.actualiser:hover svg{transition:none;transform:none}
  .actualiser.en-cours svg{animation:none}
  .actualiser.en-cours{opacity:.7}
}
@media (max-width:620px){
  .actualiser span{display:none}
  .actualiser{padding:0 8px;height:28px}
  .actualiser svg{width:14px;height:14px}
}

.aide{
  margin:0 0 14px;padding:10px 14px;
  border:1px solid var(--line);border-left:2px solid var(--line-hi);border-radius:var(--r);
  background:var(--bg-2);font-size:var(--t3);color:var(--ink-dim);max-width:80ch}
.aide p{margin:0}
.aide p + p{margin-top:8px}

@media print{
  .menu-wrap,.aide-btn,.aide{display:none!important}
}

/* En dessous de 700 px, l'en-tête se replie proprement : le titre et les
   chiffres passent l'un sous l'autre, les commandes restent accessibles. */
@media (max-width:700px){
  header{padding:10px 14px 0}
  main{padding:14px 14px 90px}
  .brand{gap:6px 10px}
  .toolbar{margin-left:0;width:100%}
  .sub{width:100%}
}

/* ---------- JOURS DE SPORT CLIQUABLES ---------- */
.jours-sport{display:flex;flex-wrap:wrap;gap:4px}
.jours-vide{color:var(--ink-dim);opacity:.7}
.jour-sport{
  display:inline-flex;align-items:center;gap:5px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  border:1px solid rgba(255,92,31,.45);color:var(--fire);
  background:rgba(255,92,31,.08);
  padding:3px 8px;border-radius:99px;transition:.15s}
.jour-sport:hover{background:var(--fire);border-color:var(--fire);color:#000}
.jour-sport-n{
  font-size:var(--t1);opacity:.75;font-variant-numeric:tabular-nums;
  border-left:1px solid currentColor;padding-left:5px}

/* ---------- VUE SÉANCE ---------- */
/* Plein écran, gros caractères, rien que l'entraînement du jour : elle
   se lit à un mètre, le téléphone posé sur le banc. */
.focus{
  position:fixed;inset:0;z-index:1150;background:var(--bg);
  display:flex;flex-direction:column;overflow:hidden}
.focus[hidden]{display:none}
/* La boîte intérieure : plein écran par défaut (vue séance), contrainte
   en panneau par le mode jour, plus bas. */
.focus-boite{display:flex;flex-direction:column;flex:1;min-height:0;min-width:0}
body.focus-ouvert{overflow:hidden}

.focus-tete{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding:14px 24px;border-bottom:1px solid var(--line);
  background:
    radial-gradient(700px 220px at 8% -60%, rgba(255,92,31,.14), transparent 70%)}
.focus-jours{display:flex;flex-wrap:wrap;gap:6px}
.focus-jour{
  display:inline-flex;align-items:center;gap:7px;
  font-family:'Anton',Impact,sans-serif;
  font-size:var(--t4);letter-spacing:.04em;
  border:1px solid var(--line-hi);border-radius:var(--r);
  padding:7px 14px;color:var(--ink-dim);background:var(--bg-2);transition:.15s}
.focus-jour:hover{color:var(--ink);border-color:var(--ink-dim)}
.focus-jour.on{background:var(--fire);border-color:var(--fire);color:#000;cursor:default}
.focus-meta{display:flex;align-items:center;gap:12px}
.focus-semaine{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}

.focus-corps{
  flex:1;overflow-y:auto;padding:24px;
  max-width:900px;width:100%;margin:0 auto}
.focus-vide{color:var(--ink-dim);font-style:italic;margin:0 0 16px}

/* ---------- Vue agrandie d'un jour ----------
   Même écran que la vue séance, même navigation entre les jours ; seule
   la couleur d'accent change, pour dire de quel domaine on parle : acide
   pour l'assiette, orange pour la salle. */
/* En mode jour, le conteneur devient un voile et la boîte un panneau
   centré : on n'a pas quitté la semaine, on en regarde un jour de près.
   Le voile reçoit le clic qui referme. */
.focus.mode-jour{
  background:var(--voile-fenetre);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  align-items:center;justify-content:center;padding:28px}
.focus.mode-jour .focus-boite{
  flex:0 1 auto;width:min(1040px,100%);max-height:100%;
  border:1px solid var(--line-hi);border-radius:var(--r-lg);background:var(--bg);
  box-shadow:var(--ombre-fenetre);
  animation:rise .18s ease-out}
.focus.mode-jour .focus-tete{
  background:radial-gradient(700px 220px at 8% -60%, rgba(217,255,61,.12), transparent 70%)}
.focus.mode-jour .focus-jour.on{background:var(--acid);border-color:var(--acid)}
.focus.mode-jour .focus-corps{max-width:none}

.focus-jour-tete{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:22px}
.focus-jour-tete .focus-titre{margin:0;flex:1 1 auto}
.focus-jour-tete .kcal-tag.jour{font-size:var(--t3);padding:5px 10px}

/* Les quatre repas en deux colonnes : assez large pour lire chaque puce,
   assez serré pour que le jour tienne sous les yeux sans défiler. */
.focus-repas{
  display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:14px}
.meal.meal-grand{
  border-radius:var(--r);background:var(--bg-2);
  padding:16px 18px;box-shadow:var(--ombre)}
.meal.meal-grand:last-child{border-bottom:1px solid var(--line)}
.meal.meal-grand .meal-t{font-size:var(--t2);letter-spacing:.18em;margin-bottom:12px}
.meal.meal-grand .add{font-size:var(--t5);padding:3px 8px}
.meal.meal-grand .chips{gap:8px}
.meal.meal-grand .chip{font-size:var(--t4);padding:6px 6px 6px 12px}
.meal.meal-grand .chip .x{width:24px;height:24px;font-size:var(--t4)}
.meal.meal-grand .empty{font-size:var(--t4)}

.focus-sous-t{margin:30px 0 10px;font-size:var(--t3);font-weight:600;color:var(--ink-dim)}
.focus-rappels{display:flex;flex-wrap:wrap;gap:10px}
.focus-rappel{
  display:inline-flex;align-items:baseline;gap:10px;
  border:1px solid rgba(255,92,31,.5);border-radius:var(--r);background:none;
  padding:10px 14px;color:var(--ink);cursor:pointer;transition:.15s;text-align:left}
.focus-rappel:hover{background:rgba(255,92,31,.10);border-color:var(--fire)}
.focus-rappel-nom{font-family:'Anton',Impact,sans-serif;font-size:var(--t5);color:var(--fire)}
.focus-rappel-n{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}

/* Le nom du jour dans la grille est un bouton : il garde l'apparence du
   titre et gagne seulement un soulignement au survol. */
.day-titre{
  background:none;border:none;padding:0;margin:0;color:inherit;font:inherit;
  letter-spacing:inherit;text-transform:inherit;cursor:pointer;text-align:left;
  border-bottom:1px solid transparent;transition:border-color .15s}
.day-titre:hover,.day-titre:focus-visible{border-bottom-color:currentColor;outline:none}

.focus-seance + .focus-seance{margin-top:40px;padding-top:28px;border-top:1px solid var(--line)}
.focus-titre{
  font-family:'Anton',Impact,sans-serif;font-weight:400;
  font-size:clamp(24px,4vw,38px);line-height:1.05;letter-spacing:.01em;
  margin:0 0 6px;color:var(--fire);text-wrap:balance}
.focus-note{margin:0 0 22px;font-size:var(--t4);color:var(--ink-dim);font-style:italic;max-width:65ch}

.focus-exo{
  border-radius:var(--r);background:var(--bg-2);
  padding:16px 18px;margin-bottom:14px;box-shadow:var(--ombre)}
.focus-exo-tete{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:4px}
.focus-exo-n{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);
  color:var(--acid);font-variant-numeric:tabular-nums}
.focus-exo-nom{
  font-family:'Anton',Impact,sans-serif;font-weight:400;
  font-size:var(--t6);letter-spacing:.02em;margin:0}
.focus-exo-note{margin:6px 0 0;font-size:var(--t4);color:var(--ink-2);max-width:65ch}

.focus-series{display:flex;flex-direction:column;gap:6px;margin-top:14px}
.focus-serie{
  display:grid;grid-template-columns:44px 1fr 1fr 1fr;gap:8px;align-items:center}
.focus-serie-tete{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim);
  padding-bottom:2px;border-bottom:1px solid var(--line)}
.focus-serie-n{
  font-family:'Anton',Impact,sans-serif;font-size:var(--t6);color:var(--ink-dim);
  text-align:center;font-variant-numeric:tabular-nums}
.focus-serie-in,.focus-serie-val{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t5);
  padding:9px 10px;border-radius:var(--r)}
.focus-serie-in{background:var(--saisie);border:1px solid var(--line-hi);outline:none;width:100%}
.focus-serie-in:focus{border-color:var(--acid)}
.focus-serie-val{color:var(--ink-dim);border:1px solid transparent}

@media (max-width:640px){
  .focus-tete{padding:12px 14px}
  .focus-corps{padding:16px 14px}
  .focus-serie{grid-template-columns:34px 1fr 1fr 1fr;gap:6px}
  .focus-serie-in,.focus-serie-val{font-size:16px;padding:8px}
  /* Un repas par ligne sur téléphone : deux colonnes couperaient les puces. */
  .focus-repas{grid-template-columns:1fr;gap:10px}
  .meal.meal-grand{padding:13px 14px}
  .meal.meal-grand .chip{font-size:var(--t4)}
  /* Le voile garde une marge, mince : la fenêtre doit rester une fenêtre
     même sur téléphone, sinon on ne sait plus qu'on peut cliquer à côté. */
  .focus.mode-jour{padding:14px 10px}
}

@media print{
  .focus{display:none!important}
  .jour-sport{border-color:#999;background:none;color:#000}
}

/* ---------- DEUX DOMAINES ---------- */
/* Alimentaire et sport ne sont pas cloisonnés : ils sont simplement
   distingués. Un écart dans la barre d'onglets, un libellé effacé, et
   l'accent de l'onglet actif — acide d'un côté, orange de l'autre, les
   deux couleurs déjà employées partout ailleurs dans la page. */
.tabs-groupe{display:flex;flex-direction:column;align-items:center;gap:5px}
.tabs-groupe[hidden]{display:none}
.tabs-row{display:flex}

/* Le libellé coiffe son groupe, centré sur lui : la coupure se lit d'un
   coup d'œil, sans qu'aucun trait ne vienne cloisonner la barre. */
.tabs-eyebrow{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.26em;text-transform:uppercase;color:var(--ink-dim);
  opacity:.5;white-space:nowrap;text-align:center;padding:0 4px;
  /* L'interlettrage ajoute une chasse après la dernière lettre : sans
     cette retouche, le libellé paraît décalé à gauche de son groupe. */
  text-indent:.26em}
.tabs-groupe.alim  .tabs-eyebrow{color:var(--acid);opacity:.7}
.tabs-groupe.sport .tabs-eyebrow{color:var(--fire);opacity:.7}

/* Le premier onglet de chaque groupe retrouve sa bordure gauche : c'est
   l'écart, et non un trait, qui marque la coupure. */
.tabs-row .tab:first-of-type{border-left:1px solid var(--line)}
.tabs-groupe + .tabs-groupe{position:relative}
.tabs-groupe + .tabs-groupe::before{
  content:'';position:absolute;left:-15px;bottom:6px;
  width:1px;height:20px;background:var(--line)}
/* Seul le sport s'ecarte de l'accent generique : l'alimentaire EST cet
   accent, il n'a donc pas de regle propre. */
.tabs-groupe.sport .tab.on{background:var(--fire);border-color:var(--fire);color:#000}

/* Puce de domaine devant chaque titre de section : trois pixels suffisent
   à dire de quel côté on se trouve. */
.sec-head h2::before{
  content:'';display:inline-block;width:3px;height:.8em;
  margin-right:10px;vertical-align:baseline;border-radius:3px;
  background:var(--line-hi)}
.domaine-alim   .sec-head h2::before{background:var(--acid)}
.domaine-sport  .sec-head h2::before{background:var(--fire)}
/* Les comptes ne relèvent d'aucun des deux : puce grise, assumée. */
.domaine-neutre .sec-head h2::before{background:var(--line-hi)}

@media (max-width:700px){
  nav.tabs{gap:18px}
  .tabs-eyebrow{font-size:var(--t1);letter-spacing:.18em}
}

@media print{
  .tabs-eyebrow{display:none}
}

@media print{
  /* Le pied de page a maintenant un fond sombre : il faut le neutraliser
     à l'impression, sinon il ressort en pavé noir. */
  .foot{background:none;border-color:#999;color:#333}
  .foot #saveState{color:#333;opacity:1}
}

/* Compte de séances, à côté du badge sport/repos dans l'en-tête d'un jour.
   Deux informations distinctes, deux objets distincts. */
.day-head-actions{display:flex;align-items:center;gap:8px}
.seances-n{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);
  white-space:nowrap}

/* ---------- INTERRUPTEUR DE SUPPRESSION ---------- */
/* Une seule garde pour toute l'application, au lieu d'un armement en deux
   temps répété sur chaque bouton : éteint, aucun bouton de suppression
   n'existe ; allumé, un clic suffit — et l'interrupteur rouge reste sous
   les yeux tant que le mode dure. */
.switch{
  display:inline-flex;align-items:center;gap:8px;
  border:1px solid var(--line-hi);border-radius:var(--r);
  padding:5px 10px;background:var(--bg-2);transition:.15s}
.switch[hidden]{display:none}
.switch-txt{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-dim)}
.switch-track{
  position:relative;width:26px;height:14px;flex:0 0 26px;
  border-radius:99px;background:var(--line-hi);transition:background .18s}
.switch-knob{
  position:absolute;top:2px;left:2px;width:10px;height:10px;border-radius:50%;
  background:var(--ink-dim);transition:transform .18s, background .18s}
.switch:hover{border-color:var(--ink-dim)}
.switch:hover .switch-txt{color:var(--ink)}

.switch.on{border-color:var(--danger);background:rgba(255,59,78,.10)}
.switch.on .switch-txt{color:var(--danger)}
.switch.on .switch-track{background:var(--danger)}
.switch.on .switch-knob{transform:translateX(12px);background:var(--bouton-knob)}

/* Les boutons de suppression n'apparaissent qu'en mode actif : ils portent
   donc d'emblée la couleur d'alerte, sans survol. */
.mini.suppr{border-color:rgba(255,59,78,.55);color:var(--danger)}
.mini.suppr:hover{background:var(--danger);color:#fff;border-color:var(--danger)}

/* Rappel discret que le mode est actif, même après avoir fait défiler. */
body.suppression-on header{border-bottom-color:var(--danger)}

@media print{
  .switch{display:none!important}
}

/* Les croix de retrait n'apparaissent qu'en mode suppression : elles
   portent donc la couleur d'alerte d'emblée, comme les boutons. */
.x.suppr-x{color:var(--danger);opacity:.8}
.x.suppr-x:hover{background:var(--danger);color:#fff;opacity:1}

/* Bloc des exercices d'une séance : même en-tête que celui d'un repas —
   intitulé à gauche, « + » à droite, saisie qui apparaît dessous. */
.seance-exos{margin-top:12px}
.seance-exos .meal-t{margin-bottom:10px}

/* ---------- CALORIES ---------- */
/* kcal pour UNE portion : les repas ne portent pas de quantité, donc une
   valeur pour 100 g ne s'additionnerait pas. Une portion, si. */
.kcal{white-space:nowrap}
.kcal-btn,.kcal-vide,.kcal .kcal-sep{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);
  color:var(--ink-dim);font-variant-numeric:tabular-nums}
.kcal-btn{
  border:1px solid transparent;border-radius:var(--r-sm);padding:3px 6px;
  text-align:left;transition:.15s}
.kcal-btn:hover{border-color:var(--line-hi);color:var(--ink)}
/* Une valeur absente se dit : ce n'est pas un zéro. */
.kcal-btn.vide,.kcal-vide{opacity:.45;font-style:italic}
.kcal-in{
  background:var(--saisie);border:1px solid var(--acid);border-radius:var(--r-sm);
  padding:3px 6px;font-size:var(--t3);width:60px;outline:none;
  font-family:'JetBrains Mono',ui-monospace,monospace}
.kcal-in.portion-in{width:76px;font-style:normal}
.kcal-sep{margin:0 4px}

/* Macronutriments : trois grammages pour la portion des calories. La
   lettre reste en retrait, le nombre porte la lecture — c'est lui qu'on
   compare d'une ligne à l'autre. */
/* Trois groupes « lettre nombre g » : l'écart entre les groupes doit être
   nettement plus grand que celui entre la lettre et son nombre, sinon
   « P 24 g G 12 g L 5 g » se lit comme une seule suite. */
.macros{display:inline-flex;gap:18px;align-items:baseline}
.macro{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);
  color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.macro em{
  font-style:normal;color:var(--ink-dim);margin-right:5px;
  font-size:var(--t2);letter-spacing:.08em}
.macro.vide{opacity:.4}
/* L'unité, collée au nombre, en retrait comme la lettre : elle se lit avec
   lui sans lui disputer l'œil. Même pièce dans les champs de saisie, où
   elle reste affichée pendant qu'on tape — une indication de champ, elle,
   disparaît à la première touche. */
.unite-fixe{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);margin-left:2px;letter-spacing:.04em}
.macro-in .unite-fixe,.kcal .unite-fixe{margin:0 6px 0 3px}
.macro-in{margin-right:4px}
.macros-cell{white-space:nowrap}
.macro-in{display:inline-flex;align-items:center;gap:4px;margin-right:6px}
.macro-in em{
  font-style:normal;color:var(--ink-dim);
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);letter-spacing:.08em}
.macro-in input{
  background:var(--saisie);border:1px solid var(--acid);border-radius:var(--r-sm);
  padding:3px 5px;font-size:var(--t3);width:52px;outline:none;
  font-family:'JetBrains Mono',ui-monospace,monospace;color:var(--ink)}

/* Totaux par repas et par jour. L'astérisque signale un total partiel. */
.kcal-tag{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  letter-spacing:.06em;color:var(--acid);white-space:nowrap;
  font-variant-numeric:tabular-nums;opacity:.85}
.kcal-tag.jour{
  font-size:var(--t2);border:1px solid rgba(217,255,61,.35);
  border-radius:99px;padding:2px 8px;opacity:1}
#foodAddWrap3 input{width:70px}
#foodAddWrap3 input[type="number"]{width:64px}

/* ---------- MODÈLES DE SÉANCE ---------- */
/* Le choix précède la saisie : on part d'un programme tout fait, ou on
   compose. Chaque carte annonce son contenu pour qu'on choisisse sans
   avoir à l'ouvrir. */
.gate-box.large{width:min(620px,100%)}
.gate-box.large .modeles{max-height:52vh;overflow-y:auto;margin-bottom:14px}

.modeles-groupe{
  font-size:var(--t3);font-weight:600;
  color:var(--fire);
  margin:14px 0 6px}
.modeles-groupe:first-child{margin-top:0}

.modele{
  display:block;width:100%;text-align:left;
  border-radius:var(--r);background:var(--bg-2);
  padding:10px 12px;margin-bottom:6px;transition:.15s;box-shadow:var(--ombre)}
.modele:hover{border-color:var(--fire);background:rgba(255,92,31,.08)}
.modele-tete{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.modele-nom{
  font-family:'Anton',Impact,sans-serif;
  font-size:var(--t4);letter-spacing:.02em;color:var(--ink)}
.modele-n{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim);white-space:nowrap}
.modele-exos{
  margin-top:5px;font-size:var(--t3);color:var(--ink-dim);line-height:1.45}
.modele-perso{width:100%;text-align:center}

/* ---------- RÉORDONNER PAR GLISSEMENT ---------- */
/* Seule la poignée porte draggable : sur la ligne entière, l'attribut
   empêcherait de sélectionner le texte des champs qu'elle contient. */
.poignee{
  color:var(--ink-dim);font-size:var(--t3);line-height:1;cursor:grab;
  letter-spacing:-1px;user-select:none;flex:none;width:14px;text-align:center}
.poignee:hover{color:var(--fire)}
.poignee:active{cursor:grabbing}
.en-deplacement{opacity:.4}
.poignee-vide{flex:none;width:14px}

/* ---------- ÉDITEUR DE MODÈLES ---------- */
.modeles-admin{display:flex;flex-direction:column}
.modele-admin{
  border-radius:var(--r);background:var(--bg-2);
  padding:12px 14px;margin-bottom:8px;box-shadow:var(--ombre)}
.modele-admin .modele-tete{align-items:center}
.modele-note{margin:6px 0 0;font-size:var(--t3);color:var(--ink-dim);font-style:italic}

.modele-champs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}
.field.bloc{margin-bottom:8px}
.field.bloc input{width:100%}
.modele-exos-t{margin:14px 0 8px}
.modele-lignes{
  display:flex;flex-direction:column;gap:6px;
  max-height:40vh;overflow-y:auto;margin-bottom:14px}
.modele-ligne{display:flex;align-items:center;gap:5px}
.modele-ligne input{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:6px 8px;font-size:var(--t3);outline:none;min-width:0}
.modele-ligne input:focus{border-color:var(--acid)}
.modele-ligne .l-nom{flex:2 1 150px}
.modele-ligne .l-note{flex:1 1 110px}
.modele-ligne .l-n{width:46px;text-align:center;font-family:'JetBrains Mono',ui-monospace,monospace}
.modele-ligne .l-reps{width:70px;font-family:'JetBrains Mono',ui-monospace,monospace}
.modele-ligne .l-repos{width:78px;font-family:'JetBrains Mono',ui-monospace,monospace}
.modele-ligne .l-x{color:var(--ink-dim);font-size:var(--t2)}

/* L'éditeur de modèle empile ses blocs : deux champs sur une rangée, la
   note en pleine largeur, puis la liste des exercices et les boutons. */
#modeleForm{display:flex;flex-direction:column}
#modeleForm .modele-champs .field{flex:1 1 220px}
#modeleForm .field.bloc{width:100%}
#modeleForm .field input{width:100%}
/* Les champs d'une ligne d'exercice gardent leur largeur propre : sans
   flex:none, une base souple les ramènerait toutes à la même. */
#modeleForm .modele-ligne input,#seanceForm .modele-ligne input{flex:none}
/* Un nom d'exercice fait couramment vingt-cinq caractères — « Développé
   couché haltères » — et on ne le lisait qu'à moitié. Il prend trois
   parts de la place souple contre une à la note, qui est facultative et
   se relit dans l'infobulle. La fenêtre s'élargit aussi, plus bas. */
#modeleForm .modele-ligne .l-nom,#seanceForm .modele-ligne .l-nom{flex:3 1 200px}
#modeleForm .modele-ligne .l-note,#seanceForm .modele-ligne .l-note{flex:1 1 90px}

/* En-tête des colonnes de l'éditeur de modèle. Il reprend les classes des
   champs pour hériter de leurs largeurs, et compense leur retrait interne
   (bordure 1 px + padding 8 px) afin que les intitulés tombent juste
   au-dessus du texte saisi. */
.modele-entete{
  font-size:var(--t2);font-weight:600;
  color:var(--ink-dim);
  padding-bottom:4px;margin-bottom:2px;border-bottom:1px solid var(--line)}
/* Même retrait que les champs — 8 px — pour que l'intitulé commence à
   l'aplomb exact de ce qu'il nomme. Et « flex:none », comme les champs
   de la ligne : sans cela l'en-tête se comprimait quand eux ne le
   faisaient pas. Les deux colonnes souples, le nom et la note, gardent
   leur flex par une règle plus spécifique, juste en dessous. */
.modele-entete span{
  padding:0 8px;white-space:nowrap;overflow:hidden;flex:none;
  /* Les champs portent une bordure d'1 px que l'en-tête n'a pas :
     sans elle, l'intitulé commencerait un pixel trop à gauche. Une
     bordure transparente rend les deux boîtes identiques. */
  border:1px solid transparent}
/* « Séries » ne tient pas dans 46 px, et encore moins avec 8 px de
   retrait de chaque côté : la colonne s'élargit, ligne et en-tête
   ensemble pour rester alignés. */
#modeleForm .modele-ligne .l-n,#seanceForm .modele-ligne .l-n{width:58px}
/* Les deux cellules sans intitulé — le « × » de multiplication et la
   colonne du bouton de retrait — doivent occuper la même place que dans
   une ligne, sinon tout se décale d'un cran. */
#modeleForm .modele-ligne .l-x,#seanceForm .modele-ligne .l-x{width:10px;flex:none;text-align:center;padding:0}
#modeleForm .modele-ligne > .x,#seanceForm .modele-ligne > .x{width:22px;flex:none;text-align:center;padding:0}
.modele-entete .l-vide{width:22px;flex:none;padding:0}

/* ---------- RECETTES GROUPÉES ---------- */
/* La carte reste un aperçu et devient cliquable : le détail complet, avec
   ses ingrédients, vit dans une fenêtre. */
.rec-groupe{
  font-size:var(--t3);font-weight:600;
  color:var(--cool);
  margin:18px 0 8px}
.rec-groupe:first-child{margin-top:0}
.recipes-grille{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}

/* .rec devient un bouton : il faut annuler les réglages par défaut. */
.rec{
  display:block;width:100%;text-align:left;font:inherit;color:inherit;
  cursor:pointer;transition:.15s}
.rec:hover{border-color:var(--cool);background:rgba(94,200,255,.05)}
.rec h3{margin-right:0}
.rec p{
  margin-top:8px;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.rec-chiffres{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:8px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}
.rec-temps{white-space:nowrap}

/* ---------- Filtres et régimes des recettes ----------
   Les recettes parlent en bleu (--cool) partout ailleurs ; leurs pastilles
   de régime aussi, pour ne pas emprunter l'orange des propositions à
   valider ni le vert des actions. */
.rec-filtres .field,.cat-filtres .field{padding:6px 10px}
.rec-filtres .field select,.cat-filtres .field select{width:auto;font-size:var(--t3)}
/* Les menus des catalogues, au doigt : deux par rangée sous la recherche,
   chacun prenant sa part plutôt que de flotter à sa largeur. */
@media (max-width:620px){
  .cat-filtres .field{flex:1 1 140px;min-width:0}
  .cat-filtres .field select{flex:1;min-width:0;width:100%}
}
.rec-regimes{display:flex;flex-wrap:wrap;gap:6px}
.chip-filtre.regime{border-color:rgba(94,200,255,.5);color:var(--cool)}
.chip-filtre.regime:hover{background:rgba(94,200,255,.10)}
.chip-filtre.regime.on{background:var(--cool);border-color:var(--cool);color:#000}

/* Sur la carte : de petites pastilles, dans la même voix que l'étiquette. */
.rec-regimes{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
.rec-regime{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.1em;text-transform:uppercase;color:var(--cool);
  border:1px solid rgba(94,200,255,.4);border-radius:var(--r);padding:2px 6px}

/* Dans la fenêtre : des cases à cocher lisibles, sur une rangée. */
.recette-regimes{display:flex;flex-wrap:wrap;gap:8px 16px;margin:2px 0 12px}
.regime-case{
  display:inline-flex;align-items:center;gap:7px;font-size:var(--t3);cursor:pointer;
  color:var(--ink)}
.regime-case input{accent-color:var(--cool);width:15px;height:15px;margin:0}
.regime-case:has(input:disabled){color:var(--ink-dim);cursor:default}
.champ-temps input{width:70px}

/* ---------- FENÊTRE DE RECETTE ---------- */
#recetteForm{display:flex;flex-direction:column}
#recetteForm .modele-champs .field{flex:1 1 200px}
#recetteForm .field.bloc{width:100%}
#recetteForm .field input{width:100%}
#recetteForm textarea{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:9px 11px;font-size:var(--t4);outline:none;resize:vertical;margin-bottom:14px;
  font-family:'Chivo',ui-sans-serif,system-ui,sans-serif}
#recetteForm textarea:focus{border-color:var(--acid)}
#recetteForm textarea[readonly],#recetteForm input[readonly]{opacity:.75;cursor:default}
.recette-ing-t{margin:14px 0 6px}

.recette-ligne input{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:6px 8px;font-size:var(--t3);outline:none;min-width:0}
.recette-ligne input:focus{border-color:var(--acid)}
#recetteForm .recette-ligne .l-nom{flex:2 1 150px}
#recetteForm .recette-ligne .l-qte{flex:1 1 90px}
#recetteForm .recette-ligne .l-kcal{
  width:120px;flex:none;padding:0 4px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);white-space:nowrap;overflow:hidden}
#recetteForm .recette-ligne > .x{width:22px;flex:none;text-align:center;padding:0}
.recette-entete .l-qte{flex:1 1 90px}
.recette-entete .l-kcal{width:120px;flex:none}

/* ---------- ILLUSTRATIONS D'EXERCICE ---------- */
.exo-vignette{
  width:34px;height:34px;display:block;object-fit:cover;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);background:var(--saisie);
  transition:border-color .15s, transform .15s}
/* Le bouton qui porte la vignette : invisible en soi, il ne fait que
   rendre l'image atteignable au clic et au clavier. */
.exo-vignette-btn{
  display:inline-flex;flex:none;padding:0;border:none;background:none;
  line-height:0;cursor:zoom-in;border-radius:var(--r-sm)}
.exo-vignette-btn:hover .exo-vignette,.exo-vignette-btn:focus-visible .exo-vignette{
  border-color:var(--fire);transform:scale(1.06)}
.exo-vignette-btn:focus-visible{outline:none}
/* min-height à la hauteur d'une vignette : sans elle, une ligne illustrée
   serait plus haute qu'une ligne sans image, et le tableau perdrait son
   rythme régulier d'une ligne à l'autre. */
.exo-cellule{display:flex;align-items:center;gap:9px;flex-wrap:wrap;min-height:34px}
.focus-vignette{width:44px;height:44px}

#exoForm{display:flex;flex-direction:column}
#exoForm .modele-champs .field{flex:1 1 180px}
#exoForm .field.bloc{width:100%}
#exoForm .field input{width:100%}

.exo-image-zone{display:flex;gap:12px;align-items:flex-start;margin-bottom:14px}
.exo-apercu{
  width:110px;height:110px;flex:none;
  border:1px solid var(--line-hi);border-radius:var(--r);background:var(--saisie);
  display:grid;place-items:center;overflow:hidden}
.exo-apercu-img{width:100%;height:100%;object-fit:cover}
.exo-apercu .exo-vignette-btn{width:100%;height:100%;display:block}
.exo-apercu-vide{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim);
  text-align:center;padding:0 8px}
.exo-image-cmd{display:flex;flex-direction:column;gap:6px;align-items:flex-start;flex:1;min-width:0}
.exo-image-aide{margin:2px 0 0;font-size:var(--t2);color:var(--ink-dim);line-height:1.4}
.exo-image-aide code{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink);background:var(--voile-2);padding:1px 4px;border-radius:4px}
.exo-image-aide b{color:var(--ink);font-weight:600}
#exoImageUrl{
  width:100%;background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:6px 8px;font-size:var(--t3);outline:none;
  font-family:'JetBrains Mono',ui-monospace,monospace}
#exoImageUrl:focus{border-color:var(--acid)}

@media print{
  .exo-vignette,.exo-vignette-btn{display:none!important}
}

/* Filet de sécurité : une version antérieure du script posait la classe
   directement sur le <td>, ce qui le sortait du contexte de tableau et
   désalignait la colonne. Si ce script est encore servi, cette règle lui
   rend son comportement de cellule ; le nom et la vignette s'y placent
   alors côte à côte en flux normal, sans casser les colonnes. */
table.foods td.exo-cellule{display:table-cell}
table.foods td.exo-cellule .exo-vignette-btn{vertical-align:middle;margin-right:9px}

/* ---------- Illustration en grand ----------
   Au-dessus de toutes les autres fenêtres, éditeur compris. L'image
   se cale dans la hauteur de l'écran, jamais plus grande que nature. */
.image-modal{z-index:1300}
.gate-box.image-box{
  width:min(940px,100%);display:flex;flex-direction:column;gap:14px;
  padding:18px 20px 16px}
.image-tete{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap}
.image-tete h2{margin:0;font-size:var(--t6)}
#imageLien{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--fire);
  text-decoration:none;border-bottom:1px solid transparent;white-space:nowrap}
#imageLien:hover,#imageLien:focus-visible{border-bottom-color:currentColor;outline:none}
#imageGrande{
  display:block;max-width:100%;max-height:min(72vh,900px);margin:0 auto;
  object-fit:contain;border:1px solid var(--line-hi);border-radius:var(--r);background:var(--saisie)}
.image-fermer{align-self:flex-end}

/* ============================================================
   MOBILE
   Trois principes : les tableaux deviennent des cartes, les
   fenêtres défilent, et tout ce qui se touche fait au moins
   34 px. Les champs passent à 16 px, en dessous de quoi iOS
   agrandit la page au moment de la saisie.
   ============================================================ */

/* ---------- Fenêtres modales : toujours atteignables ---------- */
/* Sans défilement, l'éditeur de modèle ou de recette dépassait du bas de
   l'écran, boutons compris. */
.gate{overflow-y:auto;overscroll-behavior:contain}

@media (max-width:620px){
  .gate{align-items:start;justify-items:center;padding:10px}
  .gate-box,.gate-box.large{width:100%;padding:16px 14px}
  .gate-box h2{font-size:var(--t6)}
  .gate-box p{margin-bottom:12px}
  .gate-box.large .modeles{max-height:none}
  .modele-lignes{max-height:none}
  .gate-row{flex-wrap:wrap}
  .gate-row .tbtn{flex:1 1 auto}
}

/* ---------- Tableaux en cartes ---------- */
/* Sous 760 px, un tableau de cinq colonnes ne tient plus : chaque ligne
   devient une carte, et chaque cellule porte le nom de sa colonne, que
   l'en-tête n'affiche plus. */
@media (max-width:760px){
  .table-scroll{overflow-x:visible}
  table.foods{min-width:0;display:block}
  table.foods thead{display:none}
  table.foods tbody{display:block}

  table.foods tr{
    display:block;padding:11px 13px;margin-bottom:8px;
    border:1px solid var(--line);border-radius:var(--r);background:var(--bg-2)}
  table.foods tr:hover td{background:none}

  table.foods td{
    display:flex;align-items:center;justify-content:space-between;gap:14px;
    padding:4px 0;border-bottom:none;text-align:right}
  table.foods td[data-label]::before{
    content:attr(data-label);flex:none;text-align:left;
    font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
    color:var(--ink-dim)}

  /* La première cellule est le titre de la carte : pleine largeur, pas
     d'intitulé, elle se lit d'abord. */
  table.foods td:first-child{
    display:block;text-align:left;padding:0 0 8px;font-size:var(--t4)}
  table.foods td:first-child::before{display:none}

  /* Les actions ferment la carte, détachées du reste. */
  table.foods td:last-child{
    margin-top:6px;padding-top:9px;border-top:1px dashed var(--line)}
  table.foods td:last-child::before{display:none}
  table.foods .acts{justify-content:flex-start;width:100%}
}

/* ---------- Lignes d'édition : elles se replient ----------
   Les sélecteurs sont longs pour une raison. Les deux formulaires qui
   portent ces lignes — la recette et le modèle de séance — règlent leurs
   colonnes par des sélecteurs qui commencent par un identifiant
   (#recetteForm, #modeleForm). Un identifiant bat n'importe quel nombre
   de classes, et une requête média ne pèse rien dans la cascade : sans
   rappeler ces identifiants ici, le repliement n'avait tout simplement
   jamais lieu, et l'éditeur de recette restait en trois colonnes
   serrées sur un écran de téléphone. */
@media (max-width:620px){
  .modele-entete,.recette-entete{display:none}
  .modele-ligne{
    flex-wrap:wrap;gap:6px;padding:9px;
    border:1px solid var(--line);border-radius:var(--r)}

  #recetteForm .modele-ligne .l-nom,#modeleForm .modele-ligne .l-nom,#seanceForm .modele-ligne .l-nom,
  #recetteForm .modele-ligne .l-note,#modeleForm .modele-ligne .l-note,#seanceForm .modele-ligne .l-note,
  #recetteForm .modele-ligne .l-qte,#modeleForm .modele-ligne .l-qte,#seanceForm .modele-ligne .l-qte,
  .modele-ligne .l-nom,.modele-ligne .l-note,.modele-ligne .l-qte{
    width:auto;flex:1 1 100%}

  #recetteForm .modele-ligne .l-kcal,#modeleForm .modele-ligne .l-kcal,#seanceForm .modele-ligne .l-kcal,
  .modele-ligne .l-kcal{
    width:auto;flex:1 1 100%;text-align:left}

  /* La croix de retrait ne s'étire pas — elle se range à droite, sous
     les champs, plutôt que de rester seule à gauche de sa ligne. */
  #recetteForm .modele-ligne > .x,#modeleForm .modele-ligne > .x,#seanceForm .modele-ligne > .x{
    margin-left:auto}

  .modele-champs{flex-direction:column;gap:8px}
  /* Ces formulaires posent « flex:1 1 200px » sur leurs champs pour les
     répartir sur une rangée. En colonne, le même 200 px n'est plus une
     largeur de base mais une HAUTEUR de base, étirable par le flex-grow :
     chaque champ devenait grand comme un écran. La base revient au
     contenu.

     Les identifiants sont rappelés parce que les règles corrigées les
     portent : une classe ne bat pas un identifiant, et une requête média
     ne pèse rien dans la cascade. */
  #recetteForm .modele-champs .field,
  #modeleForm .modele-champs .field,
  #exoForm .modele-champs .field,
  .modele-champs .field{width:100%;flex:0 0 auto}
}

/* ---------- En-tête ---------- */
@media (max-width:620px){
  main{padding:12px 12px 32px}
  h1{font-size:var(--t5);white-space:normal;line-height:1.15}
  .brand{gap:6px 10px}
  .sub{width:100%}
  .toolbar{margin-left:0;width:100%;gap:6px}
  .whoami{flex:1 1 auto;min-width:0}
  .whoami-nom{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .compte-switch{flex:1 1 100%}
  .compte-switch select{width:100%}
  .menu{min-width:0;width:calc(100vw - 24px);max-width:280px}

  nav.tabs{gap:16px;margin-top:10px}
  .sec-head h2{font-size:var(--t5)}
  .semaines-outils{margin-left:0;width:100%}
  .semaines-outils .mini{flex:1 1 auto}
  .foot{flex-direction:column;align-items:flex-start;gap:6px}
}

/* ---------- Grilles à une colonne ---------- */
@media (max-width:520px){
  .week,.shop,.recipes-grille{grid-template-columns:1fr}
  .food-tools{flex-direction:column}
  .food-tools .field{width:100%}
  .field input,.field select{width:100%}
  .user-form{flex-direction:column;align-items:stretch}
  .user-form .field input{width:100%}
  .exo-image-zone{flex-direction:column}
  .exo-apercu{width:100%;height:150px}
}

/* ---------- Doigt plutôt que souris ---------- */
@media (pointer:coarse){
  /* Cibles tactiles : 34 px est le minimum pour viser sans se tromper. */
  .mini,.tbtn,.menu-item{padding:9px 13px}
  .x,.aide-btn{min-width:34px;min-height:34px}
  .add{font-size:var(--t6);padding:5px 11px}
  .ck{width:22px;height:22px;flex-basis:22px;font-size:var(--t4)}
  .tab{padding:11px 15px}
  .li{padding:11px 14px}

  /* Le glisser-déposer HTML5 ne répond pas au toucher : la poignée laisse
     place à deux flèches, qui font le même travail. */
  .poignee,.poignee-vide{display:none}
  .reordonner,.reordonner-vide{display:inline-flex}
}
@media (pointer:fine){
  .reordonner,.reordonner-vide{display:none}
}

/* Le cache de l'en-tête paraît et disparaît avec les flèches qu'il
   remplace, et à la même largeur : deux boutons de 26 px et l'écart de
   2 px entre eux. Sans lui, tout l'en-tête se décalait de 54 px dès
   qu'on éditait au doigt. */
.reordonner,.reordonner-vide{display:inline-flex;gap:2px;flex:none}
.reordonner-vide{width:54px}
.reordonner button{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);line-height:1;
  color:var(--ink-dim);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  width:26px;height:26px;display:grid;place-items:center}
.reordonner button:hover:not(:disabled){color:var(--fire);border-color:var(--fire)}
.reordonner button:disabled{opacity:.3;cursor:default}

/* ---------- Saisie ---------- */
/* Sous 16 px, iOS agrandit la page dès qu'un champ prend le focus, et ne
   la réduit jamais ensuite : on reste zoomé, bords hors de l'écran. Les
   largeurs fixes suivent.
   16px est ici un seuil imposé par le système, pas un échelon de
   l'échelle : il s'écrit en pixels et n'en bouge pas.

   Le !important n'est pas un raccourci. Cette règle ne vise que des noms
   d'éléments : c'est la spécificité la plus faible qui existe, et les
   seize règles de la feuille qui donnent une police à un champ portent
   toutes au moins une classe — .field input, .recherche input,
   .gate-stack textarea… Elles la battaient donc toutes, où qu'on la
   place. Même raison que pour [hidden] : ce n'est pas une composition
   qu'on impose, c'est un seuil du système qu'aucune règle de mise en
   forme n'a le droit de faire passer.

   Et la condition porte sur l'APPAREIL, pas sur la largeur : un iPhone
   tourné en paysage fait 844 px, un iPad davantage, et tous deux
   agrandissent de la même façon. Sur une requête max-width, il suffisait
   de tourner le téléphone pour retrouver le défaut entier — et comme iOS
   ne revient jamais en arrière, la page restait agrandie au retour en
   portrait. */
@media (hover:none) and (pointer:coarse){
  input,select,textarea{font-size:16px!important}
}

/* Les largeurs, elles, relèvent bien de la place disponible. */
@media (max-width:620px){
  .serie-in{width:88px;font-size:16px}
  /* Même piège que pour les autres colonnes : #modeleForm règle cette
     largeur, et un identifiant bat une classe. */
  #modeleForm .modele-ligne .l-n,#seanceForm .modele-ligne .l-n,.modele-ligne .l-n{width:64px}
  .modele-ligne .l-reps,.modele-ligne .l-repos{width:auto;flex:1 1 90px}
  .kcal-in{width:76px}
  .kcal-in.portion-in{width:96px}
  /* Trois champs de 16 px sur une ligne de téléphone : ils passent à la
     ligne plutôt que de déborder de la carte. */
  .macro-in input{width:72px;font-size:16px}
  .macros-cell{white-space:normal}
  .macro-in{margin:0 8px 6px 0}
  .cat form input.q{width:90px}
}

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

/* ---------- BARRE D'OUTILS REPLIÉE (mobile) ---------- */
/* Profil, compte, suppression et actions occupaient quatre lignes en
   pleine largeur sur téléphone. Un seul bouton les regroupe, et le
   panneau s'ouvre dans le flux : rien à positionner, rien à rogner. */
.barre-btn{display:none}

@media (max-width:620px){
  .barre-btn{
    display:inline-flex;align-items:center;justify-content:center;
    margin-left:auto;font-size:var(--t4);line-height:1;padding:7px 13px;letter-spacing:0}
  .barre-btn[aria-expanded="true"]{background:var(--acid);border-color:var(--acid);color:var(--bg)}

  .toolbar{display:none}
  .toolbar.ouverte{
    display:flex;flex-direction:column;align-items:stretch;
    width:100%;margin-top:8px;padding:9px;gap:8px;
    border:1px solid var(--line-hi);border-radius:var(--r);background:var(--bg-2)}
  .toolbar.ouverte .whoami{justify-content:space-between}
  .toolbar.ouverte .switch{justify-content:space-between}

  /* Dans le panneau, le menu d'actions n'a plus à se déplier : il est
     déjà dans un panneau. Le « ⋯ » disparaît, ses entrées s'affichent. */
  .toolbar.ouverte .menu-wrap{width:100%}
  .toolbar.ouverte .menu-btn{display:none}
  .toolbar.ouverte .menu{
    position:static;width:100%;min-width:0;padding:0;
    border:none;background:none;box-shadow:none;
    border-top:1px solid var(--line);padding-top:8px}
  .toolbar.ouverte .menu-item{padding:11px 10px}
}

/* ---------- JOURS DE SPORT DANS L'EN-TÊTE ---------- */
/* Ils ouvrent la vue séance : ce sont les boutons les plus utilisés de
   l'en-tête, ils méritent d'être visés sans effort. */
.jour-sport{font-size:var(--t2);padding:5px 11px;gap:6px}
.jour-sport-n{font-size:var(--t2);padding-left:6px}

@media (pointer:coarse){
  .jour-sport{font-size:var(--t3);padding:8px 14px;letter-spacing:.12em}
  .jour-sport-n{font-size:var(--t2)}
  .jours-sport{gap:6px}
  .sub-label{font-size:var(--t2)}
}

/* Ligne de courses issue du planning : un liseré la distingue de celles
   ajoutées à la main, qu'une régénération ne touchera pas. */
.li.auto{border-left:2px solid rgba(217,255,61,.35)}
.li.auto .li-n::after{
  content:'auto';margin-left:8px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-dim);opacity:.7}

/* ---------- LOGO ---------- */
/* Le signe et le mot forment un seul bloc. Sur mobile le mot s'efface au
   profit du signe, mais reste lisible par les lecteurs d'écran : le titre
   de la page ne doit jamais devenir muet. */
.logo{display:flex;align-items:center;gap:12px}
.logo-mark{height:34px;width:auto;flex:none;display:block}
.logo-mot{white-space:nowrap}

@media (max-width:620px){
  .logo-mark{height:30px}
  .logo-mot{
    position:absolute;width:1px;height:1px;
    overflow:hidden;clip-path:inset(50%);white-space:nowrap}
}

@media print{
  /* Sur papier, le mot suffit : les trois couleurs ne portent plus rien. */
  .logo-mark{display:none}
  .logo-mot{position:static;width:auto;height:auto;clip-path:none}
}

/* ---------- CALCUL DES BESOINS ---------- */
.calcul{display:flex;flex-direction:column;gap:22px}

/* ---------- Bandeau : la réponse d'abord ----------
   Trois chiffres sur une ligne — cible, moyenne, écart — dans l'ordre où
   on les lit ; la cible en vert parce que c'est elle qu'on vise. */
.stats-bandeau{
  display:flex;flex-wrap:wrap;align-items:flex-end;gap:10px 36px;
  padding:18px 20px 16px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--bg-2)}
.bandeau-cible,.bandeau-moyenne,.bandeau-ecart{display:flex;flex-direction:column;gap:4px;min-width:0}
.bandeau-valeur{
  font-family:'Anton',Impact,sans-serif;font-size:var(--t8);line-height:1;
  color:var(--ink);font-variant-numeric:tabular-nums}
.bandeau-cible .bandeau-valeur{color:var(--acid)}
.bandeau-cible.vide .bandeau-valeur{color:var(--ink-dim)}
.bandeau-moyenne .bandeau-valeur{font-size:var(--t8)}
.bandeau-ecart .bandeau-valeur{font-size:var(--t8)}
.bandeau-ecart.ecart-plus .bandeau-valeur{color:var(--fire)}
.bandeau-ecart.ecart-moins .bandeau-valeur{color:var(--cool)}
.bandeau-intitule{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim)}
.bandeau-reserve{flex-basis:100%;margin:2px 0 0}

/* Le profil en une ligne, dépliable : un <details> natif, dont le
   résumé porte le profil et l'affordance « Modifier ». */
.stats-profil{overflow:hidden;border-radius:var(--r);background:var(--bg-2);box-shadow:var(--ombre)}
.stats-profil-ligne{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:11px 16px;cursor:pointer;list-style:none;font-size:var(--t3);color:var(--ink)}
.stats-profil-ligne::-webkit-details-marker{display:none}
.stats-modifier{
  flex:none;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--acid);
  border:1px solid rgba(217,255,61,.4);border-radius:var(--r-sm);padding:4px 9px;transition:.15s}
.stats-profil[open] .stats-modifier{background:var(--acid);color:#000;border-color:var(--acid)}
.stats-profil-ligne:hover .stats-modifier{border-color:var(--acid)}
.stats-profil .calcul-form{border:none;border-top:1px dashed var(--line);border-radius:0;background:none}

/* D'où vient la cible : replié, discret, explicatif. */
.stats-detail{margin-top:-8px}
.stats-detail summary{
  cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:6px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}
.stats-detail summary::-webkit-details-marker{display:none}
.stats-detail summary::before{content:'▸';font-size:var(--t2);transition:transform .15s}
.stats-detail[open] summary::before{transform:rotate(90deg)}
.stats-detail summary:hover{color:var(--ink)}
.methode-ligne{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 14px;margin:12px 0 8px}
.methode-chiffre{display:inline-flex;flex-direction:column;gap:2px}
.methode-chiffre b{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t5);font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.methode-chiffre .calcul-unite{font-size:var(--t2);margin-left:4px}
.methode-intitule{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);color:var(--ink-dim)}
.methode-op{color:var(--ink-dim);font-size:var(--t4);align-self:center}
.methode-texte{margin:0;font-size:var(--t3);color:var(--ink-dim);max-width:70ch;line-height:1.5}

/* Sélecteur de semaine dans l'en-tête : même champ que les autres. */
.stats-semaine-champ{padding:5px 10px;margin-left:auto}
.stats-semaine-champ select{width:auto;font-size:var(--t3)}

/* Répartition : indicatif et réel en face, une barre par valeur, même
   échelle sur toute la ligne pour que les longueurs se comparent. */
.macros-comp{display:flex;flex-direction:column;gap:8px}
.macros-comp-ligne{
  display:grid;grid-template-columns:90px 1fr 1fr 64px;gap:12px;align-items:center}
.macros-comp-ligne.tete span{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim)}
.macros-comp-nom{font-size:var(--t3);color:var(--ink)}
.macro-barre{position:relative;display:flex;align-items:center;height:22px;min-width:0}
.macro-barre i{
  position:absolute;left:0;top:0;bottom:0;border-radius:var(--r)}
.macro-barre.indic i{background:var(--voile-3);border-right:2px solid var(--ink-dim)}
.macro-barre.reel  i{background:rgba(217,255,61,.16);border-right:2px solid var(--acid)}
.macro-barre-val{
  position:relative;z-index:1;padding-left:8px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.macro-barre-val.vide{color:var(--ink-dim);opacity:.5}
.macros-comp-ecart{
  text-align:right;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  font-variant-numeric:tabular-nums}
.calcul-form{
  display:flex;flex-direction:column;gap:10px;
  border-radius:var(--r);background:var(--bg-2);padding:16px;box-shadow:var(--ombre)}
.calcul-champs{display:flex;flex-wrap:wrap;gap:10px}
.calcul-champs .field input{width:90px}
.calcul-champs .field.large{flex:1 1 280px}
.calcul-champs .field.large select{width:100%}
.field .unite{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-dim)}
.calcul-note{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);align-self:center}

/* Les trois chiffres sont le cœur de l'onglet : ils portent la taille. */
.calcul-tuiles{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}
.calcul-tuile{
  border-radius:var(--r);background:var(--bg-2);padding:14px 16px;box-shadow:var(--ombre)}
.calcul-tuile.cible{border-color:var(--acid);background:rgba(217,255,61,.06)}
.calcul-valeur{
  font-family:'Anton',Impact,sans-serif;font-size:var(--t7);line-height:1;
  color:var(--ink);font-variant-numeric:tabular-nums}
.calcul-tuile.cible .calcul-valeur{color:var(--acid)}
.calcul-unite{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  letter-spacing:.1em;color:var(--ink-dim);margin-left:6px}
.calcul-intitule{
  margin-top:6px;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim)}

.calcul-ecart{margin:0;font-size:var(--t4);color:var(--ink-dim)}
.calcul-ecart b{color:var(--ink)}
.ecart-plus{color:var(--fire)}
.ecart-moins{color:var(--cool)}
.calcul-reserve{margin:8px 0 0;font-size:var(--t3);color:var(--ink-dim);font-style:italic}

/* ---------- Statistiques : l'assiette en regard de l'entraînement ----------
   Un seul axe de jours porte les deux mesures — calories au-dessus,
   travail en dessous. Deux barres de même longueur côte à côte laissaient
   croire que les échelles se comparaient ; ce qui se compare, c'est le
   jour, et cela se lit maintenant verticalement. */
/* Les blocs de l'onglet Stats : un titre espacé plutôt qu'un séparateur,
   les tuiles réservées aux deux endroits où un gros chiffre se justifie. */
.stats-bloc{margin-top:8px}
.stats-titre{margin:0 0 12px;font-size:var(--t3);font-weight:600;color:var(--ink-dim)}
.stat-graphe-seul{display:block}
/* stat-bloc sert encore à l'onglet Suivi. */
.stat-bloc{border-top:1px dashed var(--line);padding-top:18px}
.stat-bloc .meal-t{margin-bottom:12px}
.stat-sous-t{margin:18px 0 8px;font-size:var(--t3);font-weight:600;color:var(--ink-dim)}

/* --- Le graphe de la semaine --- */
.stat-graph{display:flex;flex-direction:column}
/* Les trois rangées partagent le même gabarit de colonnes : c'est ce qui
   fait tenir l'alignement entre une barre verte et sa contrepartie
   orange, sans grille commune ni largeur codée en dur. */
.stat-rangee{display:flex;gap:4px}
.stat-plot{
  position:relative;display:flex;align-items:flex-end;
  height:150px;border-bottom:1px solid var(--line-hi)}
.stat-plot .stat-rangee{flex:1;height:100%;align-items:flex-end}
.stat-col{
  flex:1 1 0;min-width:0;height:100%;
  display:flex;flex-direction:column;justify-content:flex-end;align-items:center}
.stat-b-kcal{
  width:100%;background:rgba(217,255,61,.16);
  border-top:2px solid var(--acid);border-radius:var(--r) var(--r) 0 0}
/* Au-delà de la cible, la colonne se remplit davantage : plus, c'est plus. */
.stat-b-kcal.au-dessus{background:rgba(217,255,61,.30)}
.stat-chiffre{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  line-height:1.4;color:var(--ink-dim);white-space:nowrap}
.stat-plot .stat-chiffre{margin-bottom:3px}
/* Un trait continu en travers de la semaine, plutôt que sept repères. */
.stat-cible{
  position:absolute;left:0;right:0;height:0;z-index:1;pointer-events:none;
  border-top:1px dashed var(--ink-dim)}

.stat-axe{padding-top:7px}
.stat-axe-j{
  flex:1 1 0;min-width:0;text-align:center;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}
.stat-axe-j.est-sport{color:var(--fire);font-weight:600}

/* La bande d'entraînement pend sous l'axe : la symétrie dit assez qu'il
   s'agit de l'autre moitié de la même journée. */
.stat-effort{align-items:flex-start;height:60px;padding-top:5px}
.stat-col-e{
  flex:1 1 0;min-width:0;height:100%;
  display:flex;flex-direction:column;align-items:center}
.stat-b-effort{
  width:100%;min-height:2px;background:rgba(255,92,31,.16);
  border-bottom:2px solid var(--fire);border-radius:0 0 var(--r) var(--r)}
/* Sport annoncé, séance non saisie : la place est marquée, pas remplie. */
.stat-b-vide{
  width:100%;height:9px;border:1px dashed var(--fire);
  border-radius:var(--r);opacity:.45}
.stat-col-e .stat-chiffre{margin-top:4px}

.stat-legende{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:14px}
.lg{
  display:inline-flex;align-items:center;gap:7px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  letter-spacing:.06em;color:var(--ink-dim)}
.lg::before{content:'';width:13px;height:10px;border-radius:2px}
.lg-kcal::before{background:rgba(217,255,61,.16);border-top:2px solid var(--acid)}
.lg-effort::before{background:rgba(255,92,31,.16);border-bottom:2px solid var(--fire)}
.lg-cible::before{width:15px;height:0;border-top:1px dashed var(--ink-dim)}

/* --- Répartition par groupe : des rangées, faute d'axe du temps --- */
.stat-jours{display:flex;flex-direction:column;gap:6px}
.stat-jour{display:grid;grid-template-columns:130px 1fr;gap:12px;align-items:center}
.stat-nom{font-size:var(--t3);color:var(--ink)}
.stat-pistes{display:flex;flex-direction:column;gap:4px;min-width:0}
.stat-piste{
  position:relative;display:flex;align-items:center;height:22px;
  background:var(--voile-1);border-radius:var(--r);overflow:hidden}
.stat-barre{position:absolute;left:0;top:0;bottom:0;border-radius:var(--r) 0 0 var(--r)}
.piste-sport .stat-barre{background:rgba(255,92,31,.16);border-right:2px solid var(--fire)}
.stat-val{
  position:relative;z-index:1;padding:0 10px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---------- Import d'aliments : l'aperçu avant d'écrire ---------- */
.import-box{width:min(960px,100%)}
.import-aide{margin:0 0 12px;font-size:var(--t3);color:var(--ink-dim)}
.import-bilan{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}
.import-pastille{
  display:inline-flex;align-items:center;gap:5px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);letter-spacing:.08em;text-transform:uppercase;
  border:1px solid var(--line-hi);border-radius:var(--r);padding:4px 9px;color:var(--ink-dim)}
.import-pastille b{font-size:var(--t3);color:var(--ink);letter-spacing:0}
.import-nouveau{border-color:var(--acid);color:var(--acid)}
.import-nouveau b{color:var(--acid)}
.import-different{border-color:var(--fire);color:var(--fire)}
.import-different b{color:var(--fire)}
.import-identique{opacity:.7}
.import-doublon,.import-invalide{border-color:var(--danger);color:var(--danger)}
.import-doublon b,.import-invalide b{color:var(--danger)}
.import-proche{border-color:rgba(255,92,31,.5);color:var(--fire)}
.import-scroll{max-height:min(46vh,420px);overflow:auto;border:1px solid var(--line);border-radius:var(--r-sm)}
.import-table{min-width:520px}
.import-etat{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);letter-spacing:.08em;text-transform:uppercase;
  white-space:nowrap}
.import-etat.import-nouveau{color:var(--acid)}
.import-etat.import-different{color:var(--fire)}
.import-etat.import-identique{color:var(--ink-dim)}
.import-etat.import-doublon,.import-etat.import-invalide{color:var(--danger)}
tr.ligne-identique td,tr.ligne-doublon-fichier td,tr.ligne-invalide td{opacity:.6}
.import-valeurs{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-2)}
.import-choix{display:flex;align-items:center;gap:8px 18px;flex-wrap:wrap;margin:14px 0 4px;font-size:var(--t3)}
.import-choix-t{color:var(--ink-dim)}
.import-choix .regime-case input{accent-color:var(--fire)}

/* ---------- Administration : statistiques figées, journal ---------- */
.admin-bloc{margin-top:22px}
.admin-bloc-t{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.admin-bloc-droite{display:inline-flex;align-items:center;gap:12px}
.admin-tuiles{margin-bottom:8px}
.admin-tuiles .calcul-valeur{font-size:var(--t7)}
.admin-tops{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:24px;margin-top:6px}
.admin-top .stat-jour{grid-template-columns:150px 1fr}
.journal-barre{margin:10px 0}
.journal-table{min-width:560px}
.journal-quand{white-space:nowrap;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim)}
.journal-heure{color:var(--ink)}
.journal-cible{font-size:var(--t3);color:var(--ink-2);word-break:break-word}
.activite-cell{white-space:nowrap}
.activite-quand{font-size:var(--t3);color:var(--ink)}
.activite-quand.loin{color:var(--ink-dim)}
.activite-n{
  display:block;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim);margin-top:2px}
.tag-jamais{color:var(--ink-dim);border-color:var(--line-hi)}

.calcul-tuile.jour-sport{border-color:var(--fire);background:rgba(255,92,31,.06)}
.calcul-tuile.jour-sport .calcul-valeur{color:var(--fire)}

/* ---------- Suivi ----------
   Même grammaire graphique que l'onglet Stats — colonnes, chiffres,
   axe — dans la couleur du sport. Le record d'un exercice se distingue
   par une barre pleine. */
.stat-b-sport{
  width:100%;background:rgba(255,92,31,.16);
  border-top:2px solid var(--fire);border-radius:var(--r) var(--r) 0 0}
.stat-b-sport.record{background:rgba(255,92,31,.42)}
.stat-sous{padding-top:3px}
.stat-sous-j{
  flex:1 1 0;min-width:0;text-align:center;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.04em;color:var(--ink-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.suivi-resume{margin-bottom:6px}
.suivi-exo-t{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.suivi-select{
  background:var(--bg-2);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  color:var(--ink);padding:5px 8px;font-size:var(--t3);letter-spacing:0;text-transform:none}
.suivi-exo-tuiles{margin-bottom:14px}
.suivi-poids-form{margin-bottom:12px}
.suivi-poids-form .field input[type=date]{width:150px}
.suivi-poids-form .field input[type=number]{width:80px}

/* Le bouton « faite » : une action positive, dans la couleur du domaine. */
.mini.faite{border-color:var(--fire);color:var(--fire)}
.mini.faite:hover{background:var(--fire);color:#000}
.tbtn.faite{border-color:var(--fire);color:var(--fire)}
.tbtn.faite:hover{background:var(--fire);color:#000}
.focus-pied{margin-top:22px;display:flex;justify-content:flex-end}

/* Courbe de poids */
.poids-svg{display:block;width:100%;height:auto;max-height:200px}
.poids-grille{stroke:var(--line);stroke-width:1}
.poids-ligne{fill:none;stroke:var(--fire);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.poids-point{fill:var(--bg);stroke:var(--fire);stroke-width:2}
.poids-point.dernier{fill:var(--fire)}
.poids-axe{fill:var(--ink-dim);font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2)}
.poids-valeur{fill:var(--ink);font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);font-weight:600}
.poids-liste{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:8px}
.poids-item{
  display:inline-flex;align-items:center;gap:6px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim)}

/* Journal : une entrée = un pli natif ; ouvert, ses séries se retouchent. */
.suivi-journal{display:flex;flex-direction:column;gap:8px}
.suivi-journal .stat-sous-t{margin:14px 0 4px}
.journal-entree{overflow:hidden;border-radius:var(--r);background:var(--bg-2);box-shadow:var(--ombre)}
.journal-entree[open]{border-color:var(--line-hi)}
.journal-tete{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  padding:10px 14px;cursor:pointer;list-style:none}
.journal-tete::-webkit-details-marker{display:none}
.journal-tete::before{content:'▸';color:var(--ink-dim);font-size:var(--t2);transition:transform .15s}
.journal-entree[open] .journal-tete::before{transform:rotate(90deg)}
.journal-date{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);white-space:nowrap}
.journal-nom{font-family:'Anton',Impact,sans-serif;font-size:var(--t5);color:var(--fire)}
.journal-chiffres{
  margin-left:auto;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);white-space:nowrap}
.journal-corps{padding:4px 14px 14px;border-top:1px dashed var(--line)}
.journal-outils{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:10px 0 6px}
.journal-date-in{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:4px 8px;font-size:var(--t3);color:var(--ink);outline:none}
.journal-date-in:focus{border-color:var(--fire)}
.journal-exo{margin-top:12px}
.journal-exo-tete{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}
.journal-exo-nom{font-size:var(--t4);font-weight:600}
.journal-series{display:flex;flex-direction:column;gap:4px}
.journal-serie{display:flex;align-items:center;gap:8px}
.journal-serie-n{
  width:20px;flex:none;text-align:right;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);color:var(--ink-dim)}
.journal-serie-in{
  width:76px;background:var(--saisie);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:5px 8px;font-size:var(--t3);color:var(--ink);outline:none;
  font-family:'JetBrains Mono',ui-monospace,monospace;text-align:center}
.journal-serie-in:focus{border-color:var(--fire)}
.journal-serie-val{
  width:76px;text-align:center;padding:5px 8px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);color:var(--ink)}
.journal-serie-x{color:var(--ink-dim);font-size:var(--t3)}

@media (max-width:620px){
  .suivi-poids-form .field{width:100%}
  .suivi-poids-form .field input[type=date],.suivi-poids-form .field input[type=number]{width:100%}
  .journal-chiffres{margin-left:0;width:100%}
  .journal-serie-in,.journal-serie-val{width:64px;font-size:16px}
  .stat-sous-j{font-size:var(--t1)}
}

@media (max-width:620px){
  .calcul-champs .field{width:100%}
  .calcul-champs .field input{width:100%}
  .calcul-valeur{font-size:var(--t7)}
  /* Sept colonnes tiennent sur un téléphone, mais de justesse : on rend
     l'écart entre elles et la taille des chiffres au dessin. */
  .bandeau-valeur{font-size:var(--t8)}
  .bandeau-moyenne .bandeau-valeur,.bandeau-ecart .bandeau-valeur{font-size:var(--t7)}
  .stats-bandeau{gap:10px 22px;padding:14px 14px 12px}
  .stats-semaine-champ{margin-left:0;width:100%}
  .stats-semaine-champ select{width:100%}
  .macros-comp-ligne{grid-template-columns:70px 1fr 1fr 52px;gap:8px}
  .stat-plot{height:120px}
  .stat-rangee{gap:2px}
  .stat-chiffre{font-size:var(--t1)}
  .stat-effort{height:52px}
  /* Une colonne de 130 px pour le nom du groupe ne laisse plus rien à la
     barre : le nom passe au-dessus. */
  .stat-jour{grid-template-columns:1fr;gap:5px}
  .stat-jours{gap:12px}
  .stat-val{font-size:var(--t2);padding:0 8px}
}

/* ---------- SEMAINE ALLÉGÉE ---------- */
/* La carte d'un jour empilait quatre en-têtes de repas en capitales
   espacées, un dégradé, un titre de 22 px et des puces cerclées : beaucoup
   de matière pour peu d'information. On baisse le contraste de tout ce qui
   n'est pas un aliment, seul contenu réel de l'écran. */
.day-head{
  padding:10px 13px;
  background:none}
.day-head h3{font-size:var(--t5)}

.meal{padding:9px 13px}
.meal-t{
  font-size:var(--t1);letter-spacing:.12em;margin-bottom:6px;opacity:.75}

/* Les puces perdent leur cadre au profit d'un fond discret : à quinze par
   carte, quinze bordures faisaient une grille. */
.chip{
  border-color:transparent;background:var(--voile-2);
  padding:4px 9px}
.chip:hover{border-color:var(--line-hi);background:var(--voile-3)}
.chip.recipe{background:rgba(94,200,255,.10)}
.chip.recipe:hover{border-color:rgba(94,200,255,.45)}

.kcal-tag{opacity:.65}
.kcal-tag.jour{opacity:.9}

.meal-masques{border-bottom:none;padding-top:6px;opacity:.6}
.meal-masques:hover{opacity:1}

/* Mode compact : moins d'air, plus de jours à l'écran. */
.week.compact{gap:10px;grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.week.compact .day-head{padding:8px 11px}
.week.compact .day-head h3{font-size:var(--t5)}
.week.compact .meal{padding:7px 11px}
.week.compact .meal-t{margin-bottom:5px}
.week.compact .chips{gap:4px}
.week.compact .chip{padding:3px 8px;font-size:var(--t3)}

/* Panneau des réglages d'affichage. */
.affichage-wrap{margin-left:auto}
.affichage-menu{min-width:210px;gap:4px}
.affichage-menu .switch{width:100%;justify-content:space-between;border-color:transparent}
.affichage-menu .switch:hover{border-color:var(--line-hi)}
.affichage-menu .switch.on .switch-txt{color:var(--acid)}
.affichage-menu .switch.on{border-color:transparent;background:none}
.affichage-menu .switch.on .switch-track{background:var(--acid)}
.affichage-menu .switch.on .switch-knob{transform:translateX(12px);background:var(--bg)}

/* Le bouton d'aide reste le dernier de la rangée. */
.sec-head .affichage-wrap + .aide-btn{margin-left:0}

/* ---------- RÉSERVE DE PLATS PRÉPARÉS ---------- */
/* Ce qui est déjà cuisiné, en attente d'être posé dans un repas. Le bloc
   se tient au-dessus de la grille, à portée de glissement. */
.reserve{
  border-radius:var(--r);background:var(--bg-2);
  padding:11px 13px;margin-bottom:14px;box-shadow:var(--ombre)}
.reserve-t{margin-bottom:8px}
.reserve-aide{color:var(--acid);opacity:.8}
.reserve-lignes{display:flex;flex-wrap:wrap;gap:8px}

.plat{
  display:inline-flex;align-items:center;gap:8px;
  border:1px solid var(--line-hi);border-radius:var(--r);
  background:var(--voile-1);padding:5px 8px;transition:.15s;
  cursor:grab}
.plat:hover{border-color:var(--ink-dim)}
.plat.en-deplacement{opacity:.4;cursor:grabbing}
/* Le plat sélectionné attend un repas : il reste visible pendant qu'on
   parcourt la semaine des yeux. */
.plat.arme{border-color:var(--acid);background:rgba(217,255,61,.10)}
.plat-nom{font-size:var(--t3);color:var(--ink);text-align:left}
.plat.arme .plat-nom{color:var(--acid)}
.plat-parts{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);
  color:var(--acid);font-variant-numeric:tabular-nums}
.plat-kcal{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim)}
.plat-btn{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t3);line-height:1;
  color:var(--ink-dim);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  width:22px;height:22px;display:grid;place-items:center}
.plat-btn:hover{color:var(--acid);border-color:var(--acid)}

.reserve-form{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap}
.reserve-form input{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:6px 8px;font-size:var(--t3);outline:none;min-width:0}
.reserve-form input:focus{border-color:var(--acid)}
.reserve-form #reserveNom{flex:1 1 200px}
.reserve-form #reserveParts{width:64px;font-family:'JetBrains Mono',ui-monospace,monospace}

/* Repas prêt à recevoir une part. */
.meal.cible{background:rgba(217,255,61,.10);outline:1px dashed var(--acid);outline-offset:-2px}
/* Un plat sélectionné : le survol ne dit rien au doigt, il faut que chaque
   repas se signale de lui-même comme atteignable. */
.week.en-attente .meal.cible-possible{
  cursor:copy;border-color:rgba(217,255,61,.35)}
.week.en-attente .meal.cible-possible:hover{background:rgba(217,255,61,.07)}

@media (max-width:620px){
  .reserve-form #reserveNom{flex:1 1 100%}
}

/* ---------- En-tête collant sur téléphone ----------
   Il ne reste qu'une rangée — le signe et le bouton ☰ — depuis que la
   navigation est passée en bas. Elle se colle plutôt que de disparaître :
   sinon le profil, le thème et le mode suppression deviennent
   inatteignables dès qu'on descend dans la semaine.

   Le fond doit être plein : collé, l'en-tête laisserait voir le contenu
   défiler à travers ses dégradés. */
@media (max-width:620px){
  header{
    position:sticky;top:0;z-index:850;
    background:
      radial-gradient(900px 300px at 10% -40%, rgba(217,255,61,.10), transparent 70%),
      radial-gradient(600px 260px at 90% -60%, rgba(255,92,31,.10), transparent 70%),
      var(--bg);
    padding-bottom:8px;
  }
  /* Le panneau du ☰ peut être plus haut que l'écran : il défile seul
     plutôt que de pousser l'en-tête hors du cadre. */
  .toolbar.ouverte{max-height:70vh;overflow-y:auto}
}

/* ---------- En-tête de section en une ligne ----------
   Titre, portée, boutons d'action et « ? » se repliaient sur trois ou
   quatre lignes imprévisibles. La portée — « Propre à ton compte ·
   commune à ses semaines » — s'apprend une fois : elle rejoint l'aide,
   derrière le « ? », et ne prend plus de place au quotidien. */
@media (max-width:620px){
  .sec-head{
    gap:6px 8px;margin-bottom:10px;padding-bottom:6px;
    flex-wrap:nowrap;align-items:center;
  }
  /* Le titre prend ce qui reste et se coupe proprement plutôt que de
     pousser les boutons à la ligne. */
  .sec-head h2{
    flex:1 1 auto;min-width:0;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .sec-head .portee{display:none}
  section.aide-ouverte .sec-head{flex-wrap:wrap}
  section.aide-ouverte .sec-head .portee{
    display:block;flex:1 1 100%;order:10;margin-top:2px;
  }
  /* Les commandes restent groupées à droite, sans s'étirer. */
  .sec-head .mini,.sec-head .actualiser,.sec-head .aide-btn,
  .sec-head .menu-wrap,.sec-head .field{flex:0 0 auto}
  .sec-head .field{padding:4px 8px}
  .sec-head .field select{font-size:var(--t3)}
}

/* ---------- Bande de la barre d'état ----------
   La page occupe tout l'écran : elle passe sous l'horloge et la
   batterie, et iOS floute ce qu'il trouve là pour les garder lisibles.
   Les deux halos de l'en-tête, dessinés pour une en-tête de plusieurs
   rangées et désormais compressés dans une seule, s'y étalaient en
   traînée trouble.

   On repeint la bande en aplat, et l'en-tête avec — sinon la limite de
   la bande se verrait comme un trait. Sur un appareil sans encoche,
   env() vaut zéro : la bande fait zéro pixel et rien ne change. */
@media (max-width:620px){
  body::after{
    content:'';position:fixed;top:0;left:0;right:0;
    height:env(safe-area-inset-top);
    background:var(--bg);
    /* Au-dessus du grain (999), sous les fenêtres (1050 et plus) : une
       fenêtre ouverte doit continuer de couvrir tout l'écran. */
    z-index:1000;
    pointer-events:none;
  }
  header{background:var(--bg)}
  /* Le trait d'activité était sous l'horloge, donc invisible. Il
     redescend sous la bande. */
  .busy{top:env(safe-area-inset-top)}
}

/* ---------- Questionnaire d'accueil ----------
   Un enchaînement de quatre écrans dans une fenêtre. Ce qui le
   distingue des autres fenêtres : on y avance, donc il faut voir où
   l'on en est (la jauge) et pouvoir revenir (le pied de page). */
.gate-box.accueil{
  width:min(560px,100%);
  /* Le quatrième écran peut être long ; il défile seul plutôt que de
     déborder de l'écran sur un téléphone. */
  max-height:min(84vh,780px);overflow-y:auto;
  padding:20px 22px 18px;
}
.accueil-jauge{
  height:3px;border-radius:99px;background:var(--voile-2);
  margin:0 0 18px;overflow:hidden;
}
.accueil-jauge i{
  display:block;height:100%;width:0;border-radius:99px;
  background:var(--acid);transition:width .25s cubic-bezier(.2,.8,.3,1);
}
.accueil-vue[hidden]{display:none}
.gate-box.accueil .accueil-intro{margin:0 0 16px}
/* Un bloc peut porter deux questions : ce titre les sépare sans
   prendre la place d'un écran de plus. */
.gate-box.accueil .accueil-sous{
  margin:18px 0 8px;font-size:var(--t2);color:var(--ink-dim);
  letter-spacing:.08em;text-transform:uppercase;
  font-family:'JetBrains Mono',ui-monospace,monospace;
}
.gate-box.accueil .accueil-note{
  margin:12px 0 0;font-size:var(--t2);color:var(--ink-2);
}
.gate-box.accueil .accueil-reco{
  margin:14px 0 0;font-size:var(--t3);color:var(--ink);
  border-left:2px solid var(--acid);padding-left:10px;
}
/* Le fond de la fenêtre et celui des champs sont la même couleur : les
   champs se creusent d'un ton pour rester lisibles comme des champs. */
.gate-box.accueil .field{background:var(--bg)}

/* Les objectifs : cinq cartes plutôt qu'un menu déroulant. Cinq choix
   qu'on compare valent d'être montrés ensemble. */
.accueil-choix{display:flex;flex-direction:column;gap:6px}
.accueil-carte{
  display:flex;align-items:baseline;gap:10px;width:100%;text-align:left;
  border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--bg);color:var(--ink);
  padding:11px 13px;font-size:var(--t4);cursor:pointer;
  transition:border-color .15s,background .15s;
}
.accueil-carte:hover{border-color:var(--line-hi)}
.accueil-carte.on{border-color:var(--acid);background:var(--voile-1)}
.accueil-carte-nom{flex:1 1 auto}
.accueil-carte-detail{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);white-space:nowrap;
}
.accueil-carte.on .accueil-carte-detail{color:var(--acid)}

/* Le rythme : huit nombres, de zéro à sept. Un chiffre se choisit plus
   vite qu'une tranche décrite en toutes lettres. */
.accueil-nombres{display:flex;flex-wrap:wrap;gap:6px}
.accueil-nb{
  flex:1 1 52px;min-width:48px;min-height:48px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--bg);color:var(--ink);cursor:pointer;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t5);
  transition:border-color .15s,background .15s,color .15s;
}
.accueil-nb:hover{border-color:var(--line-hi)}
.accueil-nb.on{border-color:var(--acid);background:var(--acid);color:var(--bg)}
.accueil-nb span{font-size:var(--t1);letter-spacing:.04em;text-transform:uppercase}
#acDecoupeWrap{margin-top:14px}
#acDecoupeWrap select{width:100%}

/* Le récapitulatif : la cible d'abord, le programme ensuite. */
.accueil-cible{
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  border:1px solid var(--line-hi);border-radius:var(--r);
  padding:14px 16px;margin-bottom:14px;
}
.accueil-cible-valeur{
  font-family:'Anton',Impact,sans-serif;font-size:var(--t8);line-height:1;
  color:var(--acid);
}
.accueil-cible-unite{font-size:var(--t3);color:var(--ink-dim)}
.accueil-macros{
  display:flex;gap:16px;flex-wrap:wrap;width:100%;margin-top:6px;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);
}
.gate-box.accueil .accueil-manque{
  margin:0 0 14px;color:var(--danger);font-size:var(--t3);
}
/* Un avertissement, pas une faute : la semaine a le droit de porter
   déjà des séances. */
.gate-box.accueil .accueil-avis{
  margin:0 0 10px;color:var(--fire);font-size:var(--t2);
}
.accueil-prog-titre{
  font-size:var(--t3);font-weight:600;color:var(--fire);
  margin:0 0 8px;
}
.accueil-prog{display:flex;flex-direction:column;gap:4px;margin-bottom:12px}
.accueil-prog-ligne{
  display:flex;align-items:baseline;gap:10px;
  padding:8px 12px;border-radius:var(--r-sm);background:var(--bg);
  font-size:var(--t3);
}
.accueil-prog-jour{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);min-width:74px;
}
.accueil-prog-nom{flex:1 1 auto}
.accueil-creer{
  display:flex;align-items:flex-start;gap:9px;cursor:pointer;
  font-size:var(--t3);color:var(--ink-dim);
}
.accueil-creer input{margin-top:2px;flex:none}

/* Le pied : revenir à gauche, avancer au milieu, renoncer à droite. */
.accueil-pied{align-items:center;gap:8px;margin-top:20px}
.accueil-pied .tbtn.suite{border-color:var(--acid);color:var(--acid)}
.accueil-pied .tbtn.discret{
  margin-left:auto;border-color:transparent;color:var(--ink-2);
}
.accueil-pied .tbtn.discret:hover{color:var(--bg)}
.accueil-compte{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);
}

@media (max-width:620px){
  .gate-box.accueil{padding:16px 15px 14px}
  /* Sur téléphone, « Plus tard » passe à la ligne plutôt que de serrer
     les deux boutons qui comptent. */
  .accueil-pied{flex-wrap:wrap}
  .accueil-pied .tbtn.discret{margin-left:0;order:10}
  .accueil-compte{margin-left:auto}
}

@media (prefers-reduced-motion:reduce){
  .accueil-jauge i{transition:none}
}

/* ---------- Barème du questionnaire d'accueil ----------
   Huit lignes, une par rythme. Chacune tient sur deux rangées : les
   réglages courts en haut, la phrase de conseil en dessous, où elle a
   la place de se lire. */
.reco-bloc{
  margin-top:22px;border-top:1px solid var(--line);padding-top:16px;
}
.reco-bloc > summary{
  cursor:pointer;font-size:var(--t3);color:var(--fire);
  font-weight:600;list-style:none;
}
.reco-bloc > summary::-webkit-details-marker{display:none}
.reco-bloc > summary::before{content:'▸ ';font-size:var(--t2)}
.reco-bloc[open] > summary::before{content:'▾ '}
.reco-intro{
  margin:10px 0 14px;font-size:var(--t2);color:var(--ink-dim);max-width:68ch;
}
.reco-lignes{display:flex;flex-direction:column;gap:8px}
/* Les trois tables se suivent dans une seule colonne : un titre les
   sépare, dans l'ordre des blocs du questionnaire. */
.reco-titre{
  margin:16px 0 2px;font-size:var(--t2);color:var(--ink-dim);
  letter-spacing:.06em;text-transform:uppercase;
  font-family:'JetBrains Mono',ui-monospace,monospace;
}
.reco-titre:first-child{margin-top:0}
.reco-ligne .field.reco-bonus,.reco-ligne .field.reco-plafond{max-width:150px}
.reco-ligne{
  display:grid;
  grid-template-columns:auto minmax(110px,1fr) minmax(150px,1fr) minmax(130px,1fr);
  gap:8px;align-items:center;
  padding:10px 12px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--bg-2);
}
.reco-nb{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t5);
  color:var(--acid);min-width:1.2em;text-align:center;
}
.reco-ligne .field{background:var(--bg);padding:6px 10px}
.reco-ligne .field input,.reco-ligne .field select{width:100%;font-size:var(--t3)}
.reco-ligne .field.reco-conseil{grid-column:1 / -1}
/* Le rythme « zéro séance » ne compose aucun programme : sa case de
   découpe n'aurait rien à décrire. */
.reco-ligne .field.vide{opacity:.4}
.reco-pied{margin-top:14px}

@media (max-width:820px){
  .reco-ligne{grid-template-columns:auto 1fr}
  .reco-ligne .field.reco-activite,
  .reco-ligne .field.reco-decoupe{grid-column:2 / -1}
}

/* ---------- Comptes suspendus ----------
   Un compte désactivé garde tout et se relit : il s'éteint, il ne
   disparaît pas. Assez pâle pour qu'on voie qu'il ne compte plus, assez
   lisible pour qu'on sache qui c'est. */
.compte-inactif > td{opacity:.5}
.compte-inactif:hover > td{opacity:.8}
.tag-inactif{border-color:var(--fire);color:var(--fire);margin-left:6px}
.comptes-astuce{
  margin:12px 0 0;font-size:var(--t2);color:var(--ink-dim);max-width:72ch;
}
.comptes-astuce[hidden]{display:none}

/* ---------- En-tête de carte de jour ----------
   Le compte de séances et le badge sport se rangent à droite du nom du
   jour ; sur un écran étroit ils passent à la ligne plutôt que de
   l'écraser. */
@media (max-width:620px){
  .day-head{flex-wrap:wrap}
  .day-head-actions{flex-wrap:wrap;gap:6px}
}

/* ---------- Mode séance : la zone sûre ----------
   Plein écran veut dire sous l'horloge. Cette vue n'était atteignable
   que depuis la ligne « Sport » de l'en-tête, absente du téléphone :
   le défaut ne s'y était donc jamais vu.

   Le mode jour est une fenêtre centrée sur un voile — il ne touche pas
   les bords et n'a rien à dégager. */
@media (max-width:620px){
  .focus:not(.mode-jour) .focus-tete{
    padding-top:max(14px, env(safe-area-inset-top));
    padding-left:max(14px, env(safe-area-inset-left));
    padding-right:max(14px, env(safe-area-inset-right));
  }
  .focus:not(.mode-jour) .focus-corps{
    padding-left:max(14px, env(safe-area-inset-left));
    padding-right:max(14px, env(safe-area-inset-right));
  }

  /* Sept jours ne tiennent pas sur une ligne de téléphone : ils se
     répartissent sur deux ou trois, et la dernière, incomplète et collée
     à gauche, laissait un bord déchiqueté. Centrée, la grappe se lit
     comme un tout.

     Chaque bande prend toute la largeur, sinon le space-between de la
     barre de titre les remettrait côte à côte et le centrage n'aurait
     rien à centrer. La semaine et le bouton Fermer s'écartent alors aux
     deux bouts de leur propre ligne. */
  .focus:not(.mode-jour) .focus-jours{flex:1 1 100%;justify-content:center}
  .focus:not(.mode-jour) .focus-meta{flex:1 1 100%;justify-content:space-between}
}

/* ---------- Page Version ----------
   Une frise : le numéro de version fait jalon, les changements se
   rangent dessous. La nature de chacun se lit à la couleur avant de se
   lire au mot — vert pour ce qui est neuf, bleu pour ce qui s'améliore,
   orange pour ce qui se répare. */
.version-actuelle{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  padding:16px 18px;margin-bottom:22px;
  border:1px solid var(--line-hi);border-radius:var(--r);
  background:var(--bg-2);box-shadow:var(--ombre);
}
.version-num{
  font-family:'Anton',Impact,sans-serif;font-size:var(--t7);line-height:1;
  color:var(--acid);
}
.version-dit{font-size:var(--t3);color:var(--ink-dim)}
.version-actuelle.desaccord{border-color:var(--danger)}
.version-actuelle.desaccord .version-num{color:var(--danger)}
.version-actuelle.desaccord .version-dit{color:var(--danger)}

.version-liste{display:flex;flex-direction:column}

.version-jalon{
  display:flex;align-items:baseline;gap:12px;
  margin:22px 0 10px;padding-bottom:8px;
  border-bottom:1px solid var(--line);
}
.version-jalon:first-child{margin-top:0}
.version-jalon-num{
  font-family:'Anton',Impact,sans-serif;font-size:var(--t5);line-height:1;
  color:var(--ink);letter-spacing:.02em;
}
.version-jalon-date{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t2);
  color:var(--ink-dim);
}

.version-ligne{
  display:flex;align-items:flex-start;gap:12px;
  padding:11px 2px;border-bottom:1px solid var(--voile-1);
}
.version-ligne:last-child{border-bottom:none}
.version-genre{
  flex:none;min-width:74px;text-align:center;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.1em;
  border:1px solid currentColor;border-radius:99px;padding:3px 7px;
  margin-top:2px;
}
.genre-ajout .version-genre{color:var(--acid)}
.genre-amelioration .version-genre{color:var(--cool)}
.genre-correction .version-genre{color:var(--fire)}

.version-corps{flex:1 1 auto;min-width:0}
.version-titre{margin:0;font-size:var(--t4);color:var(--ink)}
.version-detail{
  margin:4px 0 0;font-size:var(--t3);color:var(--ink-dim);
  max-width:72ch;
}
.version-ligne .acts{flex:none}

@media (max-width:620px){
  .version-actuelle{padding:13px 14px;margin-bottom:16px}
  /* L'étiquette de nature garde sa ligne ; les actions passent dessous
     plutôt que de comprimer le texte. */
  .version-ligne{flex-wrap:wrap;gap:8px 10px}
  .version-corps{flex:1 1 60%}
  .version-ligne .acts{flex:1 1 100%;justify-content:flex-start}
}

/* ---------- Cibles ----------
   Une commande se vise avec un doigt — environ 9 mm, soit 44 px — ou
   avec un pointeur, précis au pixel. Les nôtres faisaient 16 à 31 px :
   hors d'atteinte du premier, inconfortables pour le second.

   Deux réglages, donc, et non un seul. À la souris, les commandes
   grossissent juste assez pour qu'on ne les manque plus. Au doigt, le
   dessin grossit un peu et une zone transparente déborde autour pour
   atteindre 44 px sans que l'interface s'alourdisse.

   Ce débordement est borné par l'écart qui sépare deux commandes
   voisines : au-delà, elles se voleraient les clics. C'est pourquoi les
   marges ci-dessous ne sont pas toutes égales — chacune est calculée
   sur l'écart réel de son voisinage. */

/* Aucune déclaration « display » ici, et c'est délibéré. Un <button>
   centre déjà son contenu dans les deux sens : la poser n'apportait
   rien, et elle écrasait les règles qui masquent certains boutons —
   .barre-btn{display:none} a la même spécificité et vient avant, si
   bien que le ☰ du téléphone réapparaissait sur grand écran. Une règle
   partagée ne doit toucher que les propriétés qu'elle a besoin de
   toucher. */

.mini,.tbtn{min-height:34px;padding-left:12px;padding-right:12px}
.add{min-width:30px;min-height:30px;padding:0 6px}
.aide-btn{width:28px;height:28px;flex:0 0 28px}
.chip .x{min-width:26px;min-height:26px;padding:0 4px}
.ck{width:20px;height:20px;flex:0 0 20px}

@media (hover:none) and (pointer:coarse){
  .mini,.tbtn{min-height:44px;padding-left:14px;padding-right:14px}
  .add{min-width:40px;min-height:40px}
  .aide-btn{width:36px;height:36px;flex:0 0 36px}
  .chip .x{min-width:34px;min-height:34px}
  .ck{width:24px;height:24px;flex:0 0 24px}
  /* La croix d'une ligne d'ingrédient : les formulaires lui fixent
     22 px par un sélecteur à identifiant, mais min-width passe devant
     width sans avoir à le battre en spécificité. */
  .modele-ligne > .x{min-width:40px;min-height:40px}

  .add,.aide-btn,.chip .x,.ck{position:relative}
  /* 4 px de débordement : les voisins les plus serrés sont à 6 px
     (.acts, .chips), donc 3 px chacun sans se toucher — on prend 4,
     l'écart le plus fréquent étant de 10 px. */
  .add::after,.aide-btn::after,.chip .x::after{
    content:'';position:absolute;inset:-4px;
  }
  /* La case d'une ligne de courses et son nom déclenchent la même
     bascule : leurs zones peuvent se recouvrir sans conséquence. En
     hauteur, en revanche, on s'arrête au bord de la ligne — déborder
     cocherait l'article du dessus. */
  .ck::after{content:'';position:absolute;inset:-8px -10px}
}

/* ---------- Raccourci du mode séance ----------
   Il vit dans l'en-tête, à gauche du ☰, et porte la couleur du sport
   pour qu'on ne le confonde pas avec le menu. Sur grand écran il n'a pas
   lieu d'être : la ligne « Sport » de l'en-tête et l'onglet Séances y
   sont tous deux à portée de souris. */
.sport-btn{display:none}

@media (max-width:620px){
  .sport-btn:not([hidden]){
    display:inline-flex;align-items:center;justify-content:center;
    margin-left:auto;padding:7px 12px;
    border-color:var(--fire);color:var(--fire);
  }
  .sport-btn:not([hidden]):hover{background:var(--fire);color:#000}
  .sport-btn svg{width:20px;height:20px;display:block}

  /* Quand il est là, c'est lui qui pousse la paire vers la droite : le ☰
     le suit au lieu de s'en écarter. Absent — la semaine ne porte aucune
     séance — le ☰ reprend sa marge automatique et retrouve le bord. */
  .sport-btn:not([hidden]) + .barre-btn{margin-left:0}
}

/* ---------- Fermer, dans la vue séance ----------
   Petit et collé à droite. L'en-tête de la vue ne défile pas — c'est le
   corps qui défile sous lui — si bien que le bouton reste là quoi qu'on
   fasse, sans avoir à le fixer.

   Le dessin seul rapetisse : une zone transparente ramène la cible à
   44 px au doigt, comme partout ailleurs. Un bouton qu'on veut discret
   n'est pas un bouton qu'on veut manquer. */
.focus-meta{margin-left:auto;flex-wrap:nowrap}
.focus-fermer{
  position:relative;flex:none;white-space:nowrap;
  font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:var(--t1);letter-spacing:.09em;text-transform:uppercase;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:5px 10px;color:var(--ink-dim);background:none;transition:.15s;
}
.focus-fermer:hover{background:var(--fire);border-color:var(--fire);color:#000}

@media (hover:none) and (pointer:coarse){
  /* L'en-tête a 14 px de marge au-dessus et le voisin le plus proche
     est à 12 px : on déborde de 10 px en hauteur, 8 en largeur. */
  .focus-fermer::after{content:'';position:absolute;inset:-10px -8px}
}

/* ---------- Fenêtre de modèle ----------
   Neuf colonnes dans 620 px ne laissaient qu'un tiers de nom d'exercice
   visible. Elle s'élargit — sur grand écran seulement : sur téléphone
   les lignes se replient déjà et la fenêtre y occupe toute la largeur,
   qu'il ne faut pas dépasser. */
@media (min-width:621px){
  #modeleModal .gate-box,#seanceModal .gate-box{width:min(780px,100%)}
}

/* ---------- Bandeau hors ligne ----------
   Un état, pas une alerte : on le pose en bas, discret et permanent,
   plutôt qu'en haut où il recouvrirait l'en-tête et l'encoche. Au-dessus
   de la barre de navigation, en dessous des fenêtres et de la vue séance
   — celles-ci ont le droit de le cacher, on n'y modifie rien de toute
   façon. */
.hors-ligne-bandeau{
  position:fixed;z-index:1140;
  left:16px;bottom:16px;max-width:calc(100vw - 32px);
  display:flex;align-items:center;gap:10px;
  padding:9px 14px;border-radius:99px;
  border:1px solid var(--fire);background:var(--bg-2);
  box-shadow:var(--ombre-haute);
  font-size:var(--t2);color:var(--ink-dim);
}
.hors-ligne-bandeau[hidden]{display:none}
.hors-ligne-point{
  flex:none;width:8px;height:8px;border-radius:99px;background:var(--fire);
}
.hors-ligne-texte{flex:1 1 auto;min-width:0}
.hors-ligne-bandeau .mini{flex:none}

@media (max-width:620px){
  /* Au-dessus de la barre du bas, et sur toute la largeur : sur un
     téléphone, une pastille de coin passerait inaperçue. */
  .hors-ligne-bandeau{
    left:10px;right:10px;max-width:none;
    bottom:calc(70px + env(safe-area-inset-bottom));
    border-radius:var(--r);
  }
  /* La vue séance prend tout l'écran et n'a rien à modifier : le
     bandeau n'y a pas sa place. */
  body.focus-ouvert .hors-ligne-bandeau{display:none}
}

@media (prefers-reduced-motion:no-preference){
  /* Le point bat lentement : un état qui dure se signale sans crier. */
  .hors-ligne-point{animation:pouls 2.4s ease-in-out infinite}
  @keyframes pouls{0%,100%{opacity:1}50%{opacity:.35}}
}

/* ---------- Champs de date ----------
   « jj/mm/aaaa » plus l'icône du calendrier ne tiennent pas dans les
   90 px prévus pour un nombre : l'année se retrouvait coupée. Le champ
   prend la largeur qu'il lui faut, avec un plancher pour que les trois
   groupes restent lisibles même quand le navigateur les resserre. */
.field input[type="date"]{width:auto;min-width:152px}
@media (max-width:620px){
  /* En colonne, le champ occupe toute sa ligne : sans cela
     l'unité qui suit — l'âge calculé — flotterait au milieu. */
  .calcul-champs .field input[type="date"]{flex:1 1 auto}
}

/* ---------- Paragraphes des fenêtres ----------
   .gate-box p conserve les retours à la ligne, parce que le message
   d'erreur de la page de connexion en pose pour aérer son propos. Mais
   les paragraphes du questionnaire, eux, sont écrits dans le HTML : ils
   y sont indentés pour la lecture du code, et cette indentation
   s'affichait telle quelle, décalant une ligne sur deux.

   Seul celui qui en a besoin garde le réglage ; les autres reviennent au
   retour à la ligne ordinaire. */
.gate-box.accueil p{white-space:normal}
#gateMsg{white-space:pre-wrap}

/* ---------- Composeur ----------
   Deux familles de pastilles — les muscles, le matériel qu'on a sous la
   main — une recherche, et la liste de ce qui reste. Les pastilles
   reprennent celles des filtres de recettes, dans la couleur du sport. */
.composeur-pli{
  margin:2px 0 10px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--bg);
}
.composeur-pli > summary{
  cursor:pointer;list-style:none;padding:10px 12px;
  font-size:var(--t3);font-weight:600;color:var(--fire);
}
.composeur-pli > summary::-webkit-details-marker{display:none}
.composeur-pli > summary::before{content:'▸ ';font-size:var(--t2)}
.composeur-pli[open] > summary::before{content:'▾ '}

.composeur{display:flex;flex-direction:column;gap:10px;padding:0 12px 12px}
.composeur-rang{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.composeur-titre{
  flex:1 1 100%;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-dim);
}
.composeur .chip-filtre{display:inline-flex;align-items:center;gap:6px;padding:5px 10px}
.composeur-n{font-size:var(--t1);opacity:.65}
.composeur .composeur-recherche{
  background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:7px 10px;font-size:var(--t3);color:var(--ink);outline:none;width:100%;
}
.composeur .composeur-recherche:focus{border-color:var(--acid)}

/* La liste défile seule : la fenêtre ne doit pas devenir aussi longue que
   le catalogue. */
.composeur-liste{
  max-height:260px;overflow-y:auto;overscroll-behavior:contain;
  border:1px solid var(--line);border-radius:var(--r-sm);
}
.composeur-exo{
  display:flex;align-items:center;gap:10px;
  padding:6px 6px 6px 10px;border-bottom:1px solid var(--voile-1);
}
.composeur-exo:last-child{border-bottom:none}
.composeur-exo-nom{flex:1 1 auto;min-width:0;font-size:var(--t3);color:var(--ink)}
/* L'image, le nom et le muscle forment une seule zone : la toucher
   agrandit l'image. Le « + » reste à droite, à part. */
.composeur-exo-voir{
  flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:10px;
  padding:0;border:none;background:none;color:inherit;font:inherit;text-align:left;
}
button.composeur-exo-voir{cursor:zoom-in}
button.composeur-exo-voir:disabled{cursor:default}
.composeur-exo-texte{display:flex;flex-direction:column;gap:2px;min-width:0}
.composeur-exo-meta{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);color:var(--ink-dim);
}
.composeur-apercu{
  flex:none;width:40px;height:40px;display:block;object-fit:cover;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);background:var(--saisie);
  transition:border-color .15s, transform .15s;
}
/* Sans image, l'haltère remplit la vignette moins une marge : centré à
   toutes les tailles, quelle que soit la règle qui pose la vignette. */
.composeur-apercu.sans-image{color:var(--ink-dim);opacity:.6}
.composeur-apercu.sans-image svg{display:block;width:100%;height:100%;padding:22%}
button.composeur-exo-voir:not(:disabled):hover .composeur-apercu,
button.composeur-exo-voir:focus-visible .composeur-apercu{border-color:var(--fire);transform:scale(1.06)}
button.composeur-exo-voir:focus-visible{outline:none}
@media (hover:none) and (pointer:coarse){
  /* Au doigt, l'image est la cible : un peu plus grande. */
  .composeur-apercu{width:46px;height:46px}
}
.composeur-plus{flex:none;min-width:34px}
/* Déjà dans la séance : on peut l'ajouter encore — deux variantes d'un
   même mouvement, par exemple — mais on le voit. */
.composeur-exo.deja .composeur-exo-nom{color:var(--ink-dim)}
.composeur-exo.deja .composeur-plus{border-color:var(--acid);color:var(--acid)}
.gate-box .composeur-vide,.gate-box .composeur-pied{margin:0;font-size:var(--t2);color:var(--ink-dim)}
.gate-box .composeur-vide{padding:12px}

.composeur-zone{display:flex;flex-direction:column;gap:6px}
.composeur-zone[hidden]{display:none}

@media (max-width:620px){
  .composeur-liste{max-height:40vh}
}
@media (hover:none) and (pointer:coarse){
  .composeur .chip-filtre{min-height:38px}
}

/* ---------- Muscles ciblés et programmes ---------- */
.modele-muscles{display:flex;flex-direction:column;gap:6px;margin:4px 0 6px}
.modele-muscles .chip-filtre{display:inline-flex;align-items:center;gap:6px;padding:5px 10px}
.modele-muscles-vide{font-size:var(--t2);color:var(--ink-dim)}

/* La tête d'un programme, dans l'onglet Modèles : son nom et de quoi le
   renommer pour tous ses modèles à la fois. */
.modeles-groupe-admin{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.modeles-groupe-admin .mini{font-weight:400}
.modeles-groupe-admin .chip-in{flex:1 1 200px;margin-top:0;color:var(--ink);font-weight:400}

/* Les muscles sur la carte d'un modèle. */
.modele-muscles-tags{display:flex;flex-wrap:wrap;gap:4px;margin:6px 0 2px}
.modele-muscle{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.06em;text-transform:uppercase;
  border:1px solid var(--fire);color:var(--fire);border-radius:99px;padding:2px 7px;
}
@media (hover:none) and (pointer:coarse){
  .modele-muscles .chip-filtre{min-height:38px}
}

/* ---------- Ajout d'exercice guidé ----------
   Le matériel occupe sa propre rangée : des pastilles qu'on coche, et un
   petit champ pour ce qui manque. L'image et son aperçu ferment la barre,
   juste avant le bouton. */
.exo-ajout-pastilles{flex:1 1 100%;display:flex;flex-direction:column;gap:6px}
.exo-ajout-pastilles .chip-filtre{display:inline-flex;align-items:center;padding:5px 10px}
.cat-ajout .exo-ajout-autre{
  max-width:280px;background:var(--saisie);border:1px solid var(--line-hi);
  border-radius:var(--r-sm);padding:6px 9px;font-size:var(--t3);color:var(--ink);outline:none;
}
.cat-ajout .exo-ajout-autre:focus{border-color:var(--acid)}
.cat-ajout .champ-image{flex:1 1 220px}
.exo-ajout-fichier{align-self:center}
.exo-ajout-apercu{
  flex:none;align-self:center;width:42px;height:42px;object-fit:cover;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);background:var(--saisie);
}
.exo-ajout-casse{align-self:center;font-size:var(--t2);color:var(--danger)}
@media (hover:none) and (pointer:coarse){
  .exo-ajout-pastilles .chip-filtre{min-height:38px}
}

/* ---------- Vignettes de l'éditeur de lignes ----------
   Une case de plus dans chaque ligne, et la même dans l'en-tête, à la
   même largeur : l'alignement des neuf autres colonnes en dépend. */
.modele-ligne .l-img,.modele-entete .l-img-vide{flex:none;width:30px;height:30px}
.modele-entete .l-img-vide{height:auto;padding:0}
.modele-ligne .l-img{
  display:grid;place-items:center;padding:0;border:none;background:none;
  border-radius:var(--r-sm);cursor:zoom-in;
}
.modele-ligne .l-img:disabled{cursor:default}
.modele-ligne .l-img .l-img-photo,
.modele-ligne .l-img .composeur-apercu{
  width:30px;height:30px;display:block;object-fit:cover;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);background:var(--saisie);
}
.modele-ligne .l-img:not(:disabled):hover .l-img-photo{border-color:var(--fire)}
@media (hover:none) and (pointer:coarse){
  .modele-ligne .l-img,.modele-entete .l-img-vide,
  .modele-ligne .l-img .l-img-photo,.modele-ligne .l-img .composeur-apercu{width:36px;height:36px}
  .modele-entete .l-img-vide{height:auto}
}

/* ---------- Aperçu des cartes de modèle ----------
   Chaque exercice en petite étiquette : son image, son nom, son volume. */
.modele-exos-liste{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.modele-exo{
  display:inline-flex;align-items:center;gap:7px;max-width:100%;
  padding:3px 9px 3px 3px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--bg);color:var(--ink-2);font:inherit;font-size:var(--t2);text-align:left;
}
button.modele-exo{cursor:zoom-in}
button.modele-exo:disabled{cursor:default}
button.modele-exo:not(:disabled):hover{border-color:var(--fire)}
.modele-exo .modele-exo-photo,.modele-exo .composeur-apercu{
  flex:none;width:28px;height:28px;display:block;object-fit:cover;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);background:var(--saisie);
}
.modele-exo-nom{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.modele-exo-series{
  flex:none;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);color:var(--ink-dim);
}

/* ---------- Aperçu du matériel au survol ----------
   Un pointillé sous le nom d'une machine qui a une image ; la bulle, au
   survol, au-dessus de tout — y compris d'une fenêtre ouverte. Les images
   ont une taille fixe : la bulle se place avant qu'elles soient chargées,
   et ne doit pas changer de taille ensuite. */
.materiel-survol{text-decoration:underline dotted;text-underline-offset:3px;cursor:help}
.materiel-bulle{
  position:fixed;z-index:1400;pointer-events:none;
  display:flex;gap:10px;padding:10px;
  background:var(--bg-2);border:1px solid var(--line-hi);border-radius:var(--r);
  box-shadow:var(--ombre-fenetre);
}
.materiel-bulle[hidden]{display:none}
.materiel-fig{margin:0;display:flex;flex-direction:column;gap:6px;align-items:center}
.materiel-fig img{
  width:140px;height:140px;object-fit:cover;display:block;
  border-radius:var(--r-sm);background:var(--saisie);
}
.materiel-fig figcaption{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-dim);
}

/* ---------- Les images du matériel, côté admin ---------- */
.materiel-apercu{flex:none;width:40px;height:40px;display:grid;place-items:center}
.materiel-apercu img,.materiel-apercu .composeur-apercu{
  width:40px;height:40px;object-fit:cover;display:block;
  border:1px solid var(--line-hi);border-radius:var(--r-sm);background:var(--saisie);
}
.materiel-casse{color:var(--danger);font-weight:600}
.materiel-in{
  flex:1 1 220px;min-width:0;background:var(--saisie);border:1px solid var(--line-hi);
  border-radius:var(--r-sm);padding:6px 9px;font-size:var(--t3);color:var(--ink);outline:none;
}
.materiel-in:focus{border-color:var(--acid)}

/* ---------- Grille des droits ----------
   Une ligne par famille, une colonne par rôle. La première colonne reste
   en place quand la grille défile de côté : sur téléphone, on lit ce que
   coche une case sans revenir au bord. */
.droits-intro{margin:0 0 14px;font-size:var(--t2);color:var(--ink-dim);max-width:68ch}
.droits-nouveau{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;margin-bottom:16px}
.droits-nouveau .field input{width:200px}
.droits-nouveau .field select{color:var(--ink)}
.droits-grille{border-collapse:separate;border-spacing:0;min-width:100%;font-size:var(--t3)}
.droits-grille th,.droits-grille td{border-bottom:1px solid var(--line);padding:8px 10px;vertical-align:middle}
.droits-grille thead th{vertical-align:bottom;border-bottom-color:var(--line-hi)}
.droits-coin,.droits-perm{
  position:sticky;left:0;z-index:1;background:var(--bg);
  text-align:left;font-weight:normal;min-width:190px;max-width:300px}
.droits-coin{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-dim)}
.droits-lib{display:block;color:var(--ink)}
.droits-desc{display:block;margin-top:2px;font-size:var(--t2);color:var(--ink-dim);line-height:1.35}
.droits-role{min-width:104px;text-align:center;font-weight:normal}
.droits-role .role-pill{display:inline-block}
.droits-n{display:block;margin-top:5px;font-size:var(--t1);color:var(--ink-dim);
  font-family:'JetBrains Mono',ui-monospace,monospace;font-variant-numeric:tabular-nums}
.droits-acts{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;margin-top:6px}
.droits-role .chip-in{width:100%;min-width:90px;margin-top:6px}
.droits-section th{
  padding:16px 0 6px;text-align:left;font-weight:normal;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-dim)}
.droits-section th span{position:sticky;left:0;padding-left:10px}
.droits-case{text-align:center}
.droits-coche{display:inline-grid;place-items:center;width:32px;height:32px;cursor:pointer;border-radius:var(--r-sm)}
.droits-coche:hover{background:var(--voile-2)}
.droits-coche input{accent-color:var(--acid);width:17px;height:17px;margin:0;cursor:pointer}
.droits-coche input:disabled{cursor:not-allowed;opacity:.55}
.droits-coche:has(input:disabled){cursor:not-allowed}
.droits-coche:has(input:disabled):hover{background:none}
.droits-coche:has(input:focus-visible){outline:2px solid var(--acid);outline-offset:1px}
@media (hover:none) and (pointer:coarse){
  .droits-coche{width:44px;height:44px}
  .droits-coin,.droits-perm{min-width:150px}
}

/* ---------- Gestion › Listes ----------
   Une carte par liste, côte à côte quand l'écran le permet. Chaque ligne :
   le nom, son usage, ses gestes ; le matériel y ajoute son image. */
.listes-blocs{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,340px),1fr));
  gap:16px;align-items:start}
.liste-bloc{padding:14px 16px 8px;border-radius:var(--r);background:var(--bg-2);box-shadow:var(--ombre);min-width:0}
.liste-tete{display:flex;align-items:baseline;gap:10px}
.liste-tete h3{margin:0;font-family:'Anton',Impact,sans-serif;font-weight:400;font-size:var(--t5)}
.liste-aide{margin:4px 0 12px;font-size:var(--t2);color:var(--ink-dim);line-height:1.45}
.liste-ajout{display:flex;gap:8px;margin-bottom:4px}
.liste-ajout-in{
  flex:1;min-width:0;background:var(--saisie);border:1px solid var(--line-hi);border-radius:var(--r-sm);
  padding:7px 10px;font-size:var(--t3);color:var(--ink);outline:none}
.liste-ajout-in:focus{border-color:var(--acid)}
.liste-valeurs{list-style:none;margin:0;padding:0}
.liste-ligne{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;
  padding:8px 0;border-top:1px solid var(--line)}
.liste-ligne:first-child{border-top:none}
.liste-nom{flex:1 1 auto;min-width:0;font-size:var(--t3);color:var(--ink);overflow-wrap:anywhere}
.liste-n{
  flex:none;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);
  color:var(--ink-dim);font-variant-numeric:tabular-nums}
.liste-n.zero{opacity:.6}
.liste-acts{display:inline-flex;flex-wrap:wrap;gap:4px;margin-left:auto}
.liste-fleche{min-width:30px;padding-left:0;padding-right:0}
.liste-fleche:disabled{opacity:.3;cursor:default}
.liste-ligne .chip-in{flex:1 1 100%;margin-top:0}
.liste-vide{padding:10px 0;font-size:var(--t2);color:var(--ink-dim)}
.liste-ligne > .materiel-apercu{width:34px;height:34px;padding:0;border:none;background:none;cursor:pointer}
.liste-ligne > .materiel-place{cursor:default}
.liste-ligne > .materiel-apercu img,
.liste-ligne > .materiel-apercu .composeur-apercu{width:34px;height:34px}
.liste-image{flex:1 1 100%;display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:6px 0 2px}
.liste-image-aide{flex:1 1 100%;margin:0;font-size:var(--t1);color:var(--ink-dim)}

/* Le rayon d'un aliment, sous son nom : où il tombe dans les courses. */
.rayon-tag{
  display:inline-block;margin-left:6px;padding:1px 7px;vertical-align:middle;
  border:1px solid var(--line-hi);border-radius:99px;background:none;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:var(--t1);letter-spacing:.04em;color:var(--ink-dim)}
.rayon-tag.vide{opacity:.65;font-style:italic}
.rayon-btn{cursor:pointer}
.rayon-btn:hover{color:var(--ink);border-color:var(--acid)}
.rayon-sel{
  margin-left:6px;padding:2px 6px;background:var(--saisie);color:var(--ink);
  border:1px solid var(--acid);border-radius:var(--r-sm);font-size:var(--t2)}

/* La fiche d'un exercice : le matériel en pastilles, comme à l'ajout. */
.exo-fiche-pastilles{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}
.exo-fiche-pastilles .chip-filtre{display:inline-flex;align-items:center;padding:5px 10px}
.exo-fiche-note{margin:0 0 12px;font-size:var(--t2);color:var(--ink-dim)}
#recetteForm .field select{flex:1;min-width:0}
#recetteForm .field select:disabled{opacity:1;color:var(--ink)}

/* Un bouton qui se lit comme un lien, au fil d'une phrase. */
.lien{
  background:none;border:none;padding:0;font:inherit;color:var(--acid);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer}

@media (hover:none) and (pointer:coarse){
  .liste-ligne > .materiel-apercu,
  .liste-ligne > .materiel-apercu img,
  .liste-ligne > .materiel-apercu .composeur-apercu{width:44px;height:44px}
  .liste-fleche{min-width:44px}
  .rayon-btn{display:inline-flex;align-items:center;min-height:44px;padding:0 12px}
  .exo-fiche-pastilles .chip-filtre{min-height:44px}
}

/* Un petit bouton qui ne peut pas servir le dit : grisé, et sans l'éclat
   du survol — sa raison est dans son infobulle. */
.mini:disabled{opacity:.4;cursor:not-allowed}
.mini:disabled:hover,.mini.dngr:disabled:hover{background:none;color:var(--ink-dim);border-color:var(--line-hi)}
