/* Respect du réglage système « réduire les animations ». Posé une fois pour toutes plutôt
   qu'au cas par cas : chaque animation ajoutée ensuite en hérite. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

:root {
  --bg: #f4f6f4;
  --surface: #ffffff;
  --surface-2: #f0f3ef;
  --text: #1f2a24;
  --text-soft: #64756b;
  --border: #e2e8e2;
  --accent: #2e9e5b;                 /* seul l'accent est éditable ; les dérivés suivent */
  /* Couleur de TEXTE accentuée (onglet actif, kcal du jour, KPI…) : elle s'assombrit sur
     papier clair. Le thème sombre la redéfinit dans l'autre sens — voir plus bas.
     24 % et non 18 % : à 18 % l'onglet actif ne donnait que 4,11:1 sur son fond teinté et
     4,42:1 sur le fond de page — sous le 4,5:1 de WCAG AA. Palier trouvé par mesure. */
  --accent-dark: color-mix(in srgb, var(--accent), #000 24%);
  /* Fond des boutons pleins, qui portent du texte BLANC. Doit rester sombre dans les DEUX
     thèmes : #2e9e5b sous du blanc ne donne que 3,41:1, sous le 4,5:1 de WCAG AA.
     Relevé par Lighthouse sur « ＋ Ajout rapide » le 2026-07-23. */
  --accent-solide: color-mix(in srgb, var(--accent), #000 24%);
  --accent-solide-hover: color-mix(in srgb, var(--accent), #000 38%);
  --accent-soft: color-mix(in srgb, var(--accent) 14%, var(--surface));
  --danger: #d3564b;
  --amber: #e8a33d;
  --shadow: 0 2px 8px rgba(30, 50, 40, .07);
  --shadow-lg: 0 12px 40px rgba(30, 50, 40, .18);
  --radius: 14px;
  --font: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* Thème sombre : appliqué explicitement via data-theme (le JS résout "auto"). */
:root[data-theme="dark"] {
  --bg: #161a17; --surface: #1e2420; --surface-2: #262d28;
  --text: #e7efe9; --text-soft: #9db0a4; --border: #303a33;
  --accent: #43c274;
  /* ⚠️ Sur fond sombre, « accent foncé » va dans le MAUVAIS sens : c'est une couleur de
     texte, elle doit s'ÉCLAIRCIR. Sans cette ligne, un accent choisi par l'utilisateur
     (posé en style inline par applyAccent, donc prioritaire sur le thème) redescendait à
     3,29:1 sur les onglets, les segmentés et les kcal du calendrier. */
  --accent-dark: color-mix(in srgb, var(--accent), #fff 14%);
  --shadow: 0 2px 8px rgba(0,0,0,.3); --shadow-lg: 0 12px 40px rgba(0,0,0,.5);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; overflow-x: clip; }
body {
  font-family: var(--font); background: var(--bg); color: var(--text);
  font-size: 15px; line-height: 1.45;
}
h1,h2,h3 { margin: 0; font-weight: 650; }
button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; font-size: 14px; }

/* ---------- Barre supérieure ---------- */
.topbar {
  display: flex; align-items: center; gap: 20px;
  padding: 10px 22px; background: var(--surface);
  border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 20;
}
/* Logo : bascule clair/sombre en CSS pur (le thème pose data-theme sur <html>).
   Affiché ENTIER, jamais rogné. `aspect-ratio` fixe la largeur d'après la hauteur, au
   ratio réel de l'image (575x200) : pas de déformation ni de largeur codée en dur. */
.brand {
  height: 38px; aspect-ratio: 575 / 200; flex: none;
  background: url("/yafint_clair.png") left center / contain no-repeat;
}
:root[data-theme="dark"] .brand { background-image: url("/yafint_sombre.png"); }
.tabs { display: flex; gap: 4px; margin-left: 10px; }
.tab {
  border: none; background: transparent; color: var(--text-soft);
  padding: 8px 14px; border-radius: 10px; font-size: 14px; font-weight: 600;
}
.tab:hover { background: var(--surface-2); color: var(--text); }
.tab.active { background: var(--accent-soft); color: var(--accent-dark); }
.btn-quick {
  border: none; background: var(--accent-solide); color: #fff;
  padding: 10px 18px; border-radius: 11px; font-weight: 700; font-size: 14px;
  box-shadow: var(--shadow); margin-left: auto;   /* pousse le bloc compte a droite */
}
.btn-quick:hover { background: var(--accent-solide-hover); }

/* Utilitaire global. Il n'existait pas : chaque cas était scopé (.toast.hidden,
   .auth-screen.hidden…), donc un nouvel élément portant `hidden` restait visible.
   Les règles scopées plus bas restent valides, elles sont juste redondantes. */
.hidden { display: none !important; }

/* ---------- Bouton compte + menu déroulant ---------- */
.account-wrap { position: relative; flex: none; }
.account-btn {
  display: flex; align-items: center; gap: 8px; max-width: 190px;
  padding: 5px 10px 5px 5px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text); font-weight: 600; font-size: 14px;
}
.account-btn:hover { background: var(--surface-2); }
.account-pic {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  background: var(--accent) center / cover no-repeat;
  color: #fff; font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
/* Troncature native : « Llanfairpwllgwyngyll… » sans une ligne de JS. */
.account-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-caret { font-size: 10px; color: var(--text-soft); flex: none; }

.account-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40; min-width: 210px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 6px; box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}
.account-menu button {
  display: block; width: 100%; text-align: left; padding: 10px 12px;
  border: none; background: transparent; color: var(--text);
  border-radius: 8px; font-size: 14px; font-weight: 600;
}
.account-menu button:hover { background: var(--surface-2); }

/* ---------- Vues ---------- */
main { max-width: 1120px; margin: 0 auto; padding: 22px; }
.view { display: none; }
.view.active { display: block; animation: fade .18s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; } }

/* Sous-navigation (section Nourriture) */
.subnav { margin-bottom: 18px; }
.subnav button { padding: 9px 18px; font-size: 14px; }
.subview { display: none; }
.subview.active { display: block; animation: fade .18s ease; }

.search {
  flex: 1; padding: 11px 15px; border: 1px solid var(--border);
  border-radius: 11px; background: var(--surface); color: var(--text);
}
.search:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }

.btn-primary {
  border: none; background: var(--accent-solide); color: #fff;
  padding: 11px 18px; border-radius: 11px; font-weight: 650; box-shadow: var(--shadow);
}
.btn-primary:hover { background: var(--accent-solide-hover); }
.btn-ghost {
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  padding: 8px 14px; border-radius: 10px; font-weight: 600;
}
.btn-ghost:hover { background: var(--surface-2); }
.btn-danger {
  border: 1px solid transparent; background: transparent; color: var(--danger);
  padding: 8px 12px; border-radius: 10px; font-weight: 600;
}
.btn-danger:hover { background: rgba(211,86,75,.1); }

/* ---------- Calendrier ---------- */
.cal-header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 14px; }
.cal-nav { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.cal-nav h2 { min-width: 190px; text-align: center; text-transform: capitalize; }
/* Chevron DESSINÉ, pas écrit. Le glyphe « ‹ » a son encre placée selon les métriques de la
   police, jamais au centre de sa boîte : le centrer demande une constante par police et par
   taille, et toute correction se révèle fausse dès qu'on change le mode de disposition.
   Un carré à deux bordures, tourné de 45°, est symétrique par construction — donc centré
   partout, quelle que soit la police. `font-size: 0` masque le caractère du HTML (conservé
   pour le sens ; les boutons portent un aria-label). */
.icon-btn {
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  width: 38px; height: 38px; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0; padding: 0; box-sizing: border-box;
}
.icon-btn::before {
  content: ""; display: block; width: 9px; height: 9px;
  border-top: 2px solid currentColor; border-right: 2px solid currentColor;
}
/* Aucun décalage à corriger : les deux bordures tracées couvrent toute la largeur ET toute
   la hauteur de la boîte, l'encre a donc le même centre qu'elle. Flex centre la boîte, la
   rotation se fait autour de ce centre — le chevron est centré sur les deux axes, exactement.
   (Un `translate` avait été ajouté ici « pour compenser » : il ne compensait rien et décalait
   l'horizontale de 1,41 px.) */
.icon-btn.suiv::before { transform: rotate(45deg); }
.icon-btn.prec::before { transform: rotate(-135deg); }
.icon-btn:hover { background: var(--surface-2); }
.cal-objectif { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-soft); }
.cal-objectif input { width: 90px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); color: var(--text); }

