/* ==========================================================================
   datafood · design system

   RÈGLE DE GRILLE : toute piste en fr s'écrit minmax(0, Nfr), jamais Nfr.
   `Nfr` vaut `minmax(auto, Nfr)`, et le minimum automatique d'une piste se résout sur son
   min-content, pas sur zéro : la piste refuse alors de descendre sous son contenu et sort du
   conteneur. Symptômes constatés sur ce site : colonnes inégales sur l'accueil, et débordement
   horizontal de 34 à 340 px sur 12 gabarits en mobile.
   Palette et langage visuel issus des maquettes : fond sauge clair, cartes
   « verre », panneaux vert sapin, accent croix suisse. Perf : system fonts,
   animations transform/opacity uniquement, < 40 Ko.
   ========================================================================== */

/* Inter, hébergée par le site. Elle était déclarée dans --font depuis le début mais n'a
   JAMAIS été chargée : toute la maquette s'affichait en police système. Fichier variable,
   un seul woff2 couvre l'axe 100-900, sous-ensemble latin, 47 Ko.
   font-display:swap : le texte est lisible immédiatement en police système, puis bascule ;
   c'est le compromis qui évite un écran vide sur connexion lente.
   Le signe ≥ n'existe pas dans ce sous-ensemble et retombe sur la police système : c'est le
   comportement normal du repli par glyphe, invisible pour un symbole isolé. */
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-latin.3100e775.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #F2F4EE;
  --bg-soft: #E9EEE5;
  --ink: #14231B;
  --ink-2: #4A5A50;
  --ink-3: #657067;   /* 4,63:1 sur la teinte la plus claire du site */
  --green-950: #082A1E;
  --green-900: #0E3A2A;
  --green-850: #12452F;
  --green-800: #175538;
  --green-700: #1E6B45;
  --green-600: #2E8656;
  --green-500: #4CA36A;
  --green-350: #8FC2A0;
  --green-150: #D6E5D8;
  --green-100: #E3EDE2;
  --green-50: #EFF4EC;
  --wm-soft: #6FA87E;    /* premiere syllabe du mot-symbole */
  --wm-strong: #1B5E3B;  /* seconde syllabe, en gras */
  --red: #D8322A;
  --red-soft: #E25548;
  --amber: #DFA83C;
  --slate: #52717F;   /* blanc sur ardoise : 4,42:1 puis 5,21:1 */
  --card: #FFFFFF;
  --glass: rgba(255, 255, 255, 0.58);
  --glass-strong: rgba(255, 255, 255, 0.78);
  --glass-border: rgba(255, 255, 255, 0.85);
  --line: #E3E9E0;
  --line-soft: #ECF0E9;
  --track: #E7EDE4;
  --shadow-sm: 0 2px 10px -4px rgba(18, 38, 28, 0.10);
  --shadow-md: 0 14px 40px -18px rgba(18, 38, 28, 0.18);
  --shadow-lg: 0 32px 70px -30px rgba(18, 38, 28, 0.28);
  --shadow-dev: 0 40px 90px -30px rgba(8, 42, 30, 0.45);
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-xl: 28px;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* ------------------------------------------------- reset & base */
*, *::before, *::after { box-sizing: border-box; }
/* Une classe de composant l'emporte sur la feuille du navigateur : .notice { display: flex }
   annulait [hidden] et laissait s'afficher un encart vide, et la note d'exemple en permanence.
   Cette regle rend l'attribut fiable pour tout le site, pas seulement pour l'assiette. */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { max-width: 100%; height: auto; display: block; }
/* garde-fou : une icône inline sans attribut de taille ne doit jamais s'étirer.
   Les SVG portant width/height (donut du calculateur…) ne sont pas concernés. */
svg:not([width]) { width: 1.15em; height: 1.15em; flex: none; vertical-align: -0.15em; }
a { color: var(--green-700); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
h1, h2, h3, h4 { margin: 0 0 0.5em; line-height: 1.12; letter-spacing: -0.02em; font-weight: 700; color: var(--green-900); }
h1 { font-size: clamp(2rem, 4.4vw, 3.3rem); }
h2 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); }
h3 { font-size: 1.18rem; letter-spacing: -0.01em; }
p { margin: 0 0 1em; }
small { color: var(--ink-3); }
::selection { background: var(--green-150); }
:focus-visible { outline: 2px solid var(--green-600); outline-offset: 2px; border-radius: 4px; }

/* décor de fond : halos végétaux flous (CSS pur, zéro image bloquante) */
.page-bg {
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(52rem 30rem at 108% -8%, rgba(110, 168, 126, 0.20), transparent 60%),
    radial-gradient(46rem 30rem at -12% 12%, rgba(110, 168, 126, 0.16), transparent 60%),
    radial-gradient(40rem 26rem at 4% 108%, rgba(143, 194, 160, 0.20), transparent 62%),
    radial-gradient(46rem 30rem at 96% 96%, rgba(110, 168, 126, 0.13), transparent 60%),
    linear-gradient(180deg, #F4F6F0 0%, var(--bg) 42%, #EDF1E9 100%);
}
.page-leaves { position: fixed; z-index: -1; pointer-events: none; width: 30rem; max-width: 46vw; opacity: 0.5; filter: blur(7px) saturate(1.05); }
.page-leaves--tr { top: -6rem; right: -8rem; transform: rotate(12deg); }
.page-leaves--bl { bottom: -8rem; left: -9rem; transform: rotate(-160deg); }

.container { width: min(1180px, 100% - 2.5rem); margin-inline: auto; }
.section { padding-block: clamp(3rem, 7vw, 5.5rem); }
.section--tight { padding-block: clamp(2rem, 4vw, 3rem); }

/* ------------------------------------------------- wordmark & badges */
.wm { font-weight: 600; letter-spacing: -0.03em; font-size: 1.5rem; line-height: 1; white-space: nowrap; }
.wm b { font-weight: 800; color: var(--wm-strong); }
.wm span { color: var(--wm-soft); }
.swiss {
  display: inline-grid; place-items: center; width: 1.35em; height: 1.35em; border-radius: 999px;
  background: var(--red); color: #fff; box-shadow: 0 4px 10px -3px rgba(216, 50, 42, 0.55); flex: none;
}
.swiss svg { width: 58%; height: 58%; }

.eyebrow {
  display: flex; align-items: center; gap: 0.55rem; font-weight: 600; color: var(--green-700);
  font-size: 0.95rem; margin-bottom: 0.7rem; letter-spacing: -0.01em;
}
.eyebrow::before { content: ""; width: 8px; height: 8px; border-radius: 999px; background: var(--red); flex: none; }

.lede { color: var(--ink-2); font-size: 1.06rem; max-width: 58ch; }

/* ------------------------------------------------- header / nav */
.nav-wrap { position: sticky; top: 0; z-index: 50; }
.nav {
  display: flex; align-items: center; gap: 1.4rem;
  padding: 0.8rem 0;
  background: rgba(244, 246, 240, 0.72);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 1px 0 rgba(18, 38, 28, 0.04);
}
.nav__inner { display: flex; align-items: center; gap: 1.5rem; width: min(1180px, 100% - 2.5rem); margin-inline: auto; }
.nav__brand { display: flex; align-items: center; gap: 0.6rem; }
.nav__links { display: flex; gap: 0.25rem; margin-inline: auto; }
.nav__links a {
  color: var(--ink-2); font-weight: 500; font-size: 0.95rem; padding: 0.45rem 0.85rem; border-radius: 999px;
  transition: background-color 150ms var(--ease-out), color 150ms var(--ease-out);
 white-space: nowrap; }
.nav__links a:hover { text-decoration: none; background: rgba(255, 255, 255, 0.8); color: var(--green-900); }
.nav__links a[aria-current="page"], .nav__links a.nav-on { color: var(--green-900); font-weight: 600; position: relative; }
.nav__links a[aria-current="page"]::after, .nav__links a.nav-on::after {
  content: ""; position: absolute; left: 50%; bottom: -0.35rem; transform: translateX(-50%);
  width: 22px; height: 3px; border-radius: 3px; background: var(--green-700);
}
.nav__actions { display: flex; align-items: center; gap: 0.7rem; }

.nav-burger { display: none; }
.nav-burger-btn {
  display: none; border: 0; background: rgba(255, 255, 255, 0.8); border-radius: 12px; width: 42px; height: 42px;
  place-items: center; cursor: pointer; color: var(--green-900); box-shadow: var(--shadow-sm);
}
.nav-burger-btn svg, .close-btn svg { width: 22px; height: 22px; }
.foodgrid .kcal svg, .rank__val svg, a.card > svg { width: 17px; height: 17px; color: var(--ink-3); }

/* ------------------------------------------------- boutons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  border: 0; cursor: pointer; font: inherit; font-weight: 600; letter-spacing: -0.01em;
  border-radius: 999px; padding: 0.7rem 1.35rem; font-size: 0.97rem;
  transition: transform 140ms var(--ease-out), box-shadow 140ms var(--ease-out), background-color 140ms var(--ease-out);
  text-decoration: none;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: scale(0.97); }
.btn--primary { background: var(--green-800); color: #fff; box-shadow: 0 14px 26px -14px rgba(14, 58, 42, 0.6); }
.btn--primary:hover { background: var(--green-700); }
.btn--light { background: #fff; color: var(--green-900); box-shadow: var(--shadow-sm); border: 1px solid var(--line); }
.btn--light:hover { border-color: var(--green-350); }
.btn--ghost { background: transparent; color: var(--ink-2); }
.btn--ghost:hover { color: var(--green-900); }
.btn--round { width: 46px; height: 46px; padding: 0; border-radius: 999px; }
.btn--red { background: var(--red); color: #fff; box-shadow: 0 12px 24px -12px rgba(216, 50, 42, 0.7); }
.btn svg { width: 18px; height: 18px; flex: none; }

/* ------------------------------------------------- cartes */
.card {
  background: var(--card); border-radius: var(--r-lg); box-shadow: var(--shadow-md);
  border: 1px solid rgba(255, 255, 255, 0.9); padding: 1.4rem;
}
.glass {
  background: var(--glass); border-radius: var(--r-lg);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow-md);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  padding: 1.4rem;
}
.card--hover { transition: transform 200ms var(--ease-out), box-shadow 200ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .card--hover:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
}
.card__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.card__title { font-weight: 700; letter-spacing: -0.015em; color: var(--green-900); font-size: 1.06rem; margin: 0; }
.card__sub { color: var(--ink-3); font-size: 0.85rem; margin-top: 0.15rem; }

