/* ioumi — styles de l'app (sortis d'index.html le 06/10/2026, audit D31 : 346 Ko de
   CSS en ligne, retéléchargés à chaque ouverture du site ; ici, mis en cache par le
   service worker). Ensuite vient interface.css (qui
   contient depuis le 15/10/2026 l'ex-aeration.css et l'ex-app-retouches.css). */
/* ============ POLICES AUTO-HÉBERGÉES ============
   Rubik pour tout le texte et l'interface ; Alfa Slab One pour le logo,
   les titres de vue et le titre de fiche recette (var(--serif)).
   ATTENTION : Alfa Slab One n'existe qu'en 400 et n'a NI gras NI italique.
   Ne jamais lui demander l'un ou l'autre : le navigateur les synthétiserait,
   et une graisse simulée sur une égyptienne déjà très grasse est illisible.
   Servies depuis /fonts et mises en cache par le service worker,
   pour que la typographie reste correcte hors-ligne (au supermarché)
   sans dépendance render-blocking à un CDN tiers. */
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/rubik-latin-400-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/rubik-latin-ext-400-normal.woff2") format("woff2");
  unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:500; font-display:swap;
  src:url("fonts/rubik-latin-500-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:500; font-display:swap;
  src:url("fonts/rubik-latin-ext-500-normal.woff2") format("woff2");
  unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:600; font-display:swap;
  src:url("fonts/rubik-latin-600-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:600; font-display:swap;
  src:url("fonts/rubik-latin-ext-600-normal.woff2") format("woff2");
  unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:700; font-display:swap;
  src:url("fonts/rubik-latin-700-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Rubik"; font-style:normal; font-weight:700; font-display:swap;
  src:url("fonts/rubik-latin-ext-700-normal.woff2") format("woff2");
  unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Alfa Slab One"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/alfa-slab-one-latin-400-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Alfa Slab One"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/alfa-slab-one-latin-ext-400-normal.woff2") format("woff2");
  unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ============ TOKENS ============ */
:root{
  /* Charte « Cantine » (sept. 2026) : crème plus jaune, encre bleu nuit à la
     place du brun, aplats corail / moutarde / pistache. Les NOMS de jetons ne
     changent pas — --sage, --terra, --gold — pour ne pas toucher aux 21 000
     lignes qui les utilisent ; seules les valeurs bougent. --sage vaut donc
     désormais un vert pistache et --terra un corail. */
  --bg:#FBF3E4; --surface:#FFFCF5; --surface-2:#F3E7CF; --sand:#EADCC0;
  --sage:#7FB069; --sage-deep:#6B9C57; --sage-soft:#E3F0DA;
  --terra:#FF6B4A; --terra-soft:#FFE2D9;
  /* Variantes RÉSERVÉES AU TEXTE. --terra et --sage servent aussi de FOND
     (.chip.on.terra, survols…) : les assombrir casserait le design. Celles-ci
     ne changent que la luminosité, à teinte identique, pour atteindre le seuil
     WCAG AA de 4.5:1. Mesuré (audit 06/09) : --terra-text sur --terra-soft
     = 4.88:1, sur --bg = 5.43:1, sur --surface = 5.84:1, sur --surface-2
     = 4.89:1 ; --sage-text sur --sage-soft = 5.48:1. La valeur précédente
     (#C93F21) ne valait que 4.06:1 sur --terra-soft — soit sous le seuil sur
     les étiquettes de régime, la puce « ✨ Premium » ET la bannière
     d'incitation Premium, c'est-à-dire précisément le message à lire. */
  --terra-text:#B5361B; --sage-text:#3F6832;
  /* Encre posée SUR un aplat corail, pistache ou moutarde. Cantine met du bleu
     nuit sur la couleur, jamais du blanc : blanc sur --terra ne vaut que
     2.70:1, l'encre y vaut 5.67:1 (6.33:1 sur --sage, 8.57:1 sur --gold). */
  --on-accent:#14213D;
  --ink:#14213D; --ink-2:#3D4A6B; --muted:#5F687F;
  --border:#DCC9A6; --border-2:#C2AE86;
  --danger:#C0392B; --danger-soft:#FBDDDA;
  --shadow-sm:0 1px 2px rgba(20,33,61,.07), 0 2px 6px rgba(20,33,61,.05);
  --shadow-md:0 6px 18px rgba(20,33,61,.11), 0 2px 6px rgba(20,33,61,.06);
  --shadow-lg:0 18px 50px rgba(20,33,61,.24);
  --radius:12px; --radius-sm:8px; --radius-lg:18px;
  --serif:"Alfa Slab One", Georgia, serif;
  --sans:"Rubik", system-ui, -apple-system, sans-serif;
  --ease:cubic-bezier(.22,.61,.36,1);
  --gold:#F0B429; --gold-soft:#FCEBC2; --gold-deep:#7A5100;
  /* Jetons utilisés dans le code sans avoir jamais été définis (relevé au lot 1).
     Une déclaration qui référence un jeton inexistant est invalide au calcul, donc
     ignorée : le champ de note de recette n'avait AUCUN fond (transparent au lieu
     du fond doux attendu) et les cinq messages d'erreur du partage de maison
     s'affichaient en encre normale au lieu d'une couleur d'alerte. Définis ici en
     alias : le thème sombre suit tout seul, puisque les jetons cibles sont
     redéfinis sur le même élément racine. */
  --bg-soft:var(--surface-2);
  --warn:var(--danger);
  --sage-pale:var(--sage-soft);
}
html[data-theme="dark"]{
  /* Cantine en sombre : le fond devient le bleu nuit, l'encre devient la crème.
     Les accents sont éclaircis pour rester au-dessus de AA sur fond foncé. */
  --terra-text:#FF9E86;
  --sage-text:#A6D695;
  --on-accent:#14161F;
  --bg:#14161F; --surface:#1E2230; --surface-2:#282D3E; --sand:#333A4E;
  --sage:#9BCB86; --sage-deep:#87BA71; --sage-soft:#1D3320;
  --terra:#FF8467; --terra-soft:#3A211A;
  --ink:#FBF3E4; --ink-2:#C6CCDD; --muted:#99A1B7;
  --border:#3A4157; --border-2:#4A5370;
  --danger:#E8705E; --danger-soft:#3B1F1D;
  --shadow-sm:0 1px 2px rgba(0,0,0,.32); --shadow-md:0 8px 22px rgba(0,0,0,.42);
  --shadow-lg:0 20px 56px rgba(0,0,0,.56);
  --gold:#FFC94D; --gold-soft:#39300F; --gold-deep:#FFD574;
}
.skip-link{position:absolute; left:8px; top:-60px; z-index:3000; background:var(--surface); color:var(--ink);
  border:2px solid var(--ink); border-radius:10px; padding:10px 16px; font-weight:700; text-decoration:none;
  transition:top .15s ease}
.skip-link:focus{top:8px}
#mainContent:focus{outline:none}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:var(--sans); background:var(--bg); color:var(--ink);
  -webkit-font-smoothing:antialiased; line-height:1.5;
  transition:background .4s var(--ease), color .4s var(--ease);
  min-height:100vh;
}
/* I51 : le serif (Alfa Slab One) est réservé au logo (.brand-name), aux H1 de vue
   (.view-title) et au titre de la fiche recette (.rd-title — le « H1 » de cette modale).
   Tous les autres titres (cartes, modales, compteurs) passent en sans 600/700 : deux
   familles qui se disputent chaque écran rendaient la hiérarchie illisible. */
h1{font-family:var(--serif); font-weight:400; letter-spacing:-.01em; margin:0}
h2,h3{font-family:var(--sans); font-weight:700; letter-spacing:-.01em; margin:0}
.rd-title{font-family:var(--serif); font-weight:400; letter-spacing:-.008em; line-height:1.12}
button{font-family:inherit; cursor:pointer; border:none; background:none; color:inherit}
input,select,textarea{font-family:inherit; font-size:1rem; color:var(--ink)}
/* 14/10/2026 (audit F7) : l'anneau de focus est à l'encre partout, 3 px (charte). Les
   variantes vertes ou corail par composant sont retirées : interface.css les écrasait déjà. */
:focus-visible{outline:3px solid var(--ink); outline-offset:2px; border-radius:6px}
::selection{background:var(--sage-soft)}

/* ============ HEADER ============ */
.app-header{
  position:sticky; top:0; z-index:40; border-bottom:1px solid var(--border);
  display:flex; align-items:center; gap:18px;
  padding:calc(10px + env(safe-area-inset-top)) clamp(14px,3vw,28px) 10px;
}
/* Fond plein sur un pseudo-élément (15/10/2026, audit F2 : plus de verre). Jamais de
   backdrop-filter ni de transform sur .app-header lui-même : il deviendrait le repère des
   enfants en position:fixed (dont .main-nav en mobile), coincés en haut dans WebKit. */
.app-header::before{
  content:''; position:absolute; inset:0; z-index:-1;
  background:var(--surface);
}
.brand{display:flex; align-items:center; gap:11px; flex-shrink:0}
.brand-mark{width:38px; height:38px; flex-shrink:0}
.brand-name{font-family:var(--serif); font-size:1.34rem; line-height:1; color:var(--ink); letter-spacing:-.012em}
.brand-name em{color:var(--terra-text)}   /* Alfa Slab One n'a pas d'italique : la distinction passe par la couleur */
.main-nav{display:flex; gap:4px; margin-left:6px; background:var(--surface-2);
  padding:5px; border-radius:999px; border:1px solid var(--border)}
.nav-btn{
  display:flex; align-items:center; gap:7px; padding:8px 15px; border-radius:999px;
  font-size:.92rem; font-weight:600; color:var(--ink-2); transition:.2s var(--ease); position:relative;
}
.nav-btn svg{width:17px; height:17px}
.nav-lab-short{display:none}
.rcard-ecarter{display:block; width:100%; margin:0; padding:9px 12px; border:none; border-top:1px solid var(--border);
  background:transparent; color:var(--muted); font:inherit; font-size:.78rem; font-weight:600; cursor:pointer; text-align:center}
.rcard-ecarter:hover{color:var(--terra); background:color-mix(in srgb,var(--sand) 40%,transparent)}
.nav-btn:hover{color:var(--ink); background:color-mix(in srgb,var(--sand) 60%,transparent)}
.nav-btn.active{background:var(--sage); color:var(--on-accent); box-shadow:0 3px 10px rgba(127,176,105,.35)}
html[data-theme="dark"] .nav-btn.active{color:var(--on-accent)}
.nav-badge{position:absolute; top:-3px; right:-3px; min-width:18px; height:18px; padding:0 5px;
  background:var(--terra); color:var(--on-accent); font-size:.72rem; font-weight:700; border-radius:999px;
  display:flex; align-items:center; justify-content:center; border:2px solid var(--surface)}
.nav-badge-dot{position:absolute; top:2px; right:6px; width:8px; height:8px; border-radius:999px;
  background:var(--terra); border:2px solid var(--surface-2)}
body.is-premium .nav-badge-dot{display:none}
/* ---- Identité visuelle Premium : différenciation réelle vs gratuit (au-delà du simple
   déverrouillage de fonctionnalités), pour que la montée en gamme se voie d'un coup d'oeil. ---- */
.premium-mark{
  display:none; align-items:center; gap:4px; margin-left:2px; padding:3px 9px 3px 7px;
  border-radius:999px; font-size:.7rem; font-weight:800; letter-spacing:.02em;
  color:var(--gold-deep); background:var(--gold-soft); border:1px solid color-mix(in srgb, var(--gold) 45%, transparent);
  white-space:nowrap; flex-shrink:0;
}
body.is-premium .premium-mark{display:inline-flex}
.header-premium-cta{
  display:inline-flex; align-items:center; gap:6px; margin-left:10px; padding:7px 14px;
  border:none; border-radius:999px; cursor:pointer; white-space:nowrap;
  background:linear-gradient(135deg,var(--gold),var(--terra) 130%); color:var(--on-accent);
  font-size:.82rem; font-weight:700; box-shadow:0 2px 8px rgba(184,146,74,.35);
  transition:transform .15s ease, box-shadow .15s ease;
}
.header-premium-cta:hover{ transform:translateY(-1px); box-shadow:0 4px 12px rgba(184,146,74,.45); }
.header-premium-cta:active{ transform:translateY(0); }
body.is-premium .header-premium-cta{display:none}
/* Lot 3 (J56) : sur mobile le CTA reste visible sous forme compacte. Revue du gating (26/09) :
   « ✨ Premium » plutôt que l'icône seule, qui ne disait pas ce qu'elle ouvrait. */
@media (max-width:720px){ .header-premium-cta{padding:6px 10px; margin-left:6px; font-size:.76rem} .header-premium-cta .hpc-txt{display:none} }
/* Grille de prix et modale de confirmation (J57) */
#btnGoPremium{white-space:normal; line-height:1.3; padding-top:12px; padding-bottom:12px} /* libellés longs sur mobile (« Créer un compte pour commencer l'essai ») */
.premium-details-open .premium-details-head{font-size:.88rem; font-weight:700; color:var(--sage-text); padding:13px 14px; display:flex; align-items:center; gap:8px; border-bottom:1.5px solid var(--sage); background:var(--sage-soft)}
.ck-recap{display:flex; flex-direction:column; gap:8px; padding:12px 14px; border:1.5px solid var(--border); border-radius:var(--radius-sm); background:var(--surface-2, var(--sage-soft)); margin-bottom:6px}
.ck-row{display:flex; justify-content:space-between; gap:14px; font-size:.84rem; color:var(--ink-2); line-height:1.45}
.ck-row span{color:var(--muted); flex:0 0 auto}
.ck-row strong{color:var(--ink); text-align:right}
.wsv-premium-line{color:inherit; cursor:pointer}
.wsv-premium-line:hover{text-decoration:underline}
.nav-more-premium{ color:var(--gold-deep); font-weight:700; }
.nav-more-premium svg{ stroke:var(--gold-deep); }
body.is-premium .nav-more-premium, html.offre-en-pause .nav-more-premium{display:none}
/* Premium : la cocotte passe en moutarde. L'ancienne règle visait `rect`, qui
   désignait le fond du logo sauge ; dans la marque Cantine `rect` est le
   couvercle, déjà moutarde — la teindre effaçait son contour. */
body.is-premium .brand-mark .bm-pot{fill:var(--gold)}
body.is-premium .nav-btn.active{
  background:linear-gradient(135deg, var(--terra) 0%, var(--gold) 130%);
  box-shadow:0 3px 12px rgba(184,146,74,.30);
}
@media (max-width:640px){ .premium-mark span{display:none} .premium-mark{padding:3px 7px} }
.blur-teaser-wrap{position:relative; overflow:hidden}
.blur-teaser-wrap .btw-content{filter:blur(5px); pointer-events:none; user-select:none}
.blur-teaser-wrap .btw-overlay{position:absolute; inset:0; display:flex; flex-direction:column; align-items:center;
  justify-content:center; text-align:center; gap:10px; padding:20px;
  background:linear-gradient(180deg, transparent, var(--surface) 60%)}
.blur-teaser-wrap .btw-overlay p{font-size:.86rem; color:var(--ink-2); max-width:340px; line-height:1.5; margin:0}
.lib-locked-block{margin-top:22px; padding-top:18px; border-top:1.5px dashed var(--border)}
#trialBanner:empty{display:none}
#trialBanner{background:var(--terra); color:var(--on-accent); font-size:.84rem; font-weight:700; text-align:center; padding:9px 14px; display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap}
#trialBanner a{color:#fff; text-decoration:underline; font-weight:800; cursor:pointer}
/* C4 : la croix des bandeaux faisait 25×21 px à 60 % d'opacité — sous le
   minimum WCAG 2.5.8 (24×24) sur l'axe vertical, et peu lisible. */
.trial-banner .tb-fermer{min-width:32px; min-height:32px; display:inline-flex;
  align-items:center; justify-content:center; border-radius:50%; opacity:.8}
.trial-banner .tb-fermer:hover{opacity:1; background:color-mix(in srgb,currentColor 12%,transparent)}
/* S9 : le mode démo tenait sur un bandeau pleine largeur de 96 px — 11 % de la
   hauteur utile d'un téléphone, sur l'écran qui décide de tout, et il
   s'ajoutait au bandeau de semaine (que pickWeekBanner croyait pourtant
   arbitrer seul). C'est désormais une puce : une ligne, centrée, à sa largeur,
   ~30 px. Le fond de page reste visible autour, donc rien n'est « barré ». */
#demoBanner:empty{display:none}
#demoBanner{display:flex; justify-content:center; padding:8px 14px 0; background:transparent}
#demoBanner .db-chip{display:inline-flex; align-items:center; gap:8px; max-width:100%;
  background:var(--ink); color:var(--bg); font-size:.76rem; font-weight:600;
  padding:4px 6px 4px 12px; border-radius:999px; box-shadow:var(--shadow-sm)}
#demoBanner .db-txt{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
/* Le complément d'explication ne s'affiche que s'il y a la place : sur 390 px,
   une puce tronquée par des points de suspension ne vaut pas mieux qu'un
   bandeau. Le texte complet reste dans le title. */
@media(max-width:560px){ #demoBanner .db-long{display:none} }
#demoBanner a{color:var(--bg); background:color-mix(in srgb,var(--bg) 22%,transparent); padding:3px 11px; border-radius:999px; text-decoration:none; font-weight:800; cursor:pointer; white-space:nowrap}
#demoBanner a:hover{background:color-mix(in srgb,var(--bg) 34%,transparent)}
#installBanner:empty{display:none}
#installBanner{background:var(--gold); color:var(--ink); font-size:.84rem; font-weight:600; text-align:center; padding:9px 14px; display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap}
#installBanner a{color:var(--ink); background:rgba(0,0,0,.1); padding:4px 12px; border-radius:999px; text-decoration:none; font-weight:800; cursor:pointer; white-space:nowrap}
#installBanner a:hover{background:rgba(0,0,0,.16)}
#installBtn[hidden]{display:none}
.pa-preview{max-height:340px; overflow:hidden; text-align:left}
.pa-preview .pa-header{border-bottom:2px solid var(--terra); padding-bottom:10px; margin-bottom:6px}
.pa-preview h1{font-family:var(--serif); font-size:1.3rem; margin-bottom:4px; color:var(--terra-text)}
.pa-preview .pa-header p{font-size:.82rem; color:var(--muted); margin:0}
.pa-preview .pa-cat{font-weight:800; margin:12px 0 6px; font-size:.92rem; display:flex; justify-content:space-between; color:var(--sage-text)}
.pa-preview .pa-cat-total{font-weight:700; color:var(--terra-text)}
.pa-preview ul{list-style:none; padding:0; margin:0}
.pa-preview li{padding:4px 0; border-bottom:1px solid var(--border); font-size:.86rem; display:flex; justify-content:space-between}
.lib-locked-head{font-size:.9rem; font-weight:700; color:var(--terra-text); margin-bottom:12px}
.lib-locked-block .blur-teaser-wrap{border-radius:var(--radius); min-height:180px}
.price-learn-toggle.locked{position:relative}
.week-nav-lock{cursor:pointer}
.header-spacer{flex:1}
/* Micro-interaction : feedback visuel discret après chaque sauvegarde
   (scheduleSave/saveState étaient jusque-là entièrement silencieux — rien
   ne montrait que le travail de l'utilisateur avait bien été pris en
   compte). Un check qui apparaît/disparaît, jamais de pile de toasts. */
.save-indicator{display:flex; align-items:center; gap:5px; font-size:.76rem; font-weight:700; color:var(--sage-text);
  opacity:0; transform:translateY(-2px); transition:opacity .25s var(--ease), transform .25s var(--ease); pointer-events:none; white-space:nowrap}
.save-indicator svg{width:14px; height:14px}
/* S5 : quand la sauvegarde cloud échoue, le voyant cesse de dire « Enregistré »
   et reste affiché — un état durable ne doit pas s'effacer au bout de 1,4 s. */
.save-indicator.sync-error{color:var(--terra-text); cursor:pointer; pointer-events:auto}
.save-indicator.sync-error.show{opacity:1}
/* 14/10/2026 (audit F6) : hors ligne, un bandeau sous l'en-tête, la cocotte qui dort. */
.hors-ligne{display:flex; align-items:center; gap:12px; margin:10px 0 4px; padding:10px 14px;
  background:var(--surface); border:1.5px solid var(--border-2); border-radius:16px; color:var(--ink)}
.hors-ligne[hidden]{display:none}
.hors-ligne .jeu-coco-sm{width:44px; height:38px}
.hors-ligne-t{display:flex; flex-direction:column; gap:2px; min-width:0}
.hors-ligne-t b{font-size:.92rem; line-height:1.3}
.hors-ligne-t small{font-size:.8rem; color:var(--muted)}
.save-indicator.show{opacity:1; transform:translateY(0)}
@media(max-width:760px){ .save-indicator span, .save-indicator{ font-size:.7rem } .save-indicator{gap:3px} }
/* Micro-interaction : shimmer pour les zones "Chargement…" (attente async du
   statut compte/maison) — un texte figé ne dit pas si l'appli travaille
   encore ou est bloquée ; un léger effet de balayage rassure que ça avance. */
@keyframes skelShimmer{0%{background-position:-120% 0}100%{background-position:120% 0}}
.skel-loading{position:relative; color:transparent !important; border-color:transparent !important; overflow:hidden; pointer-events:none}
.skel-loading::before{content:'';position:absolute; inset:0; border-radius:inherit;
  background:linear-gradient(90deg, var(--sand) 25%, var(--surface) 50%, var(--sand) 75%);
  background-size:200% 100%; animation:skelShimmer 1.3s ease-in-out infinite}
.icon-btn{width:40px; height:40px; border-radius:12px; display:flex; align-items:center; justify-content:center; position:relative;
  background:var(--surface-2); border:1px solid var(--border); color:var(--ink-2); transition:.2s var(--ease)}
.icon-btn:hover{background:var(--sand); color:var(--ink); transform:translateY(-1px)}
.icon-btn svg{width:19px; height:19px}
.acc-dot{position:absolute; top:6px; right:6px; width:9px; height:9px; border-radius:999px; background:var(--sage); border:2px solid var(--surface-2)}
.acc-dot.premium{background:var(--terra)}
.acc-status{display:flex; align-items:center; gap:9px; padding:11px 14px; border-radius:12px; background:var(--sage-soft); color:var(--sage-text); font-weight:700; font-size:.88rem}
.acc-status-dot{width:9px; height:9px; border-radius:999px; background:var(--sage-deep); flex-shrink:0}
.acc-status.premium{background:var(--terra-soft); color:var(--terra-text)}
.acc-status.premium .acc-status-dot{background:var(--terra)}
.trial-banner{background:var(--sage-soft); color:var(--sage-text); font-size:.82rem; font-weight:600; line-height:1.4; padding:10px 14px; border-radius:var(--radius-sm); margin-bottom:2px}
.billing-tabs{display:grid; grid-template-columns:1fr 1fr; gap:6px; background:var(--surface-2, var(--sage-soft)); border-radius:var(--radius-sm); padding:4px; margin-top:2px}
.billing-tab{border:none; background:transparent; border-radius:calc(var(--radius-sm) - 4px); padding:9px 10px; font-size:.82rem; font-weight:700; color:var(--muted); cursor:pointer; transition:.15s var(--ease); display:flex; align-items:center; justify-content:center; gap:6px}
.billing-tab.active{background:var(--surface); color:var(--ink); box-shadow:var(--shadow-sm)}
.billing-tab-badge{background:var(--terra); color:var(--on-accent); font-size:.72rem; font-weight:800; padding:2px 7px; border-radius:999px; letter-spacing:.01em}
/* Écran Premium — respiration.
   Avant : 3 colonnes fixes collées (gap 10px) avec seulement 14px au-dessus, si bien que
   le badge « 💑 Couples » (positionné à top:-11px) mordait sur le sélecteur de période
   juste au-dessus, et les blocs de texte s'enchaînaient sans séparation visible.
   Après : colonnes auto-ajustées (elles passent en 1 par ligne dès que 220px ne tiennent
   plus, sans attendre le point de rupture 880px), gouttière plus large, et surtout assez
   de marge haute pour que le badge flotte dans le vide au lieu de chevaucher. */
.premium-plans{display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:14px; margin:26px 0 18px; align-items:stretch}
.plan-card{position:relative; border:1.5px solid var(--border); border-radius:var(--radius-sm); padding:20px 14px 16px; cursor:pointer; text-align:left; background:var(--surface); transition:.15s var(--ease); display:flex; flex-direction:column}
.plan-card:hover{border-color:var(--sage)}
.plan-card.selected{border-color:var(--sage-text); background:var(--sage-soft); box-shadow:var(--shadow-sm)}
.plan-card .pc-badge{position:absolute; top:-11px; left:50%; transform:translateX(-50%); background:var(--terra); color:var(--on-accent); font-size:.72rem; font-weight:800; padding:3px 9px; border-radius:999px; white-space:nowrap; box-shadow:var(--shadow-sm); letter-spacing:.01em}
.plan-card .pc-radio{position:absolute; top:12px; right:12px; width:16px; height:16px; border-radius:999px; border:2px solid var(--border-2); flex-shrink:0}
.plan-card.selected .pc-radio{border-color:var(--sage-text); background:var(--sage-deep); box-shadow:inset 0 0 0 3px var(--surface)}
.plan-card .pc-label{font-weight:700; font-size:.84rem; color:var(--ink-2); margin-bottom:6px; padding-right:26px; line-height:1.3; min-height:2.6em; display:flex; align-items:flex-start}
.plan-card.selected .pc-label{color:var(--sage-text)}
.plan-card .pc-price{font-family:var(--sans); font-weight:700; font-size:1.5rem; color:var(--ink); line-height:1.1}
.plan-card .pc-price span{font-family:var(--sans); font-size:.76rem; font-weight:600; color:var(--muted)}
.plan-card .pc-sub{font-size:.74rem; color:var(--sage-text); font-weight:700; margin-top:auto; padding-top:8px; line-height:1.45}
.plan-card .pc-strike{font-size:.78rem; color:var(--muted); text-decoration:line-through; margin-top:2px}
.nav-toggle{display:none}

/* ============ LAYOUT ============ */
.view-wrap{max-width:1180px; margin:0 auto; padding:clamp(16px,3vw,34px) clamp(14px,3vw,28px) 90px}
.view{display:none; animation:viewIn .42s var(--ease)}
.view.active{display:block}
@keyframes viewIn{from{opacity:0; transform:translateY(10px)}to{opacity:1; transform:none}}
.view-head{display:flex; align-items:flex-end; justify-content:space-between; gap:18px; flex-wrap:wrap; margin-bottom:26px}
.recette-head-actions{display:flex; gap:10px; flex-wrap:wrap}
/* Alfa Slab One est une egyptienne noire : a corps egal elle occupe bien plus
   de surface que DM Serif Display. L'echelle des titres redescend donc d'un
   cran, sinon le titre mange l'ecran avant le premier contenu utile. */
.view-title{font-family:var(--serif); font-weight:400; letter-spacing:-.012em; font-size:clamp(1.6rem,5.2vw,2.15rem); line-height:1.08}
.view-sub{color:var(--muted); font-size:.9rem; line-height:1.5; margin-top:6px; max-width:46ch}

/* ============ WEEK NAV ============ */
/* Regroupe le bouton "Aujourd'hui" et le sélecteur de semaine sur une même
   ligne : ils vont ensemble (revenir à aujourd'hui = un raccourci du
   sélecteur), contrairement à Partager/Dupliquer/Tout supprimer qui sont
   des actions indépendantes sur le contenu de la semaine. */
.week-nav-row{display:flex; align-items:center; gap:8px}
/* F39 : `hidden` seul perdait contre .btn{display:inline-flex} (même spécificité, déclaré
   après) — « Aujourd'hui » restait affiché même sur la semaine en cours. */
#goTodayBtn[hidden]{display:none}
.week-nav{display:flex; align-items:center; gap:10px; background:var(--surface);
  border:1px solid var(--border); border-radius:999px; padding:5px}
.week-nav button{width:38px; height:38px; border-radius:50%; display:flex; align-items:center;
  justify-content:center; color:var(--ink-2); transition:.18s var(--ease)}
.week-nav button:hover{background:var(--sage-soft); color:var(--sage-text)}
.week-nav svg{width:18px; height:18px}
.week-label{font-weight:600; font-size:.95rem; min-width:148px; text-align:center; text-transform:capitalize; font-variant-numeric:tabular-nums}
.week-today{font-size:.74rem; color:var(--sage-text); font-weight:700; text-transform:uppercase; letter-spacing:.5px}

/* ============ WEEK GRID ============ */
.grid-scroll{overflow-x:auto; padding-bottom:8px; margin:0 -4px}
.grid-scroll::-webkit-scrollbar{height:9px}
.grid-scroll::-webkit-scrollbar-track{background:var(--surface-2); border-radius:9px}
.grid-scroll::-webkit-scrollbar-thumb{background:var(--border-2); border-radius:9px; border:2px solid var(--surface-2)}
.grid-scroll::-webkit-scrollbar-thumb:hover{background:var(--sage)}
.week-grid{display:grid; grid-template-columns:78px repeat(7, minmax(124px,1fr)); gap:9px; min-width:760px; padding:4px}
/* ---- Vue "jour" alternative (voir weekViewMode dans index.html JS) ----
   Un seul jour affiché à la fois, empilé verticalement, plutôt que la
   grille 7 colonnes qui impose un défilement horizontal sous 760px. */
.day-view{padding:4px}
.day-switch-row{display:flex; align-items:center; gap:6px; margin-bottom:12px}
.day-switch{display:flex; gap:6px; overflow-x:auto; flex:1; scrollbar-width:none; padding:2px}
.day-switch::-webkit-scrollbar{display:none}
.day-switch button{flex:0 0 auto}
.day-meal-row{display:flex; align-items:stretch; gap:10px; margin-bottom:10px}
.day-meal-row .meal-label{flex:0 0 62px; min-width:62px; padding:4px}
.day-meal-row .slot{flex:1; min-height:92px}
.gh{display:flex; flex-direction:column; align-items:center; justify-content:center; padding:8px 4px; gap:2px}
.gh.corner{}
.gh-day{font-weight:700; font-size:.86rem; text-transform:capitalize}
.gh-date{font-size:.78rem; color:var(--muted)}
.gh.is-today{color:var(--sage-text)}
/* Jour décoché dans « Jours à planifier » : estompé, jamais masqué — la colonne
   reste cliquable pour un repas exceptionnel (voir jourEstPlanifie). */
.gh.is-off{opacity:.45}
.gh.is-off .gh-day::after{content:" ·"; opacity:.7}
.gh.is-today .gh-day{background:var(--sage); color:var(--on-accent); padding:2px 9px; border-radius:999px}
html[data-theme="dark"] .gh.is-today .gh-day{color:var(--on-accent)}
.meal-label{display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
  font-size:.74rem; font-weight:700; color:var(--ink-2); text-align:center; line-height:1.15}
.meal-label .me{font-size:1.15rem}
.slot{min-height:104px; border-radius:var(--radius-sm); padding:9px; display:flex; flex-direction:column;
  transition:.22s var(--ease); position:relative; overflow:hidden}
/* Charte Cantine : l'encre marque ce qu'on TOUCHE. Un créneau vide est
   cliquable — c'est même le geste le plus fréquent de l'écran — il porte donc
   le trait de 2 px comme les cartes remplies. Le pointillé reste, lui, pour
   dire « rien ici » : trait d'encre + tireté = « à remplir », pas « décoratif ».
   Le filet gris de 1,6 px précédent le faisait passer pour un séparateur. */
.slot.empty{border:2px dashed var(--ink); background:transparent; align-items:center; justify-content:center;
  color:var(--ink-2); cursor:pointer; opacity:.55}
.slot.empty:hover, .slot.empty:focus-visible{opacity:1}
.slot.empty:active{transform:var(--press); opacity:1}
.slot.empty:hover{border-color:var(--sage); background:var(--sage-soft); color:var(--sage-text); transform:translateY(-2px)}
.slot.empty .plus{width:30px; height:30px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:1.4rem; background:var(--surface-2); transition:.2s var(--ease)}
.slot.empty:hover .plus{background:var(--sage); color:var(--on-accent); transform:rotate(90deg)}
.slot.filled{background:var(--surface); border:1px solid var(--border); box-shadow:var(--shadow-sm); cursor:pointer}
.slot.filled:hover{transform:translateY(-3px); box-shadow:var(--shadow-md); border-color:var(--sage)}
.slot.filled.dragging{opacity:.45}
.slot.drop-target{border:1.6px dashed var(--sage); background:var(--sage-soft)}
.slot-emoji{font-size:1.5rem; line-height:1}
.slot-name{font-weight:600; font-size:.82rem; margin-top:5px; line-height:1.2;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.slot-meta{margin-top:auto; padding-top:6px; display:flex; align-items:center; gap:10px; font-size:.78rem; color:var(--muted)}
.slot-meta .ppl{display:inline-flex; align-items:center; gap:3px; font-weight:600; color:var(--sage-text)}
.slot-meta svg{width:11px;height:11px}
.slot-meta-sep{opacity:.4; font-weight:700}
.slot-kcal{font-weight:600}

/* recap */
.recap{margin-top:26px; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg);
  padding:20px clamp(16px,3vw,26px); display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:20px}
.recap-block .rl{font-size:.74rem; text-transform:uppercase; letter-spacing:.6px; color:var(--muted); font-weight:700}
.recap-block .rv{font-family:var(--sans); font-weight:700; font-size:1.85rem; line-height:1.1; margin-top:3px}
.recap-block .rv small{font-size:.9rem; color:var(--muted); font-family:var(--sans)}
.macro-bar{display:flex; height:10px; border-radius:999px; overflow:hidden; margin-top:9px; background:var(--surface-2)}
.macro-bar i{display:block; height:100%; transition:width .6s var(--ease)}
.macro-p{background:var(--sage)} .macro-c{background:var(--terra)} .macro-l{background:#E0B25A}
.macro-leg{display:flex; gap:12px; margin-top:8px; font-size:.72rem; color:var(--ink-2); flex-wrap:wrap}
.macro-leg span{display:inline-flex; align-items:center; gap:4px}
.macro-leg i{width:9px; height:9px; border-radius:3px; display:inline-block}
.meals-prog{height:8px; background:var(--surface-2); border-radius:999px; overflow:hidden; margin-top:10px}
.meals-prog i{display:block; height:100%; background:linear-gradient(90deg,var(--sage),var(--sage-deep)); transition:width .6s var(--ease)}

/* ============ FILTER BAR / CHIPS ============ */
.toolbar{display:flex; flex-direction:column; gap:14px; margin-bottom:22px}
.search-row{display:flex; gap:10px; flex-wrap:wrap}
.search-box{flex:1; min-width:210px; position:relative}
.search-box svg{position:absolute; left:14px; top:50%; transform:translateY(-50%); width:18px; height:18px; color:var(--muted)}
.search-box input{width:100%; padding:12px 14px 12px 42px; border-radius:999px; border:1px solid var(--border);
  background:var(--surface); transition:.2s var(--ease)}
.search-box input:focus{border-color:var(--sage); box-shadow:0 0 0 4px var(--sage-soft); outline:none}
.ing-search-box{display:flex; align-items:center}
.ing-search-box .ing-ic{position:absolute; left:14px; top:50%; transform:translateY(-50%); font-size:16px; line-height:1; pointer-events:none}
.ing-search-box input{width:100%; padding:12px 14px 12px 42px; border-radius:999px; border:1px solid var(--border); background:var(--surface); transition:.2s var(--ease)}
.ing-search-box input:focus{border-color:var(--sage); box-shadow:0 0 0 4px var(--sage-soft); outline:none}
.filter-group{display:flex; flex-wrap:wrap; gap:7px; align-items:center}
.filter-group .fg-label{font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--muted); margin-right:2px}
.chip{padding:7px 13px; border-radius:999px; font-size:.82rem; font-weight:600; border:1px solid var(--border);
  background:var(--surface); color:var(--ink-2); transition:.18s var(--ease); display:inline-flex; align-items:center; gap:6px}
.chip:hover{border-color:var(--sage); color:var(--sage-text)}
.chip.on{background:var(--sage); color:var(--on-accent); border-color:var(--sage); box-shadow:0 2px 8px rgba(127,176,105,.3); animation:pop .25s var(--ease)}
html[data-theme="dark"] .chip.on{color:var(--on-accent)}
.chip.on.terra{background:var(--terra); border-color:var(--terra-text); box-shadow:0 2px 8px rgba(201,123,90,.3)}
@keyframes pop{from{transform:scale(.9)}to{transform:scale(1)}}
.chip .x{opacity:.85; font-weight:700}
.chip-select{padding:7px 13px; border-radius:999px; font-size:.82rem; font-weight:600; border:1px solid var(--border);
  background:var(--surface); color:var(--ink-2); cursor:pointer}
.chip-select:hover{border-color:var(--sage)}

/* ---- Listes repliables (pays, ustensiles…) : sur mobile ces listes sont
   très longues à défiler ; on les replie par défaut derrière un <summary>
   cliquable, tout en les gardant toujours dépliées sur desktop (voir
   @media(min-width:881px) plus bas qui neutralise l'état fermé natif). ---- */
.collapsible-list{border:1px solid var(--border); border-radius:var(--radius-sm); padding:2px 12px; background:var(--surface-2)}
.collapsible-list>summary{cursor:pointer; list-style:none; display:flex; align-items:center; gap:8px;
  padding:11px 2px; font-size:.86rem; font-weight:700; color:var(--ink); user-select:none}
.collapsible-list>summary::-webkit-details-marker{display:none}
.collapsible-list>summary::before{content:'▸'; font-size:.7rem; color:var(--muted); transition:transform .2s var(--ease); display:inline-block}
.collapsible-list[open]>summary::before{transform:rotate(90deg)}
.collapsible-list>summary:hover{color:var(--sage-text)}
.collapsible-list .cl-count{background:var(--sage); color:var(--on-accent); font-size:.72rem; font-weight:700; border-radius:999px; padding:2px 8px; line-height:1.4}
.collapsible-list .cl-count:empty{display:none}
.collapsible-list>.cl-content{padding:2px 2px 14px}
/* .po-more : même habillage visuel que .collapsible-list, mais repliée par
   défaut sur TOUS les écrans (y compris desktop) — contrairement aux listes
   de filtres, un menu d'actions secondaires (popover de créneau, F5) n'a pas
   vocation à rester toujours ouvert : on veut activement réduire ce qui est
   visible au premier coup d'œil. Ne pas fusionner avec .collapsible-list. */
.po-more{border:1px solid var(--border); border-radius:var(--radius-sm); padding:2px 12px; background:var(--surface-2); margin:6px 0}
.po-more>summary{cursor:pointer; list-style:none; display:flex; align-items:center; gap:8px;
  padding:9px 2px; font-size:.84rem; font-weight:700; color:var(--ink-2); user-select:none}
.po-more>summary::-webkit-details-marker{display:none}
.po-more>summary::before{content:'▸'; font-size:.7rem; color:var(--muted); transition:transform .2s var(--ease); display:inline-block}
.po-more[open]>summary::before{transform:rotate(90deg)}
.po-more>summary:hover{color:var(--sage-text)}
.po-more>.cl-content{padding:2px 2px 10px; display:flex; flex-direction:column; gap:2px}
/* .sel-fold : bloc de filtres repliable du SÉLECTEUR DE RECETTE (modale de
   planification). Volontairement distinct de .collapsible-list, qui est forcée
   ouverte sur desktop par le media query ci-dessous et par
   syncCollapsibleListsOpenState() : dans une modale, dérouler d'office 7 groupes
   de filtres noyait la liste de recettes sous les chips. Ici, replié par défaut
   quelle que soit la largeur d'écran. */
.sel-fold{border:1px solid var(--border); border-radius:var(--radius-sm); padding:2px 12px; background:var(--surface-2); margin-top:10px}
.sel-fold>summary{cursor:pointer; list-style:none; display:flex; align-items:center; gap:8px;
  padding:10px 2px; font-size:.84rem; font-weight:700; color:var(--ink-2)}
.sel-fold>summary::-webkit-details-marker{display:none}
.sel-fold>summary::before{content:'▸'; font-size:.7rem; color:var(--muted); transition:transform .2s var(--ease); display:inline-block}
.sel-fold[open]>summary::before{transform:rotate(90deg)}
.sel-fold>summary:hover{color:var(--sage-text)}
.sel-fold .cl-count{background:var(--sage); color:var(--on-accent); font-size:.72rem; font-weight:700; border-radius:999px; padding:2px 8px; line-height:1.4; margin-left:auto}
.sel-fold .cl-count:empty{display:none}
.sel-fold>.sf-content{padding:0 2px 12px}
/* ---- Écran de validation des suggestions de la semaine (validateWeekSuggestions) ---- */
.vote-shared-note{font-size:.75rem; color:var(--sage-text); background:var(--sage-soft);
  border-radius:var(--radius-sm); padding:8px 11px; margin-top:8px; line-height:1.45}
.wsv-day{font-size:.72rem; font-weight:800; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); margin:16px 0 6px; padding-bottom:5px; border-bottom:1px solid var(--border)}
.wsv-day:first-child{margin-top:2px}
.wsv-row{display:flex; align-items:center; gap:11px; padding:9px 4px; border-radius:var(--radius-sm); transition:.15s var(--ease)}
.wsv-row:hover{background:var(--sage-soft)}
.wsv-row.removed{opacity:.42}
.wsv-row.removed .wsv-txt strong{text-decoration:line-through}
.wsv-em{font-size:1.15rem; line-height:1; flex:0 0 auto}
.wsv-txt{display:flex; flex-direction:column; gap:1px; min-width:0; flex:1 1 auto}
.wsv-txt strong{font-size:.9rem; color:var(--ink); line-height:1.3}
.wsv-meal{font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted)}
.wsv-meta{font-size:.75rem; color:var(--muted)}
.wsv-btns{display:flex; gap:6px; flex:0 0 auto; flex-wrap:wrap; justify-content:flex-end}
.wsv-btns .chip{font-size:.74rem; padding:5px 10px}
.wsv-foot{align-items:center}
.wsv-foot #wsvBatchLink{background:none; border:0; padding:0; font:inherit; font-size:.8rem; font-weight:700; color:var(--sage-text); text-decoration:underline; cursor:pointer}
.wsv-tally{margin-right:auto; font-size:.8rem; color:var(--muted); font-weight:600}
@media(max-width:560px){
  .wsv-row{flex-wrap:wrap}
  .wsv-btns{width:100%; justify-content:flex-start; padding-left:30px}
  /* .modal-foot passe déjà en column-reverse sous 560px : le compteur doit alors
     repasser au-dessus des boutons plutôt que d'être poussé par margin-right:auto. */
  .wsv-tally{margin:0 0 4px; text-align:center; order:1}
}
@media(min-width:881px){
  /* Desktop : la liste reste toujours visible, on masque juste le bouton replier/déplier. */
  .collapsible-list{border:none; padding:0; background:none}
  .collapsible-list>summary{display:none}
  .collapsible-list:not([open])>.cl-content{display:flex !important}
  .collapsible-list>.cl-content{padding:0}
}

/* ============ RECIPE CARDS ============ */
.recipe-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(216px,1fr)); gap:16px}
.rcard{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden;
  display:flex; flex-direction:column; transition:.22s var(--ease); box-shadow:var(--shadow-sm); position:relative}
.rcard:hover{transform:translateY(-4px); box-shadow:var(--shadow-md); border-color:var(--sage)}
.rcard[data-card]{cursor:pointer}
.rcard-top{height:96px; display:flex; align-items:center; justify-content:center; font-size:3.1rem;
  background:linear-gradient(135deg,var(--surface-2),var(--sand)); position:relative; overflow:hidden}
.rcard-cat{position:absolute; top:9px; left:9px; font-size:.72rem; font-weight:700; text-transform:uppercase;
  letter-spacing:.5px; background:color-mix(in srgb,var(--surface) 88%,transparent); padding:3px 8px; border-radius:999px; color:var(--ink-2)}
.rcard-time{position:absolute; bottom:9px; right:9px; font-size:.7rem; font-weight:600; background:color-mix(in srgb,var(--surface) 88%,transparent);
  padding:3px 8px; border-radius:999px; color:var(--ink-2); display:flex; align-items:center; gap:4px}
.rcard-time svg{width:11px; height:11px}
/* E30 : badge « note personnelle » sur la carte (bas gauche, symétrique de la durée) */
.rcard-note{position:absolute; bottom:9px; left:9px; font-size:.8rem; background:color-mix(in srgb,var(--surface) 88%,transparent); padding:2px 7px; border-radius:999px; line-height:1.3}
.recipe-note-input{width:100%; box-sizing:border-box; min-height:44px; resize:none; overflow:hidden; font:inherit; font-size:.9rem; line-height:1.5; padding:8px 10px; border:1px solid var(--border); border-radius:10px; background:var(--bg-soft); color:var(--ink); margin-bottom:4px}
.recipe-note-input:focus{outline:2px solid var(--sage); outline-offset:1px}
.recipe-note-status{font-size:.7rem; font-weight:600; color:var(--sage-text); text-transform:none; letter-spacing:0}
.cm-note{margin:12px 16px 0; padding:9px 12px; border-radius:10px; background:var(--sage-pale); color:var(--ink); font-size:.9rem; line-height:1.45; flex-shrink:0}
.slot-note-badge{font-size:.7rem; margin-left:3px; vertical-align:middle}
/* E31 : import par lien sans compte — message d'orientation sous le champ URL */
.import-need-account{font-size:.8rem; color:var(--ink-2); margin-top:6px; padding:8px 10px; border-radius:10px; background:var(--sage-pale); line-height:1.5}
.import-need-account .link-btn{background:none; border:0; padding:0; font:inherit; font-weight:700; color:var(--sage-text); text-decoration:underline; cursor:pointer}
.vote-badge{position:absolute; top:9px; right:9px; font-size:.9rem; background:color-mix(in srgb,var(--surface) 88%,transparent);
  width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center}
.rcard-body{padding:13px 14px 15px; display:flex; flex-direction:column; flex:1}
.rcard-name{font-weight:700; font-size:.98rem; line-height:1.25}
.rcard-desc{font-size:.8rem; color:var(--muted); margin-top:4px; line-height:1.4;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.rcard-tags{display:flex; flex-wrap:wrap; gap:5px; margin-top:8px}
.tag{font-size:.72rem; font-weight:600; padding:3px 8px; border-radius:999px; background:var(--sage-soft); color:var(--sage-text)}
.tag.diet{background:var(--terra-soft); color:var(--terra-text)}
.tag.junk{background:#FBE0D4; color:#C1440E}
html[data-theme="dark"] .tag.junk{background:#4A2A18; color:#F2A472}
.tag.canicule{background:#FFE7CC; color:#A34A08}  /* S7 : 4.14:1 → 4.96:1 */
html[data-theme="dark"] .tag.canicule{background:#4A3216; color:#FFB870}
.tag.malade{background:#DCEAFB; color:#25628F}
.tag.nouveau{background:#E4F3E1; color:#2E6B2F}
html[data-theme="dark"] .tag.nouveau{background:#1F3D22; color:#9FD79A}
html[data-theme="dark"] .tag.malade{background:#1B3A52; color:#8FC3F2}
.rcard-foot{display:flex; align-items:center; justify-content:space-between; margin-top:12px; padding-top:11px; border-top:1px solid var(--border)}
.rcard-kcal{font-weight:700; font-size:.85rem}
.rcard-kcal small{color:var(--muted); font-weight:500}
.rcard-kcal-sm{font-size:.78rem; font-weight:600; color:var(--muted)}
.rcard-body .rcard-foot{margin-top:auto}
.rcard-acts{display:flex; gap:5px}
.rcard-macros{display:flex; gap:10px; margin-top:8px; font-size:.78rem; color:var(--muted); font-weight:500}
.rcard-macros b{color:var(--ink-2); font-weight:700}
.rcard-scores{display:flex; align-items:center; gap:6px; margin-top:8px; font-size:.72rem; color:var(--muted); flex-wrap:wrap}
.rcard-scores small{margin-right:2px}
.mini-btn{width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); color:var(--ink-2); transition:.16s var(--ease)}
.mini-btn:hover{background:var(--sage); color:var(--on-accent)}
.mini-btn.del:hover{background:var(--danger)}
.mini-btn svg{width:14px; height:14px}

/* ============ BUTTONS ============ */
/* `display` déclaré dans une feuille d'auteur bat le `display:none` que la
   feuille du navigateur pose sur [hidden] : tout élément à qui l'on donne un
   display (les .btn, .chip, .seg…) restait donc VISIBLE une fois `hidden`
   passé à true. C'est ce qui laissait le bouton « Vider » à l'écran sur un
   placard vide (S8). Trois règles ponctuelles le contournaient déjà au coup par
   coup (#installBtn, #goTodayBtn, .week-menu) ; on le règle une bonne fois. */
[hidden]{display:none !important}
.btn{display:inline-flex; align-items:center; justify-content:center; gap:8px; padding:11px 18px; border-radius:12px;
  font-weight:600; font-size:.92rem; transition:.18s var(--ease); border:1px solid transparent; white-space:nowrap}
.btn svg{width:17px; height:17px}
.btn-primary{background:var(--sage); color:var(--on-accent); box-shadow:0 3px 12px rgba(127,176,105,.32)}
html[data-theme="dark"] .btn-primary{color:var(--on-accent)}
.btn-primary:hover{background:var(--sage-deep); transform:translateY(-1px); box-shadow:0 6px 18px rgba(127,176,105,.4)}
.btn-ghost{background:var(--surface); border-color:var(--border); color:var(--ink)}
.btn-ghost:hover{border-color:var(--sage); color:var(--sage-text); background:var(--surface-2)}
.btn-soft{background:var(--surface-2); color:var(--ink-2)}
.btn-soft:hover{background:var(--sand); color:var(--ink)}
.btn-danger{background:var(--danger); color:#fff}
.btn-danger:hover{filter:brightness(1.06)}
/* 15/10/2026 : une suppression qui n'est pas l'action de l'écran sort du pied (Annuler à
   gauche, l'action nommée à droite) et devient un lien rouge, à part. */
.lien-danger{display:inline-flex; align-items:center; min-height:48px; padding:0 4px; background:none; border:0; font:inherit;
  font-size:.92rem; font-weight:700; color:var(--danger); text-decoration:underline; text-underline-offset:3px; cursor:pointer}
.lien-danger-zone{margin-top:22px; padding-top:6px; border-top:1px solid var(--border)}
.btn-block{width:100%}

/* Boutons de connexion externe (Google, Apple). Volontairement neutres et de
   même gabarit que les autres boutons de la modale : les chartes des deux
   fournisseurs demandent un libellé « Continuer avec … », un fond uni et le
   logo à gauche — ce que respecte ce style, sans imiter leurs boutons officiels. */
.btn-oauth{background:var(--surface); border-color:var(--border); color:var(--ink); font-weight:600}
.btn-oauth:hover{border-color:var(--sage); background:var(--surface-2)}
.btn-oauth svg{width:18px; height:18px}
.btn-oauth[disabled]{opacity:.5; cursor:not-allowed}
/* 01/10/2026 — Sign in with Apple (app iOS) : les règles d'Apple (Human Interface
   Guidelines) veulent un bouton noir à logo blanc, ou blanc à logo noir sur fond
   sombre, au moins aussi grand que les autres. Même gabarit que .btn-oauth. */
.btn-oauth.btn-apple{background:#000; border-color:#000; color:#fff}
.btn-oauth.btn-apple:hover{background:#000; border-color:#000; filter:brightness(1.25)}
html[data-theme="dark"] .btn-oauth.btn-apple{background:#fff; border-color:#fff; color:#000}
html[data-theme="dark"] .btn-oauth.btn-apple:hover{background:#fff; border-color:#fff; filter:brightness(.92)}
.btn-oauth.btn-apple svg{width:19px; height:19px; margin-top:-2px}
/* Séparateur « ou » entre les fournisseurs et le formulaire email. */
.auth-sep{display:flex; align-items:center; gap:12px; margin:18px 0; color:var(--muted); font-size:.78rem}
.auth-sep::before,.auth-sep::after{content:""; flex:1; height:1px; background:var(--border)}

/* Pastille « brouillon » sur le bouton Nouvelle recette : sans elle, la sauvegarde
   automatique du formulaire restait invisible — retour beta demandant un
   « enregistrement des brouillons » alors que le mécanisme existait déjà. */
.draft-badge{display:inline-block;margin-left:7px;padding:2px 7px;border-radius:999px;font-size:.72rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase;background:rgba(255,255,255,.24);color:#fff}
/* Ligne d'ingrédient dont les apports sont estimés faute de figurer dans notre table
   nutritionnelle : trait discret plutôt qu'une alerte — c'est une information de
   provenance, pas une erreur de saisie (voir updateNutriSourceNote). */
.ing-row.ing-approx input[data-k="nom"]{border-style:dashed}
/* ============ BOUTON MAGIQUE — Suggérer ma semaine ============
   L'action que la cocotte fait pour toi : corail plein, texte encre (--on-accent).
   Plus de dégradé ni de halo flou (15/10/2026, audit F2). */
.btn-magic{
  position:relative; color:var(--on-accent); border:none; overflow:visible;
  background:var(--terra);
}
.btn-magic.magic-pop{animation:magicPop .38s var(--ease)}
.btn-magic .cw-spark{display:inline-block; animation:sparkPulse 2.4s ease-in-out infinite}
@keyframes magicPop{0%{transform:scale(1)}40%{transform:scale(.92)}100%{transform:scale(1)}}
@keyframes sparkPulse{0%,100%{transform:scale(1) rotate(0deg)} 50%{transform:scale(1.25) rotate(14deg)}}
@media(prefers-reduced-motion:reduce){.btn-magic,.btn-magic .cw-spark{animation:none}}

/* particules à l'activation du bouton magique */
.magic-particle{position:fixed; z-index:70; pointer-events:none; font-size:1.1rem; animation:magicFly .85s var(--ease) forwards}
@keyframes magicFly{
  0%{transform:translate(0,0) scale(.4) rotate(0deg); opacity:1}
  100%{transform:translate(var(--mx),var(--my)) scale(1.1) rotate(var(--mr)); opacity:0}
}

/* panneau de cascade explicative — que fait "Suggérer ma semaine" (voir plus bas, style .ms-*) */
.btn-magic:disabled{opacity:.85; cursor:wait}

/* panneau de cascade explicative — que fait "Suggérer ma semaine", façon didacticiel */
.ms-wrap{padding:34px 30px 26px; text-align:center; display:flex; flex-direction:column; align-items:center; position:relative}
/* Lot 3 (22/09) : « Passer › » s'affichait en carré de 36 px, le chevron sous le
   mot. .modal-close (défini plus bas, même spécificité) écrasait width/height/
   border-radius de cette règle. Sélecteur composé pour reprendre la main. */
.modal-close.ms-skip{position:absolute; top:12px; right:12px; width:auto; height:36px; padding:0 14px; border-radius:999px;
  font-size:.76rem; font-weight:700; color:var(--muted); background:var(--surface-2); white-space:nowrap; gap:4px}
.modal-close.ms-skip:hover{color:var(--ink); background:var(--sand)}
.ms-body{min-height:190px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px;
  transition:opacity .22s var(--ease), transform .22s var(--ease)}
.ms-title{font-family:var(--sans); font-weight:800; font-size:1.28rem; letter-spacing:-.01em; color:var(--ink)}
.ms-illus{height:78px; display:flex; align-items:center; justify-content:center; position:relative; margin-bottom:2px}

.ms-hearts{display:flex; gap:10px; font-size:2rem}
.ms-hearts span{display:inline-block; animation:msHeartPop 1.3s var(--ease) infinite}
@keyframes msHeartPop{0%,100%{transform:scale(.7); opacity:.5} 30%{transform:scale(1.18); opacity:1} 60%{transform:scale(1); opacity:1}}

.ms-placard{position:relative; font-size:2.3rem}
.ms-placard .ms-food{display:inline-block; animation:msFoodShake 1.6s ease-in-out infinite}
.ms-placard .ms-clock{position:absolute; font-size:1.15rem; top:-8px; right:-16px; animation:msClockPulse 1s ease-in-out infinite}
@keyframes msFoodShake{0%,100%{transform:rotate(0deg)} 25%{transform:rotate(-6deg)} 75%{transform:rotate(6deg)}}
@keyframes msClockPulse{0%,100%{transform:scale(1) rotate(0deg); opacity:.75} 50%{transform:scale(1.25) rotate(-12deg); opacity:1}}

.ms-seasons{display:flex; gap:13px; font-size:1.55rem}
.ms-seasons span{display:inline-block; opacity:.35; transform:scale(.82); animation:msSeasonWave 1.3s var(--ease) infinite}
@keyframes msSeasonWave{0%,100%{opacity:.35; transform:scale(.82)} 40%{opacity:1; transform:scale(1.15)} 65%{opacity:.6; transform:scale(.95)}}

.ms-filter{position:relative; width:74px; height:76px}
.ms-filter .ms-funnel{position:absolute; left:50%; top:6px; transform:translateX(-50%); width:0; height:0;
  border-left:24px solid transparent; border-right:24px solid transparent; border-top:32px solid color-mix(in srgb, var(--sage) 55%, transparent)}
.ms-filter .ms-dot{position:absolute; left:50%; width:8px; height:8px; margin-left:-4px; border-radius:50%; background:var(--terra);
  top:-6px; animation:msDotFall 1.3s ease-in infinite}
.ms-filter .ms-dot.d2{animation-delay:.3s; background:var(--sage-deep)}
.ms-filter .ms-dot.d3{animation-delay:.6s; background:var(--terra)}
@keyframes msDotFall{0%{top:-6px; opacity:1} 50%{top:32px; opacity:1} 100%{top:64px; opacity:0}}

.ms-gauge{position:relative; width:62px; height:62px}
.ms-gauge svg{width:100%; height:100%}
.ms-gauge circle{fill:none; stroke-width:6}
.ms-gauge .ms-gauge-bg{stroke:var(--border-2)}
.ms-gauge .ms-gauge-fg{stroke:var(--sage-deep); stroke-linecap:round; transform:rotate(-90deg); transform-origin:50% 50%;
  stroke-dasharray:163; stroke-dashoffset:163; animation:msGaugeFill 1.3s var(--ease) forwards}
html[data-theme="dark"] .ms-gauge .ms-gauge-fg{stroke:var(--sage)}
@keyframes msGaugeFill{to{stroke-dashoffset:36}}
.ms-gauge-em{position:absolute; inset:0; display:flex; align-items:center; justify-content:center; font-size:1.25rem}

.ms-grid{display:grid; grid-template-columns:repeat(3,16px); gap:6px}
.ms-grid span{width:16px; height:16px; border-radius:5px; background:var(--surface-2); animation:msCellLight 1.4s var(--ease) infinite}
.ms-grid span:nth-child(1){animation-delay:0ms} .ms-grid span:nth-child(2){animation-delay:110ms}
.ms-grid span:nth-child(3){animation-delay:220ms} .ms-grid span:nth-child(4){animation-delay:330ms}
.ms-grid span:nth-child(5){animation-delay:440ms} .ms-grid span:nth-child(6){animation-delay:550ms}
@keyframes msCellLight{0%,100%{background:var(--surface-2); transform:scale(1)} 45%{background:var(--sage); transform:scale(1.12)}}
html[data-theme="dark"] .ms-grid span{animation-name:msCellLightDark}
@keyframes msCellLightDark{0%,100%{background:var(--surface-2); transform:scale(1)} 45%{background:var(--sage); transform:scale(1.12)}}

@media(prefers-reduced-motion:reduce){
  .ms-hearts span,.ms-placard .ms-food,.ms-placard .ms-clock,.ms-seasons span,.ms-filter .ms-dot,.ms-gauge-fg,.ms-grid span{animation:none}
}

/* révélation organique des créneaux fraîchement suggérés */
.slot.just-suggested{animation:slotBloom .55s var(--ease) backwards}
@keyframes slotBloom{
  0%{transform:scale(.75) translateY(10px); opacity:0; border-radius:40% 60% 55% 45%/50% 45% 55% 50%}
  60%{transform:scale(1.03) translateY(-2px); opacity:1}
  100%{transform:scale(1) translateY(0); border-radius:var(--radius-sm)}
}

/* ============ PANNEAUX (ex-verre : interface.css § 16 leur donne un fond plein) ============ */
.glass-panel{background:color-mix(in srgb, var(--surface) 72%, transparent); backdrop-filter:blur(22px) saturate(1.4);
  -webkit-backdrop-filter:blur(22px) saturate(1.4); border:1px solid color-mix(in srgb, var(--border) 70%, transparent);
  box-shadow:var(--shadow-lg), inset 0 1px 0 color-mix(in srgb, #fff 35%, transparent)}
[data-theme="dark"] .glass-panel{box-shadow:var(--shadow-lg), inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent)}
/* effet de brillance liquide au survol des boutons et cartes principales */
.btn, .rcard, .sel-card, .slot.filled, .icon-btn{position:relative; overflow:hidden}
.btn::after, .rcard::after, .sel-card::after, .slot.filled::after{content:''; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(120deg, transparent 40%, color-mix(in srgb,#fff 35%, transparent) 50%, transparent 60%);
  background-size:220% 220%; background-position:120% 120%; opacity:0; transition:opacity .3s var(--ease), background-position .7s var(--ease)}
.btn:hover::after, .rcard:hover::after, .sel-card:hover::after, .slot.filled:hover::after{opacity:1; background-position:-20% -20%}

/* ============ MENU "PLUS D'ACTIONS" (semaine) — verre liquide organique ============ */
.week-menu-wrap{position:relative}
.week-menu-wrap #weekMoreBtn.is-open{background:var(--sand); color:var(--ink)}
.week-menu{
  position:absolute; top:calc(100% + 8px); right:0; z-index:40; min-width:210px; padding:7px;
  display:flex; flex-direction:column; gap:2px; border-radius:16px;
  transform-origin:top right; animation:menuBloom .28s var(--ease) backwards;
}
.week-menu[hidden]{display:none}
@keyframes menuBloom{
  0%{opacity:0; transform:scale(.85) translateY(-6px); border-radius:38% 62% 55% 45% / 48% 42% 58% 52%}
  60%{opacity:1}
  100%{opacity:1; transform:scale(1) translateY(0); border-radius:16px}
}
@media(prefers-reduced-motion:reduce){.week-menu{animation:none}}
.week-menu-item{
  display:flex; align-items:center; gap:10px; width:100%; padding:10px 12px; border-radius:11px;
  font-weight:600; font-size:.86rem; color:var(--ink-2); text-align:left; background:transparent; transition:.15s var(--ease);
}
.week-menu-item svg{width:16px; height:16px; flex-shrink:0}
.week-menu-item:hover{background:var(--sage-soft); color:var(--sage-text); transform:translateX(2px)}
.week-menu-item-danger{color:var(--danger)}
.week-menu-item-danger:hover{background:color-mix(in srgb, var(--danger) 12%, transparent); color:var(--danger)}
.week-menu-sep{height:1px; margin:4px 6px; background:var(--border)}

/* F : navigation à 5 destinations — Budget/Profil/Paramètres (auparavant 3 entrées
   séparées, dont 2 uniquement dans l'en-tête, hors de la barre d'onglets mobile)
   rejoignent un même menu "Plus", accessible depuis la même barre que les 4 vues
   principales, y compris sur mobile. */
.nav-more-wrap{position:relative; display:flex}
.nav-more-wrap #navMoreBtn.is-open{background:var(--sand); color:var(--ink)}
.nav-more-menu{
  position:absolute; top:calc(100% + 8px); right:0; z-index:50; min-width:190px; padding:7px;
  display:flex; flex-direction:column; gap:2px; border-radius:16px;
  transform-origin:top right; animation:menuBloom .28s var(--ease) backwards;
}
.nav-more-menu[hidden]{display:none}
.nav-more-menu .week-menu-item{position:relative}
.nav-more-menu .week-menu-item.active{background:var(--sage-soft); color:var(--sage-text)}
@media(prefers-reduced-motion:reduce){.nav-more-menu{animation:none}}
@media(max-width:880px){
  .nav-more-wrap{flex:1 1 0; max-width:88px}
  .nav-more-wrap #navMoreBtn{width:100%; height:100%}
  /* la barre est fixée en bas de l'écran sur mobile : le menu s'ouvre vers le
     haut plutôt que vers le bas, sans quoi il partirait sous l'écran. */
  .nav-more-menu{top:auto; bottom:calc(100% + 10px); right:6px; transform-origin:bottom right}
  @keyframes menuBloomUp{
    0%{opacity:0; transform:scale(.85) translateY(6px); border-radius:38% 62% 55% 45% / 48% 42% 58% 52%}
    60%{opacity:1}
    100%{opacity:1; transform:scale(1) translateY(0); border-radius:16px}
  }
  .nav-more-menu{animation:menuBloomUp .28s var(--ease) backwards}
}

/* ============ MODAL ============ */
.overlay{position:fixed; inset:0; z-index:60; background:rgba(38,30,16,.46); backdrop-filter:blur(4px);
  display:flex; align-items:center; justify-content:center; padding:18px; opacity:0; pointer-events:none; transition:.28s var(--ease)}
.overlay.show{opacity:1; pointer-events:auto}
.modal{background:color-mix(in srgb, var(--surface) 86%, transparent); backdrop-filter:blur(26px) saturate(1.3);
  -webkit-backdrop-filter:blur(26px) saturate(1.3);
  border:1px solid var(--border); border-radius:var(--radius-lg); width:100%;
  max-width:640px; max-height:90vh; display:flex; flex-direction:column; box-shadow:var(--shadow-lg);
  transform:translateY(18px) scale(.97); transition:.32s var(--ease)}
.overlay.show .modal{transform:none}
/* confirmerAction({surPlace:true}) : la question passe au-dessus de la fenêtre ouverte. */
.overlay.confirmer-voile{z-index:61}
.modal.confirmer-modal{max-width:440px}
.modal.wide{max-width:860px}
/* G42 : feuille de filtres. Desktop : modale classique un peu étroite. Mobile (≤720px) :
   ancrée en bas, coins hauts arrondis, glisse depuis le bas — le geste attendu sur
   téléphone pour un panneau de réglages. */
.modal.sheet{max-width:560px}
.lib-sheet-foot{justify-content:space-between}
.lib-sheet-foot .btn-primary{flex:1 1 auto; justify-content:center}
@media(max-width:720px){
  .overlay.has-sheet{align-items:flex-end; padding:0}
  .overlay.has-sheet .modal.sheet{max-width:none; max-height:88vh; border-radius:22px 22px 0 0; border-bottom:0;
    transform:translateY(40px); padding-bottom:env(safe-area-inset-bottom)}
  .overlay.has-sheet.show .modal.sheet{transform:none}
  .modal.sheet .modal-head{padding:16px 18px 12px}
  .modal.sheet .modal-body{padding:14px 18px}
  .modal-foot.lib-sheet-foot{flex-direction:row; padding:12px 18px calc(12px + env(safe-area-inset-bottom))}
  .modal-foot.lib-sheet-foot .btn{width:auto}
  .modal-foot.lib-sheet-foot .btn-primary{flex:1 1 auto}
}
/* G42 : éléments de la barre Recettes réservés à une taille d'écran */
.lib-mob-only{display:none}
.lib-filter-btn .cl-count{background:var(--sage); color:var(--on-accent); font-size:.72rem; font-weight:700; border-radius:999px; padding:1px 7px; line-height:1.4; margin-left:6px}
.lib-filter-btn .cl-count:empty{display:none}
.lib-filter-btn svg{width:16px; height:16px}
#libFilterBtnDesk{display:inline-flex; align-items:center; gap:4px; margin-left:auto}
@media(max-width:720px){
  .lib-desk-only{display:none !important}
  .lib-mob-only{display:inline-flex}
  #view-recettes .toolbar{gap:8px; margin-bottom:12px}
  #view-recettes .search-row{flex-wrap:nowrap}
  #view-recettes .search-box{min-width:0}
  .lib-filter-btn{flex:0 0 auto; padding:9px 12px; white-space:nowrap}
}

/* ============ AUTH GATE — bloque l'accès tant qu'on n'est pas connecté ============ */
#authGate{position:fixed; inset:0; z-index:500; display:none; align-items:center; justify-content:center;
  padding:20px; overflow-y:auto; gap:64px;
  background:radial-gradient(circle at 30% 15%, color-mix(in srgb, var(--sage) 20%, var(--bg)) 0%, var(--bg) 62%)}
#authGate.show{display:flex}
.authgate-card{position:relative; width:100%; max-width:420px; margin:0; flex-shrink:0; background:var(--surface);
  border:1px solid var(--border); border-radius:var(--radius-lg); box-shadow:var(--shadow-lg);
  padding:34px 30px; text-align:center}
/* Croix de fermeture, présente seulement quand l'écran a été ouvert à la
   demande depuis le mode sans compte (voir canDismissAuthGate). */
.authgate-close{position:absolute; top:12px; right:12px}
/* ---- Vitrine illustrée à gauche de la carte : présente les fonctionnalités
   du site à qui découvre ioumi pour la première fois. Sa présence pousse
   naturellement la carte de connexion vers la droite de l'écran (le tout
   reste centré via #authGate.justify-content:center). Masquée sur mobile,
   où l'écran est trop étroit pour deux colonnes. ---- */
.authgate-showcase{width:380px; max-width:40vw; flex-shrink:0; animation:agsFadeIn .55s var(--ease)}
.ags-brand{display:flex; align-items:center; gap:8px; margin-bottom:28px}
.ags-brand .brand-name{font-family:var(--serif); font-size:1.24rem; color:var(--ink)}
.ags-title{font-family:var(--serif); font-size:1.8rem; line-height:1.28; margin:0 0 30px; max-width:340px; color:var(--ink)}
.ags-list{display:flex; flex-direction:column; gap:19px}
.ags-item{display:flex; gap:14px; align-items:flex-start; opacity:0; transform:translateY(10px); animation:agsItemIn .5s var(--ease) forwards}
.ags-icon{width:44px; height:44px; border-radius:12px; background:color-mix(in srgb, var(--surface) 74%, transparent);
  border:1px solid var(--border); display:flex; align-items:center; justify-content:center; font-size:1.4rem; flex-shrink:0;
  box-shadow:var(--shadow-sm); animation:agsIconPulse 3.6s var(--ease) infinite}
.ags-item:nth-child(2) .ags-icon{animation-delay:.4s}
.ags-item:nth-child(3) .ags-icon{animation-delay:.8s}
.ags-item:nth-child(4) .ags-icon{animation-delay:1.2s}
.ags-item:nth-child(5) .ags-icon{animation-delay:1.6s}
.ags-item-title{font-weight:700; font-size:.95rem; margin-bottom:2px; color:var(--ink)}
.ags-item-desc{font-size:.82rem; color:var(--muted); line-height:1.48; max-width:280px}
@keyframes agsFadeIn{from{opacity:0; transform:translateX(-16px)}to{opacity:1; transform:none}}
@keyframes agsItemIn{to{opacity:1; transform:none}}
@keyframes agsIconPulse{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@media(max-width:760px){
  .authgate-showcase{display:none}
  #authGate{gap:0}
}
@media(prefers-reduced-motion:reduce){
  .authgate-showcase, .ags-item, .ags-icon{animation:none; opacity:1; transform:none}
}
.authgate-logo{display:flex; align-items:center; justify-content:center; gap:8px; margin-bottom:20px}
.authgate-logo .brand-name{font-family:var(--serif); font-size:1.24rem}
.authgate-card h2{margin:0 0 6px; font-size:1.5rem}
.authgate-sub{color:var(--muted); font-size:.88rem; margin:0 0 24px; line-height:1.5}
.authgate-avis{color:var(--sage-text); font-weight:600}
.authgate-card .field{text-align:left; margin-bottom:12px}
.authgate-card .field label{display:block; font-size:.8rem; font-weight:600; color:var(--ink-2); margin-bottom:5px}
.authgate-card .field input{width:100%; min-height:48px; padding:11px 13px; border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--surface-2)}
.authgate-toggle{font-size:.82rem; color:var(--muted); text-align:center; margin-top:18px}
.authgate-toggle a{color:var(--sage-text); font-weight:600; text-decoration:none}
.authgate-err{font-size:.8rem; color:var(--danger); margin-top:10px; min-height:1em}
@media (max-width:480px){
  .authgate-card{padding:26px 20px; border-radius:var(--radius)}
}

/* ---------- Présentation (24/09/2026) : premier écran, la cocotte présente l'app ----------
   Vit dans #authGate. La vitrine de gauche (bureau) s'efface : la cocotte fait le même travail. */
#authGate.ob-mode .authgate-showcase{display:none}
.ob{display:flex; flex-direction:column; align-items:center; text-align:center; min-height:min(540px, calc(100dvh - 110px)); touch-action:pan-y; user-select:none; -webkit-user-select:none}
.ob-top{width:100%; display:flex; align-items:center; justify-content:center; position:relative}
.ob-top .authgate-logo{margin-bottom:0}
/* 08/10/2026 : « ‹ » pour revenir d'un écran, barre de progression pendant les questions. */
.ob-prev{position:absolute; left:-12px; top:50%; transform:translateY(-50%); width:44px; height:44px; border:0; border-radius:50%; background:none;
  color:var(--muted); font:inherit; font-size:1.6rem; line-height:1; cursor:pointer; display:grid; place-items:center; padding:0 0 3px}
.ob-prev:hover, .ob-prev:focus-visible{color:var(--ink); background:var(--surface-2)}
.ob-top.avec-barre{padding-left:40px}
.ob-bar{flex:1 1 auto; min-width:0}
.ob-stage{display:flex; flex-direction:column; align-items:center; gap:14px; margin:22px 0 6px}
.ob-coco .jeu-coco{width:168px; height:140px}
.ob-coco-repli{transform:scale(1.8); margin:24px 0}
.ob .ob-bulle{flex:0 0 auto; max-width:300px; font-size:.95rem; transform-origin:50% 0; animation:obBulle .45s cubic-bezier(.2,1.4,.4,1) both .12s}
.ob .ob-bulle::before{left:50%; top:-9px; transform:translateX(-50%) rotate(135deg)}
.ob-slide{min-height:178px; animation:obIn .42s var(--ease, ease) both}
.ob[data-dir="prev"] .ob-slide{animation-name:obInPrev}
.ob-slide h2{font-size:1.45rem; margin:18px 0 8px; line-height:1.2}
.ob-texte{color:var(--ink-2); font-size:.95rem; line-height:1.55; margin:0 auto; max-width:34ch}
.ob-foot{margin-top:auto; width:100%; padding-top:24px; display:flex; flex-direction:column; gap:10px; align-items:stretch}
.ob-back{position:absolute; top:10px; left:10px; background:none; border:0; color:var(--muted); font:inherit; font-size:.85rem; font-weight:600; cursor:pointer; padding:10px; min-height:44px; z-index:1}
.ob-back:hover, .ob-back:focus-visible{color:var(--ink)}
.authgate-card .field input.ag-code{letter-spacing:.3em; font-size:1.35rem; text-align:center; font-variant-numeric:tabular-nums}
.ag-code-note{font-size:.8rem; color:var(--muted); margin:10px 0 0; line-height:1.5}
@keyframes obIn{from{opacity:0; transform:translateX(26px)} to{opacity:1; transform:none}}
@keyframes obInPrev{from{opacity:0; transform:translateX(-26px)} to{opacity:1; transform:none}}
@keyframes obBulle{from{opacity:0; transform:translateY(6px) scale(.85)} to{opacity:1; transform:none}}
@media (prefers-reduced-motion: reduce){ .ob-slide, .ob-bulle{animation:none} }
/* Les questions (08/10/2026) : mêmes pièces que le premier profil (fr-*), alignées à gauche. */
.ob-q{width:100%; text-align:left; padding-top:26px}
.ob-q .fr-checks{justify-content:flex-start}
.fr-opt.ob-prio{flex-direction:row; align-items:center; gap:14px; text-align:left}
.ob-prio-ico{flex:0 0 auto; width:40px; height:40px; border-radius:12px; display:grid; place-items:center; background:var(--surface-2); color:var(--ink-2)}
.ob-prio-ico svg{width:22px; height:22px}
.ob-prio.on .ob-prio-ico{background:var(--surface); color:var(--sage-text)}
.ob-prio-t{display:flex; flex-direction:column; gap:3px; min-width:0}
.ob-prio-t small{font-size:.8rem; font-weight:500; color:var(--muted); line-height:1.4}
/* La semaine montrée : petite cocotte et bulle sur une ligne, puis la vraie semaine. */
.ob-stage.avec-vue{gap:12px; margin:14px 0 0; width:100%; max-width:340px}
.ob-tete{display:flex; align-items:center; gap:10px; align-self:flex-start}
.ob-tete .ob-coco .jeu-coco{width:76px; height:64px}
.ob-tete .ob-bulle{font-size:.88rem; text-align:left; flex:0 1 auto; min-width:0}
.ob-tete{max-width:100%}
.ob-tete .ob-bulle::before{left:-6px; top:50%; transform:translateY(-50%) rotate(45deg)}
.ob-vue{width:100%; background:var(--surface); color:var(--ink); border:var(--bw) solid var(--ink); border-radius:var(--radius-lg);
  box-shadow:var(--shadow-hard); padding:12px 14px; text-align:left; font-size:.85rem; animation:obIn .42s var(--ease, ease) both .05s}
.ob-vue-t{display:flex; justify-content:space-between; align-items:center; font-weight:700; margin-bottom:6px}
.ob-vue-ok{color:var(--sage-text); font-size:.78rem}
.ob-vue-l{display:flex; align-items:center; gap:8px; padding:6px 0; border-top:1px solid var(--border);
  animation:obLigne .35s var(--ease, ease) both; animation-delay:calc(.25s + var(--i, 0) * .12s)}
.ob-vue-j{width:30px; color:var(--muted); font-weight:700; font-size:.75rem}
.ob-vue-e{font-size:1.05rem}
.ob-vue-n{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.ob-vue-p{color:var(--ink-2); font-weight:600; font-variant-numeric:tabular-nums}
/* Chaque dîner se touche pour une autre idée : toute la ligne est le bouton. */
.ob-ap-l{width:100%; min-height:40px; background:none; border-left:0; border-right:0; border-bottom:0; font:inherit; color:inherit; text-align:left; cursor:pointer;
  border-radius:0; -webkit-tap-highlight-color:transparent}
.ob-ap-l:first-child{border-top:0}
.ob-ap-l:hover .ob-vue-n, .ob-ap-l:focus-visible .ob-vue-n{text-decoration:underline; text-decoration-color:var(--border-2); text-underline-offset:3px}
.ob-ap-l.ob-ap-change{animation:obCarte .42s var(--ease, ease) both}
.ob-ap-liste{margin-top:2px}
.ob-ap-total{display:flex; align-items:baseline; flex-wrap:wrap; gap:4px 8px; margin-top:8px; padding-top:10px; border-top:var(--bw) solid var(--ink)}
.ob-ap-big{font-family:var(--serif); font-size:1.7rem; line-height:1.1}
.ob-ap-sous{color:var(--ink-2); font-size:.85rem}
.ob-ap-note{display:flex; align-items:flex-start; gap:6px; margin:6px 0 0; font-size:.84rem; color:var(--sage-text); font-weight:600; line-height:1.4}
.ob-ap-note svg{flex:0 0 auto; width:16px; height:16px; margin-top:2px}
.ob-ap-astuce{margin:8px 0 0; font-size:.8rem; color:var(--muted)}
.ob-ap-gratuit{margin:-2px 0 0; font-size:.82rem; color:var(--muted); text-align:center}
.ob-ap-deja{margin-top:2px}
.ob-apercu .ob-foot{padding-top:16px}
/* Le formulaire de compte rappelle la semaine qu'il garde. */
.ag-apercu{display:flex; align-items:center; gap:10px; margin:-4px 0 18px; padding:10px 12px; border-radius:var(--radius-sm); background:var(--sage-soft);
  color:var(--sage-text); font-size:.88rem; text-align:left; line-height:1.4}
.ag-apercu-ico{flex:0 0 auto; display:grid; place-items:center}
.ag-apercu-ico svg{width:22px; height:22px}
@keyframes obLigne{from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:none}}
@keyframes obCarte{0%{opacity:0; transform:rotateX(70deg)} 100%{opacity:1; transform:none}}
@media (prefers-reduced-motion: reduce){ .ob-vue, .ob-vue-l, .ob-ap-l.ob-ap-change{animation:none} }
@media(max-width:760px){ #authGate .ob-stage.avec-vue{margin-top:2vh} }

/* ---- didacticiel d'accueil ---- */
.onb-wrap{padding:36px 30px 26px; text-align:center; display:flex; flex-direction:column; align-items:center; position:relative}
.onb-skip{position:absolute; top:12px; right:12px}
.onb-body{min-height:170px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px;
  transition:opacity .18s var(--ease), transform .18s var(--ease)}
.onb-em{font-size:3rem; line-height:1; margin-bottom:4px}
.onb-title{font-family:var(--sans); font-weight:800; letter-spacing:-.01em; font-size:1.4rem}
.onb-desc{font-size:.92rem; color:var(--muted); max-width:400px; line-height:1.55}
.onb-dots{display:flex; gap:7px; margin:22px 0 20px}
.onb-dot{width:7px; height:7px; border-radius:999px; background:var(--border-2); transition:.25s var(--ease)}
.onb-dot.on{background:var(--sage); width:20px}
.onb-nav{display:flex; gap:10px; width:100%; max-width:320px}
.onb-nav .btn{flex:1}
/* ---- Pop-up « Quoi de neuf » (carrousel de nouveautés — voir openWhatsNewModal).
   Volontairement calqué sur le didacticiel (.onb-*) : mêmes proportions, mêmes points
   de progression, mêmes boutons — la pop-up doit ressembler au reste de l'app, pas à
   une bannière marketing collée par-dessus. ---- */
.wn-wrap{padding:30px 26px 22px; text-align:center; display:flex; flex-direction:column; align-items:center; position:relative}
.wn-close{position:absolute; top:12px; right:12px}
.wn-kicker{font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; font-weight:700; color:var(--sage-text)}
.wn-fig{width:100%; max-width:260px; margin:2px auto 0}
.wn-fig svg{display:block; width:100%; height:auto}
.wn-body{width:100%; min-height:300px; display:flex; flex-direction:column; align-items:center; gap:14px}
.wn-title{font-family:var(--sans); font-weight:800; letter-spacing:-.01em; font-size:1.3rem; line-height:1.25; margin:2px 0 0}
/* Aération du 22/09 : un chapeau d'une phrase, puis une liste de points — émoji,
   titre en gras, complément en dessous. Plus de paragraphe compact ni d'encadré
   empilé : la note passe en pied, en petit, sans boîte. */
.wn-desc{font-size:.95rem; color:var(--ink-2); max-width:360px; line-height:1.55; margin:0 0 6px}
.wn-desc-after{font-size:.86rem; color:var(--muted); margin:8px 0 0}
/* Aération du 24/09 : trois points au plus, 22 px entre eux, compléments d'une ligne. */
.wn-points{list-style:none; margin:10px 0 0; padding:0; width:100%; max-width:360px; display:flex; flex-direction:column; gap:22px; text-align:left}
.wn-points li{display:flex; align-items:center; gap:14px}
.wn-points .wp-e{flex:0 0 auto; width:40px; height:40px; display:grid; place-items:center; font-size:1.2rem; line-height:1;
  background:var(--surface); border:2px solid var(--ink); border-radius:50%; box-shadow:0 2px 0 var(--ink)}
.wn-points .wp-t{flex:1 1 auto; min-width:0; min-height:40px; display:flex; flex-direction:column; justify-content:center; gap:3px; line-height:1.45}
.wn-points .wp-t b{font-size:.95rem; color:var(--ink); font-weight:700}
.wn-points .wp-t span{font-size:.84rem; color:var(--muted)}
.wn-note{font-size:.8rem; color:var(--muted); max-width:360px; width:100%; line-height:1.55; text-align:left;
  margin:18px 0 0; padding:14px 0 0; border-top:1px dashed var(--border)}
.wn-anim{animation:wnIn .26s var(--ease) both}
@keyframes wnIn{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none}}
@media(prefers-reduced-motion:reduce){.wn-anim{animation:none}}
.wn-dots{display:flex; gap:8px; margin:14px 0 12px; flex-wrap:wrap; justify-content:center}
/* Le point mesure 8 px mais la CIBLE fait 24 px : background-clip:content-box laisse le
   rembourrage transparent, ce qui donne une zone tactile confortable sans gros pastille. */
.wn-dot{width:8px; height:24px; padding:8px 0; border-radius:999px; background:var(--border-2);
  background-clip:content-box; transition:.25s var(--ease)}
.wn-dot.on{background:var(--sage); background-clip:content-box; width:24px}
.wn-nav{display:flex; align-items:center; gap:10px; width:100%; max-width:400px}
.wn-nav .wn-next{flex:1}
.wn-arrow{width:42px; height:42px; flex:0 0 42px; border-radius:12px; border:1px solid var(--border);
  background:var(--surface-2); color:var(--ink-2); font-size:1.05rem; line-height:1}
.wn-arrow:hover:not([disabled]){background:var(--sage-soft); color:var(--sage-text)}
.wn-arrow[disabled]{opacity:.3; cursor:default}
.wn-foot{margin-top:13px; font-size:.79rem; color:var(--muted); line-height:1.55; max-width:430px}
.wn-foot a{color:var(--sage-text); font-weight:600; text-decoration:underline}
@media(max-width:520px){
  .wn-wrap{padding:26px 15px 16px}
  .wn-body{min-height:0}
  .wn-fig{max-width:160px}
  .wn-title{font-size:1.14rem}
  .wn-desc{font-size:.88rem}
  .wn-points{gap:10px}
  .wn-points .wp-e{width:36px; height:36px; font-size:1.05rem}
  .wn-points .wp-t{min-height:36px}
}
/* ---- « Quoi de neuf » en story (01/10/2026, Paul : « pas du tout animé et premium »).
   Voir openWhatsNewModal. Barres de progression en haut, une scène animée, un titre
   court, une phrase, un gros bouton ; les diapos glissent, le contenu entre en
   cascade. Les règles .wn-* ci-dessus ne servent plus qu'au bilan de fin d'essai.
   Fond plein : la .modal standard est translucide (color-mix 86 %, backdrop-filter). ---- */
.modal.qn-modal{background:var(--surface); -webkit-backdrop-filter:none; backdrop-filter:none; max-width:440px;
  height:min(720px, calc(100dvh - 36px)); overflow:hidden}
.qn{flex:1 1 auto; min-height:0; display:flex; flex-direction:column; padding:16px 22px 18px}
.qn-top{flex:0 0 auto; display:flex; align-items:center; gap:14px}
.qn-close{position:static}
.qn-bars{flex:1; display:flex; gap:6px}
.qn-bar{flex:1; height:28px; padding:0; border:0; background:none; cursor:pointer; position:relative; -webkit-tap-highlight-color:transparent}
.qn-bar::before,.qn-bar i{content:""; position:absolute; left:0; top:50%; height:5px; margin-top:-2.5px; border-radius:999px}
.qn-bar::before{right:0; background:var(--border)}
.qn-bar i{width:0; background:var(--sage-text); transition:width .6s var(--ease)}
.qn-bar.done i,.qn-bar.on i{width:100%}
.qn-stage{flex:1 1 auto; min-height:0; position:relative; overflow:hidden; margin:4px -22px 0; cursor:pointer; -webkit-tap-highlight-color:transparent}
.qn-slide{position:absolute; inset:0; overflow-y:auto; overscroll-behavior:contain; padding:10px 28px 18px;
  display:flex; flex-direction:column; align-items:center; text-align:center; scrollbar-width:thin}
.qn-slide > :first-child{margin-top:auto}
.qn-slide > :last-child{margin-bottom:auto}
.qn-slide.from-right{animation:qnInR .44s var(--ease) both}
.qn-slide.from-left{animation:qnInL .44s var(--ease) both}
.qn-slide.to-left{animation:qnOutL .38s var(--ease) both; pointer-events:none}
.qn-slide.to-right{animation:qnOutR .38s var(--ease) both; pointer-events:none}
@keyframes qnInR{from{transform:translateX(60%); opacity:0} to{transform:none; opacity:1}}
@keyframes qnInL{from{transform:translateX(-60%); opacity:0} to{transform:none; opacity:1}}
@keyframes qnOutL{to{transform:translateX(-45%) scale(.96); opacity:0}}
@keyframes qnOutR{to{transform:translateX(45%) scale(.96); opacity:0}}
/* La scène : un disque doux de la palette derrière, l'illustration par-dessus. */
.qn-scene{position:relative; isolation:isolate; width:100%; max-width:250px; margin:0 auto 26px; padding:10px 0}
.qn-scene::before{content:""; position:absolute; left:50%; top:50%; width:86%; aspect-ratio:1; border-radius:50%;
  background:var(--sage-soft); z-index:-1; transform:translate(-50%,-50%); animation:qnBlob .7s cubic-bezier(.3,1.4,.5,1) both}
.qn-soir .qn-scene::before,.qn-gratuit .qn-scene::before,.qn-fin .qn-scene::before{background:var(--gold-soft)}
.qn-recettes .qn-scene::before{background:var(--terra-soft)}
@keyframes qnBlob{from{transform:translate(-50%,-50%) scale(.5); opacity:0} to{transform:translate(-50%,-50%) scale(1); opacity:1}}
.qn-scene svg{display:block; width:100%; height:auto; overflow:visible}
.qn-scene svg:not(.jeu-coco) *{transform-box:fill-box; transform-origin:center}
.qn-scene.is-coco{display:flex; justify-content:center; padding:26px 0 18px}
.qn-coco .jeu-coco{width:176px; height:147px}
.qn-coco{animation:qnPop .6s cubic-bezier(.3,1.6,.5,1) .1s both}
.qn-svg-txt{font:700 12px var(--sans); fill:var(--ink-2)}
.qn-svg-b{font-size:11px; fill:var(--on-accent)}
/* Les textes : petit chapeau en pastille, titre en display, une phrase, des puces. */
.qn-kicker{display:inline-block; font-size:.72rem; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--sage-text); background:var(--sage-soft); padding:5px 12px; border-radius:999px}
.qn-title{font-family:var(--serif); font-weight:400; font-size:1.8rem; line-height:1.14; color:var(--ink); margin:14px 0 12px; max-width:340px}
.qn-num{font-variant-numeric:tabular-nums; color:var(--terra-text)}
.qn-slide p{font-size:1rem; line-height:1.55; color:var(--ink-2); max-width:340px; margin:0}
.qn-chips{list-style:none; padding:0; margin:22px 0 0; display:flex; flex-wrap:wrap; gap:9px; justify-content:center; max-width:360px}
.qn-chips li{font-size:.82rem; font-weight:700; color:var(--ink); background:var(--surface-2); border:1.5px solid var(--ink);
  border-radius:999px; padding:6px 13px; box-shadow:2px 2px 0 var(--ink)}
.qn-slide .qn-note{font-size:.82rem; color:var(--muted); margin-top:22px; padding-top:14px; border-top:1px dashed var(--border)}
.qn-c{animation:qnUp .5s var(--ease) both; animation-delay:calc(200ms + var(--d,0) * 85ms)}
@keyframes qnUp{from{opacity:0; transform:translateY(16px)} to{opacity:1; transform:none}}
/* Pied : flèche retour discrète, gros bouton, le mot de la fin sous le dernier écran. */
.qn-foot{flex:0 0 auto; padding-top:12px}
.qn-nav{display:flex; align-items:center; gap:10px}
.qn-prev{width:54px; height:54px; flex:0 0 54px; border-radius:14px; border:2px solid var(--ink); background:var(--surface);
  color:var(--ink); font-size:1.5rem; line-height:1; cursor:pointer; box-shadow:var(--shadow-hard, 3px 3px 0 var(--ink))}
.qn-prev:active{transform:translate(2px,2px); box-shadow:none}
/* Sur la première diapo, la flèche retour s'efface et le bouton prend toute la largeur. */
.qn-prev{transition:flex-basis .3s var(--ease), width .3s var(--ease), opacity .2s, margin .3s var(--ease)}
.qn-prev[disabled]{flex-basis:0; width:0; margin-right:-10px; border-width:0; opacity:0; box-shadow:none; overflow:hidden; pointer-events:none}
.qn-next{flex:1; min-height:54px; font-size:1.06rem; font-weight:800}
.qn-next.is-fin{background:var(--gold); color:var(--on-accent)}
.qn-small{min-height:1.5em; margin:12px 0 0; text-align:center; font-size:.8rem; color:var(--muted); line-height:1.55}
.qn-small a{color:var(--sage-text); font-weight:700; text-decoration:underline}
/* Animations des scènes (délai par élément via --i). */
.qn-pop{animation:qnPop .5s cubic-bezier(.3,1.6,.5,1) both; animation-delay:calc(300ms + var(--i,0) * 110ms)}
@keyframes qnPop{from{transform:scale(0); opacity:0} to{transform:none; opacity:1}}
.qn-rise{animation:qnRise .55s var(--ease) both; animation-delay:calc(200ms + var(--i,0) * 120ms)}
@keyframes qnRise{from{transform:translateY(18px); opacity:0} to{transform:none; opacity:1}}
.qn-wiggle{animation:qnRise .55s var(--ease) calc(200ms + var(--i,0) * 120ms) both, qnWiggle .7s ease-in-out 1.3s 2}
@keyframes qnWiggle{0%,100%{transform:rotate(0)} 25%{transform:rotate(-12deg)} 75%{transform:rotate(12deg)}}
.qn-tap{animation:qnTap 1s ease-in-out .2s both}
@keyframes qnTap{0%{opacity:0; transform:translate(16px,16px)} 40%{opacity:1; transform:none} 58%{transform:scale(.78)} 76%,100%{opacity:1; transform:none}}
.qn-ripple{animation:qnRipple 1s ease-out .75s both}
@keyframes qnRipple{from{transform:scale(.5); opacity:1} to{transform:scale(1.8); opacity:0}}
.qn-deal{animation:qnDeal .55s cubic-bezier(.3,1.3,.5,1) both; animation-delay:calc(260ms + var(--i,0) * 130ms)}
@keyframes qnDeal{from{transform:translateX(46px) rotate(9deg); opacity:0} to{transform:none; opacity:1}}
.qn-ticket{animation:qnTicket .7s var(--ease) .15s both}
@keyframes qnTicket{from{transform:translateY(34px); opacity:0} to{transform:none; opacity:1}}
.qn-scene svg .qn-fill{transform-origin:0 50%; animation:qnFill 1.1s cubic-bezier(.3,1,.4,1) .7s both}
@keyframes qnFill{from{transform:scaleX(0)} to{transform:none}}
.qn-fly{animation:qnFly .7s cubic-bezier(.3,1.4,.5,1) both; animation-delay:calc(380ms + var(--i,0) * 140ms)}
@keyframes qnFly{from{transform:translate(0,30px) scale(.4); opacity:0} to{transform:translate(var(--x,0),-30px); opacity:1}}
.qn-scene svg .qn-anse{transform-origin:100% 100%; animation:qnUnlock .6s cubic-bezier(.3,1.6,.5,1) .8s both}
@keyframes qnUnlock{to{transform:translateY(-9px) rotate(-22deg)}}
.qn-spark{animation:qnSpark 1.8s ease-in-out infinite both; animation-delay:calc(var(--i,0) * 160ms)}
@keyframes qnSpark{0%,100%{transform:scale(0) rotate(0); opacity:0} 40%,60%{transform:scale(1) rotate(45deg); opacity:1}}
/* La fin : des confettis de la palette, une fois. */
.qn-confettis{position:absolute; left:50%; top:46%; width:0; height:0; pointer-events:none}
.qn-confettis i{position:absolute; left:-4px; top:-6px; width:9px; height:13px; border-radius:2px; background:var(--c);
  border:1.5px solid var(--ink); opacity:0; animation:qnConf 1.5s cubic-bezier(.2,.8,.3,1) both; animation-delay:calc(380ms + var(--i,0) * 45ms)}
@keyframes qnConf{0%{opacity:0; transform:translate(0,0) rotate(0) scale(.4)} 12%{opacity:1}
  65%{opacity:1; transform:translate(var(--x),var(--y)) rotate(var(--r)) scale(1)}
  100%{opacity:0; transform:translate(var(--x),calc(var(--y) + 70px)) rotate(var(--r)) scale(1)}}
@media(max-width:520px){
  .qn{padding:14px 16px 14px}
  .qn-stage{margin:4px -16px 0}
  .qn-slide{padding:8px 22px 14px}
  .qn-title{font-size:1.55rem}
  .qn-scene{max-width:224px; margin-bottom:20px}
  .qn-slide p{font-size:.96rem}
}
@media(max-height:700px){
  .qn-scene{max-width:180px; margin-bottom:14px}
  .qn-coco .jeu-coco{width:136px; height:114px}
  .qn-title{font-size:1.4rem; margin:10px 0 8px}
  .qn-chips{margin-top:14px}
}
@media(prefers-reduced-motion:reduce){
  .qn-slide, .qn-slide *, .qn-slide *::before, .qn-slide *::after{animation:none !important; transition:none !important}
  .qn-bar i{transition:none}
}
.qn-slide.is-calme, .qn-slide.is-calme *, .qn-slide.is-calme *::before{animation:none !important}
/* J58 : rappel « profil incomplet » (Profil + récap) */
.profile-complete-hint{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; padding:10px 12px; margin-bottom:14px;
  border-radius:11px; background:var(--sage-soft); color:var(--ink-2); font-size:.82rem; line-height:1.4}
.profile-complete-hint .btn{flex:0 0 auto}
.btn.btn-sm{padding:7px 12px; font-size:.8rem}
.recap-estimate .rg-note a{color:var(--sage-text); text-decoration:underline; font-weight:600}
/* J58 : mini-questionnaire — 4 gros boutons 1/2/3/4+ */
.qs-people{max-width:320px; margin:6px auto 0}
.qs-people{display:grid; grid-template-columns:repeat(4,1fr); width:100%}
.qs-people button{font-size:1.05rem; font-weight:800; padding:12px 0; min-width:0}
/* J58 : bulles contextuelles (showCoachTip). Position fixe : la cible peut être dans la
   barre d'onglets fixe du mobile ; on referme au défilement plutôt que de suivre. */
.coach-tip{position:fixed; z-index:1200; max-width:min(300px, calc(100vw - 16px)); padding:10px 12px 10px 14px;
  display:flex; align-items:flex-start; gap:8px; border-radius:12px; font-size:.86rem; line-height:1.4; font-weight:600;
  color:var(--ink); background:var(--surface); border:1px solid var(--sage); box-shadow:0 8px 24px rgba(0,0,0,.14);
  animation:coachIn .25s var(--ease)}
.coach-tip::before{content:""; position:absolute; width:12px; height:12px; background:var(--surface); border-left:1px solid var(--sage); border-top:1px solid var(--sage);
  left:calc(var(--tip-arrow, 24px) - 6px); transform:rotate(45deg)}
.coach-tip.is-below::before{top:-7px}
.coach-tip.is-above::before{bottom:-7px; transform:rotate(225deg)}
.coach-tip-txt{flex:1}
.coach-tip-close{flex:0 0 auto; width:26px; height:26px; border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--muted); font-size:.8rem; margin:-4px -6px -4px 0}
.coach-tip-close:hover{background:var(--sand); color:var(--ink)}
@keyframes coachIn{from{opacity:0; transform:translateY(4px)} to{opacity:1; transform:none}}
@media(prefers-reduced-motion:reduce){.coach-tip{animation:none}}
.pw-progress{font-size:.7rem; font-weight:700; letter-spacing:.6px; text-transform:uppercase; color:var(--muted); margin-bottom:2px}
.pw-field{width:100%; max-width:280px; margin:6px auto 0; text-align:left}
.pw-field input{text-align:center; font-size:1.1rem; padding:12px 14px}
.pw-seg{margin-top:4px; flex-wrap:wrap; justify-content:center; max-width:380px}
.pw-checks{margin-top:4px; justify-content:center; max-width:380px}
.pw-err{color:var(--danger); font-size:.8rem; min-height:16px; margin-top:8px}
.modal-head{display:flex; align-items:center; justify-content:space-between; gap:14px; padding:20px 22px 16px; border-bottom:1px solid var(--border)}
.modal-head h2{font-size:1.3rem}
.modal-head .mh-sub{font-size:.84rem; color:var(--muted); margin-top:2px}
.modal-close{width:36px; height:36px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); color:var(--ink-2); transition:.16s var(--ease); flex-shrink:0}
.modal-close:hover{background:var(--danger-soft); color:var(--danger)}
.modal-close svg{width:18px; height:18px}
.modal-body{padding:18px 22px; overflow-y:auto; flex:1 1 auto; min-height:0}
.modal-foot{padding:16px 22px; border-top:1px solid var(--border); display:flex; flex-wrap:wrap; gap:10px; justify-content:flex-end}
.free-recap{margin:14px 0 0; padding:12px 15px; background:var(--surface-2); border-radius:var(--radius-sm); border:1.5px solid var(--border)}
.free-recap summary{font-size:.84rem; font-weight:700; color:var(--ink); cursor:pointer; list-style:none; display:flex; align-items:center; gap:8px}
.free-recap summary::-webkit-details-marker{display:none}
.free-recap summary::after{content:'▾'; margin-left:auto; opacity:.6; transition:.2s var(--ease)}
.free-recap[open] summary::after{transform:rotate(180deg)}
.free-recap ul{margin:10px 0 0; padding-left:18px; font-size:.82rem; line-height:1.6; color:var(--ink-2)}
.free-recap li{margin-bottom:4px}
.free-recap .fr-note{margin:9px 0 0; font-size:.76rem; color:var(--muted)}
.pricing-stance{margin:16px 0 4px; padding:13px 15px; background:var(--sage-soft); border-radius:var(--radius-sm); font-size:.8rem; line-height:1.55; color:var(--ink-2)}
.pricing-stance strong{color:var(--sage-text)}
.pw-skip-now{text-align:center; margin-top:18px}
.pw-skip-now a{font-size:.82rem; font-weight:600; color:var(--muted); text-decoration:none}
.pw-skip-now a:hover{color:var(--sage-text); text-decoration:underline}
.retract-consent{display:flex; gap:10px; align-items:flex-start; margin:14px 0 12px; font-size:.78rem; color:var(--ink-2); line-height:1.5; cursor:pointer}
.retract-consent input{width:18px; height:18px; flex-shrink:0; margin-top:1px; accent-color:var(--sage); cursor:pointer}
.btn[disabled]{opacity:.45; cursor:not-allowed; transform:none; box-shadow:none}

/* Certaines fiches (détail recette) empilent jusqu'à 6 boutons dans le footer
   (Retour/Programmer, Mode Cuisine, Modifier, Partager, Proposer, Fermer/Ajouter) :
   sans flex-wrap ils se tassaient et débordaient (pire encore sur mobile, où le
   dernier bouton était carrément coupé). En dessous de 560px on les empile en
   pleine largeur pour rester lisible et facile à toucher. */
@media(max-width:560px){
  .modal-foot{flex-direction:column-reverse}
  .modal-foot .btn{width:100%}
}

/* ---- Écran de confirmation après création de compte : occupe tout le
   pop-up (pas de modal-head/modal-foot séparés) avec une icône animée,
   pour rendre visible et rassurant le fait que le compte a bien été créé
   (+ la nécessité de confirmer par email quand c'est le cas). ---- */
.auth-success{padding:46px 34px 36px; text-align:center; display:flex; flex-direction:column; align-items:center}
.as-icon{width:84px; height:84px; border-radius:50%; display:flex; align-items:center; justify-content:center; margin-bottom:22px; position:relative; animation:asPop .45s var(--ease)}
.as-icon-check{background:var(--sage-soft)}
.as-icon-check svg{width:44px; height:44px; color:var(--sage-text); overflow:visible}
.as-icon-check svg .as-circle{stroke-dasharray:152; stroke-dashoffset:152; animation:asDraw .55s var(--ease) forwards}
.as-icon-check svg .as-check{stroke-dasharray:40; stroke-dashoffset:40; animation:asDraw .3s var(--ease) .5s forwards}
.as-icon-mail{background:var(--terra-soft)}
.as-icon-mail svg{width:40px; height:40px; color:var(--terra-text); animation:asFloat 2.4s ease-in-out infinite}
.as-icon-mail::after{content:''; position:absolute; inset:-6px; border-radius:50%; border:2px solid var(--terra); opacity:0; animation:asRing 1.8s var(--ease) .35s infinite}
@keyframes asPop{from{transform:scale(.55); opacity:0}to{transform:scale(1); opacity:1}}
@keyframes asDraw{to{stroke-dashoffset:0}}
@keyframes asFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
@keyframes asRing{0%{opacity:.55; transform:scale(.82)}100%{opacity:0; transform:scale(1.28)}}
.auth-success h2{margin:0 0 10px; font-size:1.42rem}
.auth-success p{font-size:.9rem; line-height:1.62; color:var(--ink-2); max-width:380px; margin:0 0 8px}
.auth-success .as-email{color:var(--ink); font-weight:700}
.auth-success .as-actions{margin-top:22px; width:100%; max-width:280px; display:flex; flex-direction:column; gap:10px}
.auth-success .as-resend{font-size:.8rem; color:var(--muted)}
.auth-success .as-resend a{color:var(--sage-text); font-weight:600; text-decoration:none}
@media(prefers-reduced-motion:reduce){
  .as-icon, .as-icon-mail svg, .as-icon-mail::after, .as-icon-check svg .as-circle, .as-icon-check svg .as-check{animation:none; stroke-dashoffset:0}
}
/* 25/09 : les documents en modale (guide, mentions, confidentialité, CGV) se lisent comme
   un texte : corps à .94rem, interligne 1.7, listes aérées. L'ancien corps à .85rem /
   4 px entre les puces était le « texte tout serré » remonté par Paul. */
.legal-doc h3{font-family:var(--sans); font-weight:700; font-size:1.15rem; color:var(--ink); margin:30px 0 12px; line-height:1.3}
.legal-doc h3:first-child{margin-top:0}
.legal-doc p{font-size:.94rem; line-height:1.7; color:var(--ink-2); margin:0 0 12px}
.legal-doc ul{margin:0 0 16px; padding-left:22px}
.legal-doc li{font-size:.94rem; line-height:1.7; color:var(--ink-2); margin-bottom:9px}
.legal-doc strong{color:var(--ink)}
.legal-updated{font-size:.82rem; color:var(--muted); margin-bottom:20px}
.legal-todo{background:var(--sage-soft); border-radius:10px; padding:12px 14px; font-size:.88rem; line-height:1.6; color:var(--sage-text); margin-bottom:18px}
.app-footer{max-width:1180px; margin:40px auto 0; padding:22px 24px 32px; display:flex; flex-wrap:wrap; gap:6px 18px; align-items:center; justify-content:center; border-top:1px solid var(--border)}
.app-footer a{font-size:.78rem; color:var(--muted); text-decoration:none; background:none; border:none; cursor:pointer; font-family:inherit; padding:2px}
.app-footer a:hover{color:var(--sage-text); text-decoration:underline}
.app-footer .foot-sep{color:var(--border)}
.app-footer .foot-copy{width:100%; text-align:center; font-size:.78rem; color:var(--muted); margin-top:6px}

/* recipe selector inside modal */
.sel-results{display:grid; grid-template-columns:repeat(auto-fill,minmax(170px,1fr)); gap:12px; margin-top:14px}
.sel-card{text-align:left; background:var(--surface-2); border:1px solid var(--border); border-radius:var(--radius-sm);
  padding:12px; transition:.18s var(--ease); display:flex; flex-direction:column; gap:5px}
.sel-card:hover{border-color:var(--sage); background:var(--sage-soft); transform:translateY(-2px)}
.sel-card .se{font-size:1.8rem}
.sel-card .sn{font-weight:700; font-size:.85rem; line-height:1.2}
.sel-card .sm{font-size:.78rem; color:var(--muted); display:flex; gap:8px; flex-wrap:wrap; margin-top:auto}
.sel-card-quickadd{position:absolute; top:8px; right:8px; width:28px; height:28px; border-radius:50%; border:1px solid var(--border);
  background:var(--surface); color:var(--sage-text); font-size:.95rem; line-height:1; display:flex; align-items:center; justify-content:center;
  cursor:pointer; transition:.15s var(--ease); z-index:2}
.sel-card-quickadd:hover{background:var(--sage); color:var(--on-accent); border-color:var(--sage); transform:scale(1.08)}

/* form */
.field{margin-bottom:15px}
.field label{display:block; font-size:.8rem; font-weight:700; color:var(--ink-2); margin-bottom:6px}
.field input[type=text],.field input[type=number],.field input[type=email],.field input[type=password],.field select,.field textarea{
  width:100%; padding:10px 13px; border-radius:11px; border:1px solid var(--border); background:var(--surface-2); transition:.18s var(--ease)}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--sage); box-shadow:0 0 0 3px var(--sage-soft); outline:none; background:var(--surface)}
.field textarea{resize:vertical; min-height:62px}
.field-row{display:grid; grid-template-columns:1fr 1fr; gap:13px}
.field-row-3{display:grid; grid-template-columns:1fr 1fr 1fr; gap:10px}
.checks{display:flex; flex-wrap:wrap; gap:7px}
.dislikes-chips{display:flex; flex-wrap:wrap; gap:7px}
.dislikes-empty{font-size:.8rem; color:var(--muted)}
.dislike-chip{display:inline-flex; align-items:center; gap:6px; padding:6px 8px 6px 12px; border-radius:999px; background:var(--terra-soft); color:var(--terra-text); font-size:.82rem; font-weight:600}
.dislike-chip button{width:17px; height:17px; border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--terra-text); font-size:.9rem; line-height:1; flex-shrink:0}
.dislike-chip button:hover{background:var(--terra); color:var(--on-accent)}
.check-chip{display:inline-flex; align-items:center; gap:6px; padding:7px 12px; border-radius:999px; border:1px solid var(--border);
  background:var(--surface-2); font-size:.82rem; font-weight:600; color:var(--ink-2); cursor:pointer; transition:.16s var(--ease)}
.check-chip input{display:none}
.check-chip.on{background:var(--sage-soft); border-color:var(--sage); color:var(--sage-text)}
.nutri-auto-badge{display:inline-flex; align-items:center; padding:2px 9px; border-radius:999px; font-size:.72rem; font-weight:700;
  background:var(--surface-2); color:var(--muted); vertical-align:middle; margin-left:4px}
.nutri-auto-badge.is-auto{background:var(--sage-soft); color:var(--sage-text)}
.nutri-recalc-btn{color:var(--sage-text); font-weight:700; text-decoration:underline; text-underline-offset:2px}
.nutri-recalc-btn:hover{color:var(--sage)}
.plan-pick-grid{display:flex; flex-direction:column; gap:6px}
.plan-pick-row{display:flex; align-items:center; gap:10px}
.ppr-day{width:92px; flex-shrink:0; font-size:.82rem; font-weight:700; display:flex; flex-direction:column; line-height:1.25}
.ppr-day small{font-weight:500; color:var(--muted); font-size:.78rem}
.ppr-cells{display:flex; gap:6px; flex:1}
.plan-pick-cell{flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; padding:9px 4px; border-radius:11px;
  border:1px dashed var(--border); background:var(--surface-2); cursor:pointer; transition:.16s var(--ease)}
.plan-pick-cell:hover{border-color:var(--sage); background:var(--sage-soft)}
.plan-pick-cell.filled{border-style:solid; border-color:var(--border)}
.ppc-emoji{font-size:.85rem; opacity:.6}
.ppc-cur{font-size:1.1rem}
.ing-row{display:grid; grid-template-columns:1fr 70px 92px 1fr 34px; gap:7px; margin-bottom:8px; align-items:center}
.ing-row input,.ing-row select{padding:8px 10px; border-radius:9px; border:1px solid var(--border); background:var(--surface-2); font-size:.85rem; width:100%}
.ing-del{width:32px; height:32px; border-radius:9px; background:var(--danger-soft); color:var(--danger); display:flex; align-items:center; justify-content:center}
.ing-del svg{width:15px;height:15px}
@media(max-width:560px){.ing-row{grid-template-columns:1fr 1fr; }.ing-row .ing-del{grid-column:span 2}}

/* number stepper */
.stepper{display:inline-flex; align-items:center; gap:0; border:1px solid var(--border); border-radius:11px; overflow:hidden; background:var(--surface-2)}
.stepper button{width:38px; height:38px; font-size:1.2rem; color:var(--ink-2); display:flex; align-items:center; justify-content:center; transition:.15s}
.stepper button:hover{background:var(--sage); color:var(--on-accent)}
.stepper .val{min-width:46px; text-align:center; font-weight:700}

/* ============ SHOPPING LIST ============ */
.shop-prog-card{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:16px 20px; margin-bottom:20px;
  display:flex; align-items:center; gap:18px; flex-wrap:wrap}
.shop-prog-card .spc-info{flex:1; min-width:180px}
.shop-prog-card .spc-num{font-family:var(--sans); font-weight:700; font-size:1.5rem}
.shop-prog-card .spc-sous{font-size:.88rem; color:var(--muted); font-weight:600; margin:2px 0 8px}
/* 05/10/2026 : les articles cochés rangés dans un volet replié, sous ce qui reste à acheter. */
details.panier-section{margin:6px 0 18px; border:1px solid var(--border); border-radius:var(--radius); background:var(--surface-2); padding:4px 14px}
details.panier-section > summary.panier-head{display:flex; align-items:center; gap:8px; min-height:48px; font-weight:700; color:var(--sage-text); cursor:pointer; list-style:none}
details.panier-section > summary.panier-head::-webkit-details-marker{display:none}
details.panier-section > summary.panier-head .cl-count{margin-left:auto}
details.panier-section .shop-cat{margin:0 0 10px}
.shop-reste-head .ct{font-weight:600; color:var(--muted); font-size:.8rem}
#storeModeWrap .sm-panier{opacity:.75}
.shop-prog-bar{height:10px; background:var(--surface-2); border-radius:999px; overflow:hidden; margin-top:8px}
.shop-prog-bar i{display:block; height:100%; background:linear-gradient(90deg,var(--terra),var(--sage)); border-radius:999px; transition:width .5s var(--ease)}
.shop-cat{margin-bottom:18px}
.shop-cat-head{display:flex; align-items:center; gap:9px; font-weight:700; font-size:1.02rem; margin-bottom:9px}
.rayon-reorder{display:flex; gap:6px; margin-left:auto}
.rayon-move{width:32px; height:32px; border-radius:8px; border:1px solid var(--border); background:var(--surface); color:var(--muted); font-size:.72rem; line-height:1; cursor:pointer; transition:.14s}
.rayon-move:hover:not(:disabled){background:var(--sage-soft); color:var(--sage-text); border-color:var(--sage)}
.rayon-move:disabled{opacity:.3; cursor:default}
.shop-cat-head .cc{font-size:1.2rem}
.shop-cat-head .ct{color:var(--muted); font-size:.8rem; font-weight:600}
.shop-items{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden}
.shop-item{display:flex; align-items:center; gap:12px; padding:11px 15px; border-bottom:1px solid var(--border); transition:.16s var(--ease); position:relative}
.shop-item:last-child{border-bottom:none}
.shop-item:hover{background:var(--surface-2)}
.shop-item.checked .si-name{text-decoration:line-through; color:var(--muted)}
.shop-item.checked{opacity:.62}
.scheck{width:23px; height:23px; border-radius:7px; border:2px solid var(--border-2); flex-shrink:0; display:flex; align-items:center; justify-content:center; transition:.18s var(--ease)}
.scheck svg{width:14px; height:14px; opacity:0; transform:scale(.4); transition:.18s var(--ease); color:#fff}
.shop-item.checked .scheck{background:var(--sage); border-color:var(--sage)}
.shop-item.checked .scheck svg{opacity:1; transform:scale(1)}
.si-main{flex:1; min-width:0}
.si-name{font-weight:600; font-size:.92rem}
.si-from{font-size:.78rem; color:var(--muted); margin-top:1px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.si-qty{font-weight:700; font-size:.9rem; color:var(--sage-text); white-space:nowrap; flex-shrink:0; font-variant-numeric:tabular-nums}
.si-tip{position:absolute; bottom:calc(100% - 2px); left:50px; background:var(--ink); color:var(--bg); font-size:.74rem;
  padding:7px 11px; border-radius:9px; max-width:260px; box-shadow:var(--shadow-md); opacity:0; pointer-events:none;
  transform:translateY(6px); transition:.18s var(--ease); z-index:5; line-height:1.4}
.shop-item:hover .si-tip{opacity:1; transform:none}
.have-section{background:var(--sage-soft); border:1px solid var(--sage); border-radius:var(--radius); padding:14px 16px; margin-bottom:18px}
.have-head{display:flex; align-items:center; gap:8px; font-weight:700; color:var(--sage-text); margin-bottom:8px}
.have-list{display:flex; flex-wrap:wrap; gap:8px}
.have-pill{background:var(--surface); border:1px solid var(--sage); color:var(--sage-text); font-size:.8rem; font-weight:600;
  padding:5px 11px; border-radius:999px; display:inline-flex; gap:6px; align-items:center}
.have-pill svg{width:13px; height:13px}

/* ============ B : MODE MAGASIN ============
   Plein écran par-dessus toute l'appli, réutilise le balisage .shop-item
   (mêmes data-attributes, même logique de coche que la liste normale) mais
   agrandit les cibles tactiles et masque les détails superflus au
   supermarché (prix appris, bio, tooltip nécessaire/stock) pour rester
   utilisable d'une seule main, sans avoir à lire finement l'écran. */
body.store-mode-open{overflow:hidden}
#storeModeWrap{position:fixed; inset:0; z-index:900; background:var(--bg); display:flex; flex-direction:column; animation:smIn .22s var(--ease)}
@keyframes smIn{from{opacity:0; transform:translateY(12px)}to{opacity:1; transform:translateY(0)}}
.sm-head{display:flex; align-items:center; gap:14px; padding:calc(16px + env(safe-area-inset-top)) 16px 12px; border-bottom:1px solid var(--border); background:var(--surface); flex-shrink:0}
.sm-close{width:42px; height:42px; border-radius:50%; border:1px solid var(--border); background:var(--surface-2); font-size:1.1rem; color:var(--ink-2); flex-shrink:0}
.sm-list{flex:1; overflow-y:auto; padding:10px 0 calc(60px + env(safe-area-inset-bottom)); -webkit-overflow-scrolling:touch}
.sm-cat-head{font-weight:800; font-size:1rem; padding:16px 18px 8px; color:var(--sage-text); position:sticky; top:0; background:var(--bg); z-index:1}
/* B10 : articles au-delà du plafond gratuit, annoncés en fin de liste (cliquable → upsell) */
.sm-hidden-note{display:block; width:calc(100% - 36px); margin:18px 18px 0; padding:14px 16px; border-radius:14px; border:1px dashed var(--border); background:var(--surface-2); color:var(--ink-2); font:inherit; font-weight:700; font-size:.95rem; text-align:center; cursor:pointer}
#storeModeWrap .shop-item{padding:18px; gap:16px; cursor:pointer; -webkit-tap-highlight-color:transparent}
#storeModeWrap .scheck{width:32px; height:32px; border-radius:9px}
#storeModeWrap .scheck svg{width:19px; height:19px}
#storeModeWrap .si-name{font-size:1.08rem; font-weight:700}
#storeModeWrap .si-qty{font-size:1.02rem}
/* Détails utiles à la préparation mais superflus une fois au magasin : la
   quantité "réellement achetée", le prix appris, le statut bio, l'infobulle
   nécessaire/stock déjà chez soi. Le clic sur la ligne coche toujours,
   coursesToggleChecked() gère le reste en arrière-plan (stock, budget…). */
#storeModeWrap .si-buy,#storeModeWrap .si-tip,#storeModeWrap [data-si-action="prix"],#storeModeWrap [data-si-action="bio"]{display:none !important}
/* Le menu « ⋯ » reste disponible en Mode Magasin pour « Indisponible → équivalent » et
   « J'en ai déjà » : c'est leur cas d'usage principal (voir shopItemHtml). */
#storeModeWrap .si-subst-row .sr-txt{font-size:.9rem}
@media(max-width:600px){
  .sm-head{padding:calc(14px + env(safe-area-inset-top)) 12px 10px}
  #storeModeWrap .shop-item{padding:16px 12px}
}

/* ============ A : MODE CUISINE ============
   Plein écran pas-à-pas, réutilise .sm-close et le verrou de scroll
   body.store-mode-open déjà posés pour le Mode Magasin (B) — même famille
   de composant "vue plein écran par-dessus l'appli", pas de doublon CSS. */
#cookModeWrap{position:fixed; inset:0; z-index:900; background:var(--bg); display:flex; flex-direction:column; animation:smIn .22s var(--ease)}
/* 05/10/2026 (Paul : « pas du tout au bon format ») : l'en-tête passait sous l'heure et la
   batterie, et la barre d'onglets native couvrait Précédent / Suivant. Marges de sécurité
   des deux côtés ; la barre native s'efface (initBarreNative, body.store-mode-open). */
.cm-head{display:flex; align-items:center; gap:12px; padding:calc(10px + env(safe-area-inset-top)) 16px 10px; background:var(--bg); flex-shrink:0}
.cm-head .sm-close{width:48px; height:48px}
.cm-head-title{flex:1; font-weight:800; font-size:1.02rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.cm-progress{display:flex; gap:5px; padding:0 16px 6px; flex-shrink:0}
.cm-progress i{flex:1; height:6px; border-radius:99px; background:var(--surface-2); transition:background .3s var(--ease)}
.cm-progress i.on{background:var(--sage)}
.cm-body{flex:1; overflow-y:auto; display:flex; flex-direction:column; align-items:stretch; padding:22px 22px 28px; gap:16px; max-width:680px; width:100%; margin:0 auto; -webkit-overflow-scrolling:touch}
.cm-step-num{font-size:.84rem; font-weight:800; text-transform:uppercase; letter-spacing:.05em; color:var(--sage-text)}
.cm-titre-ings{font-family:var(--serif, inherit); font-size:1.6rem; line-height:1.2; margin:-6px 0 0}
.cm-sous{margin:-6px 0 0; color:var(--muted); font-size:.92rem; line-height:1.45}
.cm-step-text{margin:0; font-family:var(--sans); font-weight:700; font-size:1.6rem; line-height:1.4; color:var(--ink)}
.cm-cites{display:flex; flex-wrap:wrap; gap:8px}
.cm-cite{display:inline-flex; align-items:center; gap:6px; padding:9px 14px; border-radius:99px; background:var(--sage-pale, var(--surface-2)); font-size:.95rem; line-height:1.2}
.cm-cite b{font-weight:800}
.cm-timer-host{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.cm-timer-host .cm-timer-display{flex:1 1 220px}
/* 05/10/2026 : la voix qui lit les étapes, allumée ou non, dans l'en-tête du mode cuisine. */
.cm-voix{display:inline-flex; align-items:center; gap:6px; min-height:48px; padding:0 14px; border-radius:14px; border:1.5px solid var(--border);
  background:var(--surface); color:var(--ink-2); font:inherit; font-size:.9rem; font-weight:800; cursor:pointer; flex-shrink:0}
.cm-voix svg{width:20px; height:20px}
.cm-voix.is-on{background:var(--sage); border-color:var(--sage); color:var(--on-accent)}
.cm-timer-host:empty{display:none}
.cm-timer-btn{min-height:52px; padding:12px 20px; font-size:1rem; display:inline-flex; align-items:center; gap:8px}
.cm-timer-btn .ic,.cm-timer-display .ic{width:1.2em; height:1.2em}
.cm-timer-display{display:flex; align-items:center; gap:12px; padding:10px 12px 10px 18px; border-radius:18px; background:var(--surface); border:1.5px solid var(--border); font-size:1.7rem; font-weight:800; color:var(--sage-text); font-variant-numeric:tabular-nums}
.cm-timer-display.is-fini{color:var(--terra, var(--sage-text)); border-color:currentColor}
.cm-timer-n{flex:1}
.cm-timer-display .cm-timer-stop{min-height:44px; padding:0 16px; border-radius:12px; border:1px solid var(--border); background:var(--surface-2); font:inherit; font-size:.9rem; font-weight:700; color:var(--ink-2)}
.cm-ings-list{list-style:none; padding:0; margin:0; display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:8px}
.cm-ing{display:flex; align-items:center; gap:12px; width:100%; min-height:52px; padding:10px 14px; border-radius:14px; border:1.5px solid var(--border); background:var(--surface); font:inherit; font-size:1rem; color:var(--ink); text-align:left; cursor:pointer; -webkit-tap-highlight-color:transparent}
.cm-ing-coche{width:26px; height:26px; flex-shrink:0; border-radius:8px; border:2px solid var(--border); display:grid; place-items:center; color:#fff}
.cm-ing-coche svg{width:16px; height:16px}
.cm-ing-nom{flex:1; min-width:0}
.cm-ing-qte{font-weight:800; white-space:nowrap; color:var(--ink-2)}
.cm-ing.is-pret{opacity:.6}
.cm-ing.is-pret .cm-ing-nom{text-decoration:line-through}
.cm-ing.is-pret .cm-ing-coche{background:var(--sage); border-color:var(--sage)}
.cm-tous{margin-top:4px}
.cm-tous summary{min-height:48px; display:flex; align-items:center; gap:8px; font-weight:700; color:var(--ink-2); cursor:pointer; list-style:none}
.cm-tous summary::-webkit-details-marker{display:none}
.cm-tous summary::after{content:''; width:8px; height:8px; border-right:2.5px solid currentColor; border-bottom:2.5px solid currentColor; transform:rotate(45deg) translate(-2px,-2px); transition:transform .2s var(--ease)}
.cm-tous[open] summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.cm-tous[open] summary{margin-bottom:6px}
#cookModeWrap .cm-note{margin:0}
.cm-nav{display:flex; gap:10px; padding:12px 16px calc(12px + env(safe-area-inset-bottom)); background:var(--bg); flex-shrink:0; max-width:680px; width:100%; margin:0 auto}
.cm-nav-btn{flex:1; min-height:56px; font-size:1.05rem; padding:14px}
.cm-nav-btn.cm-nav-prev{flex:0 0 64px; font-size:1.3rem}
@media(max-width:600px){
  .cm-step-text{font-size:1.4rem}
  .cm-body{padding:18px 18px 24px}
}

/* ============ STOCK ============ */
.stock-add{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:18px 20px; margin-bottom:22px}
.stock-add-row{display:grid; grid-template-columns:2fr 90px 110px 150px auto; gap:10px; align-items:end}
@media(max-width:620px){.stock-add-row{grid-template-columns:1fr 1fr}.stock-add-row>.field.autoc-wrap{grid-column:span 2}.stock-add-row>.field:nth-child(4){grid-column:span 2}.stock-add-row .sa-btn{grid-column:span 2}}
.autoc-wrap{position:relative}
.autoc{position:absolute; top:calc(100% + 4px); left:0; right:0; background:var(--surface); border:1px solid var(--border);
  border-radius:11px; box-shadow:var(--shadow-md); z-index:10; max-height:200px; overflow-y:auto; display:none}
.autoc.show{display:block}
.autoc button{display:block; width:100%; text-align:left; padding:9px 13px; font-size:.88rem; transition:.12s}
.autoc button:hover,.autoc button.hl{background:var(--sage-soft); color:var(--sage-text)}
.stock-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:12px}
.stock-pill{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-sm); padding:13px 15px;
  display:flex; align-items:center; gap:12px; transition:.18s var(--ease)}
.stock-pill:hover{border-color:var(--sage); box-shadow:var(--shadow-sm)}
.stock-pill .sp-em{font-size:1.5rem; width:40px; height:40px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:var(--sage-soft); flex-shrink:0}
.stock-pill .sp-info{flex:1; min-width:0}
.stock-pill .sp-name{font-weight:700; font-size:.9rem}
.stock-pill .sp-qty{font-size:.78rem; color:var(--muted)}

/* ============ EMPTY STATES ============ */
.empty-state{text-align:center; padding:54px 20px; color:var(--muted)}
.empty-state .es-emoji{font-size:3.4rem; animation:floaty 3.5s ease-in-out infinite}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
.empty-state h3{font-size:1.4rem; color:var(--ink); margin:14px 0 6px}
.empty-state p{max-width:340px; margin:0 auto 18px; font-size:.92rem; line-height:1.5}

/* ============ SKELETON ============ */
.skel-grid{display:grid; grid-template-columns:78px repeat(7,minmax(124px,1fr)); gap:9px; min-width:760px; padding:4px}
.skel{background:linear-gradient(100deg,var(--surface-2) 30%,var(--sand) 50%,var(--surface-2) 70%);
  background-size:200% 100%; animation:shimmer 1.3s infinite; border-radius:var(--radius-sm)}
.skel.h{min-height:54px} .skel.s{min-height:104px}
@keyframes shimmer{from{background-position:200% 0}to{background-position:-200% 0}}

/* ============ TOASTS ============ */
.toast-wrap{position:fixed; bottom:22px; left:50%; transform:translateX(-50%); z-index:950; display:flex; flex-direction:column; gap:10px; align-items:center; width:max-content; max-width:92vw}
.toast{display:flex; align-items:center; gap:11px; background:var(--ink); color:var(--bg); padding:13px 18px; border-radius:13px;
  box-shadow:var(--shadow-lg); font-weight:600; font-size:.9rem; animation:toastIn .35s var(--ease); max-width:100%}
.toast.out{animation:toastOut .3s var(--ease) forwards}
.toast .ti{width:22px; height:22px; border-radius:50%; background:var(--sage); display:flex; align-items:center; justify-content:center; flex-shrink:0}
.toast.warn .ti{background:var(--terra)}
/* 15/10/2026 : « Annuler » se lit aussi en sombre, où le toast est clair (le blanc à 16 % y disparaissait). */
@supports (background:color-mix(in srgb, red 10%, transparent)){ .toast-action{background:color-mix(in srgb, currentColor 16%, transparent)} }
.toast.info .ti{background:transparent; border:1.5px solid currentColor}
.toast.info .ti svg{color:currentColor}
.toast .ti svg{width:14px; height:14px; color:#fff}
.toast-action{margin-left:4px; padding:5px 12px; border-radius:999px; background:rgba(255,255,255,.16); color:inherit; font-weight:800; font-size:.82rem; white-space:nowrap; flex-shrink:0}
.toast-action:hover{background:rgba(255,255,255,.28)}
/* 30/09/2026 : la cocotte dans le toast des petites victoires (toast(…, {coco})).
   Pastille claire derrière : ses contours sont à l'encre, comme le fond du toast. */
.toast.has-coco{padding-left:10px}
.toast .ti-coco{flex:0 0 auto; width:46px; height:40px; padding:2px 3px 0; border-radius:12px; background:var(--bg); line-height:0}
.toast .ti-coco .jeu-coco{width:40px; height:34px; transform-origin:50% 90%}
@media (prefers-reduced-motion:no-preference){
  .toast.has-coco .ti-coco .jeu-coco{animation:jeuSaut 1.1s cubic-bezier(.4,0,.2,1) .25s 1 both}
}
@keyframes toastIn{from{opacity:0; transform:translateY(20px)}to{opacity:1; transform:none}}
@keyframes toastOut{to{opacity:0; transform:translateY(20px)}}

/* slot options popover */
.popover{position:fixed; z-index:70; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow-lg); width:248px; padding:8px; opacity:0; pointer-events:none; transform:scale(.94); transition:.2s var(--ease);
  /* Marge généreuse (48px, pas 20px) en haut et en bas : ce popover est
     souvent plus haut que l'écran (têtes de repas + actions + profils +
     ingrédients + bouton cuisiné + bouton supprimer), il doit toujours
     garder de la place visible sous le dernier bouton ("Retirer ce repas")
     plutôt que de s'arrêter pile au bord de la fenêtre. */
  max-height:calc(100vh - 48px); overflow-y:auto; text-align:left}
.popover.show{opacity:1; pointer-events:auto; transform:none}
.popover button{text-align:left}
.po-head{padding:8px 10px 10px; border-bottom:1px solid var(--border); margin-bottom:6px}
.po-head .pe{font-size:1.5rem}
.po-head .pn{font-weight:700; font-size:.92rem; margin-top:3px; line-height:1.2}
.po-row{display:flex; align-items:center; justify-content:space-between; padding:8px 10px; border-radius:9px; font-size:.88rem; font-weight:600; width:100%; transition:.14s}
/* Raccourcis clavier (Ctrl+C/Ctrl+V) : utile uniquement sur un appareil avec
   un vrai clavier. Masqué sur pointeur tactile (mobile/tablette) où ce texte
   n'a aucune action associée et n'est qu'une ligne morte dans le popover ;
   visible sur desktop où le raccourci fonctionne réellement. */
.kbd-hint{color:var(--muted); font-weight:500}
@media (pointer:coarse){ .kbd-hint{display:none} }
.po-row:hover{background:var(--surface-2)}
.po-row.btn-like:hover{background:var(--sage-soft); color:var(--sage-text)}
/* F40 : action primaire du popover (Mode Cuisine quand le repas est du jour) */
.po-row.po-row-primary{background:var(--sage); color:var(--on-accent)}
.po-row.po-row-primary:hover{background:var(--sage-text); color:#fff}
html[data-theme="dark"] .po-row.po-row-primary{color:var(--on-accent)}
.po-row.del{color:var(--danger)}
.po-row.del:hover{background:var(--danger-soft); color:var(--danger)}
.po-row svg{width:16px; height:16px}
.po-subhead{font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--muted); padding:10px 10px 2px; border-top:1px solid var(--border); margin-top:4px}
.po-subhead:first-child{border-top:none; margin-top:0; padding-top:2px}
.po-ppl{display:flex; align-items:center; justify-content:space-between; padding:6px 10px}
.po-mini-step{display:inline-flex; align-items:center; border:1px solid var(--border); border-radius:9px; overflow:hidden}
.po-mini-step button{width:30px; height:30px; color:var(--ink-2)}
.po-mini-step button:hover{background:var(--sage); color:var(--on-accent)}
.po-mini-step .v{min-width:30px; text-align:center; font-weight:700; font-size:.9rem}

/* confetti */
.confetti{position:fixed; width:10px; height:14px; z-index:95; pointer-events:none; top:-20px; border-radius:2px}

/* detail modal */
.detail-hero{display:flex; gap:16px; align-items:center; margin-bottom:16px}
/* Encart photo du détail recette : appel à contribution quand la recette n'est pas
   illustrée, accusé de réception quand elle l'est (voir le bloc PHOTOS DE PLATS). */
.photo-cta{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0 0 14px; padding:11px 13px;
  border:1px dashed var(--terra); border-radius:12px; background:var(--terra-soft); font-size:.86rem; line-height:1.55}
.photo-cta.is-mine{border-style:solid; border-color:var(--sage); background:var(--sage-soft)}
.photo-cta .pc-em{font-size:1.15rem; flex-shrink:0}
.photo-cta span:not(.pc-em){flex:1; min-width:170px}
/* Vignette photo sur les cartes de recette : remplace l'emoji quand elle existe. */
.rcard-photo{width:100%; height:100%; object-fit:cover; display:block; border-radius:inherit}
.detail-emoji{font-size:3.4rem; width:84px; height:84px; border-radius:20px; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(135deg,var(--surface-2),var(--sand)); flex-shrink:0}
.detail-nut{display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin:16px 0}
.nut-box{background:var(--surface-2); border:1px solid var(--border); border-radius:12px; padding:11px; text-align:center}
.nut-box .nv{font-family:var(--sans); font-weight:700; font-size:1.3rem; line-height:1}
.nut-box .nl{font-size:.74rem; color:var(--muted); text-transform:uppercase; letter-spacing:.4px; margin-top:3px; font-weight:600}
.detail-ings{list-style:none; padding:0; margin:8px 0 0}
.detail-ings li{display:flex; flex-wrap:wrap; justify-content:space-between; padding:8px 0; border-bottom:1px dashed var(--border); font-size:.9rem}
.detail-ings li:last-child{border-bottom:none}
.di-sub{flex-basis:100%; font-size:.78rem; color:var(--sage-text); margin-top:4px; font-family:var(--sans)}
.detail-ings .di-q{color:var(--sage-text); font-weight:700}
.detail-benefits{list-style:none; padding:0; margin:8px 0 0; display:flex; flex-direction:column; gap:10px}
.detail-benefits li{padding:9px 11px; border-radius:10px; background:rgba(0,0,0,.03); font-size:.85rem}
.detail-benefits strong{display:block; margin-bottom:3px}
.detail-benefits .ib-text{color:var(--muted)}
.section-label{font-size:.74rem; font-weight:700; text-transform:uppercase; letter-spacing:.6px; color:var(--muted); margin:16px 0 6px}
.linklike{background:none; border:0; padding:0; font:inherit; color:var(--sage-text); font-weight:700; cursor:pointer; text-decoration:underline}

/* ============ SLOT SOURCE BADGE (frigo / courses) ============ */
.slot-src{position:absolute; top:6px; right:6px; display:inline-flex; align-items:center; gap:3px;
  font-size:.72rem; font-weight:700; padding:2px 6px; border-radius:999px; line-height:1.3;
  border:1px solid transparent; z-index:2; pointer-events:none}
.slot-src svg{width:9px; height:9px}
.slot-src.s-frigo{background:var(--sage-soft); color:var(--sage-text); border-color:var(--sage)}
.slot-src.s-courses{background:var(--terra-soft); color:var(--terra-text); border-color:color-mix(in srgb,var(--terra) 40%,transparent)}
.slot-src.s-partiel{background:#F6EAD2; color:#9A7B25; border-color:#E0B25A}
html[data-theme="dark"] .slot-src.s-partiel{background:#3A3220; color:#E0B25A}
.slot-src.s-malbouffe{background:#FBE0D4; color:#C1440E; border-color:#E8956B}
html[data-theme="dark"] .slot-src.s-malbouffe{background:#4A2A18; color:#F2A472}
.slot.filled{padding-top:22px}

/* ============ SHOPPING — quantité achetée ============ */
.si-buy{display:none; align-items:center; gap:8px; flex-wrap:wrap; width:100%; margin-top:9px;
  padding:10px 12px; background:var(--surface-2); border:1px dashed var(--border-2); border-radius:11px}
.shop-item.checked .si-buy{display:flex}
.si-buy-lab{font-size:.74rem; font-weight:700; color:var(--ink-2); display:flex; align-items:center; gap:5px}
.si-buy-lab svg{width:13px; height:13px; color:var(--sage-text)}
.si-buy-field{display:inline-flex; align-items:center; border:1px solid var(--border); border-radius:9px; overflow:hidden; background:var(--surface)}
.si-buy-field input{width:74px; padding:6px 9px; border:none; background:transparent; font-weight:700; font-size:.86rem; text-align:right; -moz-appearance:textfield}
.si-buy-field input::-webkit-outer-spin-button,.si-buy-field input::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}
.si-buy-field .si-buy-unit{padding:6px 10px 6px 4px; font-size:.78rem; font-weight:600; color:var(--muted); background:var(--surface-2)}
.si-buy-surplus{font-size:.74rem; font-weight:700; color:var(--sage-text); display:inline-flex; align-items:center; gap:4px}
.si-buy-surplus svg{width:13px; height:13px}
.si-buy-surplus.zero{color:var(--muted); font-weight:600}
.shop-item{flex-wrap:wrap}
.shop-item .scheck,.shop-item .si-main,.shop-item .si-qty{align-self:center}

/* ============ TOOLBAR SEMAINE ============ */
.week-actions{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
/* F39 : conteneur de la 2e ligne mobile (Jour | Aujourd'hui | ‹ semaine › | Plus). Sur
   desktop il est transparent pour la mise en page : ses enfants restent des items
   directs de .week-actions, comme avant. */
.week-bar-mobile{display:contents}

/* ============ NUTRI-SCORE MAISON ============ */
.nutri-badge{display:inline-flex; align-items:center; gap:9px; padding:8px 12px 8px 8px; border-radius:999px; border:1px solid var(--border); background:var(--surface)}
.nutri-letters{display:inline-flex; border-radius:999px; overflow:hidden; box-shadow:var(--shadow-sm)}
.nutri-letters span{width:24px; height:24px; display:flex; align-items:center; justify-content:center; font-size:.72rem; font-weight:800; color:#fff; opacity:.32}
.nutri-letters span.cur{opacity:1; width:30px; height:30px; font-size:.92rem; transform:scale(1.05)}
.nl-a{background:#3C8A3C}.nl-b{background:#8AB23C}.nl-c{background:#E0B25A}.nl-d{background:#D9813F}.nl-e{background:#C0573F}
.nutri-txt{display:flex; flex-direction:column; line-height:1.25}
.nutri-txt b{font-size:.84rem}
.nutri-txt small{color:var(--muted); font-size:.78rem}
.nutri-mini{display:inline-flex; align-items:center; justify-content:center; width:20px; height:20px; border-radius:50%; font-size:.72rem; font-weight:800; color:#fff; flex-shrink:0}
.bday .nutri-mini{margin-top:3px}
.nutri-detail{display:flex; gap:14px; margin-top:10px; flex-wrap:wrap; font-size:.78rem; color:var(--ink-2)}
.nutri-detail b{color:var(--ink)}

/* ============ SCORES PAR RECETTE (santé + impact climat) ============ */
.score-mini{display:inline-flex; align-items:center; justify-content:center; width:20px; height:20px; border-radius:50%; font-size:.72rem; font-weight:800; color:#fff; flex-shrink:0}
.eco-a{background:#3C8A3C}.eco-b{background:#8AB23C}.eco-c{background:#E0B25A}.eco-d{background:#D9813F}.eco-e{background:#C0573F}
.detail-scores{display:flex; flex-direction:column; gap:8px; margin:14px 0}
/* G44/G45 : fiche recette — lien photo discret, section repliable, pied avec menu ⋯ */
.photo-add-link{display:inline-flex; align-items:center; gap:4px; margin-top:8px; font-size:.8rem; font-weight:600; color:var(--muted); text-decoration:underline dotted; padding:0}
.photo-add-link:hover{color:var(--sage-text)}
.detail-more-fold{margin-top:18px}
.detail-more-fold>summary{font-weight:700; font-size:.88rem}
.detail-more-fold .detail-nut{margin-top:10px}
.detail-foot{flex-wrap:nowrap; align-items:center; gap:8px}
.detail-foot .btn{white-space:nowrap}
.detail-foot-spacer{flex:1 1 auto}
.detail-more-btn{width:44px; padding:11px 0; font-size:1.2rem; line-height:1; justify-content:center; flex:0 0 auto}
.detail-more-menu{top:auto; bottom:calc(100% + 8px); right:auto; left:0; transform-origin:bottom left}
@media(max-width:720px){
  /* plus fort que la règle générique .modal-foot (column-reverse sous 560px) : ici une
     seule rangée ⋯ | secondaire | primaire, la primaire prenant la place restante */
  .modal-foot.detail-foot{flex-direction:row; padding:12px 14px calc(12px + env(safe-area-inset-bottom))}
  .modal-foot.detail-foot .btn{width:auto; padding:11px 12px; font-size:.86rem}
  .modal-foot.detail-foot .btn-primary{flex:1 1 auto}
  .modal-foot.detail-foot .detail-more-btn{width:44px; padding:11px 0}
  .detail-foot-spacer{display:none}
}
.nutri-badge-btn{width:100%; text-align:left; cursor:pointer; transition:.16s var(--ease)}
.nutri-badge-btn:hover{border-color:var(--sage); background:var(--sage-soft)}
.score-detail-list{list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:2px}
.score-detail-list li{display:flex; align-items:center; gap:8px; padding:8px 4px; border-bottom:1px solid var(--border); font-size:.85rem}
.score-detail-list li:last-child{border-bottom:none}
.sd-label{flex:1; font-weight:600}
.sd-detail{color:var(--muted); font-size:.8rem}
.sd-pts{font-weight:800; min-width:28px; text-align:right}
.sd-pts.pos{color:var(--sage-text)}
.sd-pts.neg{color:var(--terra-text)}

/* ============ INGRÉDIENTS LIBRES (repas) ============ */
.extras-list{display:flex; flex-direction:column; gap:5px; padding:4px 4px 0}
.extra-row{display:flex; align-items:center; justify-content:space-between; gap:8px; padding:7px 10px; background:var(--surface-2); border-radius:9px; font-size:.82rem}
.extra-row .ex-name{font-weight:600}
.extra-row .ex-qty{color:var(--muted); margin-left:6px; font-weight:500}
.extra-rm{width:22px; height:22px; border-radius:7px; display:flex; align-items:center; justify-content:center; color:var(--muted); flex-shrink:0; position:relative}
.extra-rm::before{content:'';position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%)}
.extra-rm:hover{background:var(--danger-soft); color:var(--danger)}
.extra-rm svg{width:12px;height:12px}
.extra-add-row{display:flex; flex-direction:column; gap:6px; padding:8px 4px 2px}
.extra-add-row input,.extra-add-row select{padding:7px 8px; border-radius:8px; border:1px solid var(--border); background:var(--surface); font-size:.8rem; width:100%}
.extra-add-sub{display:grid; grid-template-columns:64px 1fr 34px; gap:6px}
.extra-add-btn{width:34px; height:34px; border-radius:9px; background:var(--sage); color:var(--on-accent); display:flex; align-items:center; justify-content:center; flex-shrink:0}
.extra-add-btn:hover{background:var(--sage-deep)}
.extra-add-btn svg{width:16px;height:16px}
.slot-extras-badge{position:absolute; top:6px; left:6px; font-size:.72rem; font-weight:700; background:var(--terra-soft); color:var(--terra-text);
  padding:2px 6px; border-radius:999px; z-index:2}
.slot-leftover-tag{display:block; font-size:.72rem; font-weight:700; color:var(--sage-text); margin-top:1px}
.slot.is-leftover{background:var(--sage-soft); border-style:dashed}
.slot.free .slot-emoji{opacity:.7}
.slot-free-list{font-size:.72rem; color:var(--muted); margin-top:2px; line-height:1.3; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}

/* Turnstile : en taille « flexible » le widget prend la largeur disponible
   (300 px min.) et mesure 65 px de haut ; min-height évite un saut de mise en
   page pendant son chargement. */
.captcha-host{display:flex; justify-content:center; margin:14px 0 4px; min-height:65px}
.captcha-host > div{width:100%; max-width:400px}
.captcha-host iframe{max-width:100%}
.captcha-err{font-size:.82rem; color:var(--danger); line-height:1.5; text-align:center; margin:0}
.captcha-loading{font-size:.82rem; color:var(--muted); text-align:center; margin:0; align-self:center}
/* Les libellés longs des boutons d'authentification (« Recevoir un lien de
   connexion par email ») débordaient à 390 px : white-space:nowrap est la
   valeur par défaut de .btn, utile dans une barre d'outils, nuisible sur un
   bouton pleine largeur. */
.btn-block{white-space:normal; line-height:1.35}

/* ============ EXPORT COURSES ============ */
.export-bar{display:flex; gap:10px; flex-wrap:wrap; align-items:center}
.export-bar .btn{white-space:nowrap}
.export-menu-wrap .week-menu{right:0; left:auto}
@media(max-width:880px){
  /* H46 : une seule rangée sur mobile — Mode magasin absorbe la largeur restante,
     Partager et ⋯ Exporter gardent leur taille naturelle. */
  .export-bar{flex-wrap:nowrap; width:100%}
  .export-bar #storeModeBtn{flex:1 1 auto; justify-content:center; min-width:0; overflow:hidden; text-overflow:ellipsis; font-size:.84rem; padding-left:10px; padding-right:10px}
  .export-bar #shareListBtn,.export-bar #exportMoreBtn{flex:0 0 auto; padding:11px 10px; font-size:.84rem}
  /* libellé court sous 420 px : « Magasin » suffit, l'icône panier fait le reste */
  @media(max-width:420px){ .export-bar #storeModeBtn .btn-txt-long{display:none} .export-bar #storeModeBtn .btn-txt-short{display:inline!important} }
}
/* H47 : menu « ⋯ » par ligne de la liste de courses (bio, indisponible, j'en ai déjà,
   prix réel). Remplace les deux chips « Bio ? » / « Pas dispo ? » qui encombraient chaque
   ligne ; les états actifs restent visibles par une pastille discrète (.si-state). */
.si-more-wrap{position:relative; margin-left:auto; flex:0 0 auto}
.si-more-btn{width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center; color:var(--muted);
  background:transparent; border:1px solid transparent; font-size:1.05rem; line-height:1; font-weight:700}
.si-more-btn:hover,.si-more-btn[aria-expanded="true"]{background:var(--surface-2); border-color:var(--border); color:var(--ink)}
/* I52 : cibles tactiles ≥ 44 px. La géométrie visuelle des petits boutons (30, 28, 26 px)
   reste compacte ; un pseudo-élément transparent centré étend la zone cliquable à 44×44
   (même principe que .extra-rm::before). Les chips gardent leur hauteur visuelle mais
   reçoivent une zone verticale de 44 px : dans une rangée, deux chips voisines se partagent
   l'espace, ce qui reste préférable à une cible de 32 px. */
.mini-btn,.sel-card-quickadd,.si-more-btn,.detail-portion-btn,.coach-tip-close,.price-learn-toggle,.cm-timer-display button,.chip{position:relative}
.mini-btn::before,.sel-card-quickadd::before,.si-more-btn::before,.detail-portion-btn::before,.coach-tip-close::before,.price-learn-toggle::before,.cm-timer-display button::before{content:''; position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%)}
.chip::before{content:''; position:absolute; top:50%; left:0; right:0; height:44px; transform:translateY(-50%)}
.chip[disabled]::before{display:none}
.si-more-wrap .week-menu{min-width:230px; z-index:45}
.si-more-wrap .week-menu-item.on{background:var(--sage-soft); color:var(--sage-text)}
.si-more-wrap .week-menu-item .wmi-state{margin-left:auto; font-size:.72rem; font-weight:700; color:var(--muted)}
.si-more-wrap .week-menu-item.locked{opacity:.75}
.si-state{display:inline-flex; align-items:center; gap:3px; font-size:.72rem; font-weight:700; padding:1px 7px; border-radius:999px; border:1px solid var(--border); white-space:nowrap}
.si-state.bio{background:var(--sage-soft); color:var(--sage-text); border-color:var(--sage)}
.si-state.nonbio{background:var(--surface-2); color:var(--ink-2)}
.si-state.indispo{background:var(--terra-soft); color:var(--terra-text); border-color:var(--terra-text)}
#storeModeWrap .si-more-btn{width:40px; height:40px; font-size:1.25rem}
/* IMPORTANT : cette règle doit rester AVANT le bloc @media print ci-dessous.
   Les deux règles ciblent #printArea avec la même spécificité ; en cas d'égalité,
   c'est la dernière déclarée dans la feuille qui gagne, y compris à l'impression.
   Si "display:none" était placé APRÈS le bloc @media print, il écraserait le
   "display:block" du mode impression même pendant window.print() → page blanche
   (bug déjà rencontré : toujours garder cet ordre-ci). */
#printArea{display:none}
@media print{
  body *{visibility:hidden}
  #printArea,#printArea *{visibility:visible}
  #printArea{display:block; position:absolute; left:0; top:0; width:100%; padding:24px; color:#000; background:#fff}
  #printArea .pa-header{border-bottom:2px solid #14213D; padding-bottom:10px; margin-bottom:6px}
  #printArea h1{font-family:var(--serif); font-size:1.6rem; margin-bottom:4px; color:#14213D}
  #printArea .pa-header p{font-size:.86rem; color:#555; margin:0}
  #printArea .pa-cat{font-weight:800; margin:14px 0 6px; font-size:1rem; display:flex; justify-content:space-between; color:#3F6832}
  #printArea .pa-cat-total{font-weight:700; color:#C93F21}
  #printArea ul{list-style:none; padding:0; margin:0}
  #printArea li{padding:5px 0; border-bottom:1px solid #ddd; font-size:.92rem; display:flex; justify-content:space-between}
}

/* ============ ANTI-GASPI & PÉREMPTION ============ */
.section-card{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); padding:clamp(16px,3vw,24px); margin-bottom:20px; box-shadow:var(--shadow-sm)}
.section-card h2{font-size:1.25rem; margin-bottom:3px}
.section-card .sc-sub{color:var(--muted); font-size:.86rem; margin-bottom:14px}
.premium-lock-chip{display:inline-flex; align-items:center; gap:3px; font-size:.72rem; font-weight:700; color:var(--terra-text); background:var(--terra-soft); padding:1px 7px; border-radius:999px; margin-left:7px; vertical-align:middle; letter-spacing:.2px}
body.is-premium .premium-lock-chip{display:none}
.premium-feature-list{display:flex; flex-direction:column; gap:2px; margin:0}
.premium-feature-list .pf-row{display:flex; align-items:flex-start; gap:12px; font-size:.83rem; color:var(--ink-2); line-height:1.4; padding:9px 6px; border-radius:var(--radius-sm); transition:background .15s var(--ease)}
.premium-feature-list .pf-row:hover{background:var(--sage-soft)}
.premium-feature-list .pf-icon{flex:0 0 auto; width:32px; height:32px; border-radius:999px; display:flex; align-items:center; justify-content:center;
  font-size:1.02rem; background:linear-gradient(150deg,var(--sage-soft),var(--terra-soft)); box-shadow:inset 0 0 0 1px var(--border)}
.premium-feature-list .pf-txt strong{color:var(--ink); display:block; font-size:.86rem; margin-bottom:2px}
.premium-feature-list .pf-desc{color:var(--muted)}
.plan-note{font-size:.78rem; color:var(--muted); line-height:1.55; margin:0; padding:11px 13px;
  background:var(--surface-2); border-radius:var(--radius-sm)}
.acc-section{margin-top:26px; padding-top:20px; border-top:1px solid var(--border)}
.acc-section:first-of-type{margin-top:16px}
.acc-section-title{font-size:.78rem; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--muted); margin:0 0 10px}
.acc-danger-zone .acc-section-title{color:var(--danger)}
.premium-details{margin:18px 0 16px; border:1.5px solid var(--sage); border-radius:var(--radius-sm); background:linear-gradient(150deg,var(--sage-soft),var(--surface-2)); overflow:hidden}
.premium-details summary{cursor:pointer; font-size:.88rem; font-weight:700; color:var(--sage-text); list-style:none; padding:13px 14px; display:flex; align-items:center; gap:8px}
.premium-details summary::-webkit-details-marker{display:none}
.premium-details summary::before{content:''; width:18px; height:18px; flex:0 0 auto; background:currentColor; -webkit-mask:var(--masque-couronne) center/contain no-repeat; mask:var(--masque-couronne) center/contain no-repeat}
.premium-details summary::after{content:'▾'; margin-left:auto; color:var(--sage-text); transition:transform .15s var(--ease)}
.premium-details[open] summary::after{transform:rotate(180deg)}
.premium-details[open] summary{border-bottom:1.5px solid var(--sage); background:var(--sage-soft)}
/* H49 : onglets internes de la vue Profil (Foyer / Préférences de planning) + lignes « Temps en cuisine » */
.profil-tab-seg{display:inline-flex; gap:4px; padding:4px; border:1.5px solid var(--border); border-radius:999px; background:var(--surface-2); margin-bottom:16px}
.profil-tab-seg button{border:0; background:transparent; border-radius:999px; padding:8px 16px; font-weight:600; font-size:.88rem; color:var(--ink-2); cursor:pointer; font-family:inherit}
.profil-tab-seg button.on{background:var(--surface); color:var(--ink); box-shadow:0 1px 3px rgba(0,0,0,.08)}
.temps-rows{display:grid; grid-template-columns:1fr 1fr; gap:10px 14px; margin-bottom:12px}
.temps-row label{display:block; font-size:.82rem; font-weight:600; margin-bottom:4px}
.temps-row select{width:100%; padding:9px 12px; border-radius:11px; border:1px solid var(--border); background:var(--surface-2); font-size:.92rem}
.temps-row select:focus{border-color:var(--sage); box-shadow:0 0 0 3px var(--sage-soft); outline:none}
@media(max-width:480px){.temps-rows{grid-template-columns:1fr}}
/* H48 : réglages Budget repliés sous un résumé d'une ligne (« Ville · Moyenne grande surface · non bio · objectif 80 €/sem ») */
.budget-settings{margin-top:18px; border:1.5px solid var(--border); border-radius:var(--radius); background:var(--surface); overflow:hidden}
.budget-settings>summary{cursor:pointer; list-style:none; padding:14px 16px; display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.budget-settings>summary::-webkit-details-marker{display:none}
.budget-settings>summary .bs-title{font-weight:700; font-size:1rem}
.budget-settings>summary .bs-resume{font-size:.82rem; color:var(--muted); flex:1; min-width:160px}
.budget-settings>summary::after{content:'▾'; color:var(--muted); transition:transform .15s var(--ease)}
.budget-settings[open]>summary::after{transform:rotate(180deg)}
.budget-settings[open]>summary{border-bottom:1px solid var(--border)}
.budget-settings .bs-body{padding:6px 16px 16px}
.budget-settings .bs-more summary{cursor:pointer; font-size:.8rem; color:var(--muted)}
.budget-settings .bs-more p{font-size:.78rem; color:var(--muted); margin:6px 0 0; line-height:1.5}
.premium-details .premium-feature-list{padding:8px 10px 12px}
.premium-teaser{border:1.5px dashed var(--terra); background:var(--terra-soft)}
.modal-body>.premium-teaser{margin-bottom:0}
.premium-teaser .pt-badge{display:inline-flex; align-items:center; gap:5px; background:var(--terra); color:var(--on-accent); font-size:.7rem; font-weight:700; letter-spacing:.4px; text-transform:uppercase; padding:4px 10px; border-radius:999px; margin-bottom:10px}
.premium-teaser h2{color:var(--terra-text)}
.premium-teaser p{font-size:.86rem; color:var(--ink-2); margin:6px 0 14px; line-height:1.5}
.premium-teaser .pt-actions{display:flex; flex-wrap:wrap; align-items:center; gap:10px}
.premium-teaser .pt-actions .btn{flex:0 0 auto}
.pt-price{font-size:.76rem !important; color:var(--muted) !important; margin:10px 0 0 !important}
.waste-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:12px}
.waste-card{text-align:left; background:var(--surface-2); border:1px solid var(--border); border-radius:var(--radius-sm); padding:13px; transition:.18s var(--ease); cursor:pointer}
.waste-card:hover{border-color:var(--sage); transform:translateY(-2px); box-shadow:var(--shadow-sm)}
.waste-card .wc-top{display:flex; align-items:center; gap:9px}
.waste-card .we{font-size:1.6rem}
.waste-card .wn{font-weight:700; font-size:.88rem; flex:1}
.waste-pct{font-size:.72rem; font-weight:800; padding:3px 8px; border-radius:999px}
.waste-pct.full{background:var(--sage-soft); color:var(--sage-text)}
.waste-pct.partial{background:#F6EAD2; color:#9A7B25}
html[data-theme="dark"] .waste-pct.partial{background:#3A3220; color:#E0B25A}
.waste-missing{font-size:.78rem; color:var(--muted); margin-top:7px; line-height:1.4}
.expiring-list{display:flex; flex-direction:column; gap:8px}
.expiring-item{display:flex; align-items:center; gap:11px; padding:10px 13px; border-radius:11px; background:var(--surface-2); border:1px solid var(--border)}
.expiring-item.urgent{background:var(--danger-soft); border-color:color-mix(in srgb,var(--danger) 40%,transparent)}
.expiring-item .ei-em{font-size:1.3rem}
.expiring-item .ei-info{flex:1; min-width:0}
.expiring-item .ei-name{font-weight:700; font-size:.86rem}
.expiring-item .ei-date{font-size:.78rem; color:var(--muted)}
.expiring-item.urgent .ei-date{color:var(--danger)}
.ei-badge{font-size:.72rem; font-weight:800; padding:3px 9px; border-radius:999px; background:var(--sage-soft); color:var(--sage-text); white-space:nowrap}
.expiring-item.urgent .ei-badge{background:var(--danger); color:#fff}

/* ============ PRIX RÉELS (apprentissage local) ============ */
.price-learn-toggle{width:26px; height:26px; border-radius:8px; display:flex; align-items:center; justify-content:center; background:var(--surface-2); color:var(--muted); flex-shrink:0}
.price-learn-toggle:hover{background:var(--sand); color:var(--ink)}
.price-learn-toggle.has-learned{background:var(--sage-soft); color:var(--sage-text)}
.si-name-row{display:flex; align-items:center; gap:6px; flex-wrap:wrap}
.si-bio-toggle{font-size:.72rem; font-weight:700; padding:2px 8px; border-radius:20px; border:1px solid var(--border); color:var(--muted); background:var(--surface); flex-shrink:0; white-space:nowrap}
.si-bio-toggle:hover{border-color:var(--sage)}
.si-bio-toggle.on-bio{background:var(--sage-soft); color:var(--sage-text); border-color:var(--sage)}
.si-bio-toggle.on-non{background:var(--surface-2); color:var(--ink-2); border-color:var(--border)}
.price-learn-row{display:none; width:100%; margin-top:8px; padding:10px 12px; background:var(--surface); border:1px dashed var(--sage); border-radius:11px;
  align-items:center; gap:8px; flex-wrap:wrap}
.price-learn-row.show{display:flex}
.price-learn-row .plr-lab{font-size:.74rem; font-weight:700; color:var(--sage-text)}
.price-learn-row input{width:90px; padding:6px 9px; border-radius:8px; border:1px solid var(--border); background:var(--surface-2); font-weight:700; text-align:right}
.price-learn-row .plr-save{padding:6px 12px; border-radius:8px; background:var(--sage); color:var(--on-accent); font-size:.78rem; font-weight:700}
.price-learn-row .plr-save:hover{background:var(--sage-deep)}
.price-learn-row .plr-note{font-size:.78rem; color:var(--muted); width:100%}
/* Équivalent en cas de rupture (voir ingredientSubstitute) : replié par défaut,
   déplié d'un geste devant le rayon vide. Même grammaire visuelle que la ligne
   « prix réel payé » juste au-dessus, en terracotta pour la distinguer. */
.si-subst-toggle{font-size:.72rem; font-weight:700; padding:4px 10px; border-radius:20px; border:1px solid var(--border);
  color:var(--muted); background:var(--surface); white-space:nowrap; flex-shrink:0}
.si-subst-toggle:hover{border-color:var(--terra-text); color:var(--terra-text)}
.si-subst-toggle.on{background:var(--terra-soft); color:var(--terra-text); border-color:var(--terra-text)}
.si-subst-row{display:none; width:100%; margin-top:8px; padding:10px 12px; background:var(--surface);
  border:1px dashed var(--terra); border-radius:11px; gap:8px; flex-wrap:wrap; align-items:baseline}
.si-subst-row.open{display:flex}
.si-subst-row .sr-lab{font-size:.74rem; font-weight:700; color:var(--terra-text)}
.si-subst-row .sr-txt{font-size:.8rem; color:var(--ink-2); line-height:1.5; flex:1; min-width:180px}
.learned-table{display:flex; flex-direction:column; gap:6px; margin-top:10px}
.learned-row{display:flex; align-items:center; justify-content:space-between; padding:8px 11px; background:var(--surface-2); border-radius:9px; font-size:.82rem}
.learned-row .lr-n{font-weight:600}
.learned-row .lr-p{font-weight:700; color:var(--sage-text)}

/* ============ COMPARATEUR COÛT OBJECTIF / RÉEL ============ */
.compare-card .cc-row{display:flex; gap:10px; align-items:center; margin-top:12px; flex-wrap:wrap}
.compare-card input{padding:9px 12px; border-radius:10px; border:1px solid var(--border); background:var(--surface-2); font-weight:700; width:130px}
.compare-result{margin-top:16px; border-radius:var(--radius); padding:15px 18px; display:flex; align-items:center; gap:12px; font-size:.9rem; line-height:1.5}
.compare-result.ok{background:var(--sage-soft); border:1px solid var(--sage); color:var(--sage-text)}
.compare-result.over{background:var(--danger-soft); border:1px solid color-mix(in srgb,var(--danger) 40%,transparent); color:var(--danger)}
.compare-result.under{background:#F6EAD2; border:1px solid #E0B25A; color:#9A7B25}
.compare-result .cr-ic{font-size:1.3rem; flex-shrink:0}

/* ============ PROFIL ============ */
.profile-grid{display:grid; grid-template-columns:1.1fr .9fr; gap:20px; align-items:start}
.profile-col-right{display:flex; flex-direction:column; gap:18px; min-width:0}
.profile-col-left{display:flex; flex-direction:column; gap:18px; min-width:0} /* H49 */
@media(max-width:860px){.profile-grid{grid-template-columns:1fr}}
.profile-card{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); padding:clamp(18px,3vw,26px); box-shadow:var(--shadow-sm)}
.profile-card h2{font-size:1.2rem; margin-bottom:4px}
.profile-card .pc-sub{color:var(--muted); font-size:.88rem; margin-bottom:18px}
.seg{display:flex; flex-wrap:wrap; gap:6px}
.seg button{flex:1; min-width:74px; padding:9px 10px; border-radius:11px; border:1px solid var(--border); background:var(--surface-2);
  font-size:.82rem; font-weight:600; color:var(--ink-2); transition:.16s var(--ease); text-align:center}
.seg button:hover{border-color:var(--sage); color:var(--sage-text)}
.seg button.on{background:var(--sage); color:var(--on-accent); border-color:var(--sage); box-shadow:0 2px 8px rgba(127,176,105,.3)}
html[data-theme="dark"] .seg button.on{color:var(--on-accent)}
.seg.terra button.on{background:var(--terra); border-color:var(--terra-text); box-shadow:0 2px 8px rgba(201,123,90,.3)}
.seg-help{font-size:.8rem; color:var(--muted); margin-top:8px; line-height:1.45; min-height:1.2em}
.tdee-panel{display:flex; flex-direction:column; gap:14px}
.tdee-hero{background:linear-gradient(135deg,var(--sage-soft),var(--surface-2)); border:1px solid var(--sage);
  border-radius:var(--radius); padding:20px; text-align:center}
.tdee-hero .th-lab{font-size:.74rem; text-transform:uppercase; letter-spacing:.6px; font-weight:700; color:var(--sage-text)}
.tdee-hero .th-val{font-family:var(--sans); font-weight:700; font-size:2.8rem; line-height:1.05; margin-top:4px; color:var(--ink)}
.tdee-hero .th-val small{font-size:1rem; color:var(--muted); font-family:var(--sans)}
.tdee-hero .th-goal{font-size:.84rem; color:var(--ink-2); margin-top:6px; font-weight:600}
.tdee-row{display:grid; grid-template-columns:1fr 1fr; gap:12px}
.tdee-box{background:var(--surface-2); border:1px solid var(--border); border-radius:12px; padding:13px; text-align:center}
.tdee-box .tv{font-family:var(--sans); font-weight:700; font-size:1.5rem; line-height:1}
.tdee-box .tl{font-size:.7rem; color:var(--muted); text-transform:uppercase; letter-spacing:.4px; margin-top:3px; font-weight:600}
.profile-empty{text-align:center; color:var(--muted); padding:20px 10px}
.profile-empty .pe-em{font-size:2.6rem}

/* ============ BUDGET ============ */
.budget-cats{display:flex; flex-direction:column; gap:10px; margin-top:14px}
.budget-cat-row{display:grid; grid-template-columns:170px 1fr 70px; align-items:center; gap:10px; font-size:.84rem}
.budget-cat-row .bc-lab{font-weight:600; color:var(--ink-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.bc-bar{height:9px; border-radius:999px; background:var(--surface-2); overflow:hidden}
.bc-bar i{display:block; height:100%; background:var(--terra); border-radius:999px; transition:width .6s var(--ease)}
.bc-val{font-weight:700; text-align:right; font-variant-numeric:tabular-nums}
@media(max-width:560px){.budget-cat-row{grid-template-columns:1fr; gap:4px}.bc-val{text-align:left}}
/* 30/09/2026 — Budget vivant (app.js, « BUDGET VIVANT ») : montants qui défilent,
   barres qui poussent puis répondent au doigt, cocotte dans le verdict. */
.montant-anime{font-variant-numeric:tabular-nums}
.bc-touche{cursor:pointer; margin:0 -8px; padding:6px 8px; border-radius:10px; -webkit-tap-highlight-color:transparent;
  transition:background .2s var(--ease), opacity .2s var(--ease)}
.bc-touche .bc-bar i{transition:width .6s var(--ease), box-shadow .25s var(--ease), filter .25s var(--ease)}
.bc-detail{grid-column:1/-1; display:none; font-size:.8rem; color:var(--ink-2); line-height:1.4}
.budget-cats.has-vise .bc-touche:not(.is-vise){opacity:.55}
.bc-touche.is-vise{background:var(--terra-soft)}
.bc-touche.is-vise .bc-bar i{box-shadow:0 0 10px color-mix(in srgb,var(--terra) 70%,transparent); filter:brightness(1.08)}
.bc-touche.is-vise .bc-detail{display:block}
@media(hover:hover){ .bc-touche:hover .bc-bar i{box-shadow:0 0 8px color-mix(in srgb,var(--terra) 55%,transparent)} }
.bilan-verdict.has-coco, .compare-result.has-coco{align-items:center}
.bv-coco{flex:0 0 auto; width:56px; line-height:0}
.bv-coco .jeu-coco{width:56px; height:47px}
@media (prefers-reduced-motion:no-preference){
  .bc-pousse .bc-bar i{transform-origin:0 50%; animation:bcPousse .7s cubic-bezier(.2,.9,.3,1.1) both; animation-delay:calc(var(--i,0) * 45ms)}
  .bc-touche.is-vise .bc-detail{animation:bcDetail .25s var(--ease) both}
  .bilan-verdict.has-coco .bv-coco, .compare-result.has-coco .bv-coco{animation:bvCoco .55s cubic-bezier(.2,1.5,.4,1) .15s both}
}
@keyframes bcPousse{from{transform:scaleX(0)}}
@keyframes bcDetail{from{opacity:0; transform:translateY(-3px)}}
@keyframes bvCoco{from{opacity:0; transform:translateY(8px) scale(.8)}}
.rcard-price{font-weight:700; font-size:.85rem; color:var(--terra-text)}
.rcard-price small{color:var(--muted); font-weight:500}
.rcard-foot-left{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; min-width:0}
.rcard-price, .rcard-kcal{white-space:nowrap}

/* ---- multi-profil tabs ---- */
.profile-tabs{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:18px}
.ptab{display:flex; align-items:center; gap:8px; padding:7px 8px 7px 14px; border-radius:999px; border:1.6px solid var(--border);
  background:var(--surface); font-weight:700; font-size:.86rem; color:var(--ink-2); transition:.16s var(--ease)}
.ptab:hover{border-color:var(--sage)}
.ptab.on{background:var(--sage-soft); border-color:var(--sage); color:var(--sage-text)}
.ptab .ptab-x{width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); color:var(--muted); flex-shrink:0; position:relative}
.ptab .ptab-x::before{content:'';position:absolute; top:50%; left:50%; width:36px; height:36px; transform:translate(-50%,-50%)}
.ptab .ptab-x:hover{background:var(--danger-soft); color:var(--danger)}
.ptab .ptab-x svg{width:11px; height:11px}
.ptab-add{display:flex; align-items:center; gap:6px; padding:7px 14px 7px 12px; border-radius:999px; border:1.6px dashed var(--border);
  background:transparent; font-weight:700; font-size:.86rem; color:var(--ink-2); transition:.16s var(--ease); cursor:pointer}
.ptab-add svg{width:16px; height:16px; flex-shrink:0}
.ptab-add:hover{border-color:var(--sage); border-style:solid; color:var(--sage-text)}
.courses-day-filter{margin-bottom:12px}
.cdf-label{font-size:.78rem;color:var(--muted);margin-bottom:6px;font-weight:600}
.cdf-chips{display:flex; flex-wrap:wrap; gap:6px}
.day-chip{padding:6px 12px; border-radius:999px; border:1.6px solid var(--border); background:var(--surface);
  font-weight:700; font-size:.78rem; color:var(--muted); transition:.16s var(--ease); text-transform:capitalize}
.day-chip:hover{border-color:var(--sage)}
.day-chip.on{background:var(--sage-soft); border-color:var(--sage); color:var(--sage-text)}

/* ---- avatars de profil sur les repas ---- */
.slot-profiles{display:flex; gap:3px; margin-top:4px; flex-wrap:wrap}
.pchip{width:18px; height:18px; border-radius:50%; background:var(--sage); color:var(--on-accent); font-size:.72rem; font-weight:700;
  display:flex; align-items:center; justify-content:center; flex-shrink:0; border:1.5px solid var(--surface)}
html[data-theme="dark"] .pchip{color:var(--on-accent)}
.po-profiles{display:flex; flex-wrap:wrap; gap:6px; padding:10px 4px 2px}
.po-pchip{display:flex; align-items:center; gap:5px; padding:5px 10px 5px 6px; border-radius:999px; border:1.4px solid var(--border);
  background:var(--surface-2); font-size:.78rem; font-weight:700; color:var(--muted); transition:.15s var(--ease)}
.po-pchip .pdot{width:16px; height:16px; border-radius:50%; background:var(--border-2); color:#fff; font-size:.72rem;
  display:flex; align-items:center; justify-content:center; flex-shrink:0}
.po-pchip.on{border-color:var(--sage); background:var(--sage-soft); color:var(--sage-text)}
.po-pchip.on .pdot{background:var(--sage)}
html[data-theme="dark"] .po-pchip.on .pdot{color:var(--on-accent)}

/* ---- statut "cuisiné" ---- */
.slot-cooked-badge{position:absolute; top:7px; right:7px; width:22px; height:22px; border-radius:50%; background:var(--sage);
  color:#fff; display:flex; align-items:center; justify-content:center; box-shadow:var(--shadow-sm)}
html[data-theme="dark"] .slot-cooked-badge{color:var(--on-accent)}
.slot-cooked-badge svg{width:13px; height:13px}
.po-cook-btn{display:flex; align-items:flex-start; gap:9px; width:100%; padding:10px 12px; border-radius:11px; font-weight:700;
  font-size:.88rem; background:var(--sage-soft); color:var(--sage-text); margin:8px 0 2px; transition:.15s var(--ease); text-align:left}
.po-cook-btn:hover{background:var(--sage); color:var(--on-accent)}
.po-cook-btn.is-on{background:var(--sage); color:var(--on-accent)}
.po-cook-btn svg{width:17px; height:17px; flex-shrink:0; margin-top:1px}
.po-cook-btn span{text-align:left; flex:1}
/* 05/10/2026 : le repas de l'heure. Carte cerclée de sauge et étiquette « C'est l'heure »
   dans la grille ; gros bouton du mode cuisine en tête du popover ; bandeau au-dessus
   de la semaine ; « Cuisiner maintenant » sur la fiche. */
.slot.filled.is-now{outline:3px solid var(--sage); outline-offset:2px}
.slot-now-tag{display:inline-flex; align-items:center; gap:4px; font-size:.76rem; font-weight:800; color:var(--on-accent);
  background:var(--sage); border-radius:999px; padding:2px 8px 2px 6px; margin-top:3px; justify-self:start; align-self:flex-start; width:fit-content; max-width:100%; white-space:nowrap}
.slot-now-tag .ic{width:12px; height:12px; flex-shrink:0}
.po-cook-hero{display:flex; align-items:center; gap:12px; width:100%; min-height:64px; padding:12px 14px; margin:8px 0 6px;
  border-radius:16px; background:var(--sage); color:var(--on-accent); text-align:left; box-shadow:var(--shadow-sm); transition:.15s var(--ease)}
.po-cook-hero:hover{background:var(--sage-text); color:#fff}
.po-cook-hero .pch-ico{width:40px; height:40px; border-radius:12px; background:rgba(255,255,255,.2); display:flex; align-items:center; justify-content:center; flex-shrink:0}
.po-cook-hero .pch-ico .ic{width:22px; height:22px}
.po-cook-hero .pch-txt{display:flex; flex-direction:column; gap:2px; min-width:0}
.po-cook-hero strong{font-size:1rem; font-weight:800}
.po-cook-hero small{font-size:.78rem; font-weight:600; opacity:.9}
.cook-now-banner{margin:0 0 14px; display:flex; align-items:center; gap:12px; flex-wrap:wrap; border:1.5px solid var(--sage)}
.cook-now-banner .cnb-txt{flex:1 1 180px; display:flex; flex-direction:column; gap:1px; min-width:0}
.cook-now-banner .cnb-titre{font-size:.72rem; font-weight:800; text-transform:uppercase; letter-spacing:.04em}
.cook-now-banner .cnb-nom{font-size:1rem; font-weight:800; color:var(--ink)}
.cook-now-banner .cnb-meta{font-size:.78rem; font-weight:600; opacity:.85}
.cook-now-banner .cnb-go{display:inline-flex; align-items:center; gap:8px; min-height:48px; padding:0 18px}
.cook-now-banner .cnb-go .ic{width:18px; height:18px}
.cook-now-banner .cnb-x{background:none; border:none; color:inherit; font-size:1rem; cursor:pointer; opacity:.6; min-width:38px; min-height:38px}
/* 05/10/2026 : menus à thème, en tête du Livre. Le menu de la semaine en grande carte,
   les autres en rangée qui défile ; l'écran du menu coche les dîners à garder. */
.menus-theme{margin:4px 0 16px}
.mt-une{display:flex; flex-direction:column; align-items:flex-start; gap:4px; width:100%; text-align:left; padding:16px 18px;
  border-radius:var(--radius-lg); background:var(--sage-soft); color:var(--sage-text); border:2px solid var(--sage); cursor:pointer;
  box-shadow:0 4px 0 var(--sage); transition:transform .12s var(--ease), box-shadow .12s var(--ease)}
.mt-une:active{transform:translateY(3px); box-shadow:0 1px 0 var(--sage)}
.mt-une-kicker{font-size:.72rem; font-weight:800; text-transform:uppercase; letter-spacing:.05em}
.mt-une-titre{font-size:1.25rem; font-weight:800; color:var(--ink); line-height:1.2}
.mt-une-sous{font-size:.86rem; font-weight:600; line-height:1.4}
.mt-une-plats{display:grid; grid-template-columns:repeat(7,minmax(0,40px)); gap:5px; width:100%; font-size:1.25rem; margin:6px 0 2px}
.mt-une-plats span{aspect-ratio:1; border-radius:11px; background:var(--surface); display:flex; align-items:center; justify-content:center}
.mt-une-cta{display:inline-flex; align-items:center; min-height:44px; margin-top:4px; padding:0 18px; border-radius:999px;
  background:var(--sage); color:var(--on-accent); font-weight:800; font-size:.92rem}
.mt-autres-titre{font-size:.72rem; font-weight:800; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin:14px 2px 6px}
.mt-autres{display:flex; gap:8px; overflow-x:auto; padding:2px 2px 6px; scrollbar-width:none; -webkit-overflow-scrolling:touch}
.mt-autres::-webkit-scrollbar{display:none}
.mt-autre{flex:0 0 auto; display:inline-flex; align-items:center; gap:8px; min-height:48px; padding:0 16px 0 10px; border-radius:16px;
  background:var(--surface); border:1.5px solid var(--border); color:var(--ink); font-weight:700; font-size:.88rem; cursor:pointer; white-space:nowrap}
.mt-autre:hover{border-color:var(--sage)}
.mt-autre-em{font-size:1.2rem}
.mt-semaine{display:flex; gap:8px; margin:0 0 12px; flex-wrap:wrap}
.mt-semaine .chip{display:inline-flex; flex-direction:column; align-items:flex-start; gap:1px; min-height:48px; padding:6px 14px; line-height:1.2}
.mt-semaine .chip small{font-size:.72rem; font-weight:600; opacity:.8}
.mt-liste{display:flex; flex-direction:column; gap:8px}
.mt-ligne{display:flex; align-items:center; gap:12px; width:100%; min-height:60px; padding:8px 12px; border-radius:14px; text-align:left;
  background:var(--surface); border:1.5px solid var(--border); color:var(--ink); cursor:pointer; opacity:.6; transition:.12s var(--ease)}
.mt-ligne.on{opacity:1; border-color:var(--sage); background:var(--sage-soft)}
.mt-coche{width:26px; height:26px; flex-shrink:0; border-radius:8px; border:2px solid var(--border-2); display:flex; align-items:center; justify-content:center}
.mt-ligne.on .mt-coche{background:var(--sage); border-color:var(--sage); color:var(--on-accent)}
.mt-coche svg{width:16px; height:16px}
.mt-em{font-size:1.5rem; flex-shrink:0}
.mt-txt{display:flex; flex-direction:column; gap:2px; min-width:0}
.mt-txt strong{font-size:.95rem; line-height:1.25}
.mt-txt small{font-size:.78rem; color:var(--muted); font-weight:600}
.btn-cuisiner-now{display:inline-flex; align-items:center; justify-content:center; gap:7px}
.btn-cuisiner-now .ic{width:18px; height:18px}

/* bilan calorique */
.bilan{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); padding:clamp(18px,3vw,26px); box-shadow:var(--shadow-sm)}
.bilan-head{display:flex; align-items:center; gap:10px; margin-bottom:6px}
.bilan-head h2{font-size:1.4rem}
.bilan-verdict{border-radius:var(--radius); padding:15px 18px; display:flex; align-items:flex-start; gap:12px; margin:14px 0 18px; font-size:.92rem; line-height:1.5}
.bilan-verdict .bv-ic{width:34px; height:34px; border-radius:50%; flex-shrink:0; display:flex; align-items:center; justify-content:center; font-size:1.2rem}
.bilan-verdict.ok{background:var(--sage-soft); border:1px solid var(--sage); color:var(--sage-text)}
.bilan-verdict.over{background:var(--terra-soft); border:1px solid color-mix(in srgb,var(--terra) 45%,transparent); color:var(--terra-text)}
.bilan-verdict.under{background:#F6EAD2; border:1px solid #E0B25A; color:#9A7B25}
html[data-theme="dark"] .bilan-verdict.under{background:#3A3220; color:#E0B25A}
.bilan-verdict.neutral{background:var(--surface-2); border:1px solid var(--border); color:var(--ink-2)}
.bilan-verdict strong{font-weight:700}
.bilan-days{display:grid; grid-template-columns:repeat(7,1fr); gap:7px; margin-top:6px}
@media(max-width:620px){.bilan-days{grid-template-columns:repeat(4,1fr)}}
.bday{background:var(--surface-2); border:1px solid var(--border); border-radius:11px; padding:9px 6px; text-align:center}
.bday .bd-day{font-size:.72rem; font-weight:700; text-transform:capitalize}
.bday .bd-kcal{font-size:.82rem; font-weight:700; margin-top:4px}
.bday .bd-dot{width:8px; height:8px; border-radius:50%; margin:5px auto 0}
.bday.st-ok .bd-dot{background:var(--sage)} .bday.st-ok{border-color:var(--sage)}
.bday.st-over .bd-dot{background:var(--terra)} .bday.st-over{border-color:color-mix(in srgb,var(--terra) 50%,transparent)}
.bday.st-under .bd-dot{background:#E0B25A} .bday.st-under{border-color:#E0B25A}
.bday.st-empty{opacity:.5} .bday.st-empty .bd-dot{background:var(--border-2)}
.bday.st-partial .bd-dot{background:var(--muted)}
.bilan-tips{margin-top:18px}
.bilan-tips .bt-lab{font-size:.74rem; font-weight:700; text-transform:uppercase; letter-spacing:.6px; color:var(--muted); margin-bottom:8px}
.bilan-tip{display:flex; align-items:flex-start; gap:10px; padding:11px 14px; background:var(--surface-2); border:1px solid var(--border);
  border-radius:11px; margin-bottom:8px; font-size:.88rem; line-height:1.45}
.bilan-tip .bt-em{font-size:1.1rem; flex-shrink:0}

/* Micronutriments de la semaine (22/09/2026) : grille de jauges + cartes « à rattraper ».
   Uniquement des variables de la charte ; la teinte du palier vient de --sage / --terra /
   #E0B25A, les mêmes que les pastilles calories par jour (.bday.st-*). */
.micro-bilan .bt-lab{font-size:.74rem; font-weight:700; text-transform:uppercase; letter-spacing:.6px; color:var(--muted); margin-bottom:8px}
.micro-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:8px}
.micro-cell{padding:8px 10px; border:1px solid var(--border); border-radius:11px; background:var(--surface-2); font-size:.76rem; line-height:1.35}
.micro-cell .mc-top{display:flex; justify-content:space-between; gap:6px; align-items:baseline}
.micro-cell .mc-lab{font-weight:700; color:var(--ink); min-width:0}
.micro-cell .mc-pct{font-weight:700; color:var(--ink-2); font-variant-numeric:tabular-nums; white-space:nowrap; flex-shrink:0}
.micro-cell .mc-bar{height:6px; border-radius:999px; background:var(--border); margin:6px 0 4px; overflow:hidden}
.micro-cell .mc-bar i{display:block; height:100%; border-radius:999px; background:var(--sage)}
.micro-cell .mc-val{color:var(--muted); font-variant-numeric:tabular-nums}
.micro-cell .mc-val span{opacity:.8}
.micro-juste .mc-bar i, .micro-limite .mc-bar i{background:#E0B25A}
.micro-manque .mc-bar i, .micro-trop .mc-bar i{background:var(--terra)}
.micro-manque, .micro-trop{border-color:color-mix(in srgb,var(--terra) 50%,transparent)}
.micro-juste, .micro-limite{border-color:#E0B25A}
.micro-rattrap{padding:11px 14px; border:1px solid var(--border); border-radius:11px; background:var(--surface-2); margin-bottom:8px; font-size:.86rem; line-height:1.45}
.micro-rattrap.micro-ok{border-color:var(--sage)}
.micro-rattrap .mr-head{color:var(--ink)}
.micro-rattrap .mr-txt{margin:6px 0 0; color:var(--ink-2); font-size:.82rem}
.micro-rattrap .mr-src{display:block; margin-top:3px; font-size:.72rem; color:var(--muted); text-decoration:underline}
.micro-rattrap .mr-sugg{display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-top:8px; font-size:.78rem; color:var(--muted)}
.mr-chip{border:1px solid var(--border); background:var(--surface); color:var(--ink); border-radius:999px; padding:5px 10px; font:inherit; font-size:.78rem; cursor:pointer; line-height:1.3}
.mr-chip small{color:var(--muted); font-weight:600}
.mr-chip:hover{border-color:var(--sage)}
.micro-note{font-size:.74rem; color:var(--muted); margin:10px 2px 0; line-height:1.5}
.micro-note a{color:inherit; text-decoration:underline}
.micro-chips{display:flex; flex-wrap:wrap; gap:6px}
.micro-chip{display:inline-flex; align-items:baseline; gap:4px; padding:4px 9px; border-radius:999px; border:1px solid var(--border); background:var(--surface-2); font-size:.76rem; color:var(--ink-2); line-height:1.3}
.micro-chip b{color:var(--ink); font-weight:700}
.micro-chip small{color:var(--muted)}
.micro-chip.is-strong{border-color:var(--sage)}
.micro-chip-max.is-strong{border-color:#E0B25A}

/* bandeau suggestions dans le sélecteur */
.sel-suggest-banner{display:flex; align-items:center; gap:10px; background:var(--sage-soft); border:1px solid var(--sage);
  border-radius:12px; padding:11px 14px; margin-top:14px; font-size:.86rem; color:var(--sage-text); font-weight:600}
.sel-suggest-banner svg{width:18px; height:18px; flex-shrink:0}
.sel-card{position:relative}
/* Le badge est calé À GAUCHE du bouton ➕ d'ajout rapide (.sel-card-quickadd,
   28px + 8px de marge = 44px réservés à droite) : les deux étaient auparavant
   positionnés en top/right:8px et se chevauchaient. L'ellipse évite qu'un
   libellé long ("🌍 préférée") ne repasse sous le bouton. */
.sel-reco{position:absolute; top:8px; right:44px; left:auto; background:var(--sage); color:var(--on-accent); font-size:.72rem; font-weight:700;
  padding:2px 7px; border-radius:999px; letter-spacing:.3px;
  max-width:calc(100% - 90px); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
html[data-theme="dark"] .sel-reco{color:var(--on-accent)}
.sel-card .vote-badge{top:8px; left:8px; right:auto; width:20px; height:20px; font-size:.78rem}

/* recap objectif perso */
.recap-goal .rv.on-track{color:var(--sage-text)} .recap-goal .rv.off-track{color:var(--terra-text)}
.recap-goal .rg-note{font-size:.76rem; color:var(--muted); margin-top:4px}
.recap-goal-multi{display:flex; flex-direction:column; gap:5px; margin-top:4px}
.rgm-row{display:flex; align-items:baseline; gap:8px; font-size:.82rem}
.rgm-name{font-weight:700; min-width:64px}
.rgm-val{font-family:var(--sans); font-weight:700; font-size:1rem}
.rgm-val small{font-size:.76rem; color:var(--muted); font-family:var(--sans)}
.rgm-val.on-track{color:var(--sage-text)} .rgm-val.off-track{color:var(--terra-text)}
.rgm-note{font-size:.78rem; color:var(--muted); margin-left:auto}

/* responsive header — sous 880px, la navigation devient une barre d'onglets
   fixée en bas de l'écran (ergonomie pouce + convention app native iOS),
   à la place de l'ancien menu hamburger. */
@media(max-width:880px){
  .nav-toggle{display:none}            /* plus de hamburger : la nav est toujours visible en bas */
  .main-nav{
    position:fixed; left:0; right:0; bottom:0; z-index:45;
    margin:0; padding:6px 4px calc(6px + env(safe-area-inset-bottom));
    gap:2px; border:none; border-top:1px solid var(--border); border-radius:0;
    background:var(--surface);
    box-shadow:0 -4px 20px rgba(40,32,18,.10);
    justify-content:space-around;
  }
  .main-nav.open{display:flex}         /* la classe .open (ancien toggle) n'a plus d'effet */
  .nav-btn{
    flex:1 1 0; flex-direction:column; gap:3px; justify-content:center;
    padding:6px 2px; border-radius:12px; font-size:.75rem; font-weight:600;
    min-width:0; max-width:88px;
  }
  .nav-btn svg{width:22px; height:22px}
  .nav-lab-long{display:none}
  .nav-lab-short{display:inline}
  /* En barre d'onglets, on ne remplit pas le bouton actif : on colore
     seulement l'icône + le label (plus léger, plus lisible). */
  .nav-btn.active{background:transparent; color:var(--sage-text); box-shadow:none}
  html[data-theme="dark"] .nav-btn.active{color:var(--sage)}
  .nav-btn:hover{background:transparent}
  .nav-badge{top:2px; right:calc(50% - 22px)}
  .nav-badge-dot{top:6px; right:calc(50% - 14px)}
  .brand-name{font-size:1.12rem}
  /* le contenu doit pouvoir défiler au-dessus de la barre d'onglets */
  .view-wrap{padding-bottom:calc(78px + env(safe-area-inset-bottom))}
  /* 14/10/2026 (audit F7, WCAG 2.2 « focus non masqué ») : un élément atteint au clavier ne
     s'arrête jamais sous la barre d'onglets fixe. */
  html{scroll-padding-bottom:calc(86px + env(safe-area-inset-bottom))}
  /* les toasts doivent apparaître au-dessus de la barre d'onglets, pas derrière */
  .toast-wrap{bottom:calc(90px + env(safe-area-inset-bottom))}

  /* ===== Vue Semaine — agencement mobile propre, distinct du desktop =====
     Sur desktop, .week-actions est une rangée qui wrap librement (bouton
     magique + Vue jour + menu "Plus" + sélecteur de semaine). Sur mobile ça
     produisait un empilement confus avant même d'arriver au contenu. Ici :
     1) "Suggérer ma semaine" reste seule, pleine largeur (l'action
     principale) ; 2) une seconde ligne unique : bascule Jour/Semaine |
     Aujourd'hui | ‹ semaine › | menu "Plus" (Partager / Dupliquer / Batch
     cooking / Tout supprimer). F39 : les deux boutons gardent un libellé court
     visible (« Jour »/« Semaine », « Plus ») — les icônes seules n'étaient pas
     comprises. La barre est une grille à 4 colonnes : les deux boutons à
     libellé prennent leur largeur naturelle, le sélecteur de semaine absorbe
     le reste ; « Aujourd'hui » (masqué sur la semaine courante) se glisse
     entre les deux quand il apparaît. */
  #view-semaine .week-actions{ display:flex; flex-wrap:wrap; gap:8px; row-gap:16px; width:100%; }
  #view-semaine .week-actions .btn-magic{ order:1; flex:1 1 100%; }
  #view-semaine .week-actions .week-bar-mobile{
    order:2; flex:1 1 100%; display:flex; align-items:center; gap:6px; min-width:0;
  }
  #view-semaine .week-actions .week-bar-mobile .btn-soft,
  #view-semaine .week-actions .week-menu-wrap #weekMoreBtn{ padding:9px 9px; gap:5px; font-size:.78rem; white-space:nowrap; flex:0 0 auto }
  #view-semaine .week-actions .week-bar-mobile .btn svg{ width:15px; height:15px }
  #view-semaine .week-actions .week-menu-wrap{ flex:0 0 auto; margin-left:auto }
  #view-semaine .week-actions .week-menu{ right:0; left:auto }
  #view-semaine .week-actions .week-nav-row{ flex:1 1 0; min-width:0; display:flex; align-items:center; justify-content:center; gap:6px; }
  #view-semaine .week-actions .week-nav-row #goTodayBtn{ padding:9px 9px; font-size:.78rem; flex:0 0 auto }
  #view-semaine .week-actions .week-nav-row #goTodayBtn .cw-label{ display:none }
  #view-semaine .week-actions .week-nav{ flex:1 1 0; min-width:0; justify-content:space-between; gap:6px; padding:3px }
  #view-semaine .week-actions .week-nav button{ width:32px; height:32px; flex:0 0 auto }
  #view-semaine .week-actions .week-nav>div{ min-width:0 }
  #view-semaine .week-actions .week-nav .week-today{ font-size:.72rem; letter-spacing:.3px; margin-top:1px }

  /* Le selecteur de semaine est du CONTEXTE : il situe, il n'agit pas.
     Il garde ses chevrons cliquables mais perd le trait d'encre et
     l'ombre, sinon il rivalise avec le bouton d'action juste au-dessus. */
  #view-semaine .week-actions .week-nav{
    border:1px solid var(--border-2); box-shadow:none; background:var(--surface-2);
  }
  /* « Jour/Semaine » et « Plus » sont des commandes de service. */
  #view-semaine .week-actions .week-bar-mobile > .btn-soft,
  #view-semaine .week-actions .week-menu-wrap > #weekMoreBtn{
    border:none; box-shadow:none; background:transparent;
    color:var(--muted); font-weight:600; padding:7px 6px;
  }
  #view-semaine .week-actions .week-bar-mobile > .btn-soft:active,
  #view-semaine .week-actions .week-menu-wrap > #weekMoreBtn:active{
    transform:none; opacity:.55;
  }
  /* La rangee de service se resserre : deux libelles, pas deux blocs. */
  #view-semaine .week-actions{ row-gap:12px }
  #view-semaine .week-actions .week-bar-mobile{ row-gap:2px }

  /* Sous 520px, les trois blocs de la barre ne tiennent plus sur une rangee :
     le selecteur n'obtenait qu'un tiers de la largeur et la date passait en
     « 31 Aout – 6 Se... ». Or la date EST l'information de ce controle. On lui
     donne donc sa propre rangee, et les deux boutons d'action se partagent
     celle du dessous. */
  @media(max-width:520px){
    #view-semaine .week-actions .week-bar-mobile{ flex-wrap:wrap; row-gap:8px }
    #view-semaine .week-actions .week-nav-row{ order:-1; flex:1 1 100% }
    #view-semaine .week-actions .week-nav{ flex:1 1 auto }
    #view-semaine .week-actions .week-nav .week-label{ font-size:.88rem }
    #view-semaine .week-actions .week-bar-mobile > .btn-soft{ flex:1 1 0 }
    #view-semaine .week-actions .week-menu-wrap{ flex:1 1 0 }
    #view-semaine .week-actions .week-menu-wrap #weekMoreBtn{ width:100%; justify-content:center }
    #view-semaine .week-actions .week-bar-mobile > .btn-soft{ justify-content:center }
  }
  /* La regle de base impose min-width:148px au libelle : sur mobile il exigeait
     a lui seul plus de la moitie de la rangee, et les boutons voisins (« Jour »,
     « Plus ») etaient ecrases pour la lui donner. Ici le libelle prend ce qui
     reste et s'ellipse s'il le faut. */
  #view-semaine .week-actions .week-nav .week-label{ min-width:0; font-size:.82rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }

  /* ===== Grille des jours — scroll-snap au lieu du glissement libre =====
     Chaque colonne de jour se cale proprement au lieu de s'arrêter à un
     endroit arbitraire. La colonne des repas (coin + libellés Petit-déj /
     Déjeuner / Dîner…) reste épinglée à gauche pendant le défilement, pour
     ne jamais perdre le repère du repas affiché. */
  .grid-scroll{
    scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch;
    scroll-padding-left:87px;
  }
  .week-grid .gh:not(.corner){ scroll-snap-align:start; }
  .week-grid .gh.corner, .week-grid .meal-label{
    position:sticky; left:0; z-index:2; background:var(--bg);
    box-shadow:4px 0 6px -4px rgba(0,0,0,.15);
  }
}
@media(max-width:420px){
  /* Sur les très petits écrans (ex. iPhone SE, ~320-375px), la marque +
     les 4 boutons icône (compte, import/export, thème, menu) dépassaient
     la largeur disponible dans le header. */
  .app-header{gap:8px; padding:calc(10px + env(safe-area-inset-top)) 12px 10px}
  .icon-btn{width:44px; height:44px}
  .icon-btn svg{width:17px; height:17px}
  .brand-name{font-size:1.08rem}
  .brand-mark{width:32px; height:32px}
  .premium-plans{grid-template-columns:1fr}
}
@media(max-width:560px){
  .field-row,.field-row-3{grid-template-columns:1fr}
  .detail-nut{grid-template-columns:repeat(2,1fr)}
  .view-head{align-items:stretch}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms !important; transition-duration:.001ms !important}
}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}

/* ==================================================================
   LOT 2 — SIGNATURE CANTINE
   ==================================================================
   Bloc volontairement place EN DERNIER et delimite : il surcharge les
   composants de base sans toucher aux 21 000 lignes qui les utilisent,
   et se retire d'un seul coup si la direction ne convient pas.

   Trois regles, pas une de plus :
     1. Trait de 2 px a l'encre sur les OBJETS et les COMMANDES.
        Pas sur les lignes de liste : 42 articles de courses bordes a
        l'encre, c'est un quadrillage, pas une charte.
     2. Ombre portee DECALEE ET SANS FLOU. Une ombre floue simule une
        elevation ; une ombre nette affirme un objet pose. Cantine est
        du papier, pas du verre.
     3. Ce qui porte une ombre dure doit pouvoir l'ecraser quand on
        appuie dessus. Sans l'enfoncement, le trait franc sonne faux.
   ================================================================== */
:root{
  --bw:2px;
  --shadow-hard:3px 3px 0 var(--ink);      /* objets qu'on touche */
  --shadow-flat:2px 2px 0 rgba(20,33,61,.16); /* cartes de contenu */
  --press:translate(3px,3px);
}
html[data-theme="dark"]{
  --shadow-flat:2px 2px 0 rgba(251,243,228,.14);
}

/* ---------- 1. Les objets ---------- */
/* LA REGLE : l'encre marque ce qu'on TOUCHE. Ce qu'on LIT reste en filet
   doux. Sans cette separation, chaque bloc de l'ecran parle aussi fort et
   la vue mobile devient une pile de cartes sans hierarchie — c'etait le
   defaut de la premiere passe. */
.profile-card,
.section-card,
.stock-add,
.collapsible-list,
.shop-items,
.expiring-item,
.rcard,
.slot.filled{
  border:var(--bw) solid var(--ink);
  box-shadow:var(--shadow-flat);
}
/* Tableaux de bord et recapitulatifs : on les lit, on ne les actionne pas. */
.bilan,
.nut-box,
.tdee-box,
.waste-card,
.shop-prog-card{
  border:1px solid var(--border);
  box-shadow:none;
  background:var(--surface-2);
}
/* 04/10/2026 : la carte a pris le fond de la piste, la barre à 0 % laissait un vide. */
.shop-prog-card .shop-prog-bar{ background:var(--border) }

/* La carte recette se soulevait au survol (translateY -4px). Un objet
   imprime ne levite pas : au survol l'ombre s'epaissit, au clic elle
   s'ecrase. Meme information — « ceci reagit » — sans la contradiction. */
.rcard:hover{
  transform:none; border-color:var(--ink);
  box-shadow:var(--shadow-hard);
}
.rcard:active{ transform:var(--press); box-shadow:0 0 0 var(--ink) }
.glass-panel,
.modal-card,
.week-menu{ border:var(--bw) solid var(--ink) }

/* Les lignes internes gardent un filet doux : c'est la CARTE qui est
   l'objet, pas chacune de ses lignes. */
.shop-item{ border-bottom:1px solid var(--border) }

/* ---------- 2. Les commandes ---------- */
.btn,
.chip,
.stepper,
.bday,
.week-nav,
.si-state,
.rayon-move,
.po-more,
.sel-fold{
  border:var(--bw) solid var(--ink);
}
.btn{
  box-shadow:var(--shadow-hard);
  transition:transform .08s ease, box-shadow .08s ease, background .18s var(--ease);
}
/* L'enfoncement remplace le survol qui soulevait : un objet imprime ne
   levite pas. On neutralise donc les anciens translateY de survol. */
.btn:hover{ transform:none }
.btn-primary:hover{ transform:none; box-shadow:var(--shadow-hard) }
.btn:active{ transform:var(--press); box-shadow:0 0 0 var(--ink) }

/* ---------- Hierarchie des commandes ----------
   Trois niveaux, et un seul premier niveau par ecran :
     1. .btn-magic          — encre + ombre dure. L'action de l'ecran.
     2. .btn-primary/.btn   — encre + ombre plate. Les actions reelles.
     3. fantome             — ni trait ni ombre. Les commandes de service
                              (bascule d'affichage, menu « Plus »), qui
                              n'ont aucune raison de peser autant qu'une
                              action. */
.btn-magic{ box-shadow:var(--shadow-hard) }
.btn-magic:active{ transform:var(--press); box-shadow:0 0 0 var(--ink) }
.btn:not(.btn-magic){ box-shadow:var(--shadow-flat) }
.btn:not(.btn-magic):hover{ box-shadow:var(--shadow-hard) }

.btn-ghost-ui{
  border:none !important; box-shadow:none !important; background:transparent !important;
  color:var(--muted); font-weight:600;
}
.btn-ghost-ui:hover{ color:var(--ink); background:var(--surface-2) !important }
.btn-ghost-ui:active{ transform:none; opacity:.6 }

/* Champs de saisie : ce sont des commandes, elles prennent le trait. */
.ing-row input, .ing-row select,
.extra-add-row input, .extra-add-row select,
.ing-search-box input,
.price-learn-row input,
.recipe-note-input,
.si-buy-field,
.compare-card input,
.temps-row select{
  border:var(--bw) solid var(--border-2);
}
.ing-row input:focus, .ing-search-box input:focus,
.recipe-note-input:focus, .si-buy-field:focus{
  border-color:var(--ink); outline:none;
}

/* ---------- 3. Les etiquettes ----------
   Le seul endroit ou l'on s'autorise une rotation : les libelles de
   type ticket. 1,2 degre — en dessous invisible, au-dessus bricolage.
   Jamais sur un champ, jamais sur la navigation. */
.nutri-badge{ border:var(--bw) solid var(--ink); transform:rotate(-1.2deg) }

/* ==================================================================
   ANIMATIONS
   ==================================================================
   transform et opacity uniquement : tout se joue sur le compositeur,
   sans recalcul de mise en page, y compris sur un vieil Android.
   ================================================================== */

/* Rature de la liste de courses : le trait se tire de gauche a droite,
   comme un crayon. text-decoration ne s'anime pas — d'ou le pseudo. */
.shop-item .si-name{ position:relative; display:inline-block }
.shop-item .si-name::after{
  content:""; position:absolute; left:0; right:0; top:54%; height:2px;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform .28s var(--ease); pointer-events:none;
}
.shop-item.checked .si-name{ text-decoration:none }
.shop-item.checked .si-name::after{ transform:scaleX(1) }

/* La coche se remplit d'un petit rebond plutot que d'apparaitre. */
.scheck{ transition:background .18s var(--ease), border-color .18s var(--ease) }
.shop-item.checked .scheck svg{ transform:scale(1); opacity:1 }
.shop-item.checked .scheck{ animation:ioumiCheck .26s cubic-bezier(.3,1.7,.5,1) }
@keyframes ioumiCheck{
  0%{ transform:scale(1) } 45%{ transform:scale(1.22) } 100%{ transform:scale(1) }
}

/* Un creneau qui vient d'etre rempli se pose comme un tampon. */
.slot.filled.ioumi-stamped{ animation:ioumiStamp .42s cubic-bezier(.2,1.5,.4,1) }
@keyframes ioumiStamp{
  0%{ transform:scale(1.14) rotate(-1.5deg); opacity:.6 }
  60%{ transform:scale(.98) rotate(.3deg); opacity:1 }
  100%{ transform:scale(1) rotate(0); opacity:1 }
}

@media (prefers-reduced-motion: reduce){
  .btn, .scheck, .shop-item .si-name::after{ transition:none !important }
  .shop-item.checked .scheck, .slot.filled.ioumi-stamped{ animation:none !important }
  .btn:active{ transform:none }
}
/* ==================================================================
   OBJECTIF DE LA SEMAINE ET CARNET
   ================================================================== */
#weekGoal:empty{ display:none }
/* Releve de progression : filet doux, comme les autres tableaux de bord.
   Il informe entre deux actions, il ne doit pas peser comme une commande. */
.wg{
  background:var(--surface-2); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:none;
  padding:12px 15px; margin:0 0 16px;
}
.wg-top{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-bottom:9px }
.wg-count{ font-family:var(--serif); font-size:1.35rem; line-height:1; font-variant-numeric:tabular-nums }
.wg-lab{ font-size:.72rem; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--muted) }
.wg-bar{
  height:14px; border:1px solid var(--border-2); border-radius:999px;
  background:var(--surface); padding:2px; overflow:hidden;
}
.wg-bar i{
  display:block; height:100%; border-radius:999px; background:var(--terra);
  width:0; transition:width .8s cubic-bezier(.25,1,.3,1);
}
.wg.is-done .wg-bar i{ background:var(--sage) }
.wg-foot{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:12px }
.wg-serie{ flex:1 1 auto; font-size:.8rem; color:var(--ink-2) }
.wg-serie b{ color:var(--ink); font-weight:700 }
.wg-gaspi{ display:block; margin-top:4px; font-size:.76rem; color:var(--sage-text); font-weight:600 }
.wg-stamps{ display:flex; gap:6px; flex:0 0 auto }
.wg-stamp{
  width:22px; height:22px; border-radius:50%; flex:0 0 auto;
  border:1px dashed var(--border-2); background:transparent;
}
.wg-stamp.on{ border-style:solid; border-color:var(--ink); background:var(--sage) }
.wg-stamp.blanche{ border-style:solid; border-color:var(--gold-deep); background:var(--gold) }
.wg-stamp.fresh{ animation:ioumiTampon .5s cubic-bezier(.2,1.5,.4,1) }
@keyframes ioumiTampon{
  0%{ transform:rotate(-24deg) scale(2.2); opacity:0 }
  55%{ transform:rotate(-6deg) scale(.9); opacity:1 }
  100%{ transform:rotate(0) scale(1); opacity:1 }
}
@media (prefers-reduced-motion: reduce){
  .wg-bar i{ transition:none !important }
  .wg-stamp.fresh{ animation:none !important }
}
/* ================= fin LOT 2 ================= */

/* ==================================================================
   LOT 3 — JEU : cocotte, anneau, défis, collection, récap
   ==================================================================
   Bloc autonome, placé après le LOT 2. Le JS est dans jeu.js.
   transform / opacity uniquement ; tout est coupé par prefers-reduced-motion
   en fin de bloc. Les couleurs viennent des variables de la charte Cantine.
   ================================================================== */

/* ---------- La cocotte ---------- */
.jeu-coco-wrap{ flex:0 0 auto; line-height:0 }
.jeu-coco{ width:112px; height:94px; overflow:visible; display:block; transform-origin:50% 90% }
/* 01/10/2026 (Paul : « un look spécial pour la cocotte quand on est Premium ») :
   une couronne dorée posée de biais sur le couvercle et deux éclats qui
   scintillent, pour les abonnés seulement. Avec une tenue sur la tête, la
   couronne s'efface et les éclats restent. */
.jeu-coco .jc-couronne, .jeu-coco .jc-premium{ display:none }
body.is-premium .jeu-coco .jc-couronne{ display:block; fill:var(--gold); stroke:var(--ink); stroke-width:2.6; stroke-linejoin:round; transform:rotate(-12deg); transform-origin:30px 36px; transform-box:view-box }
body.is-premium .jeu-coco.a-tenue .jc-couronne{ display:none }
body.is-premium .jeu-coco .jc-premium{ display:block }
.jeu-coco .jc-eclat{ fill:var(--gold); stroke:var(--ink); stroke-width:1.4; stroke-linejoin:round; transform-box:fill-box; transform-origin:center; animation:jcEclat 2.8s ease-in-out infinite }
.jeu-coco .jc-eclat2{ animation-delay:1.4s }
@keyframes jcEclat{ 0%,100%{ opacity:.25; transform:scale(.6) } 50%{ opacity:1; transform:scale(1.1) } }
@media (prefers-reduced-motion: reduce){ .jeu-coco .jc-eclat{ animation:none; opacity:1 } }
.jeu-coco-sm{ width:64px; height:54px }
.jeu-coco-md{ width:150px; height:125px; margin:0 auto }
.jeu-coco .jc-pot{ fill:var(--terra); stroke:var(--ink); stroke-width:3; stroke-linejoin:round }
.jeu-coco .jc-anse{ fill:none; stroke:var(--ink); stroke-width:3; stroke-linecap:round }
.jeu-coco .jc-couvercle rect, .jeu-coco .jc-couvercle circle{ fill:var(--gold); stroke:var(--ink); stroke-width:3 }
.jeu-coco .jc-couvercle{ transform-origin:60px 42px }
.jeu-coco .jc-corps{ transform-origin:60px 70px }
.jeu-coco .jc-joues circle{ fill:#fff; opacity:.38 }
.jeu-coco .jc-yeux circle{ fill:var(--ink) }
.jeu-coco .jc-yeux path, .jeu-coco .jc-b{ fill:none; stroke:var(--ink); stroke-width:3; stroke-linecap:round; stroke-linejoin:round }
.jeu-coco .jc-b-grand{ fill:var(--ink) }
.jeu-coco .jc-v{ fill:none; stroke:var(--sage); stroke-width:3.2; stroke-linecap:round; opacity:0; transform-origin:60px 34px }
.jeu-coco .jc-zzz{ font:700 11px var(--sans, Rubik, sans-serif); fill:var(--muted); opacity:0 }
.jeu-coco .jc-oeil-ouvert{ transform-origin:60px 61px }
/* Les pupilles glissent vers le pointeur ou le dernier point touché (jeu.js pose un transform inline). */
.jeu-coco .jc-regard{ transition:transform .28s cubic-bezier(.2,.9,.3,1.25) }
/* Tout masqué par défaut ; chaque état allume ce qu'il faut. */
.jeu-coco .jc-oeil-ouvert, .jeu-coco .jc-oeil-ferme, .jeu-coco .jc-oeil-joie, .jeu-coco .jc-b{ display:none }

[data-etat="dort"] .jc-oeil-ferme, [data-etat="dort"] .jc-b-dort{ display:block }
[data-etat="dort"] .jc-zzz{ opacity:1; animation:jeuZzz 2.6s ease-in-out infinite }
[data-etat="dort"] .jc-corps{ animation:jeuRespire 3.4s ease-in-out infinite }
[data-etat="dort"] .jc-couvercle{ transform:translateY(1px) rotate(-2deg) }

[data-etat="fremit"] .jc-oeil-ouvert, [data-etat="fremit"] .jc-b-calme{ display:block }
[data-etat="fremit"] .jc-v2{ opacity:.9; animation:jeuVapeur 2.4s ease-out infinite }

[data-etat="chauffe"] .jc-oeil-ouvert, [data-etat="chauffe"] .jc-b-sourire{ display:block }
[data-etat="chauffe"] .jc-v1, [data-etat="chauffe"] .jc-v3{ opacity:.9; animation:jeuVapeur 1.8s ease-out infinite }
[data-etat="chauffe"] .jc-v3{ animation-delay:.6s }
[data-etat="chauffe"] .jc-couvercle{ animation:jeuCouvercle 2.2s ease-in-out infinite }

[data-etat="bout"] .jc-oeil-joie, [data-etat="bout"] .jc-b-grand{ display:block }
[data-etat="bout"] .jc-v{ opacity:1; animation:jeuVapeur 1.1s ease-out infinite }
[data-etat="bout"] .jc-v2{ animation-delay:.35s } [data-etat="bout"] .jc-v3{ animation-delay:.7s }
[data-etat="bout"] .jc-couvercle{ animation:jeuCouvercle .9s ease-in-out infinite }
[data-etat="bout"] .jc-corps{ animation:jeuBouillon .9s ease-in-out infinite }

/* 30/09/2026 — inquiète : sourcils relevés au centre, bouche qui tremble, une goutte
   perle sur le côté. Pour « rien trouvé » et un budget qui déborde : elle s'inquiète
   pour elle-même, jamais un reproche (même visage que le widget « inquiete »). */
.jeu-coco .jc-sourcils path{ fill:none; stroke:var(--ink); stroke-width:2.6; stroke-linecap:round }
.jeu-coco .jc-goutte{ fill:#BFE3F2; stroke:var(--ink); stroke-width:2; stroke-linejoin:round; transform-origin:95px 57px }
.jeu-coco .jc-sourcils, .jeu-coco .jc-goutte{ display:none }
[data-etat="inquiete"] .jc-oeil-ouvert, [data-etat="inquiete"] .jc-b-inquiete, [data-etat="inquiete"] .jc-sourcils, [data-etat="inquiete"] .jc-goutte{ display:block }
[data-etat="inquiete"] .jc-goutte{ animation:jeuGoutte 2.8s ease-in infinite }
[data-etat="inquiete"] .jc-couvercle{ animation:jeuCouvercleInquiet 3.2s ease-in-out infinite }
[data-etat="inquiete"] .jc-v2{ opacity:.55; animation:jeuVapeur 3.4s ease-out infinite }
.jeu-coco.is-joie .jc-b-inquiete, .jeu-coco.is-miam .jc-b-inquiete, .jeu-coco.is-joie .jc-sourcils, .jeu-coco.is-miam .jc-sourcils, .jeu-coco.is-joie .jc-goutte, .jeu-coco.is-miam .jc-goutte{ display:none }
@keyframes jeuGoutte{ 0%,20%{ transform:translateY(-3px) scale(.6); opacity:0 } 35%{ opacity:1; transform:translateY(0) scale(1) } 80%{ opacity:1; transform:translateY(7px) scale(1,1.08) } 100%{ opacity:0; transform:translateY(10px) } }
@keyframes jeuCouvercleInquiet{ 0%,70%,100%{ transform:translate(0,0) } 74%{ transform:translate(-1px,0) rotate(-1.5deg) } 78%{ transform:translate(1px,0) rotate(1.5deg) } 82%{ transform:translate(-1px,0) rotate(-1deg) } 86%{ transform:translate(0,0) } }

/* Clignement : seulement sur les yeux ouverts. */
[data-etat="fremit"] .jc-oeil-ouvert, [data-etat="chauffe"] .jc-oeil-ouvert, [data-etat="inquiete"] .jc-oeil-ouvert{ animation:jeuCligne 4.2s ease-in-out infinite }

/* Réactions éphémères (classe posée par jeu.js, retirée après l'animation). */
.jeu-coco.is-puff .jc-v{ opacity:1; animation:jeuPuff .7s ease-out 1 }
.jeu-coco.is-puff .jc-corps{ animation:jeuSquash .5s cubic-bezier(.3,1.6,.5,1) 1 }
.jeu-coco.is-miam .jc-oeil-ouvert, .jeu-coco.is-miam .jc-oeil-ferme, .jeu-coco.is-miam .jc-b-calme, .jeu-coco.is-miam .jc-b-sourire, .jeu-coco.is-miam .jc-b-dort{ display:none }
.jeu-coco.is-miam .jc-oeil-joie, .jeu-coco.is-miam .jc-b-grand{ display:block }
.jeu-coco.is-miam .jc-corps{ animation:jeuMiam 1s ease-in-out 1 }
.jeu-coco.is-fete{ animation:jeuSaut 1.1s cubic-bezier(.4,0,.2,1) 1 }
.jeu-coco.is-fete .jc-couvercle{ animation:jeuCouvercleFete 1.1s cubic-bezier(.4,0,.2,1) 1 }
.jeu-coco.is-fete .jc-v{ opacity:1; animation:jeuVapeur .8s ease-out infinite }

/* Passe motion du 22/09 — visage de joie (posé pendant les scènes WAAPI), tics d'inactivité
   tirés au sort par jeu.js toutes les 5 à 10 s selon l'humeur, retirés à la fin. */
.jeu-coco.is-joie .jc-oeil-ouvert, .jeu-coco.is-joie .jc-oeil-ferme, .jeu-coco.is-joie .jc-b-calme, .jeu-coco.is-joie .jc-b-sourire, .jeu-coco.is-joie .jc-b-dort{ display:none }
.jeu-coco.is-joie .jc-oeil-joie, .jeu-coco.is-joie .jc-b-grand{ display:block }
.jeu-coco.is-baille .jc-b-dort{ display:none }
.jeu-coco.is-baille .jc-b-grand{ display:block; transform-origin:60px 70px; animation:jeuBaille 1.5s ease-in-out 1 }
.jeu-coco.is-baille .jc-couvercle{ animation:jeuBailleCouvercle 1.5s ease-in-out 1 }
.jeu-coco.is-baille .jc-zzz{ opacity:0; animation:none }
.jeu-coco.is-tressaute .jc-couvercle{ animation:jeuCouvercleFete .7s cubic-bezier(.4,0,.2,1) 1 }
.jeu-coco.is-tressaute .jc-corps{ animation:jeuSquash .7s cubic-bezier(.4,0,.2,1) 1 }
.jeu-coco.is-penche .jc-corps{ animation:jeuPenche 1.7s ease-in-out 1 }
.jeu-coco.is-penche .jc-couvercle{ animation:jeuPencheCouvercle 1.7s ease-in-out 1 }
@keyframes jeuBaille{ 0%,100%{ transform:scale(.35,.15) } 30%,70%{ transform:scale(1,1.2) } }
@keyframes jeuBailleCouvercle{ 0%,100%{ transform:translateY(1px) rotate(-2deg) } 30%,70%{ transform:translateY(-5px) rotate(-6deg) } }
@keyframes jeuPenche{ 0%,100%{ transform:rotate(0) } 25%,75%{ transform:rotate(-5deg) scale(1.02,.98) } }
@keyframes jeuPencheCouvercle{ 0%,100%{ transform:translate(0,0) rotate(0) } 25%,75%{ transform:translate(-2px,1px) rotate(-6deg) } }

@keyframes jeuVapeur{ 0%{ transform:translateY(6px) scale(.85); opacity:0 } 25%{ opacity:.95 } 100%{ transform:translateY(-14px) scale(1.15); opacity:0 } }

/* 25/10/2026 — Les expressions : le visage dit la phrase (data-expr, posé par jeu.js avec la
   bulle, voir EXPRESSIONS). Elles remplacent le visage de l'humeur ; vapeur, couvercle et
   réactions (miam, joie) restent ceux de l'humeur. Mêmes dessins que les widgets et les
   images des notifications (tools/widget_cocotte_images.py). */
.jeu-coco .jc-oeil-clin, .jeu-coco .jc-oeil-grand, .jeu-coco .jc-oeil-pense, .jeu-coco .jc-oeil-ennui,
.jeu-coco .jc-sourcils-haut, .jeu-coco .jc-sourcils-leve, .jeu-coco .jc-x > *, .jeu-coco .jc-x-rougeur{ display:none }
.jeu-coco .jc-sourcils-haut path, .jeu-coco .jc-sourcils-leve path{ fill:none; stroke:var(--ink); stroke-width:2.6; stroke-linecap:round }
.jeu-coco .jc-yeux .jc-plein, .jeu-coco .jc-b-o, .jeu-coco .jc-b-parle{ fill:var(--ink); stroke:none }
.jeu-coco .jc-x-rougeur circle{ fill:#fff; opacity:.3 }
.jeu-coco .jc-x-rougeur path{ fill:none; stroke:var(--ink); stroke-width:1.6; stroke-linecap:round; opacity:.55 }
.jeu-coco .jc-x-pense circle{ fill:var(--ink); animation:jcPoint 1.2s ease-in-out infinite }
.jeu-coco .jc-x-pense circle:nth-child(2){ animation-delay:.2s } .jeu-coco .jc-x-pense circle:nth-child(3){ animation-delay:.4s }
.jeu-coco .jc-x-eclats path{ fill:var(--gold); stroke:var(--ink); stroke-width:1.4; stroke-linejoin:round; transform-box:fill-box; transform-origin:center; animation:jcEclat 1.6s ease-in-out infinite }
.jeu-coco .jc-x-eclats path:nth-child(2){ animation-delay:.8s }
.jeu-coco .jc-x-coeur{ fill:var(--terra); stroke:var(--ink); stroke-width:2; stroke-linejoin:round; transform-box:fill-box; transform-origin:center; animation:jcCoeur 1.4s ease-in-out infinite }
.jeu-coco .jc-x-surprise{ fill:none; stroke:var(--ink); stroke-width:2.4; stroke-linecap:round }
[data-expr] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > g,
[data-expr] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b,
[data-expr] .jeu-coco:not(.is-miam):not(.is-joie) .jc-sourcils,
[data-expr] .jeu-coco:not(.is-miam):not(.is-joie) .jc-goutte{ display:none }
/* Elle parle : elle ne somnole plus, même sur une semaine vide. */
[data-expr] .jeu-coco .jc-zzz{ opacity:0 !important; animation:none !important }
[data-expr="clin"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > .jc-oeil-clin,
[data-expr="clin"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b-coin,
[data-expr="surprise"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > .jc-oeil-grand,
[data-expr="surprise"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-sourcils-haut,
[data-expr="surprise"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b-o,
[data-expr="surprise"] .jeu-coco .jc-x-surprise,
[data-expr="fier"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > .jc-oeil-joie,
[data-expr="fier"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b-grand,
[data-expr="fier"] .jeu-coco .jc-x-eclats,
[data-expr="sourcil"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > .jc-oeil-ouvert,
[data-expr="sourcil"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-sourcils-leve,
[data-expr="sourcil"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b-plat,
[data-expr="pense"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > .jc-oeil-pense,
[data-expr="pense"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-sourcils-leve,
[data-expr="pense"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b-coin,
[data-expr="pense"] .jeu-coco .jc-x-pense,
[data-expr="emue"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > .jc-oeil-joie,
[data-expr="emue"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b-sourire,
[data-expr="emue"] .jeu-coco .jc-x-coeur,
[data-expr="emue"] .jeu-coco .jc-x-rougeur,
[data-expr="ennui"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-yeux > .jc-oeil-ennui,
[data-expr="ennui"] .jeu-coco:not(.is-miam):not(.is-joie) .jc-bouches > .jc-b-plat{ display:block }
/* La bouche suit les syllabes du babil (jeu.js, parler). */
.jeu-coco.is-parle .jc-bouches > .jc-b{ display:none !important }
.jeu-coco.is-parle .jc-bouches > .jc-b-parle{ display:block !important }
.jeu-bulle .jb-reste{ opacity:0 }
@keyframes jcPoint{ 0%,100%{ opacity:1 } 50%{ opacity:.2 } }
@keyframes jcCoeur{ 0%,100%{ transform:scale(1) } 40%{ transform:scale(1.18) } 60%{ transform:scale(.96) } }
@keyframes jeuPuff{ 0%{ transform:translateY(4px) scale(.6); opacity:0 } 30%{ opacity:1 } 100%{ transform:translateY(-22px) scale(1.5); opacity:0 } }
@keyframes jeuCouvercle{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-2.5px) rotate(1.2deg) } }
@keyframes jeuCouvercleFete{ 0%,100%{ transform:translateY(0) rotate(0) } 14%{ transform:translateY(2px) } 40%{ transform:translateY(-14px) rotate(-9deg) } 56%{ transform:translateY(-8px) rotate(-3deg) } 66%{ transform:translateY(0) rotate(3deg) } 80%{ transform:translateY(-3px) rotate(-1deg) } }
@keyframes jeuBouillon{ 0%,100%{ transform:scale(1,1) } 50%{ transform:scale(1.025,.975) } }
@keyframes jeuRespire{ 0%,100%{ transform:scale(1,1) } 50%{ transform:scale(1.015,.985) } }
@keyframes jeuZzz{ 0%{ transform:translate(0,0); opacity:0 } 30%{ opacity:1 } 100%{ transform:translate(6px,-10px); opacity:0 } }
@keyframes jeuCligne{ 0%,92%,100%{ transform:scaleY(1) } 95%{ transform:scaleY(.08) } }
@keyframes jeuSquash{ 0%{ transform:scale(1,1) } 30%{ transform:scale(1.1,.88) } 60%{ transform:scale(.95,1.07) } 80%{ transform:scale(1.02,.98) } 100%{ transform:scale(1,1) } }
@keyframes jeuMiam{ 0%{ transform:rotate(0) scale(1,1) } 20%{ transform:rotate(-5deg) scale(1.05,.95) } 45%{ transform:rotate(4deg) scale(.97,1.04) } 70%{ transform:rotate(-2deg) scale(1.02,.98) } 100%{ transform:rotate(0) scale(1,1) } }
@keyframes jeuSaut{ 0%{ transform:translateY(0) scale(1,1) } 14%{ transform:translateY(3px) scale(1.1,.86) } 32%{ transform:translateY(-16px) scale(.92,1.1) rotate(-3deg) } 48%{ transform:translateY(-18px) scale(1,1) rotate(2deg) } 64%{ transform:translateY(0) scale(1.14,.86) } 78%{ transform:translateY(-5px) scale(.97,1.04) } 90%{ transform:translateY(0) scale(1.03,.98) } 100%{ transform:translateY(0) scale(1,1) } }

/* ---------- Les tenues (25/09) : accessoires dessinés dans le SVG, voir TENUES_SVG dans jeu.js ---------- */
.jeu-coco .jc-tenue{ stroke:var(--ink); stroke-width:2.6; stroke-linejoin:round; stroke-linecap:round }
.jeu-coco .jt-toque path, .jeu-coco .jt-toque rect{ fill:#FFFCF5 }
.jeu-coco .jt-foulard path{ fill:#C93F21 } .jeu-coco .jt-foulard .jt-pois circle{ fill:#FFFCF5; stroke:none }
.jeu-coco .jt-lunettes circle{ fill:var(--ink); opacity:.92 } .jeu-coco .jt-lunettes path{ fill:none }
.jeu-coco .jt-noeud-pap path, .jeu-coco .jt-noeud-pap circle{ fill:#C93F21 }
.jeu-coco .jt-couronne path{ fill:var(--gold) } .jeu-coco .jt-couronne circle{ fill:#C93F21; stroke-width:1.5 }
.jeu-coco .jt-medaille path{ fill:none } .jeu-coco .jt-medaille circle{ fill:var(--gold) } .jeu-coco .jt-medaille .jt-etoile{ fill:var(--ink); stroke:none }
.jeu-coco .jt-bonnet path{ fill:#C93F21 } .jeu-coco .jt-bonnet rect, .jeu-coco .jt-bonnet circle{ fill:#FFFCF5 }
.jeu-coco .jt-echarpe path{ fill:var(--sage) } .jeu-coco .jt-echarpe .jt-rayures{ fill:none; stroke-width:1.6; opacity:.7 }
.jeu-coco .jt-paille ellipse, .jeu-coco .jt-paille path{ fill:#E8C872 } .jeu-coco .jt-paille .jt-ruban{ fill:var(--ink); stroke:none }
.jeu-coco .jt-feuille path{ fill:#C93F21 } .jeu-coco .jt-feuille .jt-nervure, .jeu-coco .jt-feuille .jt-tige{ fill:none; stroke-width:1.8 }
.jeu-coco .jt-fleur .jt-petales ellipse{ fill:#FFFCF5; stroke-width:1.8 } .jeu-coco .jt-fleur .jt-coeur{ fill:var(--gold); stroke-width:1.8 } .jeu-coco .jt-fleur .jt-tige{ fill:none; stroke-width:2 }
.jeu-tenues{ display:grid; grid-template-columns:repeat(auto-fill,minmax(112px,1fr)); gap:10px }
/* 25/10/2026 : mettre la tenue sur l'icône de l'app (iPhone, jeu.js iconeHtml). */
.jeu-icone{ margin-top:12px }
/* 25/10/2026 : « Dire merci » sous la cocotte, quand un autre membre a cuisiné (jeu.js, Le merci). */
.jeu-merci{ display:flex; flex-wrap:wrap; justify-content:center; gap:8px; margin:10px 0 4px }
.jeu-tenue{ font:inherit; text-align:center; border:2px dashed var(--border-2); border-radius:16px; padding:10px 6px 9px; background:var(--surface); color:var(--ink); cursor:pointer; line-height:1.35 }
.jeu-tenue.on{ border-style:solid; border-color:var(--ink); background:var(--gold-soft); box-shadow:0 3px 0 var(--ink) }
.jeu-tenue:not(.locked):hover{ border-style:solid; border-color:var(--ink) }
.jeu-tenue.locked{ cursor:default; opacity:.72 }
.jeu-tenue .jeu-coco-wrap{ display:block; margin:0 auto 6px; width:60px }
.jeu-tenue .jeu-coco-sm{ width:60px; height:50px }
.jeu-tenue b{ display:block; font-size:.8rem; font-weight:700 }
.jeu-tenue small{ display:block; font-size:.72rem; font-weight:500; color:var(--muted); margin-top:2px; line-height:1.35 }
.jeu-maison{ font-size:.82rem; font-weight:600; color:var(--sage-text); display:inline-flex; align-items:center; gap:6px; cursor:help }
.jeu-maison:empty{ display:none }
.jeu-part{ margin:8px 0 0; font-size:.8rem; color:var(--ink-2); line-height:1.45 }
#jeuMaison:empty{ display:none }

/* ---------- La rangée cocotte + bulle dans la carte objectif ---------- */
.jeu-coco-row{ display:flex; align-items:center; gap:16px; margin:0 0 18px }
.jeu-bulle{
  position:relative; flex:1 1 auto; min-width:0;
  background:var(--surface); border:2px solid var(--ink); border-radius:18px;
  box-shadow:0 4px 0 var(--ink);
  padding:14px 16px; font-size:1rem; font-weight:700; color:var(--ink); line-height:1.35; letter-spacing:-.01em;
  transform-origin:left center;
}
.jeu-bulle::before{ content:""; position:absolute; left:-10px; top:50%; width:14px; height:14px; background:var(--surface); border-left:2px solid var(--ink); border-bottom:2px solid var(--ink); transform:translateY(-50%) rotate(45deg) }
.jeu-bulle.is-new{ animation:jeuBullePop .42s cubic-bezier(.2,1.5,.4,1) 1 }
@keyframes jeuBullePop{ 0%{ transform:scale(.7); opacity:0 } 100%{ transform:scale(1); opacity:1 } }

/* ---------- La carte objectif, version lot 3 ----------
   Elle porte désormais un personnage, un défi et un bouton : c'est un objet
   qu'on TOUCHE, pas un relevé qu'on lit — elle passe donc au trait d'encre
   (règle du lot 2), avec de l'air et une ombre de socle. */
.wg{
  background:var(--surface); border:2px solid var(--ink); border-radius:22px;
  box-shadow:0 5px 0 var(--ink); padding:20px 20px 18px; margin:0 0 22px;
}
.wg-top{ margin-bottom:12px }
.wg-count{ font-size:1.55rem; letter-spacing:-.02em; white-space:nowrap }
.wg-lab{ font-size:.72rem; white-space:nowrap }
@media(max-width:360px){ .wg-lab{ display:none } }
.wg-bar{ height:20px; border:2px solid var(--ink); background:var(--surface-2); padding:3px; border-radius:999px }
.wg-bar i{ position:relative; background:var(--terra); box-shadow:inset 0 -4px 0 rgba(0,0,0,.14) }
.wg-bar i::after{ content:""; position:absolute; left:8px; right:8px; top:3px; height:3px; border-radius:2px; background:rgba(255,255,255,.55) }
.wg.is-done .wg-bar i{ background:var(--sage) }
.wg-foot{ margin-top:14px }
.wg-serie{ font-size:.92rem; line-height:1.45 }
.wg-stamp{ width:26px; height:26px; border-width:2px }
.wg-stamp.on{ box-shadow:0 2px 0 var(--ink) }

/* ---------- Le défi, le jeton, la collection ---------- */
.jeu-defi{
  display:flex; align-items:center; gap:14px; margin-top:18px; padding:14px 16px;
  border:2px solid var(--ink); border-radius:18px; background:var(--gold-soft); font-size:.92rem; color:var(--ink);
  box-shadow:0 3px 0 var(--ink);
  width:100%; text-align:left; font:inherit; cursor:pointer; transition:transform .12s var(--ease), box-shadow .12s var(--ease);
}
button.jeu-defi:active{ transform:translateY(3px); box-shadow:0 0 0 var(--ink) }
.jeu-defi .jd-go{ flex:0 0 auto; font-size:1.5rem; line-height:1; color:var(--muted); margin-left:-4px }
.wg-top .wg-lab{ color:var(--sage-text); letter-spacing:.04em }
.jeu-collec .jeu-liens{ margin-top:14px; justify-content:flex-start }
.jeu-defi.is-done{ background:var(--sage-soft); color:var(--sage-text) }
.jeu-defi .jd-e{ flex:0 0 auto; width:44px; height:44px; display:grid; place-items:center; font-size:1.4rem; line-height:1; background:var(--surface); border:2px solid var(--ink); border-radius:50% }
.jeu-defi .jd-t{ flex:1 1 auto; min-width:0; font-weight:600; line-height:1.3 }
.jeu-defi .jd-t b{ display:block; font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; color:var(--gold-deep); font-weight:700; margin-bottom:3px }
.jeu-defi.is-done .jd-t b{ color:var(--sage-text) }
/* Défi relevé (30/09/2026) : la carte se retourne, le coche se dessine. */
.jeu-defi.is-releve{ animation:jdRetourne .7s cubic-bezier(.2,1.3,.4,1) both; transform-origin:50% 50% }
.jeu-defi .jd-e .ic{ width:24px; height:24px; color:var(--ink) }
.jeu-defi .jd-coche{ width:26px; height:26px; fill:none; stroke:var(--sage-text); stroke-width:3.2; stroke-linecap:round; stroke-linejoin:round }
.jeu-defi.is-releve .jd-coche path{ stroke-dasharray:24; stroke-dashoffset:24; animation:jdCoche .45s .35s ease-out forwards }
.jeu-defi.is-releve .jd-e{ animation:jdPastille .6s .3s cubic-bezier(.2,1.6,.4,1) both }
@keyframes jdRetourne{ 0%{ transform:perspective(700px) rotateX(0) } 45%{ transform:perspective(700px) rotateX(90deg) } 100%{ transform:perspective(700px) rotateX(0) } }
@keyframes jdCoche{ to{ stroke-dashoffset:0 } }
@keyframes jdPastille{ 0%{ transform:scale(.6) } 60%{ transform:scale(1.18); box-shadow:0 0 0 8px var(--sage-soft) } 100%{ transform:none } }
@media (prefers-reduced-motion: reduce){ .jeu-defi.is-releve, .jeu-defi.is-releve .jd-e{ animation:none } .jeu-defi.is-releve .jd-coche path{ animation:none; stroke-dashoffset:0 } }
.jeu-defi .jd-p{ flex:0 0 auto; font-family:var(--serif); font-size:1.15rem; font-variant-numeric:tabular-nums; color:var(--ink); background:var(--surface); border:2px solid var(--ink); border-radius:999px; padding:5px 12px }
.jeu-defi.is-done .jd-p{ color:var(--sage-text); font-family:inherit; font-weight:800; font-size:.82rem }
.jeu-liens{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-top:16px }
.jeu-jeton{ font-size:.82rem; font-weight:600; color:var(--ink-2); display:inline-flex; align-items:center; gap:6px; cursor:help }
.jeu-jeton.on i{ animation:jeuJetonBrille 3.6s ease-in-out infinite; display:inline-block }
.jeu-jeton.off{ color:var(--muted); text-decoration:line-through; text-decoration-color:var(--muted) }
.jeu-jeton.off i{ filter:grayscale(1); opacity:.6 }
@keyframes jeuJetonBrille{ 0%,90%,100%{ transform:rotate(0) } 93%{ transform:rotate(-12deg) } 97%{ transform:rotate(10deg) } }
.jeu-lien-collec{
  margin-left:auto; font-size:.86rem; font-weight:800; color:var(--ink); background:var(--surface);
  border:2px solid var(--ink); border-radius:999px; padding:9px 16px; cursor:pointer; box-shadow:0 3px 0 var(--ink);
  transition:transform .12s, box-shadow .12s;
}
.jeu-lien-collec:hover{ transform:translateY(-1px); box-shadow:0 4px 0 var(--ink) }
.jeu-lien-collec:active{ transform:translateY(3px); box-shadow:0 0 0 var(--ink) }

/* ---------- L'anneau de l'en-tête ---------- */
.jeu-anneau{
  display:inline-flex; align-items:center; gap:5px; flex:0 0 auto;
  background:none; border:0; padding:4px; margin-left:-6px; cursor:pointer; border-radius:999px;
  color:var(--ink); font-size:.82rem; font-weight:800; font-variant-numeric:tabular-nums;
}
.jeu-anneau svg{ width:36px; height:36px; transform:rotate(-90deg); display:block }
.jeu-anneau .ja-fond{ fill:none; stroke:var(--sand); stroke-width:4.5 }
.jeu-anneau .ja-prog{ fill:none; stroke:var(--terra); stroke-width:4.5; stroke-linecap:round; transition:stroke-dashoffset .75s cubic-bezier(.34,1.56,.64,1), stroke .3s }
.jeu-anneau.is-done .ja-prog{ stroke:var(--sage) }
.jeu-anneau.is-done .ja-txt{ color:var(--sage-text) }
/* 08/10/2026 : le cœur de l'anneau, les dîners cuisinés de la semaine (corail : la cocotte et
   le dîner). Il paraît une fois la semaine tamponnée ou un premier dîner cuisiné. */
.jeu-anneau .ja-coeur-fond, .jeu-anneau .ja-coeur{ fill:none; stroke-width:3.4; opacity:0; transition:opacity .3s }
.jeu-anneau .ja-coeur-fond{ stroke:var(--sand) }
.jeu-anneau .ja-coeur{ stroke:var(--terra); stroke-linecap:round; transition:stroke-dashoffset .75s cubic-bezier(.34,1.56,.64,1), opacity .3s }
.jeu-anneau.a-coeur .ja-coeur-fond, .jeu-anneau.a-cuits .ja-coeur{ opacity:1 }
.jeu-anneau.is-pulse svg{ animation:jeuAnneauPulse .55s cubic-bezier(.3,1.6,.5,1) 1 }
.jeu-anneau.is-flash{ animation:jeuAnneauFlash .9s ease-out 1 }
@keyframes jeuAnneauPulse{ 0%{ transform:rotate(-90deg) scale(1) } 45%{ transform:rotate(-90deg) scale(1.22) } 100%{ transform:rotate(-90deg) scale(1) } }
@keyframes jeuAnneauFlash{ 0%{ box-shadow:0 0 0 0 rgba(127,176,105,.7) } 100%{ box-shadow:0 0 0 18px rgba(127,176,105,0) } }
@media(max-width:420px){ .jeu-anneau .ja-txt{ display:none } .jeu-anneau svg{ width:28px; height:28px } }

/* ---------- Le réglage des sons ---------- */
.jeu-switch{ display:flex; align-items:center; gap:10px; margin-top:10px; font-weight:600; font-size:.9rem; cursor:pointer }
.jeu-switch input:not(.sw){ width:20px; height:20px; accent-color:var(--terra) }

/* ---------- La collection ---------- */
.jeu-collec-hero{ display:flex; align-items:center; gap:18px; margin:4px 0 10px }
.jeu-big b{ font-family:var(--serif); font-size:2.6rem; line-height:1; color:var(--terra) }
.jeu-big span{ font-weight:600; color:var(--ink-2) }
.jeu-collec-bar{ height:16px; border:2px solid var(--ink); border-radius:999px; background:var(--surface-2); padding:2px; margin:10px 0 6px; overflow:hidden }
.jeu-collec-bar i{ display:block; height:100%; border-radius:999px; background:var(--terra); transition:width .8s cubic-bezier(.25,1,.3,1) }
.jeu-collec-sub{ font-size:.78rem; color:var(--muted) }
.jeu-h3{ display:flex; justify-content:space-between; align-items:baseline; font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin:24px 0 10px }
.jeu-h3 span{ font-family:var(--serif); font-size:.95rem; letter-spacing:0; text-transform:none; color:var(--ink) }
.jeu-chips{ display:flex; flex-wrap:wrap; gap:8px }
.jeu-chip{ font-size:.8rem; font-weight:700; padding:7px 13px; border-radius:999px; border:2px dashed var(--border-2); color:var(--muted) }
.jeu-chip.on{ border-style:solid; border-color:var(--ink); background:var(--gold); color:var(--ink); box-shadow:0 2px 0 var(--ink) }
.jeu-classiques{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px }
.jeu-classiques li{ display:flex; align-items:center; gap:12px; padding:12px 14px; border:2px solid var(--ink); border-radius:16px; font-size:.92rem; font-weight:600; box-shadow:0 3px 0 var(--ink); background:var(--surface) }
.jeu-classiques li span:nth-child(2){ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.jeu-classiques li b{ color:var(--terra-text) }
/* 08/10/2026 : la page de la saison, trois dîners à découvrir qu'on ouvre d'un tap. */
.jeu-saison-lab{ margin:14px 0 8px; font-weight:700; color:var(--ink-2) }
.jeu-saison-idees li{ padding:0 }
.jeu-saison-idees button{ display:flex; align-items:center; gap:12px; width:100%; min-height:48px; padding:12px 14px; border:0; background:none; font:inherit; color:inherit; text-align:left; cursor:pointer; border-radius:14px }
.jeu-saison-idees button span:nth-child(2){ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.jeu-saison-idees .jsi-go{ color:var(--muted); font-size:1.2rem }
.jeu-saison-passees{ margin-top:10px }
.jeu-stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px }
.jeu-stats div{ text-align:center; padding:14px 6px; border:2px solid var(--ink); border-radius:16px; background:var(--surface); box-shadow:0 3px 0 var(--ink) }
.jeu-stats b{ display:block; font-family:var(--serif); font-size:1.8rem; line-height:1.1; color:var(--ink) }
.jeu-stats span{ font-size:.72rem; color:var(--muted); font-weight:600 }
.jeu-jalons{ display:grid; grid-template-columns:repeat(4,1fr); gap:10px }
.jeu-jalon{ text-align:center; padding:14px 4px; border:2px dashed var(--border-2); border-radius:16px; color:var(--muted); font-size:.7rem }
.jeu-jalon b{ display:block; font-size:.76rem; margin:3px 0 1px }
.jeu-jalon .jj-e{ font-size:1.7rem; line-height:1; filter:grayscale(1); opacity:.4; display:block }
.jeu-jalon.on{ border-style:solid; border-color:var(--ink); background:var(--gold-soft); color:var(--ink); box-shadow:0 3px 0 var(--ink) }
.jeu-jalon.on .jj-e{ filter:none; opacity:1 }
@media(max-width:420px){ .jeu-jalons{ grid-template-columns:repeat(2,1fr) } }

/* ---------- Le récap ---------- */
.jeu-recap-carte{
  text-align:center; padding:22px 18px 18px; border:2px solid var(--ink); border-radius:22px;
  background:var(--surface); box-shadow:0 5px 0 var(--ink);
}
.jeu-recap-serie{ font-size:1rem; font-weight:700; color:var(--ink-2); margin:10px 0 18px }
.jeu-recap-serie b{ font-family:var(--serif); font-size:2.4rem; color:var(--terra); margin-right:6px }
.jeu-recap-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:10px }
.jeu-recap-grid div{ padding:14px 6px; border:2px solid var(--ink); border-radius:16px; background:var(--surface-2); box-shadow:0 3px 0 var(--ink) }
.jeu-recap-grid b{ display:block; font-family:var(--serif); font-size:1.9rem; line-height:1.1 }
.jeu-recap-grid span{ font-size:.78rem; font-weight:700; color:var(--ink-2) }
.jeu-recap-ligne{ margin-top:14px; font-size:.9rem; font-weight:600; color:var(--ink-2) }
.jeu-recap-jalon{ margin-top:12px; padding:9px 12px; border-radius:999px; background:var(--gold); color:var(--ink); border:2px solid var(--ink); font-weight:700; font-size:.86rem; animation:jeuBullePop .5s cubic-bezier(.2,1.5,.4,1) 1 }
.jeu-recap-actions{ display:flex; flex-direction:column; gap:10px; margin-top:18px }
.jeu-recap-note{ text-align:center; font-size:.78rem; color:var(--muted); margin:10px 0 0 }
.jeu-recap-note a{ color:var(--ink-2); font-weight:600 }

/* ---------- Le guide d'utilisation : la cocotte fait visiter (22/09) ----------
   Réutilise la cocotte, la bulle et la carte-défi du lot ; se retire avec lui. */
.guide-hello{ margin:0 0 22px }
.guide-hello .jeu-coco{ width:96px; height:80px }
.guide-mot{ display:flex; align-items:center; gap:10px; margin:0 0 12px }
.guide-mot .jeu-coco-wrap{ display:block }
.guide-mot .jeu-coco-sm{ width:52px; height:44px }
.guide-mot > .gm-t{ position:relative; background:var(--gold-soft); border:2px solid var(--ink); border-radius:14px; box-shadow:0 3px 0 var(--ink); padding:10px 14px; font-size:.9rem; font-weight:700; color:var(--ink); line-height:1.45 }
.guide-mot > .gm-t::before{ content:""; position:absolute; left:-8px; top:50%; width:11px; height:11px; background:var(--gold-soft); border-left:2px solid var(--ink); border-bottom:2px solid var(--ink); transform:translateY(-50%) rotate(45deg) }
.guide-etapes{ display:flex; flex-direction:column; gap:10px; margin:0 0 10px }
.guide-etapes .jeu-defi{ margin-top:0; align-items:flex-start; background:var(--surface) }
.guide-etapes .jd-e{ font-family:var(--serif); font-size:1.25rem; background:var(--gold-soft) }
.guide-etapes .jd-t{ font-weight:500; font-size:.88rem; color:var(--ink-2) }
.guide-etapes .jd-t b{ font-size:.7rem; color:var(--terra); margin-bottom:4px }
.guide-humeurs{ display:grid; grid-template-columns:repeat(auto-fit,minmax(118px,1fr)); gap:10px; margin:0 0 14px }
.guide-humeur{ text-align:center; border:2px solid var(--ink); border-radius:16px; padding:12px 8px 10px; background:var(--surface); box-shadow:0 3px 0 var(--ink); font-size:.82rem; font-weight:600; color:var(--ink); line-height:1.45 }
.guide-humeur .jeu-coco-wrap{ display:block; margin:0 auto 4px; width:64px }
.guide-humeur small{ display:block; font-weight:500; color:var(--ink-2) }
.legal-doc .guide-regle{ border-left:4px solid var(--terra); padding:8px 12px; background:var(--surface-2); border-radius:0 12px 12px 0; font-weight:600; color:var(--ink) }
.legal-doc .guide-sources{ font-size:.84rem; line-height:1.6; color:var(--muted); border-top:1px dashed var(--line); padding-top:12px; margin-top:12px }
.guide-emoji{ font-size:2rem; line-height:1 }
/* 25/09 : le guide était tassé (corps à .85rem hérité des pages légales, interligne
   1.3 dans les étapes et les bulles). Il se lit comme un texte, pas comme des CGV. */
.guide-doc p, .guide-doc li{ font-size:.94rem; line-height:1.7 }
.guide-doc li{ margin-bottom:9px }
.guide-doc ul{ margin-bottom:16px }
.guide-doc h3{ font-size:1.15rem; margin:32px 0 12px }
.guide-doc .guide-hello{ margin-bottom:26px }
.guide-doc .jeu-bulle{ line-height:1.5 }
.guide-doc .guide-etapes{ gap:12px; margin-bottom:16px }
.guide-doc .guide-etapes .jd-t{ font-size:.94rem; line-height:1.6 }
.guide-doc .guide-etapes .jd-t b{ margin-bottom:6px }
.guide-doc .guide-mot{ margin-bottom:16px }
.guide-doc .guide-mot > .gm-t{ line-height:1.45; padding:10px 14px }
.guide-doc .guide-humeurs{ gap:12px; margin-bottom:20px }
.guide-doc .guide-humeur{ line-height:1.45; padding:12px 8px 10px }
.guide-doc .guide-regle{ line-height:1.6; padding:12px 14px; margin:16px 0 }
.guide-doc .guide-sources{ line-height:1.6; margin-top:12px }

@media (prefers-reduced-motion: reduce){
  .jeu-coco *, .jeu-coco, .jeu-bulle, .jeu-anneau, .jeu-anneau svg, .jeu-jeton i, .jeu-recap-jalon{ animation:none !important }
  .jeu-anneau .ja-prog, .jeu-anneau .ja-coeur, .jeu-collec-bar i{ transition:none !important }
  .jeu-coco .jc-regard{ transition:none !important; transform:none !important }
  [data-etat] .jc-v{ opacity:.9 }
  [data-etat="dort"] .jc-v{ opacity:0 }
  [data-etat="dort"] .jc-zzz{ opacity:1 }
  [data-etat="inquiete"] .jc-v{ opacity:0 }
}
/* ---------- Passe du 22/09 : hiérarchie sur grand écran ----------
   Au-delà de 820 px, la carte objectif n'est plus une pile de bandeaux
   pleine largeur : la cocotte et sa bulle prennent une colonne, le reste
   s'empile à droite. Ce qu'on perd en largeur, on le gagne en hauteur. */
@media(min-width:820px){
  .wg{
    display:grid; grid-template-columns:240px 1fr; column-gap:32px; row-gap:0;
    grid-template-areas:"coco top" "coco bar" "coco foot" "coco defi" "coco liens";
    align-items:start; padding:26px 28px 24px;
  }
  .jeu-coco-row{ grid-area:coco; flex-direction:column; align-items:center; gap:16px; margin:0; align-self:center }
  .jeu-coco-row .jeu-coco{ width:180px; height:150px }
  .jeu-bulle{ text-align:center; font-size:.95rem; transform-origin:top center; width:100% }
  .jeu-bulle::before{ left:50%; top:-9px; transform:translateX(-50%) rotate(135deg) }
  .wg-top{ grid-area:top; flex-direction:column-reverse; align-items:flex-start; gap:4px; margin-bottom:14px }
  .wg-count{ font-size:2.4rem }
  .wg-bar{ grid-area:bar; height:24px }
  .wg-foot{ grid-area:foot; margin-top:16px }
  .wg-serie{ font-size:1rem }
  .jeu-defi{ grid-area:defi }
  .jeu-liens{ grid-area:liens }
}

/* ---------- Sélecteur de recette : le ➕ et le badge ----------
   .mini-btn,.sel-card-quickadd,…{position:relative} (zone tactile de 44 px)
   écrasait le position:absolute du ➕ : il repassait dans le flux, en haut à
   gauche, et le badge « Adapté » restait seul à droite. Sélecteur composé,
   plus un vrai bouton à socle, et le badge à gauche pour ne jamais le croiser. */
.sel-card{ padding:44px 12px 12px; border:2px solid var(--ink); border-radius:16px; background:var(--surface); box-shadow:0 3px 0 var(--ink); gap:6px }
.sel-card:hover{ border-color:var(--ink); background:var(--sage-soft); transform:translateY(-2px); box-shadow:0 5px 0 var(--ink) }
.sel-card .se{ font-size:2.3rem; line-height:1 }
.sel-card .sn{ font-size:.92rem }
.sel-card .sel-card-quickadd{
  position:absolute; top:8px; right:8px; left:auto; width:34px; height:34px; border:2px solid var(--ink); background:var(--surface);
  box-shadow:0 2px 0 var(--ink); color:var(--ink); font-size:.9rem;
}
.sel-card .sel-card-quickadd:hover{ background:var(--sage); border-color:var(--ink); color:var(--ink); transform:translateY(-1px); box-shadow:0 3px 0 var(--ink) }
.sel-card .sel-card-quickadd:active{ transform:translateY(2px); box-shadow:0 0 0 var(--ink) }
.sel-card .sel-reco{ top:10px; left:10px; right:auto; max-width:calc(100% - 60px); font-size:.72rem; padding:4px 9px; border:1.5px solid var(--ink); color:var(--ink); background:var(--gold) }
.sel-card .vote-badge{ top:auto; bottom:10px; right:10px; left:auto }

/* ---------- La cocotte partout, sans excès ----------
   1. Le logo de l'en-tête (et celui de l'écran de compte, même dessin) fume
      doucement en permanence ; à gros bouillons quand l'objectif de la semaine
      est atteint (classe posée par jeu.js).
   2. Les états vides (placard, courses, sélecteur sans résultat…) montrent la
      cocotte endormie à la place de l'émoji, via un observateur dans jeu.js. */
.brand-mark path[stroke="var(--sage)"]{ transform-box:fill-box; transform-origin:50% 100%; animation:jeuLogoVapeur 3.2s ease-in-out infinite }
.brand-mark path[stroke="var(--sage)"]:nth-of-type(2){ animation-delay:1.4s }
.brand-mark.jeu-bout path[stroke="var(--sage)"]{ animation-duration:1.1s; stroke-width:6 }
.brand-mark.jeu-bout .bm-pot{ transform-box:fill-box; transform-origin:50% 100%; animation:jeuBouillon .9s ease-in-out infinite }
@keyframes jeuLogoVapeur{ 0%,100%{ transform:translateY(0) scaleY(1); opacity:.55 } 50%{ transform:translateY(-1.5px) scaleY(1.12); opacity:1 } }
.es-emoji[data-coco]{ line-height:0; display:flex; justify-content:center; margin-bottom:6px }
.es-emoji[data-coco] .jeu-coco{ width:96px; height:80px }
@media(min-width:820px){ .es-emoji[data-coco] .jeu-coco{ width:120px; height:100px } }

@media (prefers-reduced-motion: reduce){
  .brand-mark path, .brand-mark .bm-pot{ animation:none !important }
}
/* ---------- Sélecteur de recette : moins de bandeaux sur grand écran ----------
   Sept barres pleine largeur avant la première recette, dont deux boîtes
   beiges (« Repas libre », « Plus de filtres ») qui pesaient autant que la
   recherche. Au-delà de 760 px : les deux recherches côte à côte, les étiquettes
   Type / Raccourcis alignées sur une colonne fixe, et les deux boîtes beiges
   ramenées à des liens discrets sur une seule ligne. Ordre du DOM inchangé ;
   :has() est supporté par les navigateurs visés (Safari ≥ 15.4). */
@media(min-width:760px){
  .modal-body:has(> #selResults){
    display:grid; grid-template-columns:1fr 1fr; column-gap:14px; row-gap:10px; align-content:start;
    grid-template-areas:"search ing" "banner banner" "type type" "raccourcis raccourcis" "fold libre" "more more" "count count" "results results" "ext ext";
  }
  .modal-body:has(> #selResults) > *{ margin-top:0 !important; margin-bottom:0 !important }
  .modal-body:has(> #selResults) > .search-box:not(.ing-search-box){ grid-area:search }
  .modal-body:has(> #selResults) > .ing-search-box{ grid-area:ing }
  .modal-body:has(> #selResults) > .sel-suggest-banner{ grid-area:banner; padding:9px 14px }
  .modal-body:has(> #selResults) > .sel-suggest-banner:empty{ display:none }
  .modal-body:has(> #selResults) > .filter-group{ grid-area:type }
  .modal-body:has(> #selResults) > .filter-group ~ .filter-group{ grid-area:raccourcis }
  .modal-body:has(> #selResults) > .filter-group > .fg-label{ flex:0 0 96px }
  .modal-body:has(> #selResults) > .sel-fold{ grid-area:fold; align-self:center; justify-self:start; background:none; border:0; padding:0 }
  .modal-body:has(> #selResults) > .sel-fold > summary{ display:inline-flex; padding:8px 4px; font-size:.86rem; font-weight:700; color:var(--ink-2) }
  /* Ouvert, le dépliant prend une ligne entière sous « Repas libre » : la ligne
     « more » n'a de hauteur que dans ce cas. */
  .modal-body:has(> #selResults) > .sel-fold[open]{ grid-area:more; justify-self:stretch; background:var(--surface-2); border:1px solid var(--border); padding:2px 12px }
  .modal-body:has(> #selResults) > #freeMealBtn{ grid-area:libre; justify-self:end; align-self:center; width:auto; background:none; border-color:transparent; box-shadow:none; color:var(--ink-2); font-size:.86rem; padding:8px 10px }
  .modal-body:has(> #selResults) > #freeMealBtn:hover{ color:var(--ink); text-decoration:underline }
  .modal-body:has(> #selResults) > div:has(> #selCount){ grid-area:count; margin-top:2px !important; padding-top:10px; border-top:1px solid var(--border) }
  .modal-body:has(> #selResults) > #selResults{ grid-area:results }
  .modal-body:has(> #selResults) > #selExterieurBtn{ grid-area:ext; justify-self:center; width:auto }
}
/* ================= fin LOT 3 ================= */

/* ==================================================================
   AÉRATION DU 22/09 — fiche recette, bloc « En savoir plus »
   ------------------------------------------------------------------
   Placé après les lots 2 et 3 pour gagner la cascade. Trois idées :
   1. les quatre macros forment UNE carte à quatre colonnes, pas quatre boîtes ;
   2. les deux scores se mettent côte à côte dès qu'il y a la place ;
   3. les micronutriments sont des jauges alignées (libellé / barre / chiffre),
      six visibles, le reste sous un dépliant. Une jauge se compare, une puce non.
   ================================================================== */
.detail-nut{display:grid; grid-template-columns:repeat(4,1fr); gap:0; margin:14px 0 16px;
  border:1px solid var(--border); border-radius:14px; background:var(--surface-2); overflow:hidden}
.detail-nut .nut-box{border:0; border-radius:0; background:none; box-shadow:none; padding:13px 6px 11px}
.detail-nut .nut-box + .nut-box{border-left:1px dashed var(--border)}
.detail-nut .nut-box .nv{font-size:1.25rem; font-variant-numeric:tabular-nums}
.detail-nut .nut-box .nl{margin-top:4px}
.detail-scores{gap:10px; margin:0 0 6px}
@media(min-width:560px){
  .detail-scores{display:grid; grid-template-columns:1fr 1fr; align-items:stretch}
  .detail-scores .nutri-badge-btn{width:auto}
}
.detail-scores .nutri-badge{transform:none}
.detail-scores .nutri-badge:first-child{transform:rotate(-1.2deg)}
.detail-scores .nutri-badge:last-child{transform:rotate(.8deg)}
.detail-scores .nutri-txt small{font-size:.74rem; line-height:1.3}
.micro-rows{display:flex; flex-direction:column; gap:7px}
.micro-row{display:grid; grid-template-columns:minmax(96px,26%) 1fr auto; align-items:center; column-gap:10px;
  font-size:.82rem; line-height:1.3; color:var(--ink-2); padding:2px 0}
.micro-row .mr-lab{font-weight:600; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.micro-row .mr-bar{display:block; height:8px; border-radius:999px; background:var(--border); overflow:hidden}
.micro-row .mr-bar i{display:block; height:100%; border-radius:999px; background:var(--sage); opacity:.65}
.micro-row.is-strong .mr-bar i{opacity:1}
.micro-row.is-max .mr-bar i{background:#E0B25A}
.micro-row.is-over .mr-bar i{background:var(--terra)}
.micro-row .mr-num{display:flex; flex-direction:column; align-items:flex-end; line-height:1.15; min-width:64px}
.micro-row .mr-num b{font-variant-numeric:tabular-nums; color:var(--ink); font-size:.84rem}
.micro-row .mr-num small{font-size:.74rem; color:var(--muted); white-space:nowrap}
.micro-more{margin-top:6px}
.micro-more>summary{list-style:none; cursor:pointer; font-size:.8rem; font-weight:700; color:var(--sage-text); padding:8px 0 4px; display:inline-flex; align-items:center; gap:6px}
.micro-more>summary::-webkit-details-marker{display:none}
.micro-more>summary::before{content:'▸'; font-size:.7rem; display:inline-block; transition:transform .2s var(--ease)}
.micro-more[open]>summary::before{transform:rotate(90deg)}
.micro-more>summary:hover{text-decoration:underline}
.micro-more>.micro-rows{margin-top:4px}
/* Les bienfaits : mêmes cartes, un peu plus d'air entre elles et un fond de la charte. */
.detail-benefits{gap:8px}
.detail-benefits li{background:var(--surface-2); border:1px solid var(--border); padding:10px 12px; line-height:1.45}
@media(max-width:520px){
  .detail-nut .nut-box .nv{font-size:1.1rem}
  .detail-nut .nut-box .nl{font-size:.72rem; letter-spacing:.3px}
  .micro-row{grid-template-columns:minmax(84px,38%) 1fr auto; column-gap:8px; font-size:.78rem}
}
/* ================= fin AÉRATION 22/09 ================= */

/* --- Plateforme native (Capacitor) ---------------------------------------
   Dans un build App Store / Play Store, AUCUN chemin d'achat web ne doit
   exister : Apple (3.1.1) interdit jusqu'au simple lien vers ioumi.fr/premium,
   et Google applique la même règle. iap.js pose .mw-natif / .mw-web sur <html>
   au chargement ; tout ce qui mène à Stripe porte .mw-achat-web, tout ce qui
   n'a de sens que dans l'app native porte .mw-achat-natif. */
html.mw-natif .mw-achat-web{display:none !important}
html.mw-web .mw-achat-natif{display:none !important}

/* ============ FÊTE DU PASSAGE EN PREMIUM (voir ioumiFeterPremium) ============
   Piste « le tampon » : la cocotte se pose comme un tampon encreur, puis chaque
   atout s'imprime à la suite. Même langage que le lot 2 — pas de flou, pas de
   lévitation, une ombre nette et un léger écrasement à l'impact.
   Déclenchée UNE SEULE FOIS, au moment où le droit premium arrive réellement
   (après le webhook), jamais au retour du SDK : sinon on félicite quelqu'un
   avant que son abonnement existe. */
.fete-back{position:fixed; inset:0; z-index:1000; background:color-mix(in srgb,var(--ink) 62%,transparent);
  display:flex; align-items:center; justify-content:center; padding:18px; animation:feteFond .25s var(--ease) both}
@keyframes feteFond{from{opacity:0}to{opacity:1}}
.fete-card{background:var(--surface); border:2px solid var(--ink); border-radius:var(--radius-lg);
  box-shadow:6px 6px 0 var(--ink); width:min(420px,100%); max-height:88vh; overflow:auto;
  padding:26px 22px 0; text-align:center}
.fete-mark{width:78px; height:78px; margin:0 auto; display:block; animation:feteTampon .5s cubic-bezier(.22,.61,.36,1) both}
@keyframes feteTampon{0%{opacity:0; transform:scale(1.9) rotate(-9deg)}60%{opacity:1; transform:scale(.94) rotate(2deg)}100%{opacity:1; transform:none}}
.fete-title{font-family:var(--serif); font-size:1.5rem; line-height:1.12; margin:12px 0 2px; animation:fetePop .34s .42s both}
.fete-sub{font-size:.88rem; color:var(--ink-2); animation:fetePop .34s .56s both}
@keyframes fetePop{from{opacity:0; transform:translateY(7px) scale(.96)}to{opacity:1; transform:none}}
.fete-list{display:flex; flex-direction:column; gap:6px; margin:16px 0 4px; text-align:left}
.fete-row{display:flex; align-items:center; gap:9px; background:var(--surface); border:2px solid var(--ink);
  border-radius:11px; padding:8px 10px; font-size:.82rem; font-weight:700; box-shadow:var(--shadow-flat);
  animation:feteStamp .3s both}
@keyframes feteStamp{0%{opacity:0; transform:scale(1.14) rotate(-1.5deg)}70%{opacity:1; transform:scale(.985)}100%{opacity:1; transform:none}}
.fete-row .fr-em{font-size:1rem; line-height:1; flex-shrink:0}
.fete-row .fr-ck{margin-left:auto; color:var(--sage-text); font-weight:800}
/* Dix atouts, ca depasse l'ecran d'un telephone : sans pied collant, le bouton
   de sortie n'existe qu'apres un defilement, et une modale sans sortie visible
   est une modale qui piege. */
.fete-foot{position:sticky; bottom:0; background:var(--surface); padding:12px 0 20px; margin-top:10px;
  animation:fetePop .3s both}
.fete-go{width:100%}
/* Les confettis existent déjà en z-index 95 : ils passeraient DERRIÈRE le voile.
   On les remonte le temps de la fête, sans toucher à leurs autres usages. */
body.mw-fete .confetti{z-index:1100}
@media(prefers-reduced-motion:reduce){
  .fete-back,.fete-mark,.fete-title,.fete-sub,.fete-row,.fete-foot{animation:none !important}
}


/* ==================================================================
   RETOURS DU 23/09 — placé en dernier pour gagner la cascade.
   ================================================================== */
/* 1. Desktop : la liste repliable n'a ni résumé ni bouton, elle ne doit donc pas
   porter le cadre encre des éléments qu'on touche (les jours des Courses se
   retrouvaient dans un rectangle noir sans raison apparente). */
@media(min-width:881px){
  .collapsible-list{border:none; box-shadow:none; background:none; padding:0}
}

/* 2. Pop-up « Quoi de neuf » : hauteur fixe, contenu qui défile, navigation et pied
   toujours dans la carte. Avant, un écran long débordait sous la modale (90vh). */
.modal:has(> .wn-wrap), .modal:has(.wn-wrap){height:min(760px, 90vh)}
.wn-wrap{flex:1 1 auto; min-height:0; padding-bottom:18px}
.wn-body{flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; padding:0 4px 22px; scrollbar-width:thin;
  -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 26px),transparent); mask-image:linear-gradient(to bottom,#000 calc(100% - 26px),transparent)}
.wn-dots,.wn-nav,.wn-foot{flex:0 0 auto}
.wn-foot{margin-top:10px}
/* Points : la pastille est dessinée par ::after, ronde ; le bouton garde sa cible de 24 px. */
.wn-dot{position:relative; background:none !important; border:0; width:10px; padding:0; cursor:pointer}
.wn-dot::after{content:""; position:absolute; left:0; right:0; top:50%; height:8px; margin-top:-4px; border-radius:999px; background:var(--border-2); transition:.25s var(--ease)}
.wn-dot.on{width:24px}
.wn-dot.on::after{background:var(--sage)}
@media(max-height:820px){ .wn-fig{max-width:170px} }

/* 3. La cocotte propose : l'action principale de la carte objectif. */
.wg-foot .wg-cta{flex:1 0 100%; justify-content:center; margin-top:4px; padding:12px 18px; font-size:.98rem}
@media(min-width:820px){ .wg-foot .wg-cta{flex:0 0 auto; align-self:flex-start} }

/* 4. Affiner l'estimation : deux groupes titrés, des aides d'une ligne, un vrai interrupteur. */
.budget-settings .bs-body{padding:14px 18px 18px; display:flex; flex-direction:column; gap:14px}
.bs-intro{margin:0; font-size:.9rem; color:var(--ink-2)}
.bs-group{border:1.5px solid var(--border); border-radius:16px; background:var(--surface); padding:16px 16px 4px}
@media(max-width:560px){
  .budget-settings .bs-body{padding:12px 12px 14px}
  .bs-group{padding:14px 12px 2px}
  .bs-toggle{align-items:flex-start; padding:12px}
  .bs-toggle-ico{display:none}
}
.bs-h{display:flex; align-items:center; gap:8px; margin:0 0 14px; font-family:var(--sans); font-size:.98rem; font-weight:800; color:var(--ink)}
.bs-h span{font-size:1.1rem}
.bs-group .field{margin-bottom:16px}
.bs-hint{margin:7px 2px 0; font-size:.8rem; color:var(--muted); line-height:1.45}
.bs-label-note{font-weight:500; color:var(--muted)}
.bs-budget-row{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.bs-euro{display:inline-flex; align-items:center; gap:8px; font-weight:700; color:var(--ink-2)}
.field .bs-euro input[type=number]{width:110px; font-size:1.15rem; font-weight:700; text-align:right}
.bs-mois{margin-top:10px}
.bs-mois>summary{cursor:pointer; font-size:.82rem; color:var(--muted); margin-bottom:8px}
.bs-toggle{display:flex; align-items:center; gap:12px; margin:2px 0 14px; padding:12px 14px; border-radius:14px; border:1.5px dashed var(--border-2); background:var(--surface); cursor:pointer}
.bs-toggle input{position:absolute; opacity:0; width:1px; height:1px}
.bs-toggle-ico{font-size:1.2rem; flex:0 0 auto}
.bs-toggle-txt{flex:1 1 auto; display:flex; flex-direction:column; gap:3px; min-width:0}
.bs-toggle-txt b{font-size:.92rem; color:var(--ink); display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.bs-toggle-txt>span{font-size:.8rem; color:var(--muted); line-height:1.45}
.bs-pill{font-size:.72rem; font-weight:800; padding:2px 8px; border-radius:999px; background:var(--gold); color:var(--ink); border:1.5px solid var(--ink)}
.bs-switch{flex:0 0 auto; width:42px; height:24px; border-radius:999px; background:var(--border-2); border:2px solid var(--ink); position:relative; transition:.2s var(--ease)}
.bs-switch::after{content:""; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:999px; background:var(--surface); border:1.5px solid var(--ink); transition:.2s var(--ease)}
.bs-toggle.on{border-style:solid; border-color:var(--sage)}
.bs-toggle.on .bs-switch{background:var(--sage)}
.bs-toggle.on .bs-switch::after{left:20px}
.budget-settings .bs-more{padding:0 2px}
.budget-settings .bs-more p{font-size:.8rem}

/* 5. Grille des offres : prix en avant, économie en pastille, liste en deux colonnes. */
.premium-plans{gap:12px; margin:20px 0 12px}
.plan-card{border:2px solid var(--border); border-radius:16px; padding:16px 16px 14px}
.plan-card.selected{border-color:var(--ink); background:var(--sage-soft); box-shadow:4px 4px 0 var(--ink)}
.plan-card .pc-label{min-height:0; font-size:.84rem; color:var(--ink-2); margin-bottom:10px}
.plan-card .pc-price{font-size:2rem; font-weight:800; letter-spacing:-.02em}
.plan-card .pc-sub{display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; color:var(--muted); font-weight:500; font-size:.8rem; padding-top:6px}
.pc-save{display:inline-block; padding:2px 8px; border-radius:999px; background:var(--terra-soft); color:var(--terra-text); font-weight:800; font-size:.72rem; white-space:nowrap}
.plan-note{background:none; padding:0 2px; margin:0 0 4px; font-size:.82rem; color:var(--ink-2)}
.premium-details.premium-details-open{border:0; background:none; margin:22px 0 6px; overflow:visible}
.premium-details-open .premium-details-head{background:none; border:0; padding:0 2px 12px; font-family:var(--sans); font-size:1rem; font-weight:800; color:var(--ink); margin:0}
.premium-feature-list.pf-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:4px 18px; padding:0}
.pf-grid .pf-row{padding:8px 4px}
.pf-grid .pf-desc{font-size:.8rem}
@media(max-width:880px){
  .plan-card{display:grid; grid-template-columns:1fr auto; grid-template-areas:"label price" "sub sub"; align-items:center; column-gap:12px; padding:14px 16px 12px 44px}
  .plan-card .pc-radio{left:14px; right:auto; top:18px}
  .plan-card .pc-label{grid-area:label; margin:0; padding-right:0}
  .plan-card .pc-price{grid-area:price; font-size:1.5rem; text-align:right}
  .plan-card .pc-sub{grid-area:sub; padding-top:4px}
  .plan-card .pc-badge{left:auto; right:14px; transform:none}
}

/* 6. Incitation chiffrée dans les Courses. */
.nudge-card{display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:0 0 16px; padding:14px 44px 14px 16px; position:relative;
  border-radius:16px; border:2px solid var(--ink); background:linear-gradient(135deg, color-mix(in srgb,var(--gold) 26%, var(--surface)), var(--surface)); box-shadow:var(--shadow-flat)}
.nudge-em{font-size:1.6rem; flex:0 0 auto}
.nudge-txt{flex:1 1 240px; display:flex; flex-direction:column; gap:3px; min-width:0}
.nudge-txt b{font-size:.94rem; color:var(--ink)}
.nudge-txt span{font-size:.8rem; color:var(--ink-2); line-height:1.45}
.nudge-x{position:absolute; top:8px; right:8px; width:30px; height:30px; border:0; background:none; color:var(--muted); border-radius:999px; cursor:pointer}
.nudge-x:hover{background:var(--surface-2); color:var(--ink)}

/* 7. Profil de moins de 18 ans. */
.tdee-note{margin:12px 0 0; padding:10px 12px; border-radius:12px; background:var(--surface-2); font-size:.82rem; color:var(--ink-2); line-height:1.5}

/* 8. Fiche recette : ce que couvre le placard. */
.di-placard{display:flex; flex-wrap:wrap; align-items:center; gap:4px 10px; width:100%; margin:0 0 12px; padding:10px 12px; border-radius:12px;
  background:var(--sage-soft); color:var(--ink-2); font-size:.86rem; line-height:1.45; text-align:left; border:1.5px solid transparent}
.di-placard b{color:var(--ink)}
.di-placard.is-teaser{cursor:pointer; border-style:dashed; border-color:var(--sage); font:inherit; font-size:.86rem}
.di-placard.is-teaser span{margin-left:auto; font-weight:700; color:var(--sage-text)}
.di-placard.is-teaser:hover{background:color-mix(in srgb,var(--sage-soft) 70%, var(--gold) 30%)}

/* 9. Récap de la semaine : jauge du budget. */
.recap-budget-bar{height:10px; border-radius:999px; background:var(--surface-2); border:1.5px solid var(--ink); overflow:hidden; margin:8px 0 6px}
.recap-budget-bar i{display:block; height:100%; background:var(--sage); border-radius:999px}
.recap-budget-bar.is-over i{background:var(--terra)}
.recap-budget-cta{border:0; background:none; padding:0; font:inherit; font-weight:700; color:var(--terra-text); cursor:pointer; text-align:left}
.recap-budget-cta:hover{text-decoration:underline}
.recap-block .rg-note a{color:var(--sage-text); font-weight:700}

/* 10. Bilan de fin d'essai : même gabarit que « Quoi de neuf », plus court. */
.modal:has(> .trial-recap){height:auto; max-height:90vh}
.trial-recap .wn-body{-webkit-mask-image:none; mask-image:none; padding-bottom:4px}
.trial-recap .wn-nav{margin-top:18px}

/* ==== PROFIL SIMPLIFIÉ (24/09/2026) ====
   Une colonne étroite, une carte d'identité, des rangées qui résument. Le détail
   vit dans des feuilles (openProfileSheet). */
#view-profil .view-head{margin-bottom:10px}
#view-profil .profil-tab-seg{margin-bottom:18px}
.profile-tabs-row{gap:14px !important; align-items:flex-start !important; overflow-x:auto; flex-wrap:nowrap !important; padding:2px 2px 6px; scrollbar-width:none}
.profile-tabs-row::-webkit-scrollbar{display:none}
.profile-tabs{flex-wrap:nowrap; gap:14px}
.ptab,.ptab-add{flex-direction:column; gap:6px; padding:0; border:0; background:none; min-width:64px; border-radius:0; cursor:pointer; font-family:inherit; color:var(--ink-2)}
.ptab:hover,.ptab-add:hover{border:0}
.ptab.on{background:none; color:var(--ink)}
.ptab-av{position:relative; width:52px; height:52px; border-radius:50%; display:grid; place-items:center; font-weight:800; font-size:1.2rem;
  background:var(--surface-2); color:var(--ink-2); border:2px solid var(--border-2); transition:.2s var(--ease)}
.ptab.on .ptab-av{background:var(--sage-soft); color:var(--sage-text); border-color:var(--ink); box-shadow:0 3px 0 var(--ink)}
.ptab-add .ptab-av{border-style:dashed; background:transparent; color:var(--muted)}
.ptab-add .ptab-av svg{width:20px; height:20px}
.ptab-n{font-size:.8rem; font-weight:700; max-width:76px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; display:flex; align-items:center; gap:3px}
.ptab-lock{position:absolute; right:-4px; bottom:-4px; font-size:.7rem; background:var(--surface); border-radius:50%; width:20px; height:20px; display:grid; place-items:center; border:1.5px solid var(--border)}
.ptab-add .premium-lock-chip{padding:0 4px; font-size:.7rem}
.pf-wrap{max-width:620px; display:flex; flex-direction:column; gap:26px; padding-bottom:12px}
.pf-id{background:var(--surface); border:2px solid var(--ink); border-radius:22px; box-shadow:0 4px 0 var(--ink); padding:20px 20px 18px}
.pf-id-top{display:flex; align-items:center; gap:14px}
.pf-avatar{flex:0 0 auto; width:60px; height:60px; border-radius:50%; display:grid; place-items:center; font-size:1.5rem; font-weight:800;
  background:var(--sage-soft); color:var(--sage-text); border:2px solid var(--ink)}
.pf-id-main{flex:1 1 auto; min-width:0}
.pf-name{margin:0; font-family:var(--sans); font-size:1.35rem; font-weight:800; line-height:1.2; overflow:hidden; text-overflow:ellipsis}
.pf-facts{margin:3px 0 0; font-size:.88rem; color:var(--muted)}
.pf-edit{flex:0 0 auto}
.pf-stats{display:grid; grid-template-columns:repeat(3,1fr); margin-top:18px; border-top:1px dashed var(--border); padding-top:16px}
.pf-stat{display:flex; flex-direction:column; align-items:center; gap:2px; text-align:center; padding:0 4px}
.pf-stat + .pf-stat{border-left:1px dashed var(--border)}
.pf-stat b{font-size:1.15rem; font-weight:800; color:var(--ink); line-height:1.2}
.pf-stat span{font-size:.74rem; color:var(--muted); font-weight:600}
.pf-complete{display:flex; align-items:center; gap:12px; width:100%; margin-top:16px; padding:12px 14px; border-radius:14px; border:1.5px dashed var(--border-2);
  background:var(--surface-2); text-align:left; cursor:pointer; font-family:inherit; color:var(--ink)}
.pf-complete > span:first-child{font-size:1.3rem}
.pf-complete b{display:block; font-size:.92rem}
.pf-complete small{display:block; font-size:.8rem; color:var(--muted); margin-top:2px}
.pf-complete .pf-chev{margin-left:auto}
.pf-lock,.pf-claim-wrap{margin:14px 0 0; font-size:.84rem; color:var(--muted); line-height:1.5}
.pf-group{display:flex; flex-direction:column; gap:10px}
.pf-gt{margin:0 4px; font-family:var(--sans); font-size:.78rem; letter-spacing:.08em; text-transform:uppercase; font-weight:800; color:var(--muted)}
.pf-list{background:var(--surface); border:1.5px solid var(--border-2); border-radius:18px; overflow:hidden}
.pf-row{display:flex; align-items:center; gap:14px; width:100%; min-height:58px; padding:12px 16px; border:0; background:none; text-align:left;
  font-family:inherit; font-size:.95rem; color:var(--ink); cursor:pointer}
.pf-row + .pf-row{border-top:1px solid var(--border)}
button.pf-row:hover{background:var(--surface-2)}
.pf-row.is-locked{cursor:default}
.pf-ico{flex:0 0 auto; width:28px; text-align:center; font-size:1.15rem}
.pf-lab{flex:1 1 auto; font-weight:700; min-width:0}
.pf-val{flex:0 1 auto; max-width:48%; color:var(--muted); font-size:.86rem; text-align:right; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.pf-chev{flex:0 0 auto; color:var(--muted); font-size:1.3rem; line-height:1; margin-left:-4px}
.pf-del-wrap{margin:0; text-align:center}
.pf-del{color:var(--danger); font-size:.86rem}
.pf-sheet{display:flex; flex-direction:column; gap:4px}
.pf-sheet .profile-card{border:0; box-shadow:none; background:none; padding:0}
.pf-sheet .profile-card > h2{display:none}
.pf-sheet .checks{gap:10px}
.pf-sheet-note{font-size:.82rem; color:var(--muted); margin:6px 2px 0; line-height:1.5}
#pRegimesBilan .pf-sheet-note{margin-top:12px}
.pf-sheet-note.pf-regimes-vide{color:var(--terra-text); font-weight:600}
.pf-hint-inline{font-weight:500; color:var(--muted)}
.pf-seg-col{flex-direction:column}
.pf-seg-col button{width:100%}
.pf-tdee .profile-empty{padding:10px 0}
.pf-sheet-foot .btn{max-width:none}
@media(max-width:560px){
  .pf-id{padding:18px 16px 16px}
  .pf-row{padding:12px 14px; gap:12px}
  .pf-val{max-width:42%}
}

/* ==== PREMIER PROFIL (24/09/2026) — une question par écran, la cocotte pose la question ==== */
.modal.fr-modal{max-width:520px; height:min(720px, 92vh); display:flex; flex-direction:column}
.fr-wrap{flex:1 1 auto; min-height:0; display:flex; flex-direction:column; padding:18px 22px 20px}
.fr-top{display:flex; align-items:center; gap:14px; flex:0 0 auto}
.fr-x{flex:0 0 auto; width:36px; height:36px; border-radius:50%; border:0; background:none; font-size:1.1rem; color:var(--muted); cursor:pointer}
.fr-x:hover{background:var(--surface-2); color:var(--ink)}
.fr-bar{flex:1 1 auto; height:14px; border-radius:999px; background:var(--surface-2); border:1.5px solid var(--border); overflow:hidden}
.fr-bar span{display:block; height:100%; width:0; background:var(--sage); border-radius:999px; transition:width .35s var(--ease)}
.fr-body{flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; padding:26px 2px 10px}
.fr-step{display:flex; flex-direction:column; gap:18px; animation:frIn .28s var(--ease) both}
.fr-step[data-dir="prev"]{animation-name:frInPrev}
@keyframes frIn{from{opacity:0; transform:translateX(18px)} to{opacity:1; transform:none}}
@keyframes frInPrev{from{opacity:0; transform:translateX(-18px)} to{opacity:1; transform:none}}
@media(prefers-reduced-motion:reduce){.fr-step{animation:none}}
.fr-head{display:flex; align-items:center; gap:14px}
.fr-coco .jeu-coco{width:92px; height:77px}
/* 15/10/2026 (cohérence) : les fenêtres centrées (rappels, maison, avis, partage…) posent la
   cocotte avec margin:0 auto, mais l'enveloppe prenait toute la largeur : elle restait à gauche. */
div.jeu-coco-wrap.fr-coco{width:fit-content}
.fr-bulle.jeu-bulle{text-align:left; font-size:1.05rem; width:auto; transform-origin:left center}
.fr-bulle.jeu-bulle::before{left:-10px; top:50%; transform:translateY(-50%) rotate(45deg)}
.fr-sub{margin:0; font-size:.9rem; color:var(--muted); line-height:1.5}
.fr-field{margin:0}
.fr-field input{font-size:1.1rem; padding:14px 16px}
.fr-grid{display:grid; gap:12px}
.fr-grid-2{grid-template-columns:repeat(2,1fr)}
.fr-grid-3{grid-template-columns:repeat(3,1fr)}
.fr-list{display:flex; flex-direction:column; gap:10px}
.fr-opt{border:2px solid var(--border-2); border-bottom-width:4px; border-radius:16px; background:var(--surface); padding:14px 12px; font-family:inherit;
  font-size:1rem; font-weight:700; color:var(--ink); cursor:pointer; transition:transform .08s var(--ease), background .15s}
.fr-opt:active{transform:translateY(2px); border-bottom-width:2px}
.fr-opt.on{background:var(--sage-soft); border-color:var(--sage); color:var(--sage-text)}
.fr-opt-l{text-align:left; display:flex; flex-direction:column; gap:3px; padding:14px 16px}
.fr-opt-l small{font-size:.8rem; font-weight:500; color:var(--muted); line-height:1.4}
/* 26/10/2026 : « Restes et batch cooking », le nombre de restes sous l'option choisie. */
.repetes-n{display:flex; flex-direction:column; gap:8px; margin:-2px 4px 4px 16px; font-size:.84rem; color:var(--muted)}
.repetes-n-chips{display:flex; gap:8px}
.repetes-n-chips .chip{min-height:44px; min-width:64px; font-size:.92rem; justify-content:center}
.fr-checks{gap:10px}
.fr-checks .check-chip{padding:10px 14px; font-size:.92rem}
.fr-dis:empty{display:none}
.fr-body-row{display:grid; grid-template-columns:repeat(3,1fr); gap:10px}
.fr-num{display:flex; flex-direction:column; gap:6px; font-size:.82rem; font-weight:700; color:var(--ink-2)}
.fr-num input{width:100%; font-size:1.05rem; padding:12px 10px; text-align:center; border-radius:12px; border:1.5px solid var(--border-2); background:var(--surface); color:var(--ink); font-family:inherit}
.fr-err{margin:0; min-height:1em; font-size:.84rem; color:var(--danger)}
.fr-foot{flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:6px; padding-top:12px; border-top:1px solid var(--border)}
.fr-next{font-size:1.02rem; padding:14px 18px}
.fr-skip,.fr-back{border:0; background:none; font-family:inherit; font-size:.88rem; font-weight:700; color:var(--muted); cursor:pointer; padding:6px 10px}
.fr-skip:hover,.fr-back:hover{color:var(--ink)}
.fr-back{font-weight:600; font-size:.8rem}
.fr-end{align-items:center; text-align:center; padding-top:20px}
.fr-coco-fin .jeu-coco{width:170px; height:142px}
.fr-end-t{margin:0; font-family:var(--sans); font-size:1.5rem; font-weight:800}
/* Le mot de Paul (08/10/2026) : une carte simple, signée, sous le message de la cocotte. */
.fr-mot{margin-top:8px; padding:14px 16px; border-radius:var(--radius); background:var(--surface-2); border:1px solid var(--border);
  text-align:left; font-size:.9rem; line-height:1.55; color:var(--ink-2)}
.fr-mot p{margin:0}
.fr-mot a{color:var(--sage-text); font-weight:600; text-decoration:underline; text-underline-offset:2px; overflow-wrap:anywhere}
.fr-mot .fr-mot-sig{margin-top:6px; font-family:var(--serif); font-style:italic; font-size:1.05rem; color:var(--ink); text-align:right}
@media(max-width:560px){
  .modal.fr-modal{height:100%; max-height:none}
  .fr-wrap{padding:14px 16px 16px}
  .fr-coco .jeu-coco{width:76px; height:64px}
}

/* retouches profil 24/09 */
.pf-txt{flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px}
.pf-row .pf-lab{flex:none}
.pf-row .pf-val{max-width:none; text-align:left; white-space:normal; overflow:visible; font-size:.84rem; line-height:1.35}
.pf-del{color:var(--muted); font-weight:600; font-size:.84rem; text-decoration:underline}
.pf-del:hover{color:var(--danger)}
.pf-tdee > h2:first-child{display:none}
.fr-back{font-size:1.6rem; line-height:1; font-weight:400; margin-left:-8px}
.fr-back[hidden]{display:none}
.fr-foot .fr-skip[hidden]{display:block; visibility:hidden}
@media(max-width:560px){ .pf-row .pf-val{max-width:none} }

/* Aération du 24/09, 2e passe. La cause du « tout collé » : le gap de .wn-body ne
   s'appliquait pas, les éléments sont enveloppés dans .wn-anim (bloc simple). On
   pose donc les espacements sur .wn-anim, élément par élément. */
.wn-anim{display:flex; flex-direction:column; align-items:center; width:100%}
.wn-anim .wn-fig{margin:4px auto 22px}
.wn-anim .wn-kicker{margin:0 0 8px}
.wn-anim .wn-title{margin:0 0 14px}
.wn-anim .wn-desc{margin:0}
.wn-anim .wn-points{margin:30px 0 0; gap:26px}
.wn-anim .wn-points .wp-t{gap:5px}
.wn-anim .wn-desc-after{margin:26px 0 0}
.wn-anim .wn-note{margin:32px 0 0; padding-top:18px}
@media(max-height:820px){ .wn-anim .wn-fig{margin-bottom:16px} .wn-anim .wn-points{margin-top:24px; gap:22px} }

/* ============ COQUILLE iOS — fluidité & barre d'onglets native (29/09/2026) ============
   data-coquille="ios" : posé par boot.js dès que Capacitor tourne sur iPhone.
   data-barre-native + --barre-native : posés par la coquille (SceneDelegate.swift,
   window.ioumiBarre.poser) quand la barre d'onglets Liquid Glass d'iOS 26 est en place.
   Hors app native, aucun de ces sélecteurs ne matche : le site ne change pas. */

/* Réglages tactiles d'app : pas de halo gris au tap, pas de délai de double-tap. */
html[data-coquille="ios"]{ -webkit-tap-highlight-color:transparent; -webkit-text-size-adjust:100% }
html[data-coquille="ios"] body{ touch-action:manipulation }

/* Barre native posée : la barre d'onglets web s'efface (visibility, pas display —
   le menu « Plus », qui vit dedans, doit rester affichable) et tout ce qui est
   ancré en bas passe au-dessus de la barre système. --barre-native comprend déjà
   l'encoche (hauteur mesurée depuis le bord bas de l'écran). */
html[data-barre-native] .main-nav{ visibility:hidden; pointer-events:none }
html[data-barre-native] .view-wrap{ padding-bottom:calc(var(--barre-native, 0px) + 26px) }
html[data-barre-native] .toast-wrap{ bottom:calc(var(--barre-native, 0px) + 14px) }
html[data-barre-native] #installBanner{ display:none !important }
html[data-barre-native] .overlay.has-sheet .modal.sheet{ padding-bottom:var(--barre-native, 0px) }
/* Seulement pour une feuille ancrée en bas : une modale centrée est déjà écartée de la
   barre par l'overlay (sinon la fiche recette gardait un trou de 95 px sous ses boutons). */
html[data-barre-native] .overlay.has-sheet .modal-foot.lib-sheet-foot,
html[data-barre-native] .overlay.has-sheet .modal-foot.detail-foot{ padding-bottom:calc(12px + var(--barre-native, 0px)) }
/* Menu « Plus » ouvert depuis l'onglet natif : feuille flottante au-dessus de la
   barre, même verre dépoli que partout (.glass-panel reste posé sur l'élément). */
html[data-barre-native] .nav-more-menu{
  visibility:visible; pointer-events:auto;
  position:fixed; top:auto; left:14px; right:14px;
  bottom:calc(var(--barre-native, 0px) + 14px); z-index:60;
  transform-origin:bottom center;
}

/* ==================================================================
   RETOURS MOBILE (Paul, 29/09/2026, captures iPhone)
   ------------------------------------------------------------------
   1. Écran de connexion / présentation : plein écran, plus de carte.
   2. Rien ne se cache plus sous la barre d'onglets ni la barre d'état
      (modales, popover de créneau : voir aussi positionPopover).
   3. Menu « Plus » opaque : le contenu ne transparaissait plus lisiblement.
   4. Bandeau « articles cochés », objectifs du foyer, bande des jours.
   5. Allègement général sous 880px : moins d'air perdu, moins de doublons.
   ================================================================== */
:root{ --sat:env(safe-area-inset-top, 0px); --sab:env(safe-area-inset-bottom, 0px) }

/* 1. Connexion plein écran sur mobile ------------------------------- */
@media(max-width:760px){
  #authGate{ padding:0; align-items:stretch; justify-content:stretch }
  /* 08/10/2026 : align-self, sinon la carte prend tout juste la hauteur de l'écran ; un
     formulaire plus haut que l'écran (360 px, captcha) débordait par le haut, hors de portée
     du défilement : logo coupé, « ‹ Retour » sur le premier bloc. */
  #authGate .authgate-card{
    align-self:flex-start;
    max-width:none; width:100%; min-height:100dvh; border:0; border-radius:0; box-shadow:none;
    background:transparent; backdrop-filter:none; -webkit-backdrop-filter:none;
    padding:calc(22px + var(--sat)) 22px calc(20px + max(var(--sab), var(--barre-native, 0px)));
    display:flex; flex-direction:column; justify-content:center;
  }
  /* la présentation garde ses boutons au bas de l'écran, le formulaire reste centré */
  #authGate .ob{ min-height:calc(100dvh - 42px - var(--sat) - max(var(--sab), var(--barre-native, 0px))) }
  #authGate .ob-slide{ min-height:0 }
  #authGate .ob-stage{ margin-top:8vh }
  #authGate .authgate-close{ top:calc(14px + var(--sat)); right:14px }
  #authGate .ob-back{ top:calc(14px + var(--sat)); left:12px }
  #authGate .ob-top{ min-height:44px }
}

/* 2. Modales : au-dessus de la barre native et de la barre d'état ---- */
html[data-barre-native] .overlay:not(.has-sheet){
  padding-top:calc(14px + var(--sat));
  padding-bottom:calc(14px + var(--barre-native, 0px));
}
html[data-barre-native] .modal{ max-height:calc(100dvh - 28px - var(--sat) - var(--barre-native, 0px)) }
html[data-barre-native] .modal-foot{ padding-bottom:16px }           /* la barre est déjà écartée par l'overlay */
.overlay:not(.has-sheet) .modal-foot.detail-foot{ padding-bottom:12px }   /* idem pour l'encoche : l'overlay s'en charge */
/* Clavier ouvert (data-clavier, posé par native.js) : la vue web est déjà réduite au-dessus
   du clavier et la barre d'onglets est cachée dessous. On rend à la modale toute la hauteur
   visible et on replie son sous-titre, pour que la liste qu'on cherche garde de la place
   (Paul, 29/09 : « l'encart est tout petit pour le défilement »). */
html[data-clavier] .overlay:not(.has-sheet){ padding-bottom:8px }
html[data-clavier] .modal{ max-height:calc(100dvh - 22px - var(--sat)) }
html[data-clavier] .overlay.has-sheet .modal.sheet{ padding-bottom:0; max-height:calc(100dvh - 8px - var(--sat)) }
html[data-clavier] .modal-head .mh-sub,
html[data-clavier] .modal-head > div > p{ display:none }
/* Recherche d'une recette au clavier : les filtres attendent, les résultats remontent
   juste sous le champ (.sel-saisie, posée au focus par bindSelector). Ils reviennent dès
   que le clavier se ferme. */
html[data-clavier] .modal-body.sel-saisie > .filter-group,
html[data-clavier] .modal-body.sel-saisie > .sel-fold,
html[data-clavier] .modal-body.sel-saisie > .sel-suggest-banner{ display:none }
html[data-clavier] .modal-body.sel-saisie > div:has(> #selCount){ display:none !important }   /* style en ligne display:flex */
@media(max-width:880px){
  .overlay:not(.has-sheet){ padding-top:calc(14px + var(--sat)); padding-bottom:calc(14px + var(--sab)) }
  .modal{ max-height:calc(100dvh - 28px - var(--sat) - var(--sab)) }
}

/* Popover de créneau : sa hauteur maxi change avec les bornes (positionPopover) ;
   elle ne doit pas s'animer, sinon la mesure qui suit lit encore l'ancienne. */
.popover{ transition:opacity .2s var(--ease), transform .2s var(--ease) }

/* 3. Menu « Plus » : fond plein --------------------------------------- */
@media(max-width:880px){
  .nav-more-menu.glass-panel{ background:var(--surface); backdrop-filter:none; -webkit-backdrop-filter:none }
}

/* 4. Bandeau « articles cochés » : le bouton passe dessous ------------ */
.transfer-banner{ flex-wrap:wrap; row-gap:8px }
.transfer-banner .tb-txt{ flex:1 1 150px; min-width:0 }
.transfer-banner .btn{ white-space:normal; line-height:1.3; text-align:center }
@media(max-width:560px){ .transfer-banner .btn{ flex:1 1 100%; justify-content:center } }

/* Objectifs du foyer : une personne par ligne, la valeur en dessous du nom */
.rgm-row{ flex-wrap:wrap; column-gap:8px; row-gap:0; align-items:center }
.rgm-name{ min-width:0; flex:1 1 auto }
.rgm-note{ margin-left:auto; white-space:nowrap }
.rgm-val{ flex:1 1 100%; order:3; white-space:nowrap }
@media(max-width:560px){ .recap .recap-goal{ grid-column:1 / -1 } }

/* Bande des jours : la puce coupée ne « passe » plus sous le chevron. 29/09 : le fondu
   n'est plus un mask-image sur l'élément qui défile (WebKit renonçait alors au défilement
   composité : la rangée saccadait sous le doigt) ; il est peint par deux voiles fixes
   posés sur la rangée, hors du défilement. */
.day-switch{ padding:2px 10px; overscroll-behavior-x:contain; -webkit-overflow-scrolling:touch }
.day-switch-row{ position:relative }
.day-switch-row::before, .day-switch-row::after{ content:""; position:absolute; top:0; bottom:0; width:14px; pointer-events:none; z-index:1 }
.day-switch-row::before{ left:50px; background:linear-gradient(90deg, var(--bg), transparent) }
.day-switch-row::after{ right:50px; background:linear-gradient(270deg, var(--bg), transparent) }
/* Les repas du jour : le navigateur garde le défilement vertical, le glissé horizontal
   est pour nous (paintDayView). */
.day-meals{ touch-action:pan-y; backface-visibility:hidden }

/* Têtes de rayon : le titre s'ellipse, les flèches restent dans l'écran */
.shop-cat-head{ min-width:0 }
.shop-cat-head .rayon-reorder{ flex:0 0 auto }

/* 5. Allègement mobile ------------------------------------------------ */
@media(max-width:880px){
  /* en-tête : le voyant « Enregistré » devient une coche seule, la pastille Premium
     s'efface (le couvercle de la cocotte passe déjà en moutarde) */
  .save-indicator:not(.sync-error){ font-size:0; gap:0 }
  .save-indicator svg{ width:16px; height:16px }
  body.is-premium .premium-mark{ display:none }
  .app-header{ gap:10px }
  /* titres de vue plus sobres, sous-titre plus court à l'œil */
  .view-head{ margin-bottom:16px; gap:12px }
  .view-title{ font-size:clamp(1.45rem,5vw,1.8rem) }
  .view-sub{ font-size:.82rem; margin-top:4px }
  /* carte de la semaine : la cocotte parle plus petit */
  .wg{ padding:14px 14px 12px; margin-bottom:14px; border-radius:18px }
  .jeu-coco-row{ gap:10px; margin-bottom:10px }
  .jeu-coco{ width:78px; height:65px }
  .jeu-bulle{ padding:9px 12px; font-size:.88rem; border-radius:14px; box-shadow:0 3px 0 var(--ink) }
  .wg-top{ margin-bottom:8px }
  .wg-count{ font-size:1.3rem }
  .wg-bar{ height:16px }
  .wg-foot{ margin-top:10px }
  .wg-serie{ font-size:.78rem }
  .jeu-defi{ margin-top:12px; padding:9px 12px; gap:10px; font-size:.84rem; border-radius:14px; box-shadow:0 2px 0 var(--ink) }
  .jeu-defi .jd-e{ width:34px; height:34px; font-size:1.05rem }
  .jeu-defi .jd-p{ font-size:.98rem; padding:3px 10px }
  .jeu-liens{ margin-top:10px; gap:6px 12px }
  .jeu-maison, .jeu-jeton{ font-size:.76rem }
  .jeu-lien-collec{ padding:7px 12px; font-size:.78rem; box-shadow:0 2px 0 var(--ink) }
  /* récap et liste de courses : blocs plus serrés */
  .recap{ margin-top:16px; gap:14px 16px; padding:16px 14px }
  .recap-block .rv{ font-size:1.55rem }
  .shop-prog-card{ padding:12px 14px; margin-bottom:12px }
  .shop-prog-card .spc-num{ font-size:1.3rem }
  .shop-cat{ margin-bottom:12px }
  .transfer-banner{ margin-bottom:10px !important }
}

/* ==================================================================
   COMMUTATEURS (Paul, 29/09/2026 : « à la Duolingo, c'est plus sympa »)
   ------------------------------------------------------------------
   Tout réglage oui/non est un <input type="checkbox" class="sw"> : piste
   épaisse cernée d'encre avec son ombre portée, pastille qui rebondit en
   passant de côté, s'écrase un instant sous le doigt, coche qui apparaît.
   Rien que du CSS : les écouteurs « change » existants ne bougent pas.
   .sw-row : l'intitulé à gauche, le commutateur à droite.
   ================================================================== */
input.sw{
  -webkit-appearance:none; appearance:none; box-sizing:border-box; flex:0 0 auto; order:9;
  position:relative; width:54px; height:32px; margin:0; padding:0; cursor:pointer;
  border-radius:999px; border:2px solid var(--ink); background:var(--border-2);
  box-shadow:0 3px 0 var(--ink);
  transition:background-color .25s var(--ease), box-shadow .12s var(--ease), transform .12s var(--ease);
}
input.sw::before{
  content:""; position:absolute; top:2px; left:2px; width:24px; height:24px; box-sizing:border-box;
  border-radius:999px; background:#fff; border:2px solid var(--ink);
  transition:transform .42s cubic-bezier(.34,1.7,.5,1), width .14s var(--ease);
}
input.sw::after{
  content:""; position:absolute; left:9px; top:8px; width:9px; height:5px;
  border-left:2.5px solid #fff; border-bottom:2.5px solid #fff; transform:rotate(-45deg) scale(.2); opacity:0;
  transition:opacity .18s var(--ease), transform .3s cubic-bezier(.34,1.7,.5,1);
}
input.sw:checked{ background:var(--sage) }
input.sw:checked::before{ transform:translateX(22px) }
input.sw:checked::after{ opacity:1; transform:rotate(-45deg) scale(1); transition-delay:.08s }
input.sw:active:not(:disabled){ transform:translateY(2px); box-shadow:0 1px 0 var(--ink) }
input.sw:active:not(:disabled)::before{ width:30px }
input.sw:checked:active:not(:disabled)::before{ transform:translateX(16px) }
input.sw:disabled{ opacity:.45; cursor:not-allowed }
[data-theme="dark"] input.sw::before{ background:var(--surface) }
@media (prefers-reduced-motion:reduce){ input.sw, input.sw::before, input.sw::after{ transition:none } }

.sw-row{ display:flex; align-items:center; justify-content:space-between; gap:14px; min-height:44px; cursor:pointer; font-size:.92rem; font-weight:600; line-height:1.4; color:var(--ink) }
.sw-row > span, .sw-row > strong{ flex:1 1 auto; min-width:0 }
.jeu-switch{ justify-content:space-between; gap:14px; min-height:44px }
.jeu-switch > span{ flex:1 1 auto }
.bs-toggle input.sw{ position:relative; opacity:1; width:54px; height:32px }
.bs-toggle:has(input:focus-visible){ outline:none }

/* Placard (29/09) : formulaire replié à un champ tant qu'on n'a rien tapé. */
.stock-add:not(.saisie) .sa-plus{ display:none }
.stock-add:not(.saisie) .stock-add-row{ grid-template-columns:1fr }
.stock-add:not(.saisie) .stock-add-row > .field.autoc-wrap{ grid-column:auto }
.stock-add:not(.saisie){ padding-top:12px; padding-bottom:12px }
.stock-vider{ display:flex; justify-content:center; margin:22px 0 4px }
.stock-vider .btn{ color:var(--muted) }

/* Budget (29/09) : le détail par rayon se déplie à la demande. */
.budget-cats-fold > summary{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; cursor:pointer; list-style:none; font-family:var(--serif); font-size:1.1rem }
.budget-cats-fold > summary::-webkit-details-marker{ display:none }
.budget-cats-fold > summary::after{ content:"›"; font-size:1.4rem; line-height:1; color:var(--muted); transition:transform .2s var(--ease) }
.budget-cats-fold[open] > summary::after{ transform:rotate(90deg) }
.budget-cats-fold > summary > span{ white-space:nowrap }
.budget-cats-fold > summary small{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-family:var(--sans); font-size:.78rem; color:var(--muted); font-weight:600; text-align:right }
.budget-cats-fold[open] .budget-cats{ margin-top:12px }

/* Fiche recette (29/09) : remplacements repliés derrière un 🔄 par ingrédient. */
.detail-ings li:not(.sub-open) .di-sub{ display:none }
.di-sub-btn{ border:0; background:var(--sage-pale, var(--surface-2)); border-radius:999px; font-size:.72rem; line-height:1; padding:4px 6px; margin-left:4px; cursor:pointer; vertical-align:1px }
.detail-ings li.sub-open .di-sub-btn{ background:var(--sage); }

/* ==================================================================
   LA COCOTTE AU CENTRE (Paul, 30/09/2026 : « trop fouillis… la sortir de
   son carré… à la Duolingo, où le design sert l'usage »)
   ------------------------------------------------------------------
   Bloc placé en dernier : il reprend l'écran Semaine, le récap et la fiche
   recette sans toucher aux calques précédents, et se retire d'un coup.
     1. La cocotte n'est plus dans une carte : elle est posée sur la page,
        grande, et parle au-dessus d'elle. C'est le personnage, pas un décor.
     2. Une seule bande de sept pastilles dit à la fois le jour affiché et les
        dîners prévus (pleines = prévu), comme les jours d'une série. Elle
        remplace la barre de progression ET la rangée de puces à flèches.
     3. Les cartes de repas passent en filet doux avec une ombre de socle :
        l'encre est réservée à ce qui compte (pastille du jour, bouton).
   ================================================================== */

/* 1. La cocotte et sa bulle ------------------------------------------ */
.wg{ background:none; border:0; box-shadow:none; padding:0; border-radius:0; margin:0 0 6px; text-align:center }
.jeu-coco-row{ flex-direction:column; align-items:center; gap:18px; margin:6px 0 10px }
.jeu-coco-row .jeu-bulle{
  order:-1; flex:0 1 auto; max-width:320px; text-align:center;
  padding:12px 18px; font-size:1.02rem; border-radius:20px; box-shadow:0 4px 0 var(--ink);
  transform-origin:center bottom;
}
.jeu-coco-row .jeu-bulle::before{ left:50%; top:auto; bottom:-9px; transform:translateX(-50%) rotate(-45deg) }
.jeu-coco-row .jeu-coco-wrap{ position:relative }
.jeu-coco-row .jeu-coco{ width:136px; height:113px }

.wg-top{ justify-content:center; align-items:center; gap:10px; margin-bottom:10px }
.wg-count{ font-size:1.15rem }
.wg-foot{ justify-content:center; text-align:center }
.wg-serie{ flex:1 1 100% }
.wg-cta{ flex:1 1 100%; justify-content:center; padding:15px 18px; font-size:1.02rem; border-radius:18px }
/* Le défi : une ligne qu'on touche, pas un deuxième encadré */
.jeu-defi{ border:0; box-shadow:none; background:var(--gold-soft); border-radius:16px; padding:10px 14px; margin-top:14px; text-align:left }
button.jeu-defi:active{ transform:scale(.98); box-shadow:none }
.jeu-defi .jd-e{ border:0; background:var(--surface) }
.jeu-defi .jd-p{ border:0; background:var(--surface); font-size:1rem }
.jeu-defi.is-done{ background:var(--sage-soft) }

/* 2. La bande des sept jours (vue jour, mobile) ---------------------- */
body.is-dayview .wg-bar{ display:none }
body.is-dayview .wg-top{ margin-bottom:0 }
.day-view .day-switch-row{ margin:8px 0 18px }
.day-view .day-switch-row::before, .day-view .day-switch-row::after{ display:none }
.day-view .day-switch{ display:grid; grid-template-columns:repeat(7,minmax(0,1fr)); gap:4px; overflow:visible; padding:0 }
.day-switch .chip.ws-day{
  display:flex; flex-direction:column; align-items:center; gap:6px; min-width:0;
  padding:7px 0 9px; border:2px solid transparent; border-radius:18px; background:none; box-shadow:none;
  color:var(--ink); font:inherit; animation:none; cursor:pointer;
  transition:background .15s var(--ease), border-color .15s var(--ease), transform .1s var(--ease);
}
.day-switch .chip.ws-day:hover{ border-color:var(--border) }
.day-switch .chip.ws-day:active{ transform:scale(.94) }
.ws-l{ font-size:.72rem; font-weight:800; letter-spacing:.04em; text-transform:uppercase; color:var(--muted) }
.ws-n{
  width:36px; height:36px; border-radius:50%; display:grid; place-items:center;
  border:2px solid var(--border-2); background:var(--surface); color:var(--ink-2);
  font-weight:800; font-size:.9rem; font-variant-numeric:tabular-nums; box-shadow:0 3px 0 var(--border-2);
}
.ws-n svg{ width:18px; height:18px }
.ws-day.has-diner .ws-n{ background:var(--sage); border-color:var(--sage-deep); color:#fff; box-shadow:0 3px 0 var(--sage-deep) }
.ws-day.is-today .ws-l{ color:var(--terra-text, var(--terra)) }
.ws-day.is-today:not(.has-diner) .ws-n{ border-color:var(--terra); box-shadow:0 3px 0 var(--terra); color:var(--terra-text, var(--terra)) }
.ws-day.is-off:not(.has-diner) .ws-n{ border-style:dashed; box-shadow:none; opacity:.6 }
.day-switch .chip.ws-day.on{ background:var(--surface); border-color:var(--ink); box-shadow:0 3px 0 var(--ink); color:var(--ink) }
.day-switch .chip.ws-day.on .ws-l{ color:var(--ink) }

/* 3. Les repas du jour : l'intitulé au-dessus, la carte en pleine largeur */
.day-view .day-meal-row{ display:block; margin-bottom:16px }
.day-view .day-meal-row .meal-label{
  flex-direction:row; justify-content:flex-start; gap:6px; min-width:0; padding:0 4px 7px;
  font-size:.74rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); text-align:left;
}
.day-view .day-meal-row .meal-label .me{ font-size:1rem }
.day-view .slot{ min-height:0; width:100% }
.day-view .slot.filled{
  display:grid; grid-template-columns:58px minmax(0,1fr); column-gap:14px; align-items:center; align-content:center;
  padding:12px 14px; border:2px solid var(--border); border-radius:20px; background:var(--surface);
  box-shadow:0 4px 0 var(--border);
}
.day-view .slot.filled:hover{ transform:none; border-color:var(--border-2); box-shadow:0 4px 0 var(--border-2) }
.day-view .slot.filled:active{ transform:translateY(3px); box-shadow:0 1px 0 var(--border) }
.day-view .slot.filled > *{ grid-column:2 }
.day-view .slot.filled > .slot-emoji{
  grid-column:1; grid-row:1 / span 6; align-self:center;
  width:58px; height:58px; border-radius:18px; background:var(--surface-2); display:grid; place-items:center;
  font-size:2rem; opacity:1;
}
.day-view .slot-src{ position:static; justify-self:start; margin:0 0 5px; font-size:.72rem }
.day-view .slot-name{ margin-top:0; font-size:1rem; font-weight:700; line-height:1.25; padding-right:22px }
.day-view .slot-meta{ padding-top:5px; font-size:.8rem }
.day-view .slot-profiles{ margin-top:6px }
.day-view .slot-cooked-badge{ top:10px; right:10px }
.day-view .slot.filled.is-leftover{ background:var(--sage-soft); border-style:dashed }
.day-view .slot.empty{
  flex-direction:row; gap:10px; min-height:64px; border:2px dashed var(--border-2); border-radius:20px;
  background:transparent; opacity:1; color:var(--muted);
}
.day-view .slot.empty::after{ content:"Choisir un plat"; font-weight:700; font-size:.9rem }
.day-view .slot.empty .plus{ width:28px; height:28px }

/* 4. Le récap : un titre, des tuiles, le budget d'abord ------------- */
.recap-titre{ font-family:var(--serif); font-weight:400; font-size:1.2rem; margin:30px 4px 12px; color:var(--ink) }
.recap{
  margin-top:0; background:none; border:0; padding:0; border-radius:0;
  display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px;
}
.recap-block{ background:var(--surface); border:2px solid var(--border); border-radius:18px; padding:14px 16px; min-width:0 }
.recap-block.recap-budget{ grid-column:1 / -1; background:var(--sage-soft); border-color:transparent }
.recap-block.recap-macros, .recap-block.recap-goal{ grid-column:1 / -1 }
.recap-block .rl{ font-size:.7rem; letter-spacing:.07em }
.recap-block .rv{ font-size:1.6rem; font-variant-numeric:tabular-nums }
@media(max-width:880px){
  .recap{ gap:10px; padding:0; margin-top:0 }
  .recap-block .rv{ font-size:1.45rem }
}

/* 5. La fiche recette ----------------------------------------------- */
.modal-head.detail-head{ border-bottom:0; padding-bottom:0; justify-content:flex-end; min-height:0 }
.detail-hero{ flex-direction:column; align-items:center; text-align:center; gap:12px; margin:0 0 6px }
.detail-emoji{
  width:112px; height:112px; border-radius:50%; font-size:3.8rem; background:var(--gold-soft);
  border:2px solid var(--ink); box-shadow:0 5px 0 var(--ink);
}
.detail-photo{ padding:0; border:0; background:none; flex-shrink:0; cursor:pointer }
.detail-photo img{ width:180px; height:130px; object-fit:cover; border-radius:22px; display:block; border:2px solid var(--ink); box-shadow:0 5px 0 var(--ink) }
.detail-hero-txt{ min-width:0; width:100% }
.detail-hero .rd-title{ font-size:clamp(1.55rem, 6vw, 1.9rem); margin:0 }
.detail-desc{ color:var(--muted); margin:6px auto 0; font-size:.95rem; max-width:34ch; line-height:1.45 }
.detail-faits{ display:flex; flex-wrap:wrap; justify-content:center; gap:6px; margin:12px 0 0 }
.detail-faits span{ background:var(--surface-2); border-radius:999px; padding:6px 11px; font-size:.8rem; font-weight:700; color:var(--ink-2); white-space:nowrap }
.detail-hero .rcard-tags{ justify-content:center; margin-top:8px }
.detail-hero .photo-add-link{ margin:8px auto 0 }
.detail-coco{ display:flex; align-items:center; gap:12px; margin:18px 0 14px }
.detail-coco .jeu-coco{ width:78px; height:65px }
.detail-coco .jeu-bulle{ padding:11px 14px; font-size:.9rem; font-weight:600; border-radius:16px; box-shadow:0 3px 0 var(--ink); line-height:1.4 }
.detail-coco .di-placard{ display:block; margin:0; padding:0; border:0; background:none; width:auto; text-align:left; font:inherit; color:inherit; border-radius:0 }
.detail-coco .di-placard b{ display:block }
.detail-coco .di-placard.is-teaser span{ display:block; margin:4px 0 0 }
.detail-vote{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:0 0 4px }
.detail-vote .chip{ justify-content:center; padding:12px 10px; font-size:.98rem; font-weight:700; border-radius:16px; box-shadow:0 3px 0 var(--ink) }
.detail-vote .chip:active{ transform:translateY(3px); box-shadow:0 0 0 var(--ink) }
.vote-shared-note{ background:none; border:0; padding:0; margin:8px 0 0; text-align:center; font-size:.76rem; color:var(--muted) }

/* En haut de la Semaine, sur téléphone : la cocotte dit déjà où on en est. */
@media(max-width:880px){ #weekSub{ display:none } }
@media (prefers-reduced-motion:reduce){
  .day-switch .chip.ws-day, .day-view .slot.filled{ transition:none }
}

/* ==================================================================
   AÉRATION ET MOUVEMENT (Paul, 30/09/2026, deuxième passe : « ça manque
   d'aération et de minimalisme visuel » ; « augmenter le motion design de
   la cocotte »). Même règle que le bloc précédent : retirable d'un coup.
   ================================================================== */
.jeu-coco-row .jeu-coco-wrap{ cursor:pointer; -webkit-tap-highlight-color:transparent }
.jeu-coco .jc-yeux .jc-reflet{ fill:var(--bg) }
/* L'ombre au sol reste posée pendant que la cocotte flotte */
.jeu-coco-row::after{
  content:""; order:5; width:96px; height:12px; border-radius:50%;
  background:#14213D; opacity:.1; margin-top:-34px; pointer-events:none;
}
html[data-theme="dark"] .jeu-coco-row::after{ background:#000; opacity:.45 }

/* Aération : moins de traits, plus d'espace -------------------------- */
@media(max-width:880px){
  #view-semaine .view-title{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap }
  #view-semaine .view-head{ margin-bottom:8px }
  #view-semaine .week-actions .week-nav{ background:none; border:0; box-shadow:none }
}
.wg{ margin:10px 0 4px }
.wg-count{ font-size:1.05rem; color:var(--ink-2) }
.jeu-defi{
  background:none; width:auto; max-width:100%; margin:8px auto 0; padding:6px 4px; gap:8px;
  justify-content:center; font-size:.86rem; color:var(--ink-2);
}
.jeu-defi.is-done{ background:none; color:var(--sage-text) }
.jeu-defi .jd-e{ width:auto; height:auto; background:none; font-size:1rem }
.jeu-defi .jd-t{ flex:0 1 auto; font-weight:600 }
.jeu-defi .jd-t b{ display:none }
.jeu-defi .jd-t::before{ content:"Défi : "; font-weight:800; color:var(--gold-deep) }
.jeu-defi.is-done .jd-t::before{ color:var(--sage-text) }
.jeu-defi .jd-p{ background:var(--surface-2); font-size:.82rem; padding:3px 9px; font-family:var(--sans); font-weight:800 }
.jeu-defi .jd-go{ font-size:1.2rem }

.day-view .day-switch-row{ margin:18px 0 30px }
.day-view .day-meal-row{ margin-bottom:24px }
.day-view .day-meal-row .meal-label{ font-weight:700; letter-spacing:.08em; padding-bottom:9px; opacity:.85 }
.day-view .slot.filled{
  grid-template-columns:50px minmax(0,1fr); column-gap:14px; padding:16px 18px;
  border:0; border-radius:22px; background:var(--surface);
  box-shadow:0 1px 2px rgba(20,33,61,.05), 0 10px 24px -14px rgba(20,33,61,.28);
  transition:transform .15s var(--ease), box-shadow .15s var(--ease);
}
html[data-theme="dark"] .day-view .slot.filled{ box-shadow:none }
.day-view .slot.filled:hover{ border:0; box-shadow:0 1px 2px rgba(20,33,61,.05), 0 14px 28px -14px rgba(20,33,61,.34) }
.day-view .slot.filled:active{ transform:scale(.97); box-shadow:0 1px 2px rgba(20,33,61,.05) }
.day-view .slot.filled > .slot-emoji{ width:50px; height:50px; background:none; font-size:2.3rem }
.day-view .slot-src{ background:none; border:0; padding:0; font-size:.72rem; font-weight:700; margin:0 0 3px; box-shadow:none }
.day-view .slot-profiles{ display:none }
.day-view .slot.filled.is-leftover{ background:var(--sage-soft); border:0 }
.day-view .slot.empty{ min-height:58px; border:2px dashed var(--border); border-radius:22px }

.recap-titre{ margin:44px 4px 14px }
.recap{ gap:12px }
.recap-block{ border:0; padding:16px 18px; border-radius:20px }
.recap-block.recap-budget{ background:var(--sage-soft) }

.detail-hero{ margin-bottom:10px }
.detail-coco{ margin:22px 0 18px }
.detail-vote{ margin-bottom:10px }
.detail-vote .chip{ border-width:2px }

/* Mouvement ----------------------------------------------------------- */
@media (prefers-reduced-motion:no-preference){
  /* Au repos, elle flotte ; son ombre respire en dessous */
  .jeu-coco-row .jeu-coco-wrap{ animation:cocoFlotte 3.4s ease-in-out infinite }
  .jeu-coco-row::after{ animation:cocoOmbre 3.4s ease-in-out infinite }
  /* Entrée : la bulle attend l'atterrissage (scène « salut » de jeu.js) */
  .jeu-coco-row.is-entree .jeu-bulle{ animation:bulleEntree .5s cubic-bezier(.2,1.5,.4,1) 1s both }
  .jeu-coco-row.is-entree::after{ animation:ombreEntree .6s ease-out .45s both, cocoOmbre 3.4s ease-in-out 1.1s infinite }
  /* Le bouton de la cocotte respire tant qu'il y a des dîners à poser */
  .wg-cta{ animation:ctaRespire 2.8s ease-in-out 1.6s infinite }
  .wg-cta:active{ animation:none }
  /* La bande des jours arrive en cascade, la pastille choisie rebondit */
  .day-view.is-entree .ws-day{ animation:wsEntree .45s cubic-bezier(.2,1.4,.4,1) both; animation-delay:calc(.35s + var(--i) * 55ms) }
  .day-switch .chip.ws-day.on{ animation:wsChoix .38s cubic-bezier(.2,1.7,.4,1) }
  .day-view.is-entree .ws-day.on{ animation:wsEntree .45s cubic-bezier(.2,1.4,.4,1) both; animation-delay:calc(.35s + var(--i) * 55ms) }
  /* Un dîner posé : la pastille saute, la coche se dessine */
  .ws-day.is-new .ws-n{ animation:wsPop .6s cubic-bezier(.2,1.6,.4,1) }
  .ws-day.is-new .ws-n polyline{ stroke-dasharray:24; stroke-dashoffset:24; animation:wsCoche .35s ease-out .22s forwards }
  /* Les repas du jour montent un par un */
  .day-view.is-entree .day-meal-row{ animation:repasEntree .5s cubic-bezier(.2,.9,.3,1.1) both }
  .day-view.is-entree .day-meal-row:nth-child(1){ animation-delay:.55s }
  .day-view.is-entree .day-meal-row:nth-child(2){ animation-delay:.62s }
  .day-view.is-entree .day-meal-row:nth-child(3){ animation-delay:.69s }
  .day-view.is-entree .day-meal-row:nth-child(4){ animation-delay:.76s }
  /* Fiche recette : la bulle sort après le coup de couvercle */
  .detail-coco.is-entree .jeu-bulle{ transform-origin:left center; animation:bulleEntree .45s cubic-bezier(.2,1.5,.4,1) .5s both }
  .detail-hero .detail-emoji{ animation:emojiEntree .55s cubic-bezier(.2,1.5,.4,1) both }
}
@keyframes cocoFlotte{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-6px) } }
@keyframes cocoOmbre{ 0%,100%{ transform:scaleX(1); opacity:.1 } 50%{ transform:scaleX(.8); opacity:.06 } }
@keyframes ombreEntree{ 0%{ transform:scaleX(.2); opacity:0 } 100%{ transform:scaleX(1); opacity:.1 } }
@keyframes bulleEntree{ 0%{ transform:translateY(12px) scale(.4); opacity:0 } 100%{ transform:none; opacity:1 } }
@keyframes ctaRespire{ 0%,100%{ transform:scale(1) } 50%{ transform:scale(1.025) } }
@keyframes wsEntree{ 0%{ transform:translateY(14px) scale(.6); opacity:0 } 100%{ transform:none; opacity:1 } }
@keyframes wsChoix{ 0%{ transform:scale(.9) } 60%{ transform:scale(1.06) } 100%{ transform:none } }
@keyframes wsPop{ 0%{ transform:scale(.4) } 55%{ transform:scale(1.28) } 100%{ transform:none } }
@keyframes wsCoche{ to{ stroke-dashoffset:0 } }
@keyframes repasEntree{ 0%{ transform:translateY(18px); opacity:0 } 100%{ transform:none; opacity:1 } }
@keyframes emojiEntree{ 0%{ transform:scale(.5) rotate(-12deg); opacity:0 } 100%{ transform:none; opacity:1 } }
/* ==================================================================
   SEMAINE EN PAYSAGE — calendrier plein écran (30/09/2026)
   ==================================================================
   Paul : « une vue semaine style calendrier quand on tourne l'appareil à
   l'horizontale ». Téléphone tourné (paysage, hauteur ≤ 500 px) sur l'onglet
   Semaine : body.is-paysage-semaine (voir appliquerModePaysage dans app.js).
   L'en-tête, la barre d'onglets, les bandeaux, la cocotte et le récap
   s'effacent ; il reste la navigation de semaine et les 7 jours × 4 repas,
   tenus dans l'écran sans défilement horizontal. On revient au reste de
   l'app en remettant le téléphone droit. */
body.is-paysage-semaine .app-header,
body.is-paysage-semaine .main-nav,
body.is-paysage-semaine .app-footer,
body.is-paysage-semaine #trialBanner,
body.is-paysage-semaine #demoBanner,
body.is-paysage-semaine #installBanner,
body.is-paysage-semaine #view-semaine .view-head > div:first-child,
body.is-paysage-semaine #view-semaine > :not(.view-head):not(#gridScroll){ display:none !important }
body.is-paysage-semaine .view-wrap,
html[data-barre-native] body.is-paysage-semaine .view-wrap{
  max-width:none;
  padding:calc(4px + env(safe-area-inset-top)) calc(8px + env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) calc(8px + env(safe-area-inset-left));
}
body.is-paysage-semaine #view-semaine .view-head{ margin:0 0 4px; gap:0 }
body.is-paysage-semaine #view-semaine .week-actions{ width:100%; gap:6px }
body.is-paysage-semaine #view-semaine .week-bar-mobile{ width:100%; display:flex; align-items:center; gap:8px; flex-wrap:nowrap }
body.is-paysage-semaine #view-semaine .week-nav-row{ flex:1 1 auto; display:flex; justify-content:center; gap:8px }
body.is-paysage-semaine #view-semaine .week-menu-wrap{ flex:0 0 auto }
body.is-paysage-semaine #view-semaine .week-bar-mobile .btn{ min-height:34px; padding:4px 12px }
body.is-paysage-semaine .grid-scroll{ overflow:visible; margin:0; padding:0; scroll-snap-type:none }
body.is-paysage-semaine .week-grid{
  grid-template-columns:44px repeat(7, minmax(0,1fr));
  grid-template-rows:auto repeat(4, minmax(0,1fr));
  min-width:0; gap:5px; padding:0;
  height:calc(100dvh - 54px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
}
body.is-paysage-semaine .week-grid .gh.corner,
body.is-paysage-semaine .week-grid .meal-label{ position:static; box-shadow:none; background:none }
body.is-paysage-semaine .week-grid .gh{ padding:2px; flex-direction:row; gap:4px }
body.is-paysage-semaine .week-grid .gh-day{ font-size:.76rem }
body.is-paysage-semaine .week-grid .gh-date{ font-size:.72rem }
body.is-paysage-semaine .week-grid .meal-label{ font-size:0; gap:0; padding:0 }
body.is-paysage-semaine .week-grid .meal-label .me{ font-size:1.1rem }
body.is-paysage-semaine .week-grid .slot{ min-height:0; padding:5px 6px; border-radius:10px; box-shadow:none }
body.is-paysage-semaine .week-grid .slot-src,
body.is-paysage-semaine .week-grid .slot-meta,
body.is-paysage-semaine .week-grid .slot-profiles,
body.is-paysage-semaine .week-grid .slot-extras-badge,
body.is-paysage-semaine .week-grid .slot-free-list,
body.is-paysage-semaine .week-grid .slot-leftover-tag,
body.is-paysage-semaine .week-grid .slot-now-tag,
body.is-paysage-semaine .week-grid .slot-note-badge{ display:none }
body.is-paysage-semaine .week-grid .slot-emoji{ font-size:1rem }
body.is-paysage-semaine .week-grid .slot-name{
  font-size:.7rem; margin-top:2px; line-height:1.18;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden;
}
/* iPhone SE, petits Android (≤ 380 px de haut) : 2 lignes, la 3e serait rognée. */
@media (max-height:380px){ body.is-paysage-semaine .week-grid .slot-name{ -webkit-line-clamp:2 } }
body.is-paysage-semaine .week-grid .slot.is-leftover{ opacity:.7 }
body.is-paysage-semaine .week-grid .slot-cooked-badge{ top:3px; right:3px; transform:scale(.8) }
body.is-paysage-semaine .week-grid .slot.empty .plus{ width:22px; height:22px; font-size:1.05rem }
/* ==================================================================
   ATTACHE (30/09/2026) — tirelire, carnet, pause, foyer (attache.js)
   ================================================================== */
.wg-stamp.pause{ border-style:dashed; background:transparent; opacity:.7 }
.wg-tirelire{ display:inline-flex; align-items:center; gap:6px; padding:5px 12px; border-radius:999px;
  border:2px solid var(--ink); background:var(--surface); color:var(--ink); font:inherit; font-size:.78rem; font-weight:700; cursor:pointer }
.wg-tirelire:active{ transform:var(--press) }
.at-pause-bandeau{ display:flex; align-items:center; gap:10px; margin:0 0 12px; padding:10px 12px; border-radius:var(--radius-sm);
  background:var(--surface-2); color:var(--ink-2); font-size:.86rem; line-height:1.4 }
.at-pause-bandeau span:nth-child(2){ flex:1 }
.at-pause-bandeau .btn{ flex:0 0 auto; min-height:34px; padding:4px 12px }
.at-carnet{ padding-top:6px }
.at-tirelire{ text-align:center; padding:16px 12px 12px; border-radius:var(--radius-sm); background:var(--sage-soft); margin-bottom:18px }
.at-tirelire.at-vide{ background:var(--surface-2) }
.at-montant{ font-family:var(--display, inherit); font-size:2.2rem; font-weight:800; line-height:1.1; color:var(--sage-text) }
.at-sous{ font-size:.88rem; color:var(--ink-2); margin-top:4px; line-height:1.45 }
.at-lignes{ list-style:none; margin:14px 0 0; padding:0; text-align:left }
.at-lignes li{ display:flex; align-items:flex-start; gap:10px; padding:8px 0; border-top:1px solid var(--border) }
.at-lignes .at-e{ font-size:1.1rem; line-height:1.3 }
.at-lignes .at-t{ flex:1; display:flex; flex-direction:column; font-size:.84rem }
.at-lignes .at-t small{ color:var(--muted); font-size:.74rem; margin-top:2px }
.at-lignes .at-v{ font-weight:700; font-size:.88rem; white-space:nowrap }
.at-note{ font-size:.72rem; color:var(--muted); margin:10px 0 0; text-align:left }
.at-h{ font-size:.95rem; margin:4px 0 10px }
.at-tuiles{ display:grid; grid-template-columns:repeat(auto-fill, minmax(96px,1fr)); gap:8px; margin-bottom:18px }
.at-tuile{ display:flex; flex-direction:column; align-items:center; gap:2px; padding:10px 6px; border-radius:var(--radius-sm); background:var(--surface-2); text-align:center }
.at-tuile b{ font-size:1.2rem }
.at-tuile small{ font-size:.72rem; color:var(--ink-2); line-height:1.25 }
.at-classiques{ display:flex; flex-direction:column; gap:6px; margin-bottom:18px }
.at-classique{ display:flex; align-items:center; gap:10px; padding:9px 12px; border-radius:var(--radius-sm); border:2px solid var(--ink);
  background:var(--surface); color:var(--ink); font:inherit; text-align:left; cursor:pointer }
.at-classique .at-cn{ flex:1; font-weight:600; font-size:.88rem }
.at-classique small{ color:var(--muted); font-size:.76rem }
.at-export p{ font-size:.84rem; color:var(--ink-2); margin:0 0 10px }
.at-foyer-note{ font-size:.76rem; color:var(--muted); line-height:1.5; margin:12px 0 0 }
.at-pause-seg{ display:flex; flex-wrap:wrap }
.at-pause-seg button{ flex:1 1 0 }
/* ==================================================================
   DÉCLIC (30/09/2026) — semaine en un tap, ce soir, drive (declic.js)
   ================================================================== */
.dc-lien{ background:none; border:0; padding:0; font:inherit; font-weight:700; color:var(--sage-text); text-decoration:underline; cursor:pointer }
.dc-x{ background:none; border:0; color:var(--muted); font-size:1rem; line-height:1; padding:6px; cursor:pointer;
  min-width:44px; min-height:44px; display:inline-flex; align-items:center; justify-content:center; border-radius:12px }
.wg-foot .dc-cap{ flex:1 1 100%; font-size:.8rem; line-height:1.45; color:var(--ink-2); text-align:center; margin-top:2px }
.dc-bilan{ display:flex; flex-wrap:wrap; align-items:center; gap:8px 10px; margin-top:12px; padding:10px 12px; border-radius:var(--radius-sm);
  background:var(--sage-soft); color:var(--ink); font-size:.84rem; line-height:1.45 }
.dc-bilan b{ color:var(--sage-text) }
.dc-bilan-t{ flex:1 1 200px }
.dc-bilan-b{ display:flex; align-items:center; gap:4px; margin-left:auto }
.dc-soir{ margin:0 0 14px; padding:12px; border-radius:var(--radius-sm); background:var(--sage-soft); color:var(--ink) }
.dc-soir-h{ position:relative; margin-bottom:8px; padding-right:38px }
.dc-soir-h h2{ font-size:1rem; margin:0 0 2px; color:var(--sage-text) }
.dc-soir-s{ font-size:.76rem; color:var(--ink-2) }
.dc-soir-x{ position:absolute; top:-8px; right:-8px }
.dc-soir-l{ display:flex; flex-direction:column; align-items:flex-end; gap:2px; margin-top:8px }
.dc-soir-pose{ display:flex; align-items:center; gap:10px; width:100%; padding:10px 12px; border-radius:var(--radius-sm); border:2px solid var(--ink);
  background:var(--surface); color:var(--ink); font:inherit; text-align:left; cursor:pointer; -webkit-tap-highlight-color:transparent }
.dc-soir-pose:active{ transform:var(--press) }
.dc-soir-e{ font-size:1.5rem; line-height:1; flex:0 0 auto }
.dc-soir-t{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px }
.dc-soir-t b{ font-size:.9rem }
.dc-soir-t small{ font-size:.76rem; color:var(--ink-2); line-height:1.4 }
.dc-soir-t .dc-urg{ color:var(--terra-text); font-weight:700 }
.dc-soir-go{ flex:0 0 auto; font-size:.8rem; font-weight:800; padding:6px 10px; border-radius:999px; background:var(--sage); color:var(--on-accent) }
.dc-soir-fiche{ font-size:.76rem; padding:2px 4px }
.dc-drive{ display:flex; align-items:center; flex-wrap:wrap; gap:8px 12px; margin:0 0 12px; padding:10px 12px; border-radius:var(--radius-sm);
  background:var(--surface-2); color:var(--ink) }
.dc-drive-t{ flex:1 1 180px; display:flex; flex-direction:column; font-size:.86rem }
.dc-drive-t small{ font-size:.74rem; color:var(--ink-2); margin-top:2px }
.dc-drive .btn{ flex:0 0 auto }
/* Dévoilement de la semaine en un tap (30/09/2026, point 4) : les dîners se retournent
   comme des cartes, puis le bilan arrive. visibility et non opacity : les animations
   d'app.js (just-suggested, ioumi-stamped) peuvent tourner dessous sans les montrer. */
.slot.dc-cache, .dc-bilan.dc-cache, .ws-day.dc-cache .ws-n{ visibility:hidden }
.slot.dc-revele, .ws-day.dc-revele{ animation:dcRetourne .46s cubic-bezier(.2,1.3,.4,1) both; transform-origin:50% 50% }
.dc-bilan.dc-revele-bilan{ animation:dcBilanMonte .38s var(--ease) both }
@keyframes dcRetourne{ 0%{ transform:perspective(500px) rotateY(88deg) scale(.92); opacity:.2 } 60%{ transform:perspective(500px) rotateY(-10deg) scale(1.04); opacity:1 } 100%{ transform:none } }
@keyframes dcBilanMonte{ from{ transform:translateY(8px); opacity:0 } to{ transform:none; opacity:1 } }
@media (prefers-reduced-motion: reduce){ .slot.dc-revele, .ws-day.dc-revele, .dc-bilan.dc-revele-bilan{ animation:none } .slot.dc-cache, .dc-bilan.dc-cache, .ws-day.dc-cache .ws-n{ visibility:visible } }
/* ===== Audit UX du 01/10/2026 ===== */
/* Cibles tactiles (audit 01/10/2026) : 44 × 44 px au moins (Apple HIG, WCAG 2.5.5),
   par une zone invisible quand le dessin doit rester petit, comme .mini-btn plus haut. */
#view-semaine .week-actions .week-nav button, .ing-del, .rayon-move, .fr-x, .trial-banner .tb-fermer{position:relative}
#view-semaine .week-actions .week-nav button::before, .ing-del::before, .rayon-move::before, .fr-x::before, .trial-banner .tb-fermer::before{content:''; position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%)}
.modal-close{width:44px; height:44px}
#storeModeWrap .scheck{width:40px; height:40px}

/* Bascule Liste / Placard en tête de l'onglet Courses. */
.seg-cp{display:flex; gap:4px; padding:4px; margin:0 0 14px; background:var(--surface-2); border:var(--bw) solid var(--ink); border-radius:999px; max-width:360px}
.seg-cp-btn{flex:1; min-height:44px; border:0; border-radius:999px; background:none; color:var(--ink-2); font:inherit; font-weight:700; font-size:.95rem; cursor:pointer}
.seg-cp-btn.on{background:var(--sage); color:var(--on-accent); box-shadow:var(--shadow-flat)}
/* Cartes secondaires de la semaine, rangées sous la grille par ioumiRangerSemaine. */
.week-extras{display:flex; flex-direction:column; gap:12px; margin-top:18px}
.week-extras:empty{display:none}
.week-extras > *{margin:0 !important; width:100%}
.week-extras #tonightStockBanner{order:1}
.week-extras #hsPlacard{order:2}
.week-extras #jeuOuvrirCollection{order:3}
.week-extras #ofDoux{order:4}
/* Retours TestFlight du 02/10/2026 ------------------------------------------- */
/* Boutons plus aérés (Paul : « tout plats et serrés ») : 48 px de haut au moins,
   52 px pour les boutons pleine largeur, et 12 px entre deux boutons empilés.
   Les petits boutons (.btn-sm) gardent leur gabarit compact. */
.btn{min-height:48px; padding-top:12px; padding-bottom:12px}
.btn.btn-block{min-height:52px; font-size:.98rem; padding-top:14px; padding-bottom:14px}
.btn.btn-sm{padding-top:8px; padding-bottom:8px}
.btn-block + .btn-block{margin-top:16px !important}
.ob-foot{gap:16px}
/* Système unique (02/10/2026, mesuré sur les 7 vues : 5 tailles de texte de bouton,
   5 rayons de carte, 6 tailles de titre de carte). Une seule échelle désormais. */
.btn{font-size:.94rem; font-weight:700; border-radius:14px; letter-spacing:.005em}
.btn.btn-block{font-size:1rem}
.btn.btn-sm{font-size:.82rem; border-radius:12px}
.section-card, .profile-card{border-radius:var(--radius-lg)}
.section-card > h2, .profile-card > h2{font-family:var(--sans); font-size:1.15rem; font-weight:700; line-height:1.25; letter-spacing:0}
/* Petites commandes visibles à 40 px au moins (détecteur du 02/10 : 30 à 32 px). */
.si-more-btn, .rayon-move, .mini-btn, #view-semaine .week-actions .week-nav button{width:40px !important; height:40px !important; min-width:40px; border-radius:12px}
.si-more-btn svg, .mini-btn svg{width:18px; height:18px}
.rayon-move{font-size:.85rem}
.day-chip{min-height:40px; padding:8px 14px}
.profil-tab-seg button{min-height:44px; padding-left:16px; padding-right:16px}
/* 05/10/2026 (Paul, captures iPhone : « Sans limite », « Sédentaire » coupés) : min-width:0
   laissait un bouton rétrécir sous son mot le plus long. min-content garde chaque mot entier ;
   la rangée passe à la ligne (flex-wrap) quand tout ne tient pas. */
#app .seg button, body .seg button{padding-left:8px; padding-right:8px; min-width:min-content; font-size:.88rem; overflow-wrap:normal; hyphens:none}
/* Viande ou poisson : « Sans limite » sur sa ligne, les sept chiffres sur la suivante. */
body #pMeatCap{display:grid; grid-template-columns:repeat(7,minmax(0,1fr)); gap:6px}
body #pMeatCap button{min-width:0; padding-left:2px; padding-right:2px}
body #pMeatCap button:first-child{grid-column:1 / -1}
body .wg-foot .wg-cta, body .wg-cta{padding-left:12px; padding-right:12px; font-size:.98rem}
@media(max-width:380px){ body .wg-foot .wg-cta, body .wg-cta{font-size:.9rem} }
.btn.btn-sm{min-height:40px}
.detail-portion-btn{width:40px !important; height:40px !important; flex:0 0 40px; font-size:1.1rem}
.di-sub-btn{min-width:38px; min-height:38px; display:inline-flex; align-items:center; justify-content:center; border-radius:10px}
.week-menu-item{min-height:44px}
/* Retour visuel à l'appui pour tout ce qui se choisit (les .btn s'enfoncent déjà). */
.seg button, .seg-cp-btn, .chip, .check-chip, .day-chip, .nav-btn, .profil-tab-seg button, .week-menu-item, .rp-act, .si-more-btn, .mini-btn{transition:transform .09s ease, background-color .15s ease}
.seg button:active, .seg-cp-btn:active, .chip:active, .check-chip:active, .day-chip:active, .nav-btn:active, .profil-tab-seg button:active, .rp-act:active, .si-more-btn:active, .mini-btn:active{transform:scale(.95)}
.week-menu-item:active{transform:scale(.98)}
@media (prefers-reduced-motion: reduce){ .seg button:active, .seg-cp-btn:active, .chip:active, .check-chip:active, .day-chip:active, .nav-btn:active, .profil-tab-seg button:active, .rp-act:active, .si-more-btn:active, .mini-btn:active, .week-menu-item:active{transform:none} }
.chip{min-height:40px}
.dc-lien{min-height:44px; padding:8px 4px}
.detail-foot .detail-more-btn, .modal-foot.detail-foot .detail-more-btn{width:48px; min-width:48px; padding:0}
.detail-ings li{align-items:center}
.detail-ings li > span:first-child{display:inline-flex; align-items:center; gap:6px}
/* Pied de la fiche recette : les deux actions se partagent la largeur. */
.modal-foot.detail-foot .detail-foot-spacer{display:none}
.modal-foot.detail-foot > .btn{flex:1 1 0; min-width:0; width:auto; padding:12px; font-size:.92rem}
.modal-foot.detail-foot > .btn-primary{flex-grow:1.35}
@media(max-width:400px){ .modal-foot.detail-foot > .btn{font-size:.86rem; padding-left:8px; padding-right:8px; gap:5px} }
/* Champs, libellés, étiquettes, sous-titres et espacement des cartes : une seule
   échelle (mesures du 02/10 : 5 hauteurs de champ, 3 tailles de libellé, cartes
   espacées de 0 à 24 px). Référence : docs/charte-interface.md. */
.view input[type=text], .view input[type=number], .view input[type=search], .view input[type=email], .view input:not([type]), .view select,
.modal input[type=text], .modal input[type=number], .modal input[type=email], .modal input[type=password], .modal input:not([type]), .modal select{min-height:48px; border-radius:12px}
.field label{font-size:.85rem}
.tag{font-size:.78rem}
/* Livre sur téléphone : « Importer » et « Nouvelle recette » côte à côte, étiquettes
   d'un seul tenant. */
@media(max-width:600px){
  .recette-head-actions{display:flex; gap:10px; width:100%}
  .recette-head-actions > .btn{flex:1 1 0; min-width:0; padding-left:8px; padding-right:8px; gap:6px; font-size:.9rem}
  .recette-head-actions > .btn svg{flex:0 0 auto; width:16px; height:16px}
  .recette-head-actions > .btn-primary{flex-grow:1.5}
}
.rcard-tags .tag{white-space:nowrap}
/* Plancher de 11,5 px pour tout texte (contrôlé par tools/verif-visuelle.mjs). */
.rcard-cat, #view-recettes .rcard-top .rcard-cat, .rcard-time, .rcard-kcal small, .rcard-price small, .rcard-kcal-sm, .mr-num small, .premium-teaser .pt-badge, .pt-badge{font-size:.72rem}
.view-sub{font-size:.9rem}
.view > .section-card, .view > .profile-card, .view > div > .section-card, .view > div > .profile-card{margin-top:0 !important; margin-bottom:16px}
/* Boutons à bascule (Par rayon / Par péremption, Ville / Périurbain…) : même confort. */
.seg{gap:8px}
.seg button{min-height:44px; padding:10px 12px; font-size:.9rem}
.ob-foot .btn-block + .btn-block{margin-top:0 !important}
/* Budget, « Objectif vs réel » : le libellé sur sa ligne, puis le champ et le bouton
   côte à côte (le bouton tombait seul sous le champ). */
.compare-card .cc-row{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:10px; align-items:center; max-width:460px}
.compare-card .cc-row > span{grid-column:1 / -1}
.compare-card .cc-row input{width:100%; min-width:0; min-height:48px}
.compare-card .cc-row .btn{min-height:48px; white-space:nowrap}
/* Lignes à interrupteur dans un .field : la règle générale « .field label » (bloc,
   12,8 px) écrasait .sw-row. Intitulé lisible à gauche, interrupteur à droite. */
.field label.sw-row{display:flex; align-items:center; justify-content:space-between; gap:14px; font-size:.95rem; font-weight:600; color:var(--ink); margin:0; text-transform:none; letter-spacing:0}
.field label.sw-row > strong, .field label.sw-row > span{order:1; flex:1 1 auto; min-width:0; font-size:inherit; line-height:1.35}
.field label.sw-row > input.sw{order:2; flex:0 0 auto}
/* Fiche recette : moins de volume. Pastille plus petite, placard en une carte
   sobre, votes en deux boutons compacts. */
.detail-emoji{width:84px; height:84px; font-size:2.8rem; box-shadow:0 3px 0 var(--ink)}
.detail-hero{gap:8px}
.detail-hero .rd-title{font-size:clamp(1.35rem, 5.4vw, 1.7rem)}
.detail-desc{font-size:.9rem; margin-top:4px}
.detail-faits{margin-top:10px}
.modal-body > .di-placard{margin:14px 0 12px; font-size:.88rem; line-height:1.45; background:var(--sage-soft); border:0; color:var(--ink-2)}
.detail-vote{display:flex; justify-content:center; gap:8px; margin:0 0 6px}
.detail-vote .chip{flex:0 0 auto; padding:8px 14px; font-size:.88rem; border-radius:999px; box-shadow:none; min-height:40px}
/* Encarts Premium floutés : le texte de l'encart est plus haut que l'aperçu flouté,
   qui dépassait au-dessus (titre flou sous la pastille). L'encart fixe la hauteur,
   l'aperçu passe derrière, et la pastille a le même style que les autres encarts. */
.blur-teaser-wrap .btw-overlay{position:relative; inset:auto; min-height:180px; background:linear-gradient(180deg, color-mix(in srgb, var(--surface) 70%, transparent), var(--surface) 55%)}
.blur-teaser-wrap .btw-content{position:absolute; inset:0; max-height:none !important; opacity:.5}
.blur-teaser-wrap .btw-content > h2, .blur-teaser-wrap .btw-content > .pc-sub{visibility:hidden}
.blur-teaser-wrap .pt-badge{display:inline-flex; align-items:center; gap:5px; background:var(--terra); color:var(--on-accent); font-size:.72rem; font-weight:700; letter-spacing:.4px; text-transform:uppercase; padding:4px 10px; border-radius:999px}
/* Titres de cartes avec émoji : un espace entre l'émoji et le texte. */
.profile-card > h2, .section-card > h2, .budget-settings .bs-title{word-spacing:.12em}
/* Placard : la liste de ce que tu as d'abord, puis « Que cuisiner ? ». « Ce soir, avec
   ce que j'ai » faisait doublon avec « Que cuisiner ? » ; il reste sous la Semaine. */
#view-stock.active{display:flex; flex-direction:column}
#view-stock > .seg-cp{order:0} #view-stock > .view-head{order:1} #view-stock > #stockEmptyHost{order:2}
#view-stock > #stockAddCard{order:3} #view-stock > #stockContent{order:4} #view-stock > .stock-vider{order:7; margin-top:18px}
#view-stock > #cuisineSuggestHost{order:6; margin-top:22px}
#view-stock > #dcSoirPlacard{display:none}
/* « Que cuisiner ? » ne répète plus la liste des produits qui périment, déjà visible
   (avec leurs dates) dans le placard juste au-dessus : il ne montre que les idées. */
#view-stock #cuisineSuggestHost .expiring-list{display:none}
/* Livre sur téléphone : cartes en ligne (pastille à gauche, infos à droite), quatre
   recettes par écran au lieu d'une et demie. */
@media(max-width:600px){
  #view-recettes .recipe-grid{grid-template-columns:1fr; gap:10px}
  #view-recettes .rcard{flex-direction:row; min-height:0}
  #view-recettes .rcard-top{width:92px; height:auto; min-height:104px; flex:0 0 92px; font-size:2.4rem; border-bottom:0; border-right:1.5px solid var(--border)}
  #view-recettes .rcard-top .rcard-cat{top:6px; left:6px; font-size:.72rem; padding:2px 6px}
  #view-recettes .rcard-top .rcard-time{bottom:6px; right:auto; left:50%; transform:translateX(-50%)}
  #view-recettes .rcard-body{padding:10px 12px; gap:2px; min-width:0}
  #view-recettes .rcard-name{font-size:.98rem}
  #view-recettes .rcard-desc{display:-webkit-box; -webkit-line-clamp:1; -webkit-box-orient:vertical; overflow:hidden; font-size:.8rem; margin:2px 0 4px}
  #view-recettes .rcard-tags{flex-wrap:nowrap; overflow:hidden; margin-bottom:4px}
  #view-recettes .rcard-foot{padding-top:6px; border-top:0}
}
/* « La cocotte complète ma semaine », écran du résultat : un repas par ligne compacte
   (pastille, nom, boutons-icônes), et un haut plus court pour que la liste se voie. */
.rp-lignes .rp-ligne{flex-direction:row; align-items:center; gap:10px; padding:10px 10px 10px 12px; margin-bottom:8px; border-radius:14px}
.rp-lignes .rp-ligne-h{flex:1 1 auto; min-width:0; gap:10px}
.rp-lignes .rp-ligne-em{width:40px; height:40px; font-size:1.25rem; border-radius:12px}
.rp-lignes .rp-ligne-t b{font-size:.95rem}
.rp-lignes .rp-ligne-t span{font-size:.8rem}
.rp-lignes .rp-ligne-b{flex:0 0 auto; flex-wrap:nowrap; gap:6px}
.rp-lignes .rp-act{width:44px; min-height:44px; padding:0; justify-content:center; margin:0}
.rp-lignes .rp-act > span{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
.rp-lignes .rp-act.is-remettre{width:auto; padding:0 12px}
.rp-lignes .rp-act.is-remettre > span{position:static; width:auto; height:auto; clip:auto}
.rp-scene .rp-detail-t{margin:18px 0 2px; font-weight:700; color:var(--ink-2)}
/* Sur téléphone et sur les écrans peu hauts, le haut du résultat se resserre : cocotte
   et bulle sur une ligne, chiffres plus bas, pour que les premiers repas se voient. */
@media(max-width:600px), (max-height:1000px){
  .rp-scene .rp-tete.is-grand{flex-direction:row; gap:12px; margin:0 0 10px}
  .rp-scene .rp-tete.is-grand .rp-coco .jeu-coco{width:76px; height:64px}
  .rp-scene .rp-tete.is-grand .rp-bulle{text-align:left; font-size:.9rem; flex:1 1 auto; min-width:0; max-width:none}
  .rp-scene .rp-tete.is-grand .rp-coco{flex:0 0 auto}
  .rp-scene .rp-tete.is-grand .rp-bulle::before{left:-6px; top:50%; transform:translateY(-50%) rotate(45deg)}
  .rp-scene .rp-centre-t{font-size:1.35rem; margin:4px 0 0}
  .rp-scene .rp-chiffres{gap:8px; margin:10px 0 4px}
  .rp-scene .rp-chiffre{padding:10px 6px; border-radius:14px}
}
.rp-scene .rp-jour-t{margin:16px 0 8px}
/* « Affiner l'estimation » : titre et flèche sur la première ligne, résumé dessous
   (le résumé se glissait à côté du titre et la flèche tombait seule en dessous). */
.budget-settings>summary{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:4px 10px; align-items:center}
.budget-settings>summary .bs-title{grid-column:1; grid-row:1}
.budget-settings>summary::after{grid-column:2; grid-row:1}
.budget-settings>summary .bs-resume{grid-column:1 / -1; grid-row:2; min-width:0}
/* Réglages de la liste de courses, descendus sous la liste. */
details.have-section{padding:10px 14px}
details.have-section > summary.have-head{margin:0; cursor:pointer; list-style:none; min-height:28px; min-width:0}
details.have-section > summary.have-head::-webkit-details-marker{display:none}
details.have-section[open] > summary.have-head{margin-bottom:8px}
.have-apercu{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:500; color:var(--ink-2); font-size:.85rem}
details.have-section[open] .have-apercu{display:none}
.courses-reglages{margin-top:24px; padding-top:16px; border-top:1.5px dashed var(--border-2)}
.courses-reglages-t{font-size:.8rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); margin:0 0 10px}
/* ==================================================================
   IDENTITÉ D'ENSEMBLE (02/10/2026)
   ==================================================================
   Paul : reprendre l'identité d'ensemble, garantir la cohérence et l'émotion.
   Référence : docs/charte-interface.md, section « Identité ». Une couche de fin
   de feuille, comme les précédentes : elle se retire d'un bloc.

   Chaque couleur a un rôle, et un seul :
     vert sauge   l'action (un bouton plein par écran) et ce qui est choisi ;
     corail       la cocotte, le dîner, et l'action que la cocotte fait pour toi ;
     or           le couvercle : Premium et les récompenses ;
     rouge        la péremption et la suppression, rien d'autre.
   Les émojis sont des illustrations de plats et d'ingrédients. L'interface
   (titres, onglets, réglages) parle avec les icônes au trait d'icones.js.
   ================================================================== */

/* 1. Une seule bascule d'onglets : Profils / Cuisine prend le gabarit de Liste / Placard. */
.profil-tab-seg{display:flex; gap:4px; padding:4px; background:var(--surface-2); border:var(--bw) solid var(--ink); border-radius:999px; max-width:360px}
.profil-tab-seg button{flex:1; min-height:44px; font-weight:700; font-size:.95rem; color:var(--ink-2)}
.profil-tab-seg button.on{background:var(--sage); color:var(--on-accent); box-shadow:var(--shadow-flat)}

/* 2. Bascules de tri (.seg) : le trait des pastilles, à l'encre quand c'est choisi
   (avant : filet beige et halo vert flou, seul halo flou de l'app). */
body .seg button{border:var(--bw) solid var(--border-2); border-radius:12px}
body .seg button.on{border-color:var(--ink); box-shadow:var(--shadow-flat)}

/* 3. Cartes qu'on ouvre ou qu'on parcourt : le trait des autres cartes de l'écran.
   Titre de carte en Rubik partout (« Détail par rayon » était seul en Alfa Slab). */
.budget-settings{border:var(--bw) solid var(--ink); border-radius:var(--radius-lg); box-shadow:var(--shadow-flat)}
.budget-settings>summary{padding:16px 20px}
.budget-settings>summary .bs-title{font-size:1.15rem}
.budget-settings .bs-body{padding:6px 16px 18px}
.budget-settings>summary{padding-left:16px; padding-right:16px}
@media(max-width:380px){ .budget-settings .seg button{font-size:.8rem; padding-left:4px; padding-right:4px} }
.budget-cats-fold > summary{font-family:var(--sans); font-weight:700; font-size:1.15rem}
.pf-list{border:var(--bw) solid var(--ink); box-shadow:var(--shadow-flat)}

/* 4. Lignes de réglage du profil : icône au trait dans une pastille sauge. */
.pf-ico.is-trait{width:36px; height:36px; border-radius:11px; background:var(--sage-soft); color:var(--sage-text); display:inline-flex; align-items:center; justify-content:center; font-size:1.05rem}

/* 5. Premium a la couleur du couvercle. Avant : rose et rouge, les couleurs de
   l'alerte, collés au bandeau de péremption. L'or est déjà la couronne de la
   cocotte Premium et la pastille « Premium » des réglages. */
.btn.btn-premium, .premium-teaser .btn-primary, .btw-overlay .btn-primary{background:var(--gold); color:var(--on-accent)}
.btn.btn-premium:hover, .premium-teaser .btn-primary:hover, .btw-overlay .btn-primary:hover{background:var(--gold); filter:brightness(1.04)}
.premium-teaser{border:var(--bw) solid var(--ink); background:var(--gold-soft)}
.premium-teaser h2{color:var(--ink)}
.premium-teaser .pt-badge, .blur-teaser-wrap .pt-badge, .pt-badge{background:var(--gold); color:var(--on-accent); border:1.5px solid var(--ink)}
.pt-badge .ic{width:1.2em; height:1.2em; vertical-align:-.22em}
.lib-locked-head{color:var(--gold-deep)}
.trial-banner.is-premium-nudge{display:flex; align-items:center; gap:10px; margin:0 0 14px; padding:12px 8px 12px 16px; border-radius:14px; background:var(--gold-soft); color:var(--ink); border:1.5px solid var(--gold); font-size:.86rem}
.trial-banner.is-premium-nudge a{color:var(--gold-deep); font-weight:800}
.trial-banner .tb-fermer{flex:0 0 auto; min-width:40px; min-height:40px; border:0; background:none; color:inherit; font-size:1rem; cursor:pointer; opacity:.6; border-radius:12px}
/* 22/10/2026 : annonce d'une fournée de recettes (nouveautesBannerCandidate). */
.trial-banner.is-nouveautes{display:flex; align-items:center; gap:10px; margin:0 0 14px; padding:10px 8px 10px 16px; border-radius:14px; border:1.5px solid var(--sage); font-size:.86rem}
.trial-banner .tb-voir{flex:0 0 auto; min-height:40px; padding:0 16px; border:0; border-radius:999px; background:var(--sage); color:var(--ink); font:inherit; font-weight:800; cursor:pointer}

.nudge-card{background:var(--gold-soft); border:var(--bw) solid var(--ink); box-shadow:var(--shadow-flat)}
.nudge-em.is-trait{width:36px; height:36px; border-radius:11px; background:var(--gold); color:var(--on-accent); border:1.5px solid var(--ink); display:inline-flex; align-items:center; justify-content:center; font-size:1.05rem}
.nudge-x{width:40px; height:40px; top:4px; right:4px}

/* Marqueur « réservé à Premium » : la petite couronne or, à la place de l'étincelle. */
.pm-couronne{display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px; margin-left:6px; border-radius:8px; background:var(--gold); color:var(--on-accent); border:1.5px solid var(--ink); font-size:.72rem; vertical-align:middle}
.pm-couronne .ic{width:13px; height:13px; stroke-width:2.4}
.premium-lock-chip{color:var(--on-accent); background:var(--gold); border:1.5px solid var(--ink)}
/* Fiche recette : icônes au trait dans le menu « ⋯ » et sur « par quoi remplacer ». */
.week-menu-item .ic{width:18px; height:18px}
.di-sub-btn{color:var(--sage-text); font-size:.95rem}
.detail-ings li.sub-open .di-sub-btn{color:var(--on-accent)}

/* Suite du 02/10 : plus d'étincelle ni d'émoji de vote dans l'interface. */
:root{--masque-couronne:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 18.5h16 M4.5 15.5L3 7l5 3.8L12 5l4 5.8L21 7l-1.5 8.5z'/%3E%3C/svg%3E")}
.bt-em .pm-couronne{margin-left:0}
.recap-budget-cta{color:var(--gold-deep)}
.wmi-state .pm-couronne{margin-left:0}
/* « Adapté », « Tout y est » : une recommandation, donc sauge. L'or est réservé à Premium. */
.sel-card .sel-reco{background:var(--sage); color:var(--on-accent)}
/* Pastille de vote sur les cartes : pouce au trait, sauge si aimée, corail sinon. */
.vote-badge{border:1.5px solid var(--ink); font-size:.78rem}
.vote-badge.like{background:var(--sage); color:var(--on-accent)}
.vote-badge.dislike{background:var(--terra-soft); color:var(--terra-text)}
.detail-vote .chip .ic{margin-right:2px}
.meal-label .me{display:inline-flex; align-items:center}
.meal-label .me .il{vertical-align:0}
.ppc-emoji{opacity:1}

/* 6. Une couleur par repas, la même dans le Livre et sur la fiche : le matin en
   or, le midi en sauge, le goûter en sable, le soir en corail (le dîner est le
   repas de la cocotte). Le Livre était une colonne de vignettes beiges. */
.rcard[data-repas="petit-dej"] .rcard-top, .detail-emoji[data-repas="petit-dej"]{background:var(--gold-soft)}
.rcard[data-repas="dejeuner"] .rcard-top, .detail-emoji[data-repas="dejeuner"]{background:var(--sage-soft)}
.rcard[data-repas="snack"] .rcard-top, .detail-emoji[data-repas="snack"]{background:var(--sand)}
.rcard[data-repas="diner"] .rcard-top, .detail-emoji[data-repas="diner"]{background:var(--terra-soft)}

/* 7. États vides : la cocotte sur son rond de table, avec l'autocollant de
   l'écran (panier, tirelire, étiquette…). Quatre écrans vides affichaient la même
   cocotte endormie sur fond nu ; Profils avait un émoji bleu à la place. */
.empty-state .es-emoji[data-coco]{position:relative; width:148px; height:148px; margin:0 auto 12px; border-radius:50%; background:var(--es-fond, var(--surface-2)); display:flex; align-items:center; justify-content:center; animation:none}
.empty-state .es-emoji[data-coco] .jeu-coco{width:100px; height:84px; margin-top:8px}
.es-autocollant{position:absolute; right:-6px; top:4px; width:46px; height:46px; border-radius:15px; background:var(--surface); border:var(--bw) solid var(--ink); box-shadow:var(--shadow-hard); display:flex; align-items:center; justify-content:center; transform:rotate(8deg); color:var(--ink); font-size:1.25rem; line-height:1}
#view-courses .es-emoji[data-coco]{--es-fond:var(--sage-soft)}
#view-budget .es-emoji[data-coco]{--es-fond:var(--gold-soft)}
#view-stock .es-emoji[data-coco]{--es-fond:var(--sand)}
#view-profil .es-emoji[data-coco]{--es-fond:var(--terra-soft)}
@media (prefers-reduced-motion:no-preference){
  .es-autocollant{animation:esAutocollant .5s cubic-bezier(.3,1.5,.5,1) .15s both}
}
@keyframes esAutocollant{from{transform:rotate(-14deg) scale(.4); opacity:0} to{transform:rotate(8deg) scale(1); opacity:1}}

/* 8. Titres d'écran : un trait de surligneur or sous l'Alfa Slab, la signature
   des titres (ardoise de cantine). */
.view-title{display:inline; padding:0 .14em; margin-left:-.14em; -webkit-box-decoration-break:clone; box-decoration-break:clone;
  background:linear-gradient(transparent 62%, color-mix(in srgb, var(--gold) 42%, transparent) 62%, color-mix(in srgb, var(--gold) 42%, transparent) 92%, transparent 92%)}
.view-title + .view-sub{margin-top:10px}

/* 9. Défauts révélés par la passe « app remplie » du contrôle visuel : textes
   sous 11,5 px et croix de fermeture sous 40 px. */
.hs-chip small, .recap-block .rl, .tdee-box .tl{font-size:.72rem}

/* ============ VOILE DE LANGUE (21/10/2026) ============
   Changer de langue recharge l'app (app.js, changerDeLangue). Le voile couvre l'écran du fond
   de l'app, le nom de la nouvelle langue au milieu : il monte avant le rechargement, boot.js le
   repose avant le premier rendu de la page suivante, et il se lève une fois Paramètres rouvert.
   Deux pseudo-éléments de <html> : rien à ajouter au DOM, présent dès la première image, avant
   même <body>. Un tap pendant le voile tombe sur <html> et ne touche rien. */
html[data-langue-voile]::before,
html[data-langue-voile]::after{ position:fixed; inset:0; z-index:2147483646; pointer-events:auto }
html[data-langue-voile]::before{ content:""; background:var(--bg) }
html[data-langue-voile]::after{ content:attr(data-langue-voile); z-index:2147483647;
  display:flex; align-items:center; justify-content:center; padding:0 24px;
  font-family:var(--serif); font-size:clamp(2.2rem, 11vw, 3.6rem); line-height:1.1; color:var(--terra-text) }
html.langue-depart::before{ animation:langue-voile-in .3s var(--ease) both }
html.langue-depart::after{ animation:langue-mot-in .4s var(--ease) .05s both }
html.langue-arrivee::after{ animation:langue-mot-out .28s var(--ease) both }
html.langue-arrivee::before{ animation:langue-voile-out .42s var(--ease) .12s both }
@keyframes langue-voile-in{ from{opacity:0} to{opacity:1} }
@keyframes langue-voile-out{ from{opacity:1} to{opacity:0} }
@keyframes langue-mot-in{ from{opacity:0; transform:translateY(14px) scale(.96)} to{opacity:1; transform:none} }
@keyframes langue-mot-out{ from{opacity:1; transform:none} to{opacity:0; transform:translateY(-10px) scale(1.02)} }
@media(prefers-reduced-motion:reduce){
  html.langue-depart::before, html.langue-depart::after{ animation:none }
  html.langue-arrivee::before, html.langue-arrivee::after{ animation:langue-voile-out .2s linear both }
}