.cal-weekdays { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; margin-bottom: 8px; }
.cal-weekdays span { text-align: center; font-size: 12px; font-weight: 700; color: var(--text-soft); text-transform: uppercase; letter-spacing: .5px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }

.day {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  min-height: 92px; padding: 8px 9px; position: relative; text-align: left;
  display: flex; flex-direction: column; gap: 4px; transition: transform .1s, box-shadow .1s;
}
.day:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.day.empty { background: transparent; border: none; pointer-events: none; }
.day.today { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.day .num { font-size: 13px; font-weight: 700; color: var(--text-soft); }
.day.today .num { color: var(--accent-dark); }
.day .kcal { font-size: 17px; font-weight: 750; margin-top: auto; }
.day .kcal small { font-size: 11px; font-weight: 600; color: var(--text-soft); }
.day .dots { display: flex; gap: 3px; }
.day .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); opacity: .55; }
.day .bar { height: 4px; border-radius: 3px; background: var(--border); overflow: hidden; }
.day .bar i { display: block; height: 100%; }
.lvl0 { --c: var(--border); }
.lvl1 { --c: #8bd3a6; }
.lvl2 { --c: var(--accent); }
.lvl3 { --c: var(--amber); }
.day.lvl1 .kcal { color: var(--accent-dark); }
.day.lvl2 .kcal { color: var(--accent-dark); }
.day.lvl3 .kcal { color: var(--amber); }

.cal-legend { display: flex; gap: 14px; margin-top: 16px; font-size: 12px; color: var(--text-soft); }
.cal-legend .chip, .chart-legend .chip { display: inline-flex; align-items: center; gap: 6px; }
.cal-legend .chip::before, .chart-legend .chip::before {
  content: ""; width: 12px; height: 12px; border-radius: 4px; background: var(--c, var(--border));
}
/* Légende du graphe kcal : reprend le style de celle du calendrier. */
.chart-legend {
  display: flex; flex-wrap: wrap; gap: 16px; justify-content: center;
  margin-top: 10px; font-size: 12px; color: var(--text-soft);
}

/* ---------- Cartes (plats & ingrédients) ---------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow); display: flex; flex-direction: column;
  transition: transform .1s, box-shadow .15s;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.card .thumb {
  height: 130px; background: var(--surface-2); background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center; font-size: 42px; color: var(--text-soft);
}
.card .body { padding: 12px 14px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.card .body h3 { font-size: 15px; }
.card .meta { font-size: 12px; color: var(--text-soft); display: flex; flex-wrap: wrap; gap: 6px 10px; }
.card .kcal-badge { font-weight: 750; color: var(--accent-dark); font-size: 15px; }
.card .tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.tag { font-size: 11px; padding: 2px 8px; border-radius: 20px; background: var(--surface-2); color: var(--text-soft); font-weight: 600; }
.tag.compose { background: var(--accent-soft); color: var(--accent-dark); }
.tag.prepare { background: #efe6f6; color: #7a52a3; }
.card .actions { display: flex; gap: 4px; padding: 6px 10px; border-top: 1px solid var(--border); }
.card .actions button { flex: 1; font-size: 13px; padding: 7px; border-radius: 8px; border: none; background: transparent; color: var(--text-soft); font-weight: 600; }
.card .actions .edit:hover { background: var(--surface-2); color: var(--text); }
.card .actions .del:hover { background: rgba(211,86,75,.12); color: var(--danger); }
.card .actions .add:hover { background: var(--accent-soft); color: var(--accent-dark); }

.empty-state { text-align: center; color: var(--text-soft); padding: 60px 20px; grid-column: 1/-1; }
.empty-state .big { font-size: 46px; margin-bottom: 8px; }

/* ---------- Modale ---------- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(20,30,25,.5); backdrop-filter: blur(2px);
  display: flex; align-items: flex-start; justify-content: center; padding: 40px 16px; z-index: 50; overflow-y: auto;
}
.modal-overlay.hidden { display: none; }
.modal {
  background: var(--surface); border-radius: 18px; width: 100%; max-width: 640px;
  box-shadow: var(--shadow-lg); position: relative; animation: pop .18s ease;
}
.modal.wide { max-width: 980px; }
@keyframes pop { from { opacity: 0; transform: scale(.97) translateY(6px); } to { opacity: 1; } }
.modal-close {
  position: absolute; top: 12px; right: 12px; border: none; background: var(--surface-2);
  width: 34px; height: 34px; border-radius: 9px; font-size: 15px; color: var(--text-soft); z-index: 2;
}
.modal-close:hover { background: var(--danger); color: #fff; }
.modal-content { padding: 26px 28px; }
.modal-content h2 { margin-bottom: 18px; }

/* ---------- Formulaires ---------- */
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 13px; font-weight: 600; color: var(--text-soft); margin-bottom: 6px; }
.field input, .field textarea, .field select {
  width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); color: var(--text);
}
.field input:focus, .field textarea:focus, .field select:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }
.field textarea { min-height: 90px; resize: vertical; }
.row { display: flex; gap: 12px; }
.row .field { flex: 1; }
.grid-macros { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.macro-hint { font-size: 12px; color: var(--text-soft); margin: -4px 0 12px; }

.photo-picker { display: flex; gap: 14px; align-items: center; margin-bottom: 16px; }
.photo-preview {
  width: 96px; height: 96px; border-radius: 12px; background: var(--surface-2); background-size: cover;
  background-position: center; display: flex; align-items: center; justify-content: center;
  font-size: 30px; color: var(--text-soft); border: 1px solid var(--border); flex-shrink: 0;
}
.photo-btns { display: flex; flex-direction: column; gap: 6px; }

.seg { display: inline-flex; background: var(--surface-2); border-radius: 10px; padding: 3px; gap: 3px; }
/* La pastille active apparaissait d'un coup. Une transition courte suffit à rendre le geste
   lisible ; au-delà de ~200 ms l'interface donne l'impression de traîner. */
.seg button { border: none; background: transparent; padding: 8px 16px; border-radius: 8px; font-weight: 650; color: var(--text-soft);
  transition: background-color .18s ease, color .18s ease, box-shadow .18s ease, transform .12s ease; }
.seg button.on { background: var(--surface); color: var(--accent-dark); box-shadow: var(--shadow); }
.seg button:active { transform: scale(.97); }        /* retour tactile à l'appui */

.ing-line { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
/* #ingLines pour l'emporter sur les regles generiques .field select / .field input[type=number] */
#ingLines .ing-line .ing-sel { flex: 1 1 auto; width: auto; min-width: 0; }
#ingLines .ing-line .ing-count { flex: 0 0 66px; width: 66px; }
#ingLines .ing-line .ing-unit { flex: 0 0 auto; width: auto; min-width: 0; }
.ing-line .rm { flex: 0 0 32px; border: none; background: transparent; color: var(--danger); font-size: 18px; width: 32px; }
.computed { background: var(--accent-soft); border-radius: 10px; padding: 10px 14px; font-size: 13px; color: var(--accent-dark); font-weight: 600; margin-top: 8px; }

/* Éditeur d'unités d'un ingrédient */
#unitLines .unit-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; font-size: 13px; color: var(--text-soft); }
#unitLines .unit-line input { width: auto; padding: 7px 9px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); }
#unitLines .u-nom { flex: 0 0 128px; }
#unitLines .u-g { flex: 0 0 58px; }
#unitLines .u-tot { flex: 0 0 68px; }
#unitLines .u-parts { flex: 0 0 58px; }
#unitLines .unit-line .or { opacity: .65; margin-left: 4px; }
#unitLines .unit-line .rm { border: none; background: transparent; color: var(--danger); font-size: 16px; width: 26px; flex: 0 0 26px; }

.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; }

/* ---------- Détail du jour ---------- */
.day-detail h2 { text-transform: capitalize; }
.day-total b { color: var(--accent-dark); font-size: 20px; }

/* Donut de répartition des macros */
.day-head { display: flex; align-items: center; gap: 22px; margin: 6px 0 20px; flex-wrap: wrap; }
.donut-wrap { flex: 0 0 118px; }
.donut { width: 118px; height: 118px; }
.donut-kcal { font-size: 20px; font-weight: 750; fill: var(--text); }
.donut-unit { font-size: 9px; font-weight: 600; fill: var(--text-soft); }
.mlegend { flex: 1; min-width: 200px; display: flex; flex-direction: column; gap: 7px; }
.mlg { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.mlg .dot { width: 12px; height: 12px; border-radius: 4px; flex-shrink: 0; }
.mlg .mlg-name { color: var(--text-soft); }
.mlg b { color: var(--text); }
.mlg .pct { margin-left: auto; font-weight: 700; color: var(--text-soft); }
.mlg-extra { font-size: 12px; color: var(--text-soft); margin-top: 3px; padding-left: 20px; }
.slot { border: 1px solid var(--border); border-radius: 12px; margin-bottom: 12px; overflow: hidden; }
.slot-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; background: var(--surface-2); }
.slot-head .ico { font-size: 18px; }
.slot-head .name { font-weight: 700; text-transform: capitalize; }
.slot-head .stot { margin-left: auto; font-weight: 700; color: var(--accent-dark); }
.slot-head .plus { border: none; background: var(--accent-solide); color: #fff; width: 30px; height: 30px; border-radius: 8px; font-size: 18px; line-height: 1; }
.slot-head .plus:hover { background: var(--accent-solide-hover); }
.slot-head .dupbtn { border: 1px solid var(--border); background: var(--surface); color: var(--text-soft); width: 30px; height: 30px; border-radius: 8px; font-size: 14px; }
.slot-head .dupbtn:hover { background: var(--accent-soft); color: var(--accent-dark); border-color: var(--accent); }
.slot-items { padding: 6px 10px; }
.slot-empty { padding: 12px 14px; color: var(--text-soft); font-size: 13px; font-style: italic; }
.mitem { display: flex; align-items: center; gap: 10px; padding: 8px 6px; border-bottom: 1px solid var(--border); }
.mitem:last-child { border-bottom: none; }
.mitem .mthumb { width: 34px; height: 34px; border-radius: 8px; background: var(--surface-2) center/cover; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
.mitem .mname { flex: 1; font-weight: 600; font-size: 14px; }
.mitem .mname small { display: block; font-weight: 500; color: var(--text-soft); font-size: 12px; }
.mitem .mqty { width: 74px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); text-align: right; }
.mitem .mqty-sel { padding: 6px 6px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); font-weight: 600; }
.mitem .mcount { width: 56px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); text-align: right; }
.mitem .munit-sel { padding: 6px 6px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); font-weight: 600; max-width: 130px; }
.mitem .munit { font-size: 12px; color: var(--text-soft); min-width: 48px; }
.mitem .mrm { border: none; background: transparent; color: var(--text-soft); font-size: 16px; width: 26px; }
.mitem .mrm:hover { color: var(--danger); }