/* panneau sombre (carte « appareil » des maquettes) */
.devcard {
  position: relative; overflow: hidden;
  background:
    radial-gradient(120% 130% at 15% 0%, #1A5A3C 0%, var(--green-900) 48%, var(--green-950) 100%);
  color: #E9F2EB; border-radius: var(--r-xl); box-shadow: var(--shadow-dev);
  border: 1px solid rgba(255, 255, 255, 0.14);
  padding: clamp(1.4rem, 3vw, 2.2rem);
}
.devcard::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.10) 0%, transparent 34%);
}
.devcard h1, .devcard h2, .devcard h3 { color: #fff; }
.devcard a { color: #C9E4D0; }
.devcard .muted, .devcard small { color: rgba(233, 242, 235, 0.62); }

.chip {
  display: inline-flex; align-items: center; gap: 0.45rem;
  background: rgba(255, 255, 255, 0.10); border: 1px solid rgba(255, 255, 255, 0.16);
  color: #EAF3EC; border-radius: 999px; padding: 0.28rem 0.75rem; font-size: 0.82rem; font-weight: 500;
}
.chip--light { background: var(--green-50); border-color: var(--green-150); color: var(--green-800); }
.chip .dot { width: 7px; height: 7px; border-radius: 999px; background: var(--green-500); }

/* ------------------------------------------------- icônes rondes */
.ico {
  width: 40px; height: 40px; border-radius: 13px; display: inline-grid; place-items: center; flex: none;
  background: var(--green-50); color: var(--green-700); border: 1px solid var(--green-150);
}
.ico svg { width: 20px; height: 20px; }
.ico--dark { background: rgba(255, 255, 255, 0.10); border-color: rgba(255, 255, 255, 0.16); color: #DFEEE3; }
.ico--solid { background: var(--green-800); border-color: var(--green-800); color: #fff; }

/* ------------------------------------------------- barres de nutriments */
/* `display: block` est indispensable, pas décoratif : `.bar` est un <span>, donc inline par
   défaut, et `height` ne s'applique pas à une boîte inline. Là où la barre est enfant d'un
   conteneur flex (.nrow, .rank__item) elle est « blockifiée » automatiquement et tout va bien ;
   dans la grille .needs des fiches d'aliment elle restait inline, son height de 6 px était
   ignoré et elle se dessinait sur 55 px de haut, soit 4 864 pages concernées. */
.bar { display: block; height: 6px; border-radius: 999px; background: var(--track); overflow: hidden; flex: 1; min-width: 60px; }
.devcard .bar { background: rgba(255, 255, 255, 0.14); }
.bar i {
  display: block; height: 100%; border-radius: inherit;
  background: linear-gradient(90deg, var(--green-600), var(--green-500));
  transform-origin: left center;
}
/* Dépasser la valeur nutritive de référence n'est pas une alerte : 144 % de l'apport de
   référence en vitamine B12 pour de l'agneau est sans conséquence, et le site ne délivre aucun
   conseil de santé (OIDAl). Le rouge (qui est par ailleurs la couleur d'erreur du site et
   l'accent de la croix suisse) encodait un jugement dans une donnée neutre. On reste dans la
   famille verte et on marque le dépassement par une butée en fin de barre ; le pourcentage
   exact est affiché juste au-dessus. */
.bar--over i { background: linear-gradient(90deg, var(--green-700), var(--green-800)); }
.bar--over { position: relative; }
.bar--over::after {
  content: ""; position: absolute; inset-block: 0; right: 0; width: 3px;
  background: var(--green-950); border-radius: 0 999px 999px 0;
}

.nrow { display: flex; align-items: center; gap: 0.8rem; padding: 0.55rem 0; }
.nrow__label { flex: none; width: 9.5rem; display: flex; align-items: center; gap: 0.65rem; }
.nrow__name { font-weight: 600; font-size: 0.92rem; letter-spacing: -0.01em; }
.nrow__qty { display: block; font-size: 0.8rem; color: var(--ink-3); }
.devcard .nrow__qty { color: rgba(233, 242, 235, 0.6); }
.nrow__pct { flex: none; width: 3.4rem; text-align: right; font-weight: 700; font-size: 0.92rem; font-variant-numeric: tabular-nums; }
.nrow__pct--over { color: var(--green-800); }   /* même raison que .bar--over */

/* ------------------------------------------------- comparaison compacte (tuile d'accueil)
   Deux colonnes de valeurs reelles : l'ancienne tuile annoncait « A vs B » et n'affichait que
   les valeurs de A, avec une barre dessinee a une largeur codee en dur. */
/* Les deux colonnes de valeurs doivent être STRICTEMENT égales, sinon les deux côtés de la
   comparaison ne s'alignent pas. `minmax(…, auto)` ne le garantit pas : le max `auto` vaut
   max-content, et un nom d'aliment plus long d'un côté élargit sa colonne (mesuré : 136 px
   contre 71 px). Deux pistes `minmax(0, 1fr)` identiques sont égales par construction. */
.cmp-mini { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 1fr); }
.cmp-mini__h {
  display: contents;
}
/* L'en-tête s'aligne à droite comme les valeurs qu'il coiffe : centré, il flottait à côté de
   sa colonne de chiffres alignés à droite. */
.cmp-mini__food { display: flex; flex-direction: column; align-items: flex-end; gap: 0.35rem; text-align: right; padding-left: 0.5rem; }
.cmp-mini__food small {
  font-size: 0.78rem; font-weight: 600; line-height: 1.25; color: var(--ink-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.cmp-mini__unit { align-self: end; font-size: 0.76rem; color: var(--ink-3); letter-spacing: 0; }
.cmp-mini__lab { font-size: 0.88rem; font-weight: 600; color: var(--ink-2); align-self: center; }
.cmp-mini b {
  font-size: 0.95rem; font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
  text-align: right; align-self: center; color: var(--green-900); white-space: nowrap;
}
.cmp-mini > * { padding: 0.5rem 0; border-top: 1px solid var(--line-soft); }
.cmp-mini > .cmp-mini__food, .cmp-mini > .cmp-mini__unit { border-top: 0; padding-top: 0; }
.cmp-mini b { padding-left: 0.5rem; }

/* ------------------------------------------------- badges qualité & flags */
.grade {
  display: inline-grid; place-items: center; width: 2.1rem; height: 2.1rem; border-radius: 999px;
  font-weight: 800; font-size: 1rem; color: #fff; background: var(--green-700); flex: none;
}
.grade--E { background: var(--amber); color: var(--green-950); }
.grade--C { background: var(--slate); }

.flag {
  display: inline-grid; place-items: center; min-width: 1.15rem; height: 1.15rem; padding: 0 0.15rem;
  border-radius: 5px; font-size: 0.62rem; font-weight: 800; cursor: help; line-height: 1;
  background: var(--green-100); color: var(--green-800); vertical-align: 0.12em; margin-left: 0.4rem;
}
.flag--E { background: #F7ECD4; color: #8A6210; }   /* 3,88:1 puis 4,67:1 a 10 px gras */
.flag--C { background: #E2ECF1; color: #3E606F; }

/* ------------------------------------------------- listes de classement */
.rank { display: flex; flex-direction: column; }
.rank__item {
  display: flex; align-items: center; gap: 0.9rem; padding: 0.7rem 0.6rem; border-radius: var(--r-md);
  border-bottom: 1px solid var(--line-soft); color: inherit;
  transition: background-color 150ms var(--ease-out);
}
.rank__item:last-child { border-bottom: 0; }
a.rank__item { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  a.rank__item:hover { background: rgba(255, 255, 255, 0.85); }
}
a.rank__item:active { transform: scale(0.995); }   /* la ligne repond a la pression */
.rank__num { flex: none; width: 1.6rem; text-align: center; font-weight: 800; color: var(--green-900); font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.rank__name { min-width: 0; font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; }
/* Le libelle est borne a deux lignes : la hauteur d'une entree devient constante (imposee par
   la vignette de 52 px) et la tuile garde la meme hauteur en fr, de, it et en. */
.rank__label {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: break-word;
}
@supports not (-webkit-line-clamp: 2) {
  .rank__label { display: block; max-height: 2.6em; }
}
.rank__state { display: block; font-size: 0.8rem; color: var(--ink-3); font-weight: 400; }
.rank__val { margin-left: auto; text-align: right; flex: none; }
.rank__val b { font-size: 1rem; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.rank__val small { display: block; font-size: 0.76rem; }
.rank__bar { flex: none; width: 90px; }
/* Dans la tuile pleine largeur, la colonne du nom est bornée et c'est la BARRE qui absorbe le
   mou. Deux effets : le bord gauche des barres reste aligné d'une ligne à l'autre (donc les
   longueurs restent comparables) et l'espace disponible porte une information au lieu de
   laisser un vide entre le libellé et sa valeur. */
.tile--lead .rank__name { flex: 0 1 24rem; }
.tile--lead .rank__bar { flex: 1 1 auto; width: auto; min-width: 90px; }

/* vignette aliment (photo ou monogramme) */
.thumb {
  flex: none; width: 52px; height: 52px; border-radius: 14px; overflow: hidden;
  background: var(--green-50); border: 1px solid var(--line-soft);
  display: grid; place-items: center; font-weight: 700; color: var(--green-700); font-size: 1.1rem;
}
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb--lg { width: 74px; height: 74px; border-radius: 18px; }
.thumb--xl { width: 100%; height: 210px; border-radius: var(--r-lg); }
.thumb--xl img { height: 100%; }

/* ------------------------------------------------- tableaux */
.table-wrap { overflow-x: auto; }
table.nut { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
table.nut th, table.nut td { padding: 0.62rem 0.7rem; text-align: right; border-bottom: 1px solid var(--line-soft); font-variant-numeric: tabular-nums; }
table.nut th { font-weight: 600; color: var(--ink-2); font-size: 0.83rem; letter-spacing: 0.02em; }
table.nut td:first-child, table.nut th:first-child { text-align: left; }
table.nut td:first-child { color: var(--ink); font-weight: 500; }
/* Intitule de groupe : c'est l'element le plus structurant du tableau, il en etait pourtant le
   plus petit et le plus pale (11,8 px, gris clair, sans fond, sans separation). Rien ne
   signalait un changement de section. Un bandeau dans la teinte de surface du site le fait
   lire d'un coup d'oeil sans crier ; contraste du texte sur la teinte : 7,87:1. */
table.nut tr.group td {
  text-align: left; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--green-800); background: var(--green-50);
  padding: 0.52rem 0.7rem;
  border-top: 1px solid var(--green-150); border-bottom: 1px solid var(--green-150);
}
table.nut .nd { color: var(--ink-3); font-weight: 400; }
table.nut .win { color: var(--green-700); font-weight: 700; }

/* ------------------------------------------------- segmented control (portions) */
.seg { display: inline-flex; background: var(--track); border-radius: 999px; padding: 4px; gap: 2px; }
.seg button {
  border: 0; background: transparent; font: inherit; font-size: 0.88rem; font-weight: 600; color: var(--ink-2);
  padding: 0.38rem 0.95rem; border-radius: 999px; cursor: pointer;
  transition: background-color 160ms var(--ease-out), color 160ms var(--ease-out), transform 140ms var(--ease-out);
}
.seg button:active { transform: scale(0.96); }
.seg button[aria-pressed="true"] { background: #fff; color: var(--green-900); box-shadow: var(--shadow-sm); }
.seg input {
  width: 4.6rem; border: 0; background: #fff; border-radius: 999px; padding: 0.38rem 0.8rem; font: inherit;
  font-size: 0.88rem; font-weight: 600; color: var(--green-900); box-shadow: inset 0 0 0 1px var(--line);
}
.seg input:focus { outline: 2px solid var(--green-600); }

/* ------------------------------------------------- recherche */
.searchbox { position: relative; }
.searchbox__field {
  display: flex; align-items: center; gap: 0.6rem; background: #fff; border-radius: 999px;
  border: 1px solid var(--line); box-shadow: var(--shadow-sm); padding: 0.28rem 0.4rem 0.28rem 1.1rem;
  transition: box-shadow 160ms var(--ease-out), border-color 160ms var(--ease-out);
}
.searchbox__field:focus-within { border-color: var(--green-350); box-shadow: 0 0 0 4px rgba(76, 163, 106, 0.14), var(--shadow-sm); }
.searchbox__field > svg { width: 19px; height: 19px; flex: none; color: var(--ink-3); }
.searchbox input { flex: 1; border: 0; background: transparent; font: inherit; font-size: 0.98rem; color: var(--ink); min-width: 0; }
.searchbox input:focus { outline: none; }
.searchbox input::placeholder { color: var(--ink-3); }
.searchbox__list {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 40;
  background: #fff; border-radius: var(--r-md); box-shadow: var(--shadow-lg); border: 1px solid var(--line-soft);
  max-height: 21rem; overflow: auto; padding: 0.4rem;
  opacity: 0; transform: translateY(-4px) scale(0.99); pointer-events: none;
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.searchbox--open .searchbox__list { opacity: 1; transform: none; pointer-events: auto; }
.searchbox__list a { display: flex; align-items: center; gap: 0.7rem; padding: 0.5rem 0.6rem; border-radius: 10px; color: inherit; }
.searchbox__list a:hover, .searchbox__list a.sel { background: var(--green-50); text-decoration: none; }
.searchbox__list .thumb { width: 38px; height: 38px; border-radius: 10px; font-size: 0.9rem; }
.searchbox__empty { padding: 0.8rem; color: var(--ink-3); font-size: 0.92rem; }
.nav .searchbox { width: 15rem; }
.nav .searchbox__field { padding: 0.14rem 0.3rem 0.14rem 0.9rem; box-shadow: none; background: rgba(255, 255, 255, 0.8); }
.nav .searchbox input { font-size: 0.9rem; }

/* ------------------------------------------------- hero accueil */
.hero { display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr); gap: clamp(2rem, 4vw, 3.5rem); align-items: center; }
.hero__title .accent { color: var(--green-600); }
.hero__badges { display: flex; flex-wrap: wrap; gap: 1.1rem 1.6rem; margin-top: 1.6rem; }
.hero__badges .b { display: flex; align-items: center; gap: 0.6rem; font-size: 0.86rem; color: var(--ink-2); }
.hero__badges .grade { width: 1.7rem; height: 1.7rem; font-size: 0.82rem; }
.hero__badges .t b { display: block; color: var(--ink); font-size: 0.9rem; letter-spacing: -0.01em; }

.foodpanel__head { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.4rem; }
.foodpanel__head h2 { margin: 0; font-size: 1.5rem; letter-spacing: -0.02em; }
.foodpanel__tags { display: flex; align-items: center; gap: 0.9rem; margin-bottom: 1.2rem; font-size: 0.85rem; color: rgba(233, 242, 235, 0.72); }
.foodpanel__tags .dot { display: inline-block; width: 7px; height: 7px; border-radius: 99px; background: var(--green-500); margin-right: 0.4rem; }
/* Panneau d'en-tete : lignes de nutriments a gauche, photo a droite.
   Une ligne exige 292 px (libelle 152 + minimum de barre 60 + pourcentage 54,4 + deux
   gouttieres) et la colonne n'en offrait que 253,9. Aucun des trois blocs ne pouvant se reduire
   (flex: none sur le libelle et le pourcentage), la ligne debordait de 38 px dans la colonne
   voisine, ou la photo, peinte apres, recouvrait les pourcentages. Constate dans les quatre
   langues. On redonne la largeur necessaire aux donnees, et on resserre les gabarits ci-dessous. */
.devcard { container-type: inline-size; }
.foodpanel__grid { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr); gap: 1.2rem; align-items: center; }
/* La photo passe sous les donnees des que la carte n'a plus la place de les mettre cote a cote.
   Le seuil porte sur la largeur de la CARTE et non de la fenetre : la carte occupe une colonne
   du hero, si bien qu'entre 861 et 1000 px de fenetre elle ne mesurait que 339 a 381 px et la
   ligne debordait encore de 25 a 58 px. Il faut 251 px pour une ligne, 19 de gouttiere et
   environ 120 px pour que la photo dise encore quelque chose. */
@container (max-width: 470px) {
  .foodpanel__grid { grid-template-columns: minmax(0, 1fr); }
}
/* Filet de securite : meme si un futur libelle debordait, le texte resterait au-dessus de la photo. */
.foodpanel__grid > *:first-child { position: relative; z-index: 1; }
.devcard .nrow__label { width: 8.6rem; }
.devcard .nrow__pct { width: 3rem; }
.devcard .bar { min-width: 40px; }
/* L'etat « au-dela de la reference » est decline pour le panneau sombre : les teintes foncees
   choisies pour le fond blanc y tombaient a 1,07:1 sur le point le plus clair du degrade, donc
   invisibles. Les valeurs ci-dessous donnent 5,05:1 au pire endroit, et restent distinctes du
   blanc des autres pourcentages pour que le depassement se remarque toujours. */
.devcard .nrow__pct--over { color: #A9D6B7; }
.devcard .bar--over i { background: linear-gradient(90deg, var(--green-350), #C9E4D0); }
.devcard .bar--over::after { background: #EAF3EC; }
.foodpanel__img { border-radius: var(--r-lg); overflow: hidden; box-shadow: 0 24px 50px -22px rgba(0, 0, 0, 0.55); }
.foodpanel__quality {
  position: absolute; right: clamp(1rem, 2.5vw, 1.8rem); bottom: clamp(1rem, 2.5vw, 1.8rem);
  display: flex; align-items: center; gap: 0.7rem;
  background: rgba(255, 255, 255, 0.92); color: var(--ink); border-radius: 16px; padding: 0.6rem 0.95rem;
  box-shadow: var(--shadow-lg); backdrop-filter: blur(8px);
}
.foodpanel__quality small { display: block; color: var(--ink-3); font-size: 0.72rem; }
.foodpanel__quality b { font-size: 0.95rem; letter-spacing: -0.01em; }

/* ------------------------------------------------- grille de cartes accueil */
/* Bande d'accueil : une tuile maîtresse pleine largeur, deux tuiles d'appoint côte à côte.
   `minmax(0, 1fr)` et non `1fr` : `1fr` vaut `minmax(auto, 1fr)`, et le minimum automatique
   d'une piste se résout sur son min-content, pas sur zéro. Avec quatre colonnes, trois d'entre
   elles se gelaient donc sur leur min-content (325 / 302 / 286 px) et la quatrième encaissait
   tout le déficit (215 px), jusqu'à sortir du conteneur de 95 à 174 px entre 1021 et 1180 px
   de large, et de 29 px en permanence dans la version allemande. */
.tiles {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.1rem;
}
.tiles > * { min-width: 0; }          /* aucune tuile ne peut plus imposer sa largeur à la grille */
.tile--lead { grid-column: 1 / -1; }  /* le classement, cœur du site, prend toute la largeur */
.tiles .card { display: flex; flex-direction: column; }
.tiles .card .spacer { flex: 1; }     /* aligne les CTA des deux tuiles d'appoint sur la même ligne */

/* mini besoins */
/* Le tracking suit la taille : serré sur le grand nombre, neutre sur son unité et sur les
   notes. Une valeur unique appliquée partout serrerait le petit texte, qui a besoin du contraire. */
.kcal-big { font-size: 2rem; line-height: 1.1; font-weight: 800; letter-spacing: -0.03em; color: var(--green-900); margin: 0; }
.kcal-big small { font-size: 1rem; font-weight: 600; color: var(--ink-2); letter-spacing: 0; }

/* ------------------------------------------------- réglages internes des tuiles d'accueil */
.tile-note { font-size: 0.8rem; line-height: 1.45; letter-spacing: 0.005em; margin: 0.3rem 0 0; }
.nrow--tile { padding: 0.34rem 0; }
.nrow--tile .nrow__label { width: 6.4rem; }
.nrow--tile .nrow__name { font-size: 0.86rem; }
.nrow--tile .nrow__pct { width: 3rem; font-size: 0.86rem; }
.split--tags { justify-content: flex-start; gap: 0.5rem; margin-top: 0.9rem; }

/* ------------------------------------------------- barre de confiance */
/* Quatre colonnes egales, jamais un flex qui se replie. En flex, chaque element prenait la
   largeur de son texte (342, 277, 346 et 222 px) : 1 187 px de contenu plus 96 px d'espacement
   dans une barre de 1 180, donc le quatrieme tombait seul a la ligne. La grille impose le
   rythme au lieu de le subir, et c'est le TEXTE qui se replie dans sa colonne.
   Chaque piste est ecrite minmax(0, 1fr) : sans cela son minimum vaut min-content et le mot
   le plus long relance le debordement. */
.trustbar {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.1rem 1.5rem; align-items: stretch;
  border-radius: var(--r-lg); padding: 1.15rem 1.6rem;
}
/* Alignement en haut : avec des textes de 1 a 3 lignes, centrer verticalement decalerait les
   quatre pastilles les unes par rapport aux autres. En haut, elles forment une ligne nette. */
.trustbar .t { display: flex; align-items: flex-start; gap: 0.7rem; font-size: 0.83rem; line-height: 1.35; color: var(--ink-2); min-width: 0; }
.trustbar .t b { display: block; color: var(--ink); font-size: 0.9rem; letter-spacing: -0.01em; margin-bottom: 0.1rem; }
.trustbar .ico { width: 34px; height: 34px; border-radius: 10px; margin-top: 0.1rem; }
@media (max-width: 1000px) { .trustbar { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .trustbar { grid-template-columns: minmax(0, 1fr); } }

/* ------------------------------------------------- fil d'ariane */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; font-size: 0.86rem; color: var(--ink-3); padding: 1.1rem 0 0; }
.crumbs a { color: var(--ink-2); }
.crumbs svg { width: 13px; height: 13px; opacity: 0.55; }
.crumbs [aria-current] { color: var(--green-800); font-weight: 600; }

/* ------------------------------------------------- page aliment */
.food-hero { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: clamp(1.6rem, 3.5vw, 3rem); align-items: start; }
.food-hero__state { display: flex; align-items: center; gap: 0.9rem; margin: 0.4rem 0 1rem; color: var(--ink-2); font-size: 0.9rem; flex-wrap: wrap; }
.food-hero__state .dot { display: inline-block; width: 7px; height: 7px; border-radius: 99px; background: var(--green-500); margin-right: 0.4rem; }

.needs { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.7rem; }
.needs .n { background: #fff; border: 1px solid var(--line-soft); border-radius: var(--r-md); padding: 0.75rem 0.85rem; }
.needs .n b { font-size: 1.15rem; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.needs .n small { display: block; margin-bottom: 0.35rem; }
.needs .bar { margin-top: 0.5rem; }

.simil { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 0.8rem; }
.simil a {
  display: flex; align-items: center; gap: 0.7rem; background: #fff; border: 1px solid var(--line-soft);
  border-radius: var(--r-md); padding: 0.6rem 0.7rem; color: inherit;
  transition: transform 160ms var(--ease-out), box-shadow 160ms var(--ease-out);
}
.simil a { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .simil a:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
}
.simil b { font-size: 0.9rem; letter-spacing: -0.01em; line-height: 1.2; display: block; }
.simil small { font-size: 0.78rem; }

/* deltas de comparaison rapide */
.delta { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 0.86rem; }
.delta--plus { color: var(--green-700); }
.delta--minus { color: var(--red); }
.delta--eq { color: var(--ink-3); }

/* ------------------------------------------------- FAQ */
.faq details { border-bottom: 1px solid var(--line-soft); }
.faq summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.95rem 0.2rem; font-weight: 600; letter-spacing: -0.01em; color: var(--green-900);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary svg { width: 16px; height: 16px; flex: none; color: var(--ink-3); transition: transform 200ms var(--ease-out); }
.faq details[open] summary svg { transform: rotate(45deg); }
.faq .a { padding: 0 0.2rem 1rem; color: var(--ink-2); max-width: 70ch; }

/* ------------------------------------------------- attribution OSAV */
.attribution {
  display: flex; gap: 0.9rem; align-items: flex-start;
  background: var(--green-50); border: 1px solid var(--green-150); border-radius: var(--r-md);
  padding: 1rem 1.2rem; font-size: 0.88rem; color: var(--ink-2);
}
.attribution b { color: var(--ink); }
.attribution .swiss { margin-top: 0.15rem; }

/* ------------------------------------------------- comparateur */
.cmp { display: grid; grid-template-columns: minmax(0, 1fr) 92px minmax(0, 1fr); gap: 1rem; align-items: stretch; }
.cmp-portion { display: flex; justify-content: center; margin-bottom: 1.1rem; }
.cmp__col { display: flex; flex-direction: column; padding: 1.6rem 1.5rem 1.4rem; border-radius: var(--r-xl); }
.cmp__ident { justify-content: flex-start; gap: 0.85rem; margin-bottom: 0.6rem; }
/* Cadre CARRE, sur une source carree : `cover` ne rogne alors rien et ne laisse apparaitre
   aucun fond. C'est ce qui compte ici, car le fond des packshots n'est pas constant (releve sur
   40 visuels : #FEF8F6, #F9F7F1, #FAF4EE, #F7F6F2...) : un cadre de couleur fixe ferait un
   raccord visible sur la plupart, et un bandeau large en `cover` couperait le produit.
   `aspect-ratio` donne une hauteur deterministe : les deux cotes sont toujours identiques. */
.cmp__hero {
  width: min(240px, 72%); aspect-ratio: 1; margin: 0.9rem auto 1.2rem;
  border-radius: var(--r-lg); overflow: hidden; box-shadow: 0 18px 32px -20px rgba(18, 38, 28, 0.42);
}
.cmp__hero img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Echelle plus generreuse dans la comparaison : la valeur est ce que le lecteur vient chercher. */
/* Ligne et pastille tirent leur hauteur du MEME jeton : le pas des lignes valait 64,438 px
   (issu des metriques de police) contre 64 px pour les pastilles, soit une derive de 0,44 px par
   ligne. Une cale unique ne pouvait donc pas aligner les cinq a la fois. */
:root { --cmp-row: 4rem; }
.cmp .nrow { height: var(--cmp-row); padding: 0; }
.cmp .nrow__label { width: 8.5rem; }
.cmp .nrow__pct { width: auto; min-width: 4.4rem; font-size: 1.22rem; font-weight: 700; letter-spacing: -0.02em; color: var(--green-900); }
.cmp .nrow__pct small { font-size: 0.8rem; font-weight: 600; color: var(--ink-3); letter-spacing: 0; }
.cmp .nrow__name { font-size: 0.95rem; }
/* Reperage visuel de la teneur la plus ELEVEE des deux, jamais de la « meilleure » : le site ne
   hierarchise pas les aliments, et une energie plus elevee n'est pas un avantage. Meme vert et
   meme convention que le tableau complet, et une legende l'enonce sous les cartes. */
.cmp .nrow--hi .nrow__pct { color: var(--green-700); }
.cmp .nrow--hi .bar i { background: linear-gradient(90deg, var(--green-600), var(--green-500)); }
.cmp .nrow:not(.nrow--hi) .bar i { background: var(--green-350); }
.cmp .nrow:not(.nrow--hi) .nrow__pct { color: var(--ink-2); }
/* Ligne sans valeur publiee : elle occupe sa place pour que les deux colonnes et les pastilles
   restent alignees, mais elle s'efface visuellement. */
.cmp .nrow--nd .nrow__pct .nd { font-size: 0.95rem; font-weight: 600; color: var(--ink-3); }
.cmp .nrow--nd .bar { background: var(--line-soft); }
.cmp__col h2 { font-size: 1.32rem; letter-spacing: -0.02em; }
/* La colonne du milieu etait centree sur TOUTE la hauteur de la carte, en-tete et photo
   compris, avec un pas de 82 px pour des lignes de 64 px : chaque pastille tombait 130 a 202 px
   au-dessus de la ligne qu'elle decrit, et l'ecart changeait a chaque ligne. Aucune ne designait
   son nutriment. On l'ancre desormais sur le BAS des cartes, avec le meme pas que les lignes :
   chaque pastille se trouve alors exactement en face de la sienne, quel que soit le nombre de
   lignes affichees ou la hauteur de l'en-tete. */
.cmp__mid { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; padding-bottom: calc(1.4rem + 1px);   /* cale mesuree : aligne le bas de la pile sur le bas des lignes */ }
.cmp__stack { position: relative; display: flex; flex-direction: column; align-items: center; }
.cmp__stack::before { content: ""; position: absolute; top: 10px; bottom: 10px; left: 50%; width: 1px; background: var(--line); }
.cmp__bubble {
  position: relative; z-index: 1; display: grid; place-items: center; text-align: center;
  width: var(--cmp-row); height: var(--cmp-row); border-radius: 999px; background: var(--glass-strong);
  border: 1px solid var(--glass-border); box-shadow: var(--shadow-md);
  backdrop-filter: blur(10px); font-size: 0.72rem; font-weight: 700; color: var(--ink-2); line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.cmp__bubble svg { width: 15px; height: 15px; margin-bottom: 1px; }
.cmp__bubble-nut { display: none; }   /* visible seulement une fois les cartes empilees */
.cmp__bubble .to-a { color: var(--green-700); }
.cmp__bubble .to-b { color: var(--slate); }
/* La grille suit le NOMBRE de cartes reellement produites : figee a trois colonnes, elle
   laissait un trou sur 249 paires et une bande entierement vide sur 6. */
.cmp-verdicts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap: 0; border-radius: var(--r-lg); overflow: hidden; }
.cmp-verdicts .v--seule { grid-column: 1 / -1; }
.cmp-verdicts .v { display: flex; gap: 0.85rem; align-items: flex-start; padding: 1.1rem 1.3rem; }
.cmp-verdicts .v + .v { border-left: 1px solid var(--line-soft); }
.cmp-verdicts b { display: block; letter-spacing: -0.01em; margin-bottom: 0.15rem; }
.cmp-verdicts p { margin: 0; font-size: 0.88rem; color: var(--ink-2); }

.vs-pill {
  display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 999px;
  background: var(--green-900); color: #fff; font-weight: 800; font-size: 0.82rem; letter-spacing: 0.02em;
  box-shadow: var(--shadow-md); flex: none;
}

/* sélecteur d'aliment (comparateur interactif) */
.cmp-picker { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
.cmp-picker select {
  font: inherit; font-size: 0.95rem; font-weight: 600; color: var(--green-900);
  background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 0.55rem 1rem;
  box-shadow: var(--shadow-sm); cursor: pointer; max-width: 100%;
}

/* ------------------------------------------------- calculateur */
.calc-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(1.5rem, 3.5vw, 2.6rem); align-items: start; }
.calc .field { margin-bottom: 1rem; }
.calc label { display: block; font-size: 0.84rem; font-weight: 600; color: rgba(233, 242, 235, 0.8); margin-bottom: 0.4rem; }
.calc .in3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.8rem; }
.calc input[type="number"], .calc select {
  width: 100%; font: inherit; font-size: 1rem; font-weight: 600; color: #fff;
  background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 14px; padding: 0.7rem 0.9rem;
  transition: border-color 150ms var(--ease-out), background-color 150ms var(--ease-out);
}
.calc input:focus, .calc select:focus { outline: none; border-color: var(--green-500); background: rgba(255, 255, 255, 0.12); }
.calc select option { color: var(--ink); background: #fff; }
.calc .unit { position: relative; }
.calc .unit i { position: absolute; right: 0.9rem; top: 50%; transform: translateY(-50%); font-style: normal; font-size: 0.85rem; color: rgba(233, 242, 235, 0.55); }
.calc .radio2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.8rem; }
.calc .radio2 label {
  margin: 0; display: flex; align-items: center; justify-content: space-between; cursor: pointer;
  background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.18); border-radius: 14px;
  padding: 0.7rem 0.9rem; font-size: 1rem; color: #fff;
  transition: border-color 150ms var(--ease-out), background-color 150ms var(--ease-out);
}
.calc .radio2 input { position: absolute; opacity: 0; }
.calc .radio2 label.on { border-color: var(--green-500); background: rgba(76, 163, 106, 0.18); }
.calc .radio2 .tick { width: 18px; height: 18px; border-radius: 99px; border: 2px solid rgba(255, 255, 255, 0.35); display: grid; place-items: center; }
.calc .radio2 label.on .tick { border-color: var(--green-500); background: var(--green-500); }
.calc .radio2 label.on .tick::after { content: ""; width: 7px; height: 7px; border-radius: 99px; background: #fff; }
.calc__note { display: flex; gap: 0.55rem; align-items: flex-start; font-size: 0.82rem; color: rgba(233, 242, 235, 0.65); margin-top: 1rem; }
.calc__note svg { width: 15px; height: 15px; flex: none; margin-top: 0.1rem; }

/* Anneau et liste de macronutriments cote a cote. La declaration etait en style EN LIGNE sur
   l'element, ce qui rendait toute media query inoperante : en mobile l'anneau gardait ses 168 px
   et il ne restait que 98 px pour la liste, dont zero pour la colonne du libelle, qui se
   dessinait alors par-dessus le pourcentage. */
#calc-result .card { container-type: inline-size; }
.calc-res__layout { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1.4rem; align-items: center; }
/* Le basculement depend de la largeur de la CARTE, pas de celle de la fenetre : sur la page du
   calculateur la carte occupe une demi-colonne, si bien qu'a 900 px de fenetre il ne restait que
   177 px pour la liste et « Kohlenhydrate » se repliait sur 6 lignes dans 24 px de large. Un
   seuil exprime en pixels de fenetre ne peut pas couvrir ce cas. Il faut 168 px pour l'anneau,
   22 px de gouttiere et environ 230 px pour la ligne la plus longue en allemand. */
@container (max-width: 440px) {
  .calc-res__layout { grid-template-columns: minmax(0, 1fr); }
}
.calc-res .donut { width: 168px; height: 168px; margin-inline: auto; position: relative; }
.calc-res .donut svg { transform: rotate(-90deg); }
.calc-res .donut .mid { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; }
.calc-res .donut .mid b { font-size: 1.7rem; letter-spacing: -0.03em; display: block; line-height: 1.05; }
.calc-res .donut .mid small { color: var(--ink-3); }
.macros { display: flex; flex-direction: column; gap: 0.7rem; }
.macros .m { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 0.7rem; background: #fff; border: 1px solid var(--line-soft); border-radius: var(--r-md); padding: 0.7rem 0.9rem; }
.macros .m .sw { width: 10px; height: 10px; border-radius: 99px; }
.macros .m b { font-variant-numeric: tabular-nums; }
.macros .m .pct { color: var(--ink-3); font-size: 0.85rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.macros .m b { white-space: nowrap; }                       /* « 160 g » ne se coupe pas */
.macros .m > span:nth-child(2) { min-width: 0; overflow-wrap: break-word; }

/* ------------------------------------------------- méthodologie / étapes */
.steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; counter-reset: step; }
.steps .s { padding: 1.2rem; border-radius: var(--r-lg); }
.steps .s b { display: block; margin: 0.75rem 0 0.3rem; letter-spacing: -0.01em; }
.steps .s p { margin: 0; font-size: 0.87rem; color: var(--ink-2); }
.steps .s--dark { background: var(--green-900); color: #E9F2EB; box-shadow: var(--shadow-dev); }
.steps .s--dark p { color: rgba(233, 242, 235, 0.72); }
.steps .s--dark b { color: #fff; }

.qual { display: flex; gap: 0.9rem; align-items: flex-start; }
.qual .grade { margin-top: 0.1rem; }
.qual b { display: block; letter-spacing: -0.01em; }
.qual p { margin: 0.15rem 0 0; font-size: 0.86rem; color: var(--ink-2); }

/* ------------------------------------------------- listes d'aliments (explorer) */
.foodgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.9rem; }
.foodgrid a {
  display: flex; align-items: center; gap: 0.85rem; color: inherit;
  background: #fff; border: 1px solid var(--line-soft); border-radius: var(--r-md); padding: 0.7rem 0.8rem;
  transition: transform 160ms var(--ease-out), box-shadow 160ms var(--ease-out);
}
.foodgrid a { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .foodgrid a:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
}
/* Le bloc de texte doit pouvoir descendre sous son min-content : sans min-width: 0, un nom
   d'aliment tres long (« Emince, hache, escalope vegetarien a base de mycoproteine, cru »)
   imposait sa largeur intrinseque et poussait la valeur en kcal hors de la carte, jusqu'a
   24 px au-dela, ce qui faisait defiler la page. Meme correctif sur les cartes similaires. */
.foodgrid a > span:not(.thumb):not(.kcal), .simil a > span:not(.thumb) { min-width: 0; }
.foodgrid b, .simil b { overflow-wrap: break-word; }
.foodgrid b { display: block; letter-spacing: -0.01em; font-size: 0.95rem; line-height: 1.25; }
.foodgrid small { color: var(--ink-3); }
.foodgrid .kcal { margin-left: auto; text-align: right; flex: none; font-variant-numeric: tabular-nums; color: var(--ink-2); font-size: 0.85rem; }
.foodgrid .kcal b { font-size: 1rem; color: var(--ink); }

/* Grille des familles, harmonisee pour les quatre langues.
   Les intitules sont des libelles officiels OSAV, de 4 a 71 caracteres selon la langue. A
   210 px de colonne, l'habillage (32 px de marge interieure, 40 px de pictogramme, 12,8 px de
   gouttiere) consommait 38 % de la carte et il ne restait que 139 px pour le texte : le libelle
   francais le plus long se repliait sur 6 lignes, l'allemand sur 5, et la grille presentait
   trois hauteurs de carte differentes avec jusqu'a 57 px d'ecart. Colonnes elargies pour que
   trois lignes suffisent dans les quatre langues, et hauteur unique pour toutes les cartes. */
.famgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.9rem; }
.famgrid a { display: flex; align-items: center; gap: 0.8rem; padding: 0.95rem 1rem; min-height: 7.15rem;   /* hauteur unique : trois lignes de libelle plus le compte */ border-radius: var(--r-md); background: #fff; border: 1px solid var(--line-soft); color: inherit; transition: transform 160ms var(--ease-out), box-shadow 160ms var(--ease-out); }
.famgrid a { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .famgrid a:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
}
.famgrid a > span:last-child { flex: 1; min-width: 0; }
.famgrid b {
  letter-spacing: -0.01em; font-size: 0.95rem; line-height: 1.25;
  /* trois lignes reservees : la hauteur d'une carte ne depend plus de la langue */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: break-word;
  /* Cesure : sans elle un compose allemand ne coupe qu'aux espaces, et
     « Pflanzliche Proteinlieferanten und Alternativen zu tierischen Produkten » exigeait
     quatre lignes la ou trois suffisent avec cesure. Le decoupage suit l'attribut lang de la
     page, donc les regles de la bonne langue dans les quatre versions. */
  hyphens: auto; -webkit-hyphens: auto;
}
/* Deux intitules officiels depassent 56 caracteres (« Aliments proteiques vegetaux et
   substituts de produits d'origine animale » en francais, son equivalent allemand) et ne
   tiennent pas en trois lignes au corps courant. Ils passent a un corps legerement reduit
   plutot que d'etre coupes : aucun libelle officiel n'est ampute, et la carte garde sa hauteur.
   La cesure ci-dessus aide quand le navigateur du visiteur dispose du dictionnaire, mais on ne
   peut pas en dependre. */
.famgrid b.fam--long { font-size: 0.85rem; }

@supports not (-webkit-line-clamp: 3) {
  .famgrid b { display: block; max-height: 3.75em; overflow: hidden; }
}
.famgrid small { color: var(--ink-3); }

/* ------------------------------------------------- newsletter / capture */
.newsbox { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 2rem; align-items: center; }
.newsbox form { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.newsbox input[type="email"] {
  flex: 1; min-width: 220px; font: inherit; border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.1); color: #fff; border-radius: 999px; padding: 0.7rem 1.2rem;
}
.newsbox input::placeholder { color: rgba(233, 242, 235, 0.55); }
.newsbox .consent { display: flex; gap: 0.55rem; align-items: flex-start; font-size: 0.8rem; color: rgba(233, 242, 235, 0.68); margin-top: 0.8rem; }
.newsbox .consent input { margin-top: 0.2rem; accent-color: var(--green-500); }

/* ------------------------------------------------- footer */
footer.site {
  margin-top: clamp(3rem, 6vw, 5rem);
  background: var(--green-950); color: rgba(233, 242, 235, 0.8);
  padding: clamp(2.5rem, 5vw, 4rem) 0 2rem;
}
footer.site .cols { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); gap: 2rem; margin-bottom: 2.5rem; }
footer.site .ft-title { color: #fff; font-size: 0.92rem; font-weight: 700; margin: 0 0 0.9rem; letter-spacing: 0.01em; }
footer.site ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
footer.site a { color: rgba(233, 242, 235, 0.75); font-size: 0.9rem; }
footer.site a:hover { color: #fff; }
footer.site .wm span { color: #9DC3A7; }
footer.site .wm b { color: #fff; }
footer.site .legal {
  border-top: 1px solid rgba(255, 255, 255, 0.12); padding-top: 1.4rem; font-size: 0.8rem;
  color: rgba(233, 242, 235, 0.55); display: flex; flex-wrap: wrap; gap: 0.8rem 1.8rem; justify-content: space-between;
}
footer.site .legal a { font-size: 0.8rem; }
/* Le lien vers la source officielle vit AU MILIEU d'une phrase : sans soulignement, seul
   un ecart de couleur le distingue, et il mesure moins de 3:1 avec le texte voisin. Les
   autres liens du bandeau restent nus : isoles, ils s'identifient par leur position. */
footer.site .legal span a { text-decoration: underline; text-underline-offset: 2px; }
.langsw { display: flex; gap: 0.3rem; }
.langsw span, .langsw a { padding: 0.2rem 0.55rem; border-radius: 8px; font-size: 0.8rem; }
.langsw .on { background: rgba(255, 255, 255, 0.14); color: #fff; font-weight: 600; }
/* 0.45 donnait 3,85:1 sur le vert du pied de page, sous le seuil de 4,5:1 pour du texte
   de cette taille. 0.66 mesure 6,6:1 et la hierarchie face a la langue active (blanc pur
   sur pastille) reste nette. cursor: default etait un mensonge : ce sont de vrais liens. */
.langsw .off { color: rgba(233, 242, 235, 0.66); }

/* ------------------------------------------------- divers */
.muted { color: var(--ink-3); }
.tag {
  display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.8rem; font-weight: 600;
  background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 0.25rem 0.7rem; color: var(--ink-2);
}
/* `minmax(0, 1fr)` et non `1fr` : voir le commentaire de .tiles : `1fr` vaut
   `minmax(auto, 1fr)` et gèle la piste sur son min-content, ce qui déséquilibre les colonnes
   et peut faire déborder le conteneur. Le même défaut était présent ici, sur 6 emplacements
   dont les fiches d'aliment et le calculateur. */
.grid2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.1rem; }
/* Deux cartes dont les contenus n'ont aucune raison d'avoir la même hauteur : chacune s'arrête
   où son contenu s'arrête, plutôt que d'étirer la plus courte sur 180 px de vide. */
.grid2--top { align-items: start; }
.grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.1rem; }
/* colonne principale + colonne latérale (guides, classements par famille, N8) :
   en classe et non en style inline, sinon la media query ne peut pas reprendre la main */
.layout-2-1 { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 1.1rem; align-items: start; }
@media (max-width: 900px) { .layout-2-1 { grid-template-columns: minmax(0, 1fr); } }
.split { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.center { text-align: center; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: 0.5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; } .mt-4 { margin-top: 2.5rem; }
.mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; }
.w-narrow { max-width: 46rem; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* lien d'évitement : visible dès qu'il reçoit le focus clavier */
a.visually-hidden:focus {
  position: fixed; top: 10px; left: 10px; z-index: 200; width: auto; height: auto; clip: auto;
  background: var(--green-900); color: #fff; padding: 0.6rem 1rem; border-radius: 10px;
  box-shadow: var(--shadow-lg); font-weight: 600; text-decoration: none;
}

.notice { display: flex; gap: 0.7rem; align-items: flex-start; background: #fff; border: 1px solid var(--line-soft); border-radius: var(--r-md); padding: 0.9rem 1.1rem; font-size: 0.87rem; color: var(--ink-2); }
.notice svg { width: 17px; height: 17px; flex: none; color: var(--green-700); margin-top: 0.1rem; }

.prose { max-width: 68ch; }
.prose h2:first-child { margin-top: 0; }
.prose h2 { margin-top: 2.2rem; scroll-margin-top: 5.5rem; }
.prose h3 { margin-top: 1.6rem; }
.prose ul { padding-left: 1.2rem; color: var(--ink-2); }
.prose li { margin-bottom: 0.4rem; }
.prose table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.prose table th, .prose table td { text-align: left; padding: 0.55rem 0.7rem; border-bottom: 1px solid var(--line-soft); }
.prose table th { color: var(--ink-2); font-size: 0.83rem; }
/* tableaux insérés dans un guide : scroll horizontal propre sur mobile */
.prose table.nut { display: block; overflow-x: auto; white-space: nowrap; }
@media (min-width: 700px) { .prose table.nut { display: table; white-space: normal; } }
.prose table.nut td:not(:first-child), .prose table.nut th:not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; }

/* apparition douce au scroll (décoratif, désactivé si reduced motion) */
/* L'apparition au defilement n'est armee que si JS est la : sans lui, la classe `in` ne serait
   jamais posee et la page entiere resterait a opacity:0 avec ses liens focalisables (SC 2.4.7).
   La classe `js` est posee par un script en tete de <head>, avant le premier rendu. */
.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity 550ms var(--ease-out), transform 550ms var(--ease-out); transition-delay: var(--d, 0ms); }
.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js .reveal.in { opacity: 1; transform: none; transition: none; }
  .card--hover:hover, .simil a:hover, .foodgrid a:hover, .famgrid a:hover { transform: none; }
  * { animation-duration: 0.01ms !important; }
}
@media (prefers-reduced-transparency: reduce) {
  .glass, .nav, .cmp__bubble { backdrop-filter: none; -webkit-backdrop-filter: none; background: #fff; }
  .devcard { background: var(--green-900); }
}

/* ------------------------------------------------- responsive */
@media (max-width: 1020px) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  footer.site .cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
/* Le header complet reclame 1189 px (marque 130 + liens 649 + actions avec recherche 362 +
   gouttieres) alors que .nav__inner est plafonne a 1180 px : il ne rentrait a aucune largeur.
   Le debordement allait de 10 px vers 1200 px a 189 px a 1021 px, sur TOUTES les pages.
   La recherche du header ne s'affiche donc qu'au-dela, et elle peut se reduire. */
.nav .searchbox { min-width: 0; max-width: 15rem; }
@media (max-width: 1240px) {
  .nav .searchbox { display: none; }
}
/* HORS PÉRIMÈTRE de la refonte de la bande d'accueil, mais le défaut fait défiler toute la page
   latéralement : le menu de navigation ne se repliait qu'à 860 px alors que ses trois blocs
   demandent 891 px (marque 130 + liens 649 + actions 111 + gouttières), avec flex-wrap: nowrap.
   Entre 861 et 1000 px la page débordait donc de 74 px. Le seuil est porté là où le menu cesse
   réellement de tenir. Supprimer ce bloc restaure le comportement précédent. */
@media (max-width: 1000px) {
  .nav__links, .nav__actions .btn--light { display: none; }
  .nav-burger-btn { display: grid; }
  /* Le menu burger etait un label deguise en bouton (role="button" + tabindex) : promesse
     qu'Entree/Espace l'actionnent, ce qu'un label ne fait pas. La commande clavier est
     desormais la CASE elle-meme, qu'Espace actionne nativement, sans JavaScript : hors
     ecran mais focusable (surtout pas display:none, qui retire du clavier), et l'anneau de
     focus est reporte sur le pictogramme que l'utilisateur regarde. Les labels redeviennent
     de simples cibles de clic. En bureau, la regle de base display:none la retire du
     parcours puisque le bouton n'y est pas visible. */
  .nav-burger { display: block; position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
  .nav-burger:focus-visible ~ .nav .nav-burger-btn { outline: 2px solid var(--green-800); outline-offset: 2px; }
  .nav-burger:checked:focus-visible ~ .mobile-menu .close-btn { outline: 2px solid var(--green-900); outline-offset: 2px; }
  .nav__inner { justify-content: space-between; }
  .nav__actions { margin-left: auto; }
  .nav-burger:checked ~ .mobile-menu { transform: none; opacity: 1; pointer-events: auto; }
}
/* Cibles tactiles. Les commandes deliberees doivent atteindre 44 px sous le doigt ; mesure
   avant correction : marque 130x24, boutons de portion 61x34, selecteur de langue 37x29,
   fil d'Ariane 47x21. Les liens de texte en ligne dans une phrase restent exemptes (WCAG 2.5.8). */
@media (max-width: 860px), (pointer: coarse) {

  /* Hauteur imposee plutot que deduite d'une marge : une marge laissait 41 a 43 px selon la
     police, soit juste sous le seuil, et le resultat variait d'un element a l'autre. */
  .nav__brand { min-height: 44px; }
  .seg button, .seg input { min-height: 44px; }
  /* Mesures avant correction : bouton d'inscription 87x39, hamburger et fermeture 42x42,
     champ de recherche du menu 267x26, filtres de classement 25 a 40 px de haut. */
  .nav__actions .btn { min-height: 44px; }
  .nav-burger-btn, .close-btn { width: 44px; height: 44px; }
  .searchbox__field input { min-height: 44px; }
  a.tag, button.tag { min-height: 44px; }
  /* Texte des pastilles d'ecart : 11,5 px, sous le plancher de lisibilite au telephone. */
  .cmp__bubble { font-size: 0.78rem; }
  .langsw a, .langsw span { min-height: 44px; display: inline-flex; align-items: center; padding-inline: 0.7rem; }
  .crumbs a { min-height: 44px; display: inline-flex; align-items: center; }
  .cmp-picker select, .calc select { min-height: 44px; }
  /* Les pastilles d'origine A/E/C mesuraient 9,9 px : illisibles sur un telephone. */
  .flag { font-size: 0.72rem; min-width: 1.4rem; height: 1.4rem; }
}

@media (max-width: 860px) {
  .hero, .food-hero, .calc-grid, .newsbox { grid-template-columns: minmax(0, 1fr); }
  .cmp { grid-template-columns: minmax(0, 1fr); }
  /* Cartes empilees : les pastilles ne peuvent plus se placer en face des lignes, elles
     forment une bande horizontale entre les deux cartes. L'ancrage sur le bas et le trait
     vertical n'ont plus de sens ici. */
  /* Cartes empilees. La bande de pastilles ne peut plus s'aligner sur les lignes : elle devient
     une liste d'ecarts, une par nutriment, chacune portant son nom. Et les fleches pivotent :
     les deux aliments ne sont plus a gauche et a droite mais au-dessus et en dessous, une
     fleche horizontale ne designerait plus rien. Une rotation d'un quart de tour suffit pour
     les deux sens : « vers la gauche » devient « vers le haut », « vers la droite » devient
     « vers le bas ». */
  .cmp__mid { flex-direction: column; justify-content: flex-start; padding-block: 0.6rem; padding-bottom: 0.6rem; }
  .cmp__stack { flex-direction: column; align-items: stretch; width: 100%; gap: 0.4rem; }
  .cmp__stack::before { display: none; }
  .cmp__bubble {
    width: 100%; height: auto; min-height: 44px;
    display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 0.55rem;
    padding: 0.45rem 0.9rem; text-align: left; box-shadow: var(--shadow-sm);
  }
  .cmp__bubble-nut { display: block; font-weight: 600; color: var(--ink-2); font-size: 0.88rem; }
  .cmp__bubble svg { transform: rotate(90deg); margin-bottom: 0; }
  .cmp__bubble > span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
  /* Le visuel produit occupe 240 px par carte : reduit, il rapproche les deux cartes, ce qui est
     tout l'interet d'une comparaison quand on ne voit qu'un ecran a la fois. */
  .cmp__hero { width: min(150px, 46%); margin-block: 0.6rem 0.9rem; }
  .cmp-verdicts { grid-template-columns: minmax(0, 1fr); }
  .cmp-verdicts .v + .v { border-left: 0; border-top: 1px solid var(--line-soft); }
  .grid2, .grid3 { grid-template-columns: minmax(0, 1fr); }
  /* La barre de magnitude disparaît faute de largeur : sa légende n'a plus rien à décrire, et
     elle disputait la place au titre de la tuile (replié sur 3 lignes à 375 px). Les deux
     s'affichent et se retirent ensemble. */
  .rank__bar, .rank-legend { display: none; }
  .page-leaves { display: none; }
}
@media (max-width: 780px) {
  /* Les deux tuiles d'appoint ne tiennent plus cote a cote : on empile. Seuil place la ou la
     colonne de valeurs du comparateur commencerait a se replier, pas a une valeur ronde. */
  .tiles { grid-template-columns: minmax(0, 1fr); }
  .tiles .card .spacer { flex: none; }
}
@media (max-width: 720px) {
  /* Sous cette largeur, la liste ne tient plus a cote de l'anneau de 168 px : on empile. */
  .calc-res__layout { grid-template-columns: minmax(0, 1fr); justify-items: stretch; }
}
@media (max-width: 560px) {
  .steps { grid-template-columns: minmax(0, 1fr); }
  footer.site .cols { grid-template-columns: minmax(0, 1fr); }
  .foodpanel__grid { grid-template-columns: minmax(0, 1fr); }
  .calc .in3 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .nrow__label { width: 8rem; }
  h1 { font-size: 1.9rem; }
}

.mobile-menu {
  position: fixed; inset: 0; top: 0; z-index: 60; padding: 1.2rem;
  background: rgba(242, 244, 238, 0.9); backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  transform: translateY(-8px); opacity: 0; pointer-events: none;
  visibility: hidden; /* menu fermé = hors de l'ordre de tabulation */
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out), visibility 0s 220ms;
  display: flex; flex-direction: column;
}
.nav-burger:checked ~ .mobile-menu { visibility: visible; transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out), visibility 0s; }
.mobile-menu__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.5rem; }
.mobile-menu__search { margin-bottom: 1.2rem; }
.mobile-menu__search .searchbox__list { max-height: 46vh; overflow-y: auto; }
.mobile-menu nav { display: flex; flex-direction: column; gap: 0.2rem; }
.mobile-menu nav a {
  font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em; color: var(--green-900);
  padding: 0.8rem 0.6rem; border-radius: 14px;
}
.mobile-menu nav a:hover { background: rgba(255, 255, 255, 0.85); text-decoration: none; }
.mobile-menu .close-btn { border: 0; background: #fff; border-radius: 12px; width: 42px; height: 42px; display: grid; place-items: center; cursor: pointer; box-shadow: var(--shadow-sm); color: var(--green-900); }

/* ------------------------------------------------- très petits écrans (bande d'accueil)
   À 320 px, la largeur utile d'une carte tombe à 235 px : les gabarits fixes des lignes de
   répartition arrivaient à 1 px du bord. On resserre les deux colonnes fixes, la barre garde
   son minimum de 60 px. */
@media (max-width: 400px) {
  /* A 320 px, le header demande 318 px (marque 130 + gouttiere 24 + actions 164, dont le bouton
     d'inscription a 111 px et le hamburger a 42 px) pour 280 px disponibles, ce qui faisait
     defiler toutes les pages lateralement de 19 px. On resserre plutot que de masquer le bouton :
     il est le seul chemin vers la newsletter depuis le header, et le menu mobile ne le propose pas.
     Et la colonne de contenu recupere 16 px de gouttiere, utiles a cette largeur. */
  .container, .nav__inner { width: min(1180px, 100% - 1.6rem); }
  .nav__inner { gap: 0.6rem; }
  .nav__actions { gap: 0.4rem; }
  .nav__actions .btn { padding: 0.55rem 0.8rem; font-size: 0.88rem; }
  /* Ligne de nutriment : les deux colonnes fixes (9,5 rem puis 8 rem, et 3,4 rem) plus le
     minimum de 60 px de la barre demandaient 268 px pour 235 px disponibles a 320 px de large,
     d'ou 19 a 26 px de defilement lateral sur le panneau d'en-tete. */
  .nrow__label { width: 6rem; }
  .nrow__pct { width: 3rem; }
  /* `.devcard .nrow__label` est plus specifique que la regle ci-dessus et l'emportait : la ligne
     du panneau d'en-tete debordait encore de 19 px dans la marge interieure de la carte. Le
     pictogramme de ligne (40 px plus sa gouttiere) ne dit rien que le libelle ne dise deja :
     a cette largeur il cede sa place au texte. */
  .devcard .nrow__label { width: 7.5rem; }
  .devcard .nrow__label > .ico { display: none; }
  /* Meme piege de specificite dans la comparaison : `.cmp .nrow__label` l'emporte sur la regle
     generale ci-dessus, et la ligne debordait de 25 px a 320 px. */
  .cmp__col { padding: 1.2rem 1.1rem; }
  /* 6 rem laissaient 46 px au texte une fois le pictogramme et sa gouttiere deduits :
     « Vitamine D » et « Oméga-3 » se cassaient en deux lignes. La carte offre 300 px de large
     a 375 px de fenetre, la ligne en demande 255 avec ces valeurs. */
  .cmp .nrow__label { width: 9rem; }
  .cmp .nrow__pct { min-width: 3.2rem; font-size: 1.02rem; }
  .cmp .bar { min-width: 34px; }
  .nrow--tile .nrow__label { width: 5.4rem; }
  .nrow--tile .nrow__name { font-size: 0.8rem; }
  .nrow--tile .nrow__pct { width: 2.6rem; }
}

/* ------------------------------------------------- assiette (composeur) */
/* Deux colonnes dès qu'il y a la place : le composeur reste sous les yeux pendant qu'on lit
   les totaux. Chaque piste `fr` est écrite `minmax(0, …)` : sans cela son minimum vaut
   min-content et le tableau des 22 nutriments élargit la grille au lieu de défiler. */
.plate { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.4rem; align-items: start; }
@media (min-width: 1000px) {
  .plate { grid-template-columns: minmax(0, 23rem) minmax(0, 1fr); gap: 1.8rem; }
  .plate__compose { position: sticky; top: 5.5rem; }
}
.plate__res { min-width: 0; }
.plate__card { padding: 1.2rem; }

/* la recherche d'ajout : elle ne navigue pas, elle ajoute, et garde le focus pour enchaîner */
.pfind { position: relative; margin-top: 0.9rem; }
.pfind__i { position: absolute; left: 0.9rem; top: 50%; transform: translateY(-50%); color: var(--ink-3); display: grid; pointer-events: none; }
.pfind__i svg { width: 18px; height: 18px; }
.pfind input {
  width: 100%; border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  border-radius: 999px; padding: 0.72rem 1rem 0.72rem 2.7rem; font: inherit; font-size: 0.94rem;
}
.pfind input::-webkit-search-cancel-button { cursor: pointer; }
.pfind input:focus-visible { outline: 2px solid var(--green-600); outline-offset: 2px; }
.pfind__list {
  display: none; position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 0.4rem);
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-lg); max-height: 21rem; overflow: auto; padding: 0.3rem;
}
.pfind--open .pfind__list { display: block; }
.pfind__list button {
  display: flex; width: 100%; gap: 0.7rem; align-items: center; text-align: left;
  border: 0; background: transparent; font: inherit; color: var(--ink);
  cursor: pointer; padding: 0.45rem; border-radius: var(--r-sm);
}
.pfind__list button:hover, .pfind__list button.sel { background: var(--green-50); }
.pfind__list button:focus-visible { outline: 2px solid var(--green-600); outline-offset: -2px; }
.pfind__list .thumb { width: 38px; height: 38px; border-radius: 11px; font-size: 0.9rem; }
.pfind__empty { padding: 0.85rem; color: var(--ink-3); font-size: 0.9rem; }

/* une ligne d'aliment */
.plist { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 0.5rem; }
.prow {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 0.6rem; align-items: center;
  background: var(--green-50); border: 1px solid var(--green-150); border-radius: var(--r-md); padding: 0.45rem 0.5rem;
}
.prow__t { width: 44px; height: 44px; border-radius: 12px; }
.prow__id { min-width: 0; display: grid; }
.prow__id a { font-weight: 600; font-size: 0.9rem; color: var(--green-900); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prow__id a:hover { text-decoration: underline; }
.prow__id small { font-size: 0.76rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prow__q { position: relative; display: inline-flex; align-items: center; }
.prow__g {
  width: 5.1rem; padding: 0.45rem 1.5rem 0.45rem 0.55rem; border: 1px solid var(--line);
  border-radius: var(--r-sm); background: #fff; color: var(--ink);
  font: inherit; font-size: 0.92rem; text-align: right; font-variant-numeric: tabular-nums;
}
/* Les flèches natives font 12 px de large : trop petites pour être une vraie commande, et
   elles déforment le champ. La saisie et les flèches du clavier suffisent. */
.prow__g::-webkit-outer-spin-button, .prow__g::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.prow__g { -moz-appearance: textfield; appearance: textfield; }
.prow__g:focus-visible { outline: 2px solid var(--green-600); outline-offset: 1px; }
.prow__q i { position: absolute; right: 0.5rem; font-style: normal; font-size: 0.78rem; color: var(--ink-3); pointer-events: none; }
.prow__x { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: transparent; color: var(--ink-3); border-radius: 999px; cursor: pointer; }
.prow__x:hover { background: #fff; color: var(--red); }
.prow__x svg { width: 16px; height: 16px; }
.plist__empty { display: grid; gap: 0.25rem; padding: 1.2rem; text-align: center; color: var(--ink-2); border: 1px dashed var(--green-150); border-radius: var(--r-md); }
.plist__empty span { font-size: 0.87rem; }
.plist__foot { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; justify-content: space-between; margin-top: 0.9rem; }
.btn--sm { padding: 0.45rem 0.95rem; font-size: 0.86rem; }
.pnote__priv { display: flex; gap: 0.5rem; align-items: flex-start; margin: 0.9rem 0 0; font-size: 0.79rem; color: var(--ink-3); }
.pnote__priv svg { width: 14px; height: 14px; flex: none; margin-top: 0.15rem; }

/* les totaux */
.ptot__h { margin: 0; font-size: 1.2rem; }
.ptot__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.1rem; margin-top: 1.1rem; align-items: center; }
@container (min-width: 34rem) { .ptot__grid { grid-template-columns: auto minmax(0, 1fr); gap: 2rem; } }
.ptot__e { display: grid; justify-items: start; align-content: center; }
.ptot__e b { font-size: clamp(2.5rem, 8cqi, 3.5rem); line-height: 1; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.ptot__e small { font-size: 0.9rem; color: rgba(233, 242, 235, 0.72); }
.ptot__kj { font-size: 0.84rem; color: rgba(233, 242, 235, 0.75); font-variant-numeric: tabular-nums; }
/* 0,6 donnait 3,68:1 sur l'angle clair du dégradé du panneau, là où ce texte est justement
   posé ; 0,75 le remonte à 4,8:1 au pire endroit. WCAG 2.2 SC 1.4.3. */
.ptot__m { display: grid; gap: 0.5rem; }
.pm { display: grid; grid-template-columns: minmax(0, 8.5rem) auto minmax(60px, 1fr) auto; gap: 0.7rem; align-items: center; font-size: 0.89rem; }
.pm__l { color: rgba(233, 242, 235, 0.82); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pm__v { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pm__p { font-variant-numeric: tabular-nums; color: rgba(233, 242, 235, 0.72); font-size: 0.83rem; min-width: 3.2rem; text-align: right; }
@container (max-width: 27rem) {
  .pm { grid-template-columns: minmax(0, 1fr) auto auto; gap: 0.2rem 0.6rem; }
  .pm .bar { grid-column: 1 / -1; grid-row: 2; }
}

/* le tableau : même objet que celui des fiches aliment, plus une jauge de couverture */
.ptab__v, .ptab__c { white-space: nowrap; }
.ptab__sub td:first-child { padding-left: 1.5rem; color: var(--ink-2); font-weight: 400; }
.ptab__p { display: flex; align-items: center; gap: 0.6rem; justify-content: flex-end; }
.ptab__b { max-width: 5.5rem; }
.ptab__p b { font-variant-numeric: tabular-nums; min-width: 3.3rem; text-align: right; font-weight: 600; }
/* Le « ≥ » n'est pas décoratif : il dit qu'un aliment de l'assiette n'a pas de valeur publiée
   pour cette ligne, et que le total est donc un minorant. */
.pmin { color: var(--green-700); font-weight: 700; cursor: help; }
@media (max-width: 560px) { .ptab__b { display: none; } }

/* ce que chaque aliment apporte */
.pbf { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.85rem; }
.pbf__i {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.35rem 0.8rem; align-items: baseline;
  padding-bottom: 0.85rem; border-bottom: 1px solid var(--line-soft);
}
.pbf__i:last-child { border-bottom: 0; padding-bottom: 0; }
.pbf__n { min-width: 0; display: flex; flex-wrap: wrap; gap: 0.45rem; align-items: baseline; }
.pbf__n b { color: var(--green-900); }
.pbf__n small { font-size: 0.8rem; }
.pbf__e { display: flex; gap: 0.45rem; align-items: baseline; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pbf__e small { font-size: 0.8rem; }
.pbf__b { grid-column: 1 / -1; }
.pbf__m { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 0.15rem 1.1rem; font-size: 0.84rem; color: var(--ink-2); }
.pbf__m i { font-style: normal; color: var(--ink-3); }
.pbf__m b { font-variant-numeric: tabular-nums; color: var(--ink); font-weight: 600; }

/* réserves et partage */
.pnotes { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
@media (min-width: 720px) { .pnotes { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.pnote p { margin: 0.4rem 0 0; font-size: 0.87rem; }
.pshare { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.9rem; }
.pshare .btn { border: 1px solid var(--line); background: #fff; }
.pshare .btn:hover { border-color: var(--green-350); }
.pshare .btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.pflash { min-height: 1.25rem; margin: 0.6rem 0 0; font-size: 0.85rem; font-weight: 600; color: var(--green-700); }

/* ------------------------------------------------- assiette : bascule vide / rempli */
/* La page arrive vide. Tout ce qui ne peut pas encore calculer est masqué par cette paire de
   règles, jamais retiré du DOM : plate.js lie ses commandes une seule fois par getElementById,
   et un nœud retiré puis réinséré reviendrait sans écouteur. display:none sort malgré tout
   l'élément de l'ordre de tabulation et de l'arbre d'accessibilité, ce qui est le but :
   à vide, plus de tableau de 22 lignes parcourable ni de bouton de partage focalisable. */
[data-plate="empty"] .ponly-filled { display: none; }
[data-plate="filled"] .ponly-empty { display: none; }

/* Le premier clic est désigné par la bordure du champ, pas par un halo : le halo vert clair
   plafonnait à 2:1 sur blanc, sous le seuil de 3:1 exigé pour un indicateur non textuel
   (WCAG 2.2 SC 1.4.11). La désignation disparaît dès le premier aliment ajouté. */
.pfind--primed input { background: #fff; border-color: var(--green-600); border-width: 1.5px; }
.pfind__hint { margin: 0.5rem 0 0; font-size: 0.8rem; color: var(--ink-3); }
.pfind__wait { padding: 0.85rem; color: var(--ink-3); font-size: 0.9rem; }
.pfind__empty a, .pfind__wait a { color: var(--green-700); }

/* Le bloc vide porte le mode d'emploi : il se lit, donc il s'aligne à gauche comme un texte,
   et il est focalisable par programme pour recevoir le focus quand la commande qui le portait
   vient d'être détruite (retrait de la dernière ligne, ou vidage). */
.plist__empty { text-align: left; padding: 1.1rem; }
.plist__empty b { color: var(--green-900); }
.plist__empty:focus-visible { outline: 2px solid var(--green-600); outline-offset: 2px; }

/* Le panneau sombre garde son titre et son ancre visuelle, mais aucun zéro : une énergie à
   0 kcal et des jauges à plat se lisent comme une panne, pas comme une attente. */
.ptot__wait { margin: 0.9rem 0 0; font-size: 0.95rem; color: rgba(233, 242, 235, 0.82); max-width: 46ch; }

/* Ajouter deux fois le même aliment cumule les grammes : sans ce repère visuel, le geste
   passerait pour sans effet sur une ligne parfois hors écran. */
.prow--bump { outline: 2px solid var(--green-600); outline-offset: 2px; }

/* Raccourci vers les totaux : utile seulement quand la colonne de résultats passe SOUS le
   composeur, donc en une seule colonne. */
.pfoot__jump { display: none; }
@media (max-width: 999px) { [data-plate="filled"] .pfoot__jump { display: inline-flex; } }

/* ------------------------------------------------- pastille de symbole (nutriments) */
/* UN SEUL style pour les douze : pastille pleine, symbole en blanc. Une premiere version
   distinguait les elements chimiques des vitamines par trois habillages differents ; sur une
   grille de douze, cela faisait un patchwork. La distinction etait de toute facon inutile :
   le libelle « Riches en magnesium » est juste a cote et leve l'ambiguite entre le potassium
   et la vitamine K bien mieux qu'une bordure.
   Meme encombrement que .ico, pour ne pas casser le rythme des grilles ou elle la remplace. */
.sym {
  width: 40px; height: 40px; border-radius: 13px; flex: none;
  display: inline-grid; place-items: center;
  background: var(--green-800); color: #fff;
  font-weight: 700; font-size: 0.95rem; letter-spacing: -0.02em;
}
/* « B12 », « Prot », « n-3 » : la police se resserre plutot que le symbole ne deborde */
.sym--long { font-size: 0.72rem; letter-spacing: -0.03em; }
/* sur le panneau sombre, la pastille s'inverse pour rester lisible */
.devcard .sym { background: #fff; color: var(--green-900); }
@media (max-width: 860px), (pointer: coarse) { .sym { width: 44px; height: 44px; } }

/* vignette de famille : elle remplace une icone repetee dix-neuf fois. Meme gabarit que .ico
   (40 px, coins arrondis, ne se comprime pas) pour que la grille garde son rythme. */
.famgrid__t {
  width: 40px; height: 40px; border-radius: 13px; overflow: hidden; flex: none;
  background: #F8F6F5; border: 1px solid var(--line-soft);
}
.famgrid__t img { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 860px), (pointer: coarse) { .famgrid__t { width: 44px; height: 44px; } }

/* ------------------------------------------------- signature d'article */
/* Une ligne, trois informations de rang decroissant : qui signe, a quel titre, quand. Le nom
   porte le poids, la fonction et la date restent en retrait pour ne pas concurrencer le chapo. */
.byline { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem; margin: 1.2rem 0 0; font-size: 0.85rem; color: var(--ink-3); }
.byline b { color: var(--ink); font-weight: 600; }
.byline__r { color: var(--ink-2); }
.byline__r::before { content: "·"; margin-right: 0.4rem; color: var(--ink-3); }
.byline__s { color: var(--line); }

/* illustration de tete d'article : elle appartient a l'article, pas au decor, d'ou <figure> */
.artlead { margin: 1.6rem 0 0; border-radius: var(--r-lg); overflow: hidden; background: #F2F4EE; box-shadow: var(--shadow-md); }
.artlead img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }

/* ------------------------------------------------- cartes d'article (hub) */
/* Le bouton « Lire l'article » a été retiré : le titre est la seule cible cliquable de la
   carte. La carte ne se soulève donc plus au survol, car un tel mouvement promettrait une
   surface entièrement cliquable qui n'existe pas. */
.gcard { display: flex; flex-direction: column; overflow: hidden; }
/* image à fleur de carte : marges négatives égales au padding de .card (1,4rem) */
.gcard__img {
  display: block; margin: -1.4rem -1.4rem 1.1rem;
  background: #F8F6F5;   /* fond exact des packshots : le raccord ne se voit pas */
  border-bottom: 1px solid var(--line-soft);
}
.gcard__img img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.gcard__t { font-size: 1.15rem; line-height: 1.3; letter-spacing: -0.015em; margin: 0 0 0.45rem; }
.gcard__t a { color: var(--green-900); text-decoration: none; }
.gcard__t a:hover { text-decoration: underline; }
.gcard__t a:focus-visible { outline: 2px solid var(--green-600); outline-offset: 3px; border-radius: 4px; }
.gcard__l { font-size: 0.9rem; margin: 0; }
/* la date passe en pied de carte : c'est une mention de service, pas une accroche */
/* margin-top:auto plutot qu'un div .spacer : celui-ci avait flex-grow:0 et ne poussait
   rien, si bien que la date flottait a une hauteur dictee par la longueur du chapo.
   Les cartes d'une meme rangee ont la meme hauteur : les dates s'alignent donc. */
.gcard__d { margin: 1.1rem 0 0; margin-top: auto; padding-top: 0.9rem; border-top: 1px solid var(--line-soft); }

/* Cibles tactiles du composeur. Ce bloc DOIT rester après les règles d'assiette ci-dessus :
   à spécificité égale, c'est l'ordre du fichier qui tranche, et placé plus haut il était
   annulé par .prow__x (34 px) au lieu de l'élargir. WCAG 2.2 SC 2.5.8. */
@media (max-width: 860px), (pointer: coarse) {
  .pfind input { min-height: 44px; }
  .pfind__list button { min-height: 44px; }
  .prow__g { min-height: 44px; }
  .prow__x { width: 44px; height: 44px; }
  .plist__foot .btn--sm, .plist__foot .btn { min-height: 44px; }
  .pshare .btn { min-height: 44px; }
}

/* Piege anti-robot du formulaire newsletter : hors ecran plutot que display:none,
   parce qu'un champ en display:none est justement celui que les robots savent sauter. */
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Titre de carte de comparaison : lien vers la fiche. Couleur héritée pour ne pas
   trahir la hiérarchie visuelle du titre, soulignement au survol pour rester
   reconnaissable comme lien. Les deux liens explicites « Fiche complète » plus bas
   garantissent de toute façon la découvrabilité. */
.cmp__lien { color: inherit; text-decoration: none; }
.cmp__lien:hover, .cmp__lien:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