/* Formulaire de duplication d'un repas */
.slot-picker { padding: 0 12px 12px; }
.dup-form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-top: 10px; font-size: 13px; color: var(--text-soft); }
.dup-form input[type=date], .dup-form select { padding: 8px 10px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); color: var(--text); }
.dup-form .dup-go { padding: 8px 14px; font-size: 13px; }

/* Sélecteur d'aliment (ajout à un repas) */
.picker-search { width: 100%; padding: 11px 14px; border: 1px solid var(--border); border-radius: 10px; margin-bottom: 12px; background: var(--surface); color: var(--text); }
.picker-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text); text-align: left; width: 100%; }
.picker-item:hover { background: var(--accent-soft); border-color: var(--accent); }
.picker-item .pthumb { width: 36px; height: 36px; border-radius: 8px; background: var(--surface-2) center/cover; display: flex; align-items: center; justify-content: center; font-size: 17px; flex-shrink: 0; }
.picker-item .pname { flex: 1; font-weight: 600; }
.picker-item .pkcal { font-size: 12px; color: var(--text-soft); }
.picker-tabs { display: flex; gap: 6px; margin-bottom: 12px; }

/* ---------- Toast ---------- */
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--text); color: var(--bg); padding: 12px 20px; border-radius: 11px;
  box-shadow: var(--shadow-lg); z-index: 100; font-weight: 600; font-size: 14px;
}
.toast.hidden { display: none; }
.toast.err { background: var(--danger); color: #fff; }

/* ---------- Barre haute du calendrier (toggle Mois/Semaine) ---------- */
.cal-topbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 14px; }

/* ---------- Vue semaine ---------- */
.week-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }
.week-day { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; display: flex; flex-direction: column; min-width: 0; }
.week-day.today { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.week-day-head { border: none; background: var(--surface-2); color: var(--text); text-align: left; padding: 8px 10px; display: flex; flex-direction: column; gap: 2px; cursor: pointer; border-bottom: 1px solid var(--border); }
.week-day-head:hover { background: var(--accent-soft); }
.week-day-head .wd-name { font-weight: 700; font-size: 13px; text-transform: capitalize; }
.week-day-head .wd-kcal { font-size: 14px; font-weight: 750; }
.week-day.lvl1 .wd-kcal, .week-day.lvl2 .wd-kcal { color: var(--accent-dark); }
.week-day.lvl3 .wd-kcal { color: var(--amber); }
.week-slots { padding: 8px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.wslot .wslot-head { font-size: 11px; font-weight: 700; color: var(--text-soft); display: flex; justify-content: space-between; margin-bottom: 2px; text-transform: capitalize; }
.witem { font-size: 12px; color: var(--text); padding: 2px 0; line-height: 1.3; overflow-wrap: anywhere; }
.witem small { color: var(--text-soft); }
.week-act { font-size: 11px; font-weight: 650; color: var(--accent-dark); background: var(--accent-soft); padding: 4px 10px; border-bottom: 1px solid var(--border); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.week-act small { color: var(--amber); font-weight: 700; }
.wempty { color: var(--text-soft); font-size: 12px; font-style: italic; padding: 6px; }

/* ---------- Vue stats ---------- */
.stats-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 18px; }
.kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin-bottom: 18px; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; box-shadow: var(--shadow); }
.kpi-val { font-size: 26px; font-weight: 750; color: var(--accent-dark); line-height: 1.1; }
.kpi-lbl { font-size: 13px; font-weight: 600; margin-top: 4px; }
.kpi-sub { font-size: 12px; color: var(--text-soft); }
.stats-card { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px; box-shadow: var(--shadow); margin-bottom: 16px; }
.stats-card h3 { font-size: 15px; margin-bottom: 12px; }
.stats-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
.stats-stack > .stats-card:last-child { margin-bottom: 0; }
.toplist { margin: 0; padding-left: 0; list-style: none; counter-reset: t; }
.toplist li { display: flex; justify-content: space-between; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 14px; }
.toplist li:last-child { border-bottom: none; }
.toplist li b { color: var(--accent-dark); }

/* Histogramme SVG */
.chart-wrap { width: 100%; overflow-x: auto; }
.barchart { width: 100%; height: auto; }
.barchart .bar-lvl0 { fill: var(--border); }
.barchart .bar-lvl1 { fill: #8bd3a6; }
.barchart .bar-lvl2 { fill: var(--accent); }
.barchart .bar-lvl3 { fill: var(--amber); }
.barchart .grid { stroke: var(--border); stroke-width: 1; }
.barchart .objline { stroke: var(--accent-dark); stroke-width: 1.5; stroke-dasharray: 5 4; opacity: .8; }
.barchart .moyline { stroke: var(--amber); stroke-width: 1.5; opacity: .9; }
.barchart .ylab { fill: var(--text-soft); font-size: 10px; text-anchor: end; }
.barchart .xlab { fill: var(--text-soft); font-size: 10px; }
.weightchart .wline { stroke: var(--accent); stroke-width: 2.5; }
.weightchart .wdot { fill: var(--accent); }

/* Poids : saisie + historique */
.weight-add { display: flex; gap: 8px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
.weight-add input { padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); color: var(--text); }
.weight-add #wVal { width: 90px; }
.weight-add .btn-primary { padding: 9px 16px; }
.weight-list { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.weight-list li { display: flex; align-items: center; gap: 8px; background: var(--surface-2); border-radius: 9px; padding: 5px 6px 5px 11px; font-size: 13px; }
.weight-list li b { color: var(--text); }
.weight-list .wdel { border: none; background: transparent; color: var(--text-soft); font-size: 13px; width: 20px; cursor: pointer; }
.weight-list .wdel:hover { color: var(--danger); }

/* Case à cocher (objectifs) */
.checkline { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-soft); margin-top: 12px; cursor: pointer; }
/* Case dessinée plutôt que native : `accent-color` ne teinte que le remplissage, la case
   garde ses angles vifs et son épaisseur système — hors charte à côté des boutons à
   rayon 10-11 px. Le ✓ est géométrique (2 bordures + rotation), donc indépendant de la
   police, comme les chevrons de navigation. */
.checkline input[type=checkbox] {
  appearance: none; -webkit-appearance: none; margin: 0; flex: none;
  width: 20px; height: 20px; box-sizing: border-box;
  border: 1.5px solid var(--border); border-radius: 6px; background: var(--surface);
  position: relative; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
.checkline:hover input[type=checkbox] { border-color: var(--accent); }
.checkline input[type=checkbox]:checked { background: var(--accent); border-color: var(--accent); }
.checkline input[type=checkbox]:checked::after {
  content: ""; position: absolute; left: 6px; top: 2.5px; width: 5px; height: 10px;
  border-right: 2px solid #fff; border-bottom: 2px solid #fff; transform: rotate(45deg);
}
/* Le focus clavier disparaissait avec l'apparence native : on le redessine, sinon la case
   devient inatteignable à l'œil en navigation au clavier. */
.checkline input[type=checkbox]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- Filtres (vue Plats) ---------- */
.filters { display: flex; flex-wrap: wrap; gap: 14px 22px; align-items: center; margin-bottom: 18px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }
.filter-group { display: flex; align-items: center; gap: 8px; }
.filter-lbl { font-size: 12px; font-weight: 700; color: var(--text-soft); }
.filters .seg button { padding: 6px 11px; font-size: 13px; }
.tag-filter { display: flex; flex-wrap: wrap; gap: 6px; }
.tagchip { border: 1px solid var(--border); background: var(--surface-2); color: var(--text-soft); padding: 4px 11px; border-radius: 20px; font-size: 12px; font-weight: 600; }
.tagchip:hover { border-color: var(--accent); color: var(--text); }
.tagchip.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-dark); }
.tag.usertag { background: var(--accent-soft); color: var(--accent-dark); }

/* ---------- Favoris (picker) ---------- */
.fav-item { cursor: pointer; }
.fav-item .fav-del { border: none; background: transparent; color: var(--text-soft); font-size: 14px; width: 26px; flex-shrink: 0; }
.fav-item .fav-del:hover { color: var(--danger); }

/* ---------- Objectifs : progression (détail du jour) ---------- */
.goals-progress { display: flex; flex-direction: column; gap: 7px; margin: 4px 0 18px; }
.gp-row { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.gp-lbl { flex: 0 0 72px; color: var(--text-soft); font-weight: 600; }
.gp-bar { flex: 1; height: 8px; background: var(--surface-2); border-radius: 5px; overflow: hidden; }
.gp-bar i { display: block; height: 100%; background: var(--accent); border-radius: 5px; }
.gp-bar i.over { background: var(--amber); }
.gp-val { flex: 0 0 auto; color: var(--text-soft); font-variant-numeric: tabular-nums; }

/* ---------- Hydratation ---------- */
.water { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 14px; background: var(--surface-2); border-radius: 12px; margin-bottom: 18px; }
.water-lbl { font-weight: 700; font-size: 14px; }
.water-bar { flex: 1; min-width: 90px; height: 8px; background: var(--surface); border-radius: 5px; overflow: hidden; }
.water-bar i { display: block; height: 100%; background: #3b9ae1; border-radius: 5px; }
.water-count { font-size: 13px; color: var(--text-soft); font-weight: 600; }
.water-pm { margin-left: 2px; border: 1px solid var(--border); background: var(--surface); color: var(--text); width: 30px; height: 30px; border-radius: 8px; font-size: 16px; }
.water-pm:hover { background: var(--accent-soft); border-color: var(--accent); }
.wd-water { font-weight: 600; color: #5b8def; }

/* Compteur d'alcool : même gabarit que l'hydratation, mais des icônes au lieu d'une barre
   (une pinte est une unité qui se compte, pas une progression continue vers un objectif). */
.alc-icons { flex: 1; min-width: 90px; font-size: 15px; letter-spacing: 1px; line-height: 1; }
.alc-partiel { opacity: .4; }                  /* pinte entamée */
.alc-plus, .alc-vide { font-size: 13px; color: var(--text-soft); font-weight: 600; letter-spacing: 0; }

/* ---------- Liste de courses ---------- */
.shop-plats { max-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.shop-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 4px; border-bottom: 1px solid var(--border); }
.shop-row:last-child { border-bottom: none; }
.shop-name { font-weight: 600; font-size: 14px; }
.shop-name small { color: var(--text-soft); font-weight: 500; }
.shop-stepper { display: flex; align-items: center; gap: 8px; }
.shop-stepper button { border: 1px solid var(--border); background: var(--surface); color: var(--text); width: 28px; height: 28px; border-radius: 8px; font-size: 15px; }
.shop-stepper button:hover { background: var(--accent-soft); border-color: var(--accent); }
.shop-stepper span { min-width: 20px; text-align: center; font-weight: 700; }
.shop-result { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 5px; }
.shop-result li { font-size: 14px; }
.shop-total { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); font-size: 15px; }
.shop-total b { color: var(--accent-dark); font-size: 17px; }
.prix-badge { color: var(--amber); font-weight: 650; }

/* ---------- Scanner de code-barres ---------- */
.scan-video-wrap { display: none; position: relative; border-radius: 12px; overflow: hidden; background: #000; margin-bottom: 14px; aspect-ratio: 4/3; }
.scan-video-wrap.on { display: block; }
.scan-video-wrap video { width: 100%; height: 100%; object-fit: cover; display: block; }
.scan-line { position: absolute; left: 8%; right: 8%; top: 50%; height: 2px; background: var(--danger); box-shadow: 0 0 8px var(--danger); opacity: .85; }
.scan-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.scan-or { color: var(--text-soft); font-size: 13px; }
.scan-actions #manualCode { flex: 1; min-width: 180px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text); }
.scan-card { display: flex; align-items: center; gap: 14px; padding: 12px; border: 1px solid var(--accent); background: var(--accent-soft); border-radius: 12px; flex-wrap: wrap; }
.scan-thumb { width: 74px; height: 74px; border-radius: 10px; background: var(--surface) center/contain no-repeat; display: flex; align-items: center; justify-content: center; font-size: 28px; flex-shrink: 0; border: 1px solid var(--border); }
.scan-info { flex: 1; min-width: 160px; }
.scan-info h3 { font-size: 15px; margin-bottom: 4px; }

/* ---------- Frigo magique / Garde-manger ---------- */
.fridge-row { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px; margin-bottom: 8px; }
.fridge-row.ok { border-color: var(--accent); background: var(--accent-soft); }
.fridge-main { flex: 1; min-width: 0; }
.fridge-name { font-weight: 650; font-size: 14px; }
.fridge-name small { font-weight: 500; color: var(--text-soft); }
.fridge-times { background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; padding: 1px 7px; border-radius: 20px; margin-left: 2px; }
.fridge-bar { height: 6px; background: var(--surface-2); border-radius: 4px; overflow: hidden; margin: 6px 0 4px; }
.fridge-bar i { display: block; height: 100%; background: var(--amber); border-radius: 4px; }
.fridge-bar i.full { background: var(--accent); }
.fridge-missing { font-size: 12px; color: var(--text-soft); }
.fridge-missing b { color: var(--text); font-weight: 650; }
.fridge-pct { font-weight: 750; color: var(--accent-dark); font-size: 15px; flex-shrink: 0; white-space: nowrap; }
.fridge-add { flex-shrink: 0; padding: 7px 12px; font-size: 13px; }
.fridge-reshead { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }

/* Garde-manger : en-tête, ajout par recherche, liste du stock */
.pantry-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.pantry-head h3 { font-size: 16px; }
.pantry-head .macro-hint { margin: 4px 0 0; }
.pantry-add { position: relative; margin-bottom: 14px; }
.pantry-add .search { width: 100%; }
.pantry-suggest { position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; right: 0; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg); padding: 6px; max-height: 320px; overflow-y: auto; }
.pantry-suggest.hidden { display: none; }
.pantry-sg { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border: none; background: none; color: var(--text); border-radius: 9px; font-size: 14px; font-weight: 600; }
.pantry-sg:hover { background: var(--surface-2); }
.pantry-sg-th { width: 30px; height: 30px; flex-shrink: 0; border-radius: 7px; background: var(--surface-2) center/cover no-repeat; display: flex; align-items: center; justify-content: center; font-size: 16px; }
.pantry-sg-empty { padding: 10px; color: var(--text-soft); font-size: 13px; }
.pantry-row { display: flex; align-items: center; gap: 12px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 12px; margin-bottom: 8px; }
.pantry-th { width: 42px; height: 42px; flex-shrink: 0; border-radius: 9px; background: var(--surface-2) center/cover no-repeat; display: flex; align-items: center; justify-content: center; font-size: 20px; }
.pantry-name { flex: 1; min-width: 0; font-weight: 650; font-size: 14px; }
.pantry-name small { display: block; font-weight: 500; color: var(--text-soft); font-size: 12px; }
.pantry-qty { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.pantry-qty .pq-count { width: 76px; padding: 7px 9px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); color: var(--text); }
.pantry-qty .pq-unit { padding: 7px 8px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); color: var(--text); max-width: 130px; }
.pantry-del { flex-shrink: 0; width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface); color: var(--text-soft); font-size: 13px; }
.pantry-del:hover { border-color: var(--danger); color: var(--danger); }

/* ---------- Planning ---------- */
.plan-topbar { align-items: center; }
/* Barre du planning. Elle héritait de .cal-header/.cal-nav, conçus pour le calendrier :
   le titre y réserve 190 px, ce qui faisait passer les flèches à la ligne — d'où les « ‹ »
   et « › » empilés l'un sous l'autre. Barre propre, en trois blocs qui ne se coupent pas. */
/* Une seule hauteur pour TOUT ce qui est cliquable dans la barre. Sans ça chaque contrôle
   gardait celle de sa classe — flèches 38, « Cette semaine » 35, actions 40, titre 27 — et
   la barre partait en escalier. Même remède que `.view-head`, même variable. */
.plan-topbar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; --h-ctl: 40px; }
.plan-topbar :is(.icon-btn, .btn-ghost, .btn-primary) {
  height: var(--h-ctl); border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
}
.plan-topbar .icon-btn { width: var(--h-ctl); }
/* nowrap : les deux flèches restent collées à leur libellé, quoi qu'il arrive. */
.plan-nav { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
/* Le titre prend lui aussi la hauteur commune : sinon il flotte entre deux flèches plus hautes. */
.plan-nav h2 { min-width: 0; font-size: 1.15rem; white-space: nowrap; text-align: center;
  height: var(--h-ctl); display: flex; align-items: center; justify-content: center; padding: 0 2px; }
.plan-auj { flex: none; }
/* Les actions ferment la barre, « Valider » en dernier : c'est l'aboutissement du geste. */
.plan-actions { display: flex; gap: 8px; margin-left: auto; flex: 0 0 auto; }

@media (max-width: 860px) {
  /* Plus la place pour tout aligner : navigation sur un rang, actions sur le suivant,
     chacune occupant toute la largeur à parts égales. */
  .plan-nav { flex: 1 1 auto; }
  .plan-actions { flex: 1 1 100%; margin-left: 0; }
  .plan-actions button { flex: 1 1 0; min-width: 0; justify-content: center; }
}
@media (max-width: 560px) {
  /* « Cette semaine » reste à DROITE du sélecteur : c'est la même action de navigation,
     la reléguer sur son propre rang la coupait de son contexte. Pour que les deux tiennent,
     on rétrécit le titre et on resserre le bouton plutôt que de casser la ligne. */
  .plan-nav { flex: 1 1 auto; min-width: 0; gap: 6px; }
  .plan-nav h2 { font-size: .95rem; }
  /* Padding HORIZONTAL seulement : `padding: 0 10px` écrasait aussi le padding vertical,
     et comme .btn-ghost n'a pas de hauteur propre le bouton se réduisait à sa ligne de
     texte — d'où le petit bouton rabougri à côté des flèches. La hauteur vient de --h-ctl. */
  .plan-auj { flex: 0 0 auto; padding-inline: 10px; font-size: 13px; }
  /* Trois libellés côte à côte ne tiennent plus : « Valider » passe en dessous, seul et large. */
  .plan-actions { flex-wrap: wrap; }
  .plan-actions .btn-primary { flex: 1 1 100%; }
}
/* Les 7 jours tiennent dans la largeur, sans défilement. L'ancien `minmax(148px, 1fr)`
   imposait 7x148 + 6 gouttières = 1096 px, pour une zone utile de 1076 px : d'où la barre.
   `minmax(0, 1fr)` laisse les colonnes se réduire (0 = elles ignorent la largeur de leur
   contenu, sinon un nom long les regonflerait et le débordement reviendrait). */
.plan-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 10px; }
.plan-day { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 8px; display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.plan-day.today { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.plan-day-head { font-weight: 700; font-size: 13px; text-transform: capitalize; text-align: center; padding-bottom: 5px; border-bottom: 1px solid var(--border); }
.plan-slot-head { display: flex; align-items: center; justify-content: space-between; font-size: 11px; font-weight: 600; color: var(--text-soft); }
.plan-add { border: none; background: var(--surface-2); color: var(--text); width: 22px; height: 22px; border-radius: 6px; font-size: 13px; line-height: 1; flex-shrink: 0; }
.plan-add:hover { background: var(--accent-soft); color: var(--accent-dark); }
.plan-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.plan-item { display: flex; align-items: center; gap: 4px; background: var(--accent-soft); border-radius: 7px; padding: 4px 6px; font-size: 12px; font-weight: 600; }
.plan-item > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.plan-item small { display: block; font-weight: 500; color: var(--text-soft); font-size: 10px; }
.plan-rm { border: none; background: none; color: var(--text-soft); font-size: 12px; padding: 0 2px; flex-shrink: 0; }
.plan-rm:hover { color: var(--danger); }
.picker-list { display: flex; flex-direction: column; gap: 6px; max-height: 46vh; overflow-y: auto; }

/* ---------- Ajout rapide (V25) : catégorie → contenu adapté ---------- */
.qa-cats, .qa-sous { display: flex; width: 100%; margin-bottom: 14px; }
.qa-cats button, .qa-sous button { flex: 1 1 0; min-width: 0; }
/* Six créneaux ne tiennent pas en toutes lettres, même sur grand écran : l'emoji suffit,
   le créneau visé est écrit en clair juste en dessous. */
.qa-slots { display: flex; width: 100%; margin-bottom: 8px; }
.qa-slots button { flex: 1 1 0; min-width: 0; font-size: 18px; padding: 8px 0; }
.qa-cible { font-size: 13px; color: var(--text-soft); margin: 0 0 12px; }
.qa-cible b { color: var(--text); }
.qa-recap { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 12px; }
.qa-recap-t { font-size: 12px; font-weight: 700; color: var(--text-soft); margin-bottom: 6px; }
.qa-ligne { display: flex; align-items: center; gap: 10px; padding: 5px 2px; font-size: 14px; }
.qa-ligne span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qa-ligne small { color: var(--text-soft); flex: none; }
#qaExoBody { display: flex; flex-direction: column; gap: 6px; max-height: 46vh; overflow-y: auto; }

/* Étape « combien ? » : le sélecteur se replie sur l'élément choisi. */
.qte-form { border: 1px solid var(--accent); border-radius: 12px; padding: 14px; background: var(--accent-soft); }
.qte-tete { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.qte-nom { font-weight: 700; font-size: 15px; min-width: 0; }
.qte-ligne { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.qte-ligne input, .qte-ligne select {
  padding: 9px 10px; border: 1px solid var(--border); border-radius: 9px;
  background: var(--surface); color: var(--text); min-width: 0;
}
.qte-val { width: 90px; text-align: center; font-weight: 650; }
.qte-unite { font-size: 14px; color: var(--text-soft); font-weight: 600; }
.qte-unite-sel { flex: 1; }
/* Ligne d'exercice : mode élastique, nombres courts — mêmes proportions que l'éditeur. */
.exo-ligne { display: grid; grid-template-columns: minmax(0, 1fr) 66px 14px 66px 74px; }
.exo-ligne .eb-x { text-align: center; color: var(--text-soft); font-weight: 700; }
.exo-ligne input { text-align: center; }
.qte-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; }
@media (max-width: 560px) {
  /* Même raison que .eb-set : cinq colonnes fixes ne tiennent pas. Le mode prend un rang. */
  .exo-ligne { grid-template-columns: minmax(0, 1fr) 14px minmax(0, 1fr) minmax(0, 1fr); }
  .exo-ligne .qte-mode { grid-column: 1 / -1; }
  .qte-actions { flex-direction: column-reverse; }
  .qte-actions button { width: 100%; }
}

/* ---------- Exercices / Séances / Journal ---------- */
.ex-card, .seance-card { display: flex; flex-direction: column; }
.ex-card .body, .seance-card .body { flex: 1; padding: 14px; }
.ex-thumb { height: 130px; background: var(--surface-2) center/contain no-repeat; display: flex; align-items: center; justify-content: center; font-size: 40px; border-bottom: 1px solid var(--border); }
.ex-groupe { display: inline-block; background: var(--accent-soft); color: var(--accent-dark); font-size: 12px; font-weight: 650; padding: 2px 9px; border-radius: 20px; margin-top: 4px; }
.ex-notes { font-size: 13px; color: var(--text-soft); margin: 8px 0 0; }
.seance-ex { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.seance-ex li { font-size: 13px; font-weight: 600; }
.seance-ex li b { display: block; }
.seance-set { display: inline-block; background: var(--surface-2); color: var(--text-soft); font-weight: 600; font-size: 11px; padding: 1px 7px; border-radius: 6px; margin: 2px 4px 0 0; }
.seance-ex li.muted, .muted { color: var(--text-soft); font-weight: 500; }
.card-actions { display: flex; gap: 6px; padding: 10px 14px; border-top: 1px solid var(--border); flex-wrap: wrap; }
.card-actions .btn-primary, .card-actions .btn-ghost { padding: 7px 11px; font-size: 13px; }

/* Éditeur d'exercices (blocs + lignes par mode de travail) — partagé séance/activité */
.exo-editor { display: flex; flex-direction: column; gap: 10px; max-width: 600px; }
.exo-block { border: 1px solid var(--border); border-radius: 12px; padding: 10px; background: var(--surface-2); }
.exo-block-head { display: flex; gap: 8px; margin-bottom: 8px; }
.exo-block-head .eb-ex { flex: 1; min-width: 0; padding: 8px 10px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); color: var(--text); font-weight: 650; }
.eb-del-ex, .eb-del-set { flex-shrink: 0; border: 1px solid var(--border); background: var(--surface); color: var(--text-soft); border-radius: 8px; }
.eb-del-ex { width: 34px; }
.eb-del-ex:hover, .eb-del-set:hover { border-color: var(--danger); color: var(--danger); }
.eb-sets { display: flex; flex-direction: column; gap: 6px; }
.eb-set { display: grid; grid-template-columns: minmax(120px, 200px) 64px 14px 64px 76px 32px; align-items: center; gap: 6px; max-width: 560px; }
.eb-set input, .eb-set select { width: 100%; min-width: 0; height: 36px; padding: 0 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); text-align: center; }
.eb-set .eb-mode { text-align: left; font-size: 12px; padding-right: 4px; }
.eb-set .eb-x { color: var(--text-soft); font-weight: 700; text-align: center; }
.eb-set .eb-del-set { width: 32px; height: 36px; }
.eb-add-set { align-self: flex-start; margin-top: 8px; border: 1px dashed var(--border); background: none; color: var(--text-soft); border-radius: 8px; padding: 5px 10px; font-size: 12px; font-weight: 600; }
.eb-add-set:hover { border-color: var(--accent); color: var(--accent-dark); }
.eb-add-exo { border: 1px dashed var(--border); background: none; color: var(--accent-dark); border-radius: 10px; padding: 9px; font-weight: 650; width: 100%; }
.eb-add-exo:hover { border-color: var(--accent); background: var(--accent-soft); }

/* Détail d'un jour : deux colonnes (alimentation | activité) */
.day-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; }
/* Un seul panneau (module Exercices éteint) : une colonne, sinon la seconde piste reste
   réservée et le contenu se tasse à gauche d'une fenêtre à moitié vide. */
.day-cols.solo { grid-template-columns: minmax(0, 1fr); }
/* Le sélecteur de panneau ne sert que sur écran étroit ; ici les deux colonnes tiennent. */
.day-switch { display: none; }
.col-title { font-size: 16px; margin-bottom: 14px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
.dd-activite { border-left: 1px solid var(--border); padding-left: 24px; }

/* Sous 900 px les deux colonnes ne tiennent plus côte à côte.
   ⚠️ Ce bloc DOIT rester après les règles ci-dessus : à spécificité égale, c'est l'ordre
   d'écriture qui tranche. Placé plus haut (il l'était), il ne surchargeait rien et le trait
   de séparation restait affiché alors qu'il n'y avait plus rien à séparer. */
@media (max-width: 900px) {
  /* minmax(0, …) et non 1fr : un « 1fr » nu vaut minmax(auto, 1fr), donc la piste ne descend
     jamais sous le min-content du plus large enfant. Ici l'éditeur d'exercice (un <select> qui
     se dimensionne sur son option la plus longue) imposait 433 px dans un écran de 375. */
  .day-cols { grid-template-columns: minmax(0, 1fr); }
  /* Deux verrous, pas un : minmax(0,…) dimensionne la PISTE, min-width:0 autorise l'ÉLÉMENT
     à descendre sous son min-content. Sans le second, la colonne déborde de sa propre piste. */
  .dd-food, .dd-activite { min-width: 0; }
  /* Colonnes empilées : la séparation devient horizontale… */
  .dd-activite { border-left: none; padding-left: 0; border-top: 1px solid var(--border); padding-top: 18px; margin-top: 4px; }
}
/* …et sous 720 px un seul panneau s'affiche à la fois : plus rien à séparer du tout. */
@media (max-width: 720px) {
  .dd-activite { border-top: none; padding-top: 0; margin-top: 0; }
}
.act-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.act-prefill { max-width: 210px; padding: 7px 9px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); color: var(--text); font-size: 13px; }
.act-meta { margin: 4px 0 16px; }
.act-nom { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text); font-weight: 650; font-size: 15px; margin-bottom: 10px; }
.act-temps-l { font-size: 13px; color: var(--text-soft); font-weight: 600; display: block; margin-bottom: 14px; }
.act-temps { width: 70px; padding: 7px 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); text-align: center; margin: 0 4px; }
.act-lbl { font-size: 12px; color: var(--text-soft); font-weight: 700; text-transform: uppercase; letter-spacing: .03em; }

/* Échelles ressenti / effort. Elles étaient posées en bout de ligne, l'une à gauche l'autre
   à droite, sans dire ce qu'elles valaient. Maintenant : deux blocs identiques, titre à
   gauche, valeur choisie en toutes lettres à droite, échelle pleine largeur en dessous. */
.jauge { margin-bottom: 14px; }
.jauge-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.jauge-val { font-size: 13px; font-weight: 650; color: var(--text); }
.jauge-echelle { display: flex; gap: 6px; }
.act-kcal { margin-top: 12px; font-size: 14px; padding: 9px 12px; background: var(--surface-2); border-radius: 10px; }
.act-kcal b { color: var(--text); }
.act-kcal small { color: var(--text-soft); font-weight: 500; }
/* Un smiley non choisi doit se lire comme « disponible », pas comme « désactivé » : le
   grayscale total les faisait passer pour des boutons morts. On garde donc la couleur et
   on ne joue que sur l'opacité ; le choix, lui, est franc — fond teinté + contour. */
.smiley {
  flex: 1 1 0; min-width: 0; height: 40px; border: 1px solid var(--border);
  background: var(--surface); border-radius: 10px; font-size: 20px; line-height: 1;
  opacity: .5; transition: opacity .15s, transform .12s, background-color .15s, border-color .15s;
}
.smiley:hover { opacity: .85; transform: translateY(-1px); border-color: var(--sm); }
.smiley.on {
  opacity: 1; border-color: var(--sm); background: color-mix(in srgb, var(--sm) 20%, var(--surface));
  box-shadow: 0 2px 8px color-mix(in srgb, var(--sm) 35%, transparent);
}
.act-clear { margin-top: 14px; width: 100%; }

/* Indicateur de séance dans les cases du calendrier */
.cal-seance { display: flex; align-items: center; gap: 3px; font-size: 11px; font-weight: 650; color: var(--accent-dark); line-height: 1.2; margin: 1px 0; min-width: 0; }
.cal-seance i { font-style: normal; flex: none; }
/* Sur grand écran le libellé se suffit : l'emoji « pas de séance » ne sert qu'en version
   compacte, où il remplace le texte. Le 🏋️ des séances, lui, existait déjà. */
.cal-seance.none i { display: none; }
.cal-seance b { font-weight: inherit; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-seance.none { color: var(--text-soft); font-weight: 500; font-style: italic; opacity: .7; }

/* ---------- Apparence (thème + accent) ---------- */
.accent-swatches { display: flex; flex-wrap: wrap; gap: 10px; }
.swatch { width: 34px; height: 34px; border-radius: 50%; border: 2px solid var(--border); cursor: pointer; padding: 0; position: relative; }
.swatch:hover { transform: scale(1.1); }
.swatch.on { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--text); }
.swatch.custom { display: flex; align-items: center; justify-content: center; background: var(--surface-2); font-size: 15px; overflow: hidden; }
.swatch.custom input[type=color] { position: absolute; inset: -4px; opacity: 0; cursor: pointer; width: 150%; height: 150%; }

/* ---------- Boîte de confirmation ---------- */
.confirm-overlay { align-items: center; z-index: 60; }
.confirm-box { max-width: 420px; padding: 24px 26px; }
.confirm-msg { font-size: 15px; line-height: 1.5; }
.confirm-msg small { color: var(--text-soft); }
.btn-danger-solid { border: none; background: var(--danger); color: #fff; padding: 11px 18px; border-radius: 11px; font-weight: 650; }
.btn-danger-solid:hover { filter: brightness(1.08); }
.sep { border: none; border-top: 1px solid var(--border); margin: 20px 0; }

@media (max-width: 720px) {
  /* ---------- Barre supérieure ----------
     Ordre voulu : logo + photo de profil sur la 1re ligne, « Ajout rapide » pleine
     largeur en dessous, puis les onglets. */
  .topbar { flex-wrap: wrap; gap: 10px; padding: 10px 12px; }
  .brand { order: 1; }
  .account-wrap { order: 2; margin-left: auto; }
  .btn-quick { order: 3; width: 100%; margin-left: 0; text-align: center; }
  .tabs { order: 4; width: 100%; margin-left: 0; }

  /* Le bouton compte se réduit à la seule photo : le nom mange une place qu'on n'a pas.
     Il reste un bouton entier, donc toujours cliquable et toujours ouvrant le menu. */
  .account-btn { max-width: none; padding: 4px; border-radius: 999px; }
  .account-name, .account-caret { display: none; }
  .account-pic { width: 32px; height: 32px; font-size: 14px; }

  /* Onglets : défilement horizontal au doigt plutôt qu'un retour à la ligne qui
     mange trois rangées. Barre masquée — le geste suffit, et elle prend de la hauteur. */
  .tabs {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .tabs::-webkit-scrollbar { display: none; }

  /* Affordance de défilement : la barre masquée ne dit plus qu'on peut faire glisser. Un
     onglet à demi effacé au bord le dit, lui. Le fondu n'apparaît QUE du côté où il reste
     du contenu (classes posées par bordsDefilants) — un fondu permanent mentirait en
     suggérant de la matière là où la barre est finie.
     Par défaut les deux arrêts sont à 0 % / 100 % : le masque est alors opaque partout. */
  .tabs { --f-g: #000 0; --f-d: #000 100%;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, var(--f-g), var(--f-d), transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, var(--f-g), var(--f-d), transparent 100%); }
  .tabs.fade-g { --f-g: #000 26px; }
  .tabs.fade-d { --f-d: #000 calc(100% - 26px); }
  .tab { flex: none; scroll-snap-align: start; padding: 8px 13px; font-size: 14px; }

  /* ---------- Segmentés : toute la largeur, parts égales ----------
     `flex: 1 1 0` égalise les parts quelle que soit la longueur du libellé —
     « Frigo magique » et « Produits » occupent donc la même largeur. */
  .seg { display: flex; width: 100%; }
  .seg button { flex: 1 1 0; min-width: 0; padding: 9px 6px; font-size: 13px; text-align: center; }

  /* ---------- Calendrier ---------- */
  .cal-topbar { flex-wrap: nowrap; gap: 8px; }
  .cal-topbar .seg { width: auto; flex: 1 1 auto; }
  .cal-objectif { flex: none; gap: 6px; }
  .cal-objectif label { font-size: 0; }                   /* libellé remplacé par une cible */
  .cal-objectif label::before { content: "🎯"; font-size: 15px; }
  .cal-objectif input { width: 74px; padding: 8px 8px; }

  .cal-nav h2 { min-width: 0; flex: 1 1 auto; }

  /* Cases trop étroites pour du texte : on centre, on agrandit la date, et la séance
     se résume à son emoji. La barre de progression garde sa couleur — c'est elle qui
     porte l'information d'un coup d'œil. */
  .day { min-height: 74px; align-items: center; text-align: center; padding: 6px 4px; gap: 3px; }
  .day .num { font-size: 15px; }
  .day .kcal { font-size: 14px; width: 100%; }
  .day .kcal small { display: none; }
  .cal-seance { justify-content: center; font-size: 13px; }
  .cal-seance b { display: none; }
  .cal-seance.none i { display: block; }   /* masqué sur grand écran, il reprend sa place ici */
  .cal-seance.none { opacity: .4; }

  /* ---------- Semaine & planning : un jour = toute la largeur, on défile vers le bas ----------
     Sept colonnes sur un téléphone sont inutilisables ; empiler est plus simple à lire
     ET à manipuler que de défiler latéralement. */
  .week-grid, .plan-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px; overflow-x: visible; padding-bottom: 0;
  }

  /* ---------- Détail du jour : un panneau à la fois ----------
     Empilés, Alimentation et Activité font une page interminable où l'activité est
     toujours « plus bas ». Le segmenté en montre un seul, choisi. */
  .day-switch { display: flex; margin-bottom: 16px; }
  .day-cols[data-panneau="food"] .dd-activite,
  .day-cols[data-panneau="activite"] .dd-food { display: none; }

  /* ---------- Divers ---------- */
  .grid-macros { grid-template-columns: repeat(2, 1fr); }
  .kpi-row { grid-template-columns: repeat(2, 1fr); }
  .stats-2col { grid-template-columns: 1fr; }
  .filters { gap: 10px 16px; }

  /* Modales : l'écran est étroit, chaque pixel de marge est pris sur le contenu. */
  .modal-overlay { padding: 12px 8px 24px; }
  .modal-content { padding: 18px 14px; }
  .modal-content h2 { margin-bottom: 14px; font-size: 1.15rem; padding-right: 38px; }
  .modal { border-radius: 14px; }
}


/* Palier etroit : telephone. Le calendrier du mois garde ses 7 colonnes (leur
   alignement EST l'information), on retrecit donc le contenu, pas la grille. */
/* Palier très étroit (iPhone SE et en-dessous). On ne fait que resserrer : les tailles
   de la date et des kcal sont fixées par le bloc 720 px et ne doivent PAS être réduites
   ici — c'est justement là que la case doit rester lisible. */
@media (max-width: 560px) {
  main { padding: 14px 12px 28px; }

  .cal-grid, .cal-weekdays { gap: 4px; }
  .day { padding: 5px 3px; }
  .day .dots { display: none; }
  .cal-weekdays span { font-size: 10px; letter-spacing: 0; }

  .cal-header, .stats-head { gap: 8px; }
  .cal-nav { gap: 6px; width: 100%; }
  .cal-nav h2 { font-size: 1.05rem; }

  .day-cols { grid-template-columns: 1fr; }
  .kpi-row { grid-template-columns: 1fr 1fr; }

  /* Ligne de série : 6 colonnes fixes totalisant ~388 px, soit plus que l'écran. On la passe
     sur deux rangs — le mode occupe le premier, les nombres le second — et toutes les pistes
     deviennent élastiques. Seuil réel ~440 px ; on se cale sur 560 plutôt que d'ajouter un
     palier, le rang perdu entre les deux ne coûte rien. */
  .eb-set { grid-template-columns: minmax(0, 1fr) 14px minmax(0, 1fr) minmax(0, 1fr) 32px; }
  .eb-set .eb-mode { grid-column: 1 / -1; }
}

/* ---------- Écran de connexion / inscription (V1 multi-comptes) ---------- */
.auth-screen { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center;
  justify-content: center; background: var(--bg); padding: 20px; }
.auth-screen.hidden { display: none; }
.auth-card { width: 100%; max-width: 380px; background: var(--card); border: 1px solid var(--border);
  border-radius: 16px; padding: 26px 24px; box-shadow: 0 10px 40px rgba(0,0,0,.18); }
.auth-brand {
  height: 78px; aspect-ratio: 575 / 200; margin: 0 auto 20px;
  background: url("/yafint_clair.png") center / contain no-repeat;
}
:root[data-theme="dark"] .auth-brand { background-image: url("/yafint_sombre.png"); }
.auth-card h2 { margin: 0 0 14px; font-size: 1.1rem; color: var(--text); }
.auth-card .field { margin-bottom: 12px; }
.auth-submit { width: 100%; margin-top: 6px; }
.auth-err { color: var(--danger); font-size: .85rem; min-height: 1.1em; margin: 2px 0 6px; }
.auth-msg { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--text);
  border-radius: 8px; padding: 8px 10px; font-size: .85rem; margin-bottom: 12px; }
.auth-switch { text-align: center; margin-top: 14px; font-size: .85rem; color: var(--text-soft); }
.auth-switch a { color: var(--accent); text-decoration: none; font-weight: 600; }
.auth-switch a:hover { text-decoration: underline; }

/* ---------- Inscription en assistant (V26) ---------- */
.onb-tete { display: flex; justify-content: space-between; margin-bottom: 6px;
  font-size: .78rem; font-weight: 600; color: var(--text-soft); }
.onb-jauge { height: 6px; margin-bottom: 18px; border-radius: 999px;
  background: var(--surface-2); overflow: hidden; }
.onb-jauge i { display: block; height: 100%; border-radius: inherit; background: var(--accent);
  transition: width .25s ease; }
.onb-nav { display: flex; gap: 10px; margin-top: 4px; }
.onb-nav .btn-primary { flex: 1; }
/* Le libellé donne le nom du module, la ligne du dessous ce qu'on perd en décochant :
   « Poids » seul ne laisse pas deviner qu'on emporte aussi l'estimation des calories. */
.mod-line { align-items: flex-start; margin-top: 14px; }
/* Même spécificité que la règle générale ci-dessus (classe + attribut + élément) : c'est
   l'ordre d'écriture qui tranche, donc ce bloc DOIT rester après. */
.mod-line input[type=checkbox] { margin-top: 1px; }
.mod-line b { display: block; font-size: 14px; color: var(--text); }
.mod-line small { display: block; margin-top: 2px; line-height: 1.35; color: var(--text-soft); }

/* ---------- Barre d'outils de section : hauteur et style unifiés ----------
   Chaque contrôle avait le padding de sa propre classe (.search 11/15, .btn-primary 11/18,
   .btn-ghost 8/14…), d'où une barre en escalier. On impose ici la hauteur et le rayon à
   tous les enfants directs : le padding vertical de chacun ne compte plus. */
/* Trois groupes, pas six éléments en vrac : [recherche] [tri+sens] [actions]. Tout à plat,
   le retour à la ligne coupait n'importe où — la flèche de sens se retrouvait seule sur le
   rang suivant, détachée du critère auquel elle se rapporte. */
.view-head { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 18px; --h-ctl: 42px; }
.view-head :is(.search, .sort-select, button) {
  height: var(--h-ctl);
  padding: 0 14px;
  border-radius: 11px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
}
.view-head button { display: inline-flex; align-items: center; gap: 6px; }
.view-head > .search { flex: 1 1 240px; font-weight: 400; }
.vh-tri { display: flex; gap: 6px; flex: 0 0 auto; }        /* critère + sens, indissociables */
/* Poussées à droite : les actions sont la fin de la barre, pas un élément parmi d'autres. */
.vh-actions { display: flex; gap: 8px; flex: 0 0 auto; margin-left: auto; }

/* Le champ porte le compteur (« Rechercher parmi 29 produits… »). opacity:1 annule
   l'atténuation que les navigateurs ajoutent d'office : le texte devient lisible sans
   virer au blanc pur, qui donnerait l'illusion d'un champ déjà rempli. */
.view-head > .search::placeholder { color: var(--text-soft); opacity: 1; }
.view-head .sort-select {
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  padding-right: 30px;              /* place pour la flèche native du select */
  /* Largeur figée : sinon la barre entière se réorganise à chaque changement de critère
     (« Nom » et « Temps de prép. » n'ont pas du tout la même longueur). */
  width: 168px; flex: none; text-overflow: ellipsis;
}
/* Bouton carré : FLÈCHE SEULE. Le libellé du sens tient dans l'infobulle — mis en toutes
   lettres ici, il déborde de la boîte de 42 px. */
.view-head .sort-dir {
  width: var(--h-ctl); padding: 0; flex: none;
  justify-content: center; font-size: 17px; line-height: 1;
}

/* Écran étroit : chaque groupe prend un rang entier et remplit la largeur. Mieux vaut trois
   rangs nets qu'un pavé qui se casse au hasard. */
@media (max-width: 720px) {
  .view-head > .search { flex: 1 1 100%; }
  .vh-tri { flex: 1 1 100%; }
  .vh-tri .sort-select { flex: 1 1 auto; width: auto; }
  .vh-actions { flex: 1 1 100%; margin-left: 0; }
  .vh-actions button { flex: 1 1 0; min-width: 0; justify-content: center; }
}

/* ---------- 2FA : QR + codes de secours ---------- */
.qr-box { display: flex; justify-content: center; padding: 12px; background: #fff;
  border-radius: 12px; margin-bottom: 12px; }
.qr-box svg { width: 200px; height: 200px; display: block; }
.codes-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 12px 0; }
.codes-grid code { background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px; text-align: center; font-size: .95rem; letter-spacing: 1px; color: var(--text); }
