/* =================================================================
   Comptoir, charte graphique
   Fichier de jetons unique. Toute surface du produit l'importe et
   n'écrit jamais une couleur en dur.

   Nom de travail. La marque n'est pas arrêtée.
   ================================================================= */

:root {
  /* ---- Palette du CHÂSSIS PRODUIT ----------------------------
     Valeurs de la remise de design, dont les 17 rapports de
     contraste annoncés ont été recalculés un par un et retrouvés
     exacts au centième.

     Le châssis est BLEU NEUTRE et non ambré : c'est ce qui permet
     de le revendre. La couleur du commerce vit dans un bloc séparé
     plus bas, et une surface ne mélange jamais les deux. */
  --fond:#F7F5F2;
  --surface:#FFFFFF;
  --surface-2:#EDE8E1;
  --texte:#17140F;
  --texte-doux:#4A443C;
  /* Plancher de lisibilité : 5,83 sur blanc. #8A8279 (3,78) a été
     écarté pour du texte et reste réservé aux traits. */
  --texte-tertiaire:#6B645C;
  --ligne:#DDD7CF;
  --ligne-forte:#C7BFB5;

  --signal:#0F5C8C;
  --signal-fonce:#0A4468;
  --signal-appuye:#083550;
  --signal-fond:#EAF2F8;
  --signal-bord:#9CC4DE;
  --signal-texte:#FFFFFF;

  --valide:#146B41;
  --valide-fond:#E7F5EC;
  --valide-bord:#A9D8BE;

  --alerte:#A33A00;
  --alerte-texte:#8E3A00;
  --alerte-fond:#FFF0E4;
  --alerte-bord:#E3B77C;
  /* Texte des pastilles d'allergène, mention légale : 8,36 sur
     --alerte-fond. La remise annonce 8,52 pour ce texte, mais sur
     #FFF3E6, un autre orange que celui de son propre jeton. Écart
     sans conséquence, les deux sont AAA. */
  --alerte-texte-fonce:#6B3B08;

  /* ---- Typographie ------------------------------------------- */
  --titrage:"Bricolage Grotesque","Archivo",system-ui,sans-serif;
  --interface:"Archivo",system-ui,-apple-system,"Segoe UI",sans-serif;
  --donnee:"IBM Plex Mono",ui-monospace,monospace;

  --t-xs:12px; --t-sm:13px; --t-md:16px; --t-lg:18px;
  --t-xl:20px; --t-2xl:26px; --t-3xl:32px; --t-4xl:44px;
  --t-vitrine:96px;

  /* ---- L'ECHELLE D'AFFICHE -----------------------------------
     L'echelle ci-dessus va de 12 a 44 px : un rapport de 3,7 entre
     le plus petit et le plus grand. Sur un ecran, cela veut dire
     qu'AUCUN element ne commande. On lit tout, dans l'ordre, de
     haut en bas, parce que rien ne dit par ou commencer.

     POURQUOI PAS PLUS
     La regle des affiches veut un rapport de 10 pour 1. Elle ne
     s'applique pas ici : une carte de 121 recettes ne peut pas
     depenser la moitie de l'ecran en titre. Le titre passe donc a
     un rapport de 3,75 sur telephone et 4,4 sur grand ecran, ce
     qui suffit a l'ancrer, et LE CONTRASTE EST REPORTE SUR LE
     CHIFFRE : sur un ecran de gestion, ce n'est pas le mot
     « recettes » qu'on cherche, c'est un prix. */
  --t-titre:clamp(34px, 4.4vw, 56px);

  /* Le chiffre est le contenu, pas une legende. Un prix a 18 px a
     cote d'un nom a 18 px oblige a LIRE la ligne pour la
     comprendre ; a 30 px, on la voit. */
  --t-chiffre:clamp(24px, 2.3vw, 32px);
  --t-chiffre-sm:22px;

  /* ---- LE MOUVEMENT ------------------------------------------
     Une seule chose a dire : « c'est pris en compte ». Au comptoir,
     une etape qui change sans transition ne dit pas si l'appui a
     porte ou si l'ecran etait deja la.

     Les courbes sont sorties (`expo out`, `quart out`) : rapides au
     depart, elles rendent la main tout de suite. Aucune n'excede
     260 ms, et tout est deja neutralise par la regle
     `prefers-reduced-motion` plus bas. */
  --m-vif:120ms cubic-bezier(.25,1,.5,1);
  --m-entree:180ms cubic-bezier(.16,1,.3,1);
  --m-calme:260ms cubic-bezier(.16,1,.3,1);

  /* ---- Espacements, pas de 4 --------------------------------- */
  --e1:4px; --e2:8px; --e3:12px; --e4:16px; --e5:20px;
  --e6:24px; --e8:32px; --e10:40px; --e12:56px;

  --r-sm:6px; --r-md:10px; --r-lg:16px; --r-photo:20px; --r-full:999px;

  /* ---- Cibles tactiles, une par surface ---------------------- */
  --cible:64px;        /* comptoir, mains gantées */
  --cible-borne:56px;  /* borne, debout */
  --cible-mini:44px;   /* mobile, plancher iOS et Android */
  --cible-bureau:36px; /* back-office à la souris */

  /* Quasi absente. Aucune ombre sur le focus : invisible sur une
     tablette au soleil. Le focus est un trait --signal. */
  --ombre:0 40px 70px -34px rgba(23,20,15,.55);
}

/* ---- HABILLAGE DU COMMERCE -----------------------------------
   Ce bloc est le SEUL que le commerce remplace. Le châssis
   au-dessus ne bouge pas : c'est ce qui rend le produit revendable
   sans le redessiner.

   Le noir photographique n'est permis que là où l'on ne lit rien
   et où l'on ne décide rien : écran d'attente, en-tête de rubrique,
   vitrine. Dès qu'il faut choisir un pain, une sauce, ou lire des
   allergènes, le fond redevient clair. */
:root {
  --accent-commerce:#E6007E;
  --accent-commerce-fonce:#C2005F;  /* sur fond blanc : 6,07 */
  --accent-commerce-clair:#FF2E9A;  /* sur fond noir : 5,54 */
  --accent-secondaire:#A6CE39;      /* sur fond noir uniquement : 10,43 */
  --accent-fond:#FFF0F7;
  --accent-bord:#F2C3DC;
  --fond-photo:#101010;
  --texte-photo:#FFFFFF;            /* sur le noir : 19,03 */
}

/* Quatre paires ont été écartées après mesure. Elles sont écrites
   ici pour qu'on ne les réintroduise pas de bonne foi :

     encre #17140F sur magenta #E6007E ....... 4,08  → texte BLANC
     magenta #E6007E sur noir #101010 ........ 4,23  → #FF2E9A
     rose #FFD6EA sur magenta #E6007E ........ 3,44  → blanc
     gris #8A8279 sur blanc .................. 3,78  → #6B645C

   Et un avertissement que la remise ne porte pas : blanc sur
   #E6007E vaut EXACTEMENT 4,50, le seuil AA au centième près. Un
   commerce qui éclaircit son magenta d'un rien passe dessous
   (#E8008A donne 4,38). La règle « pas sous 4,5 » ne tient donc que
   si quelque chose la vérifie : voir verifier-habillage.mjs. */

/* Le commerce ouvre de 6 h à 22 h : l'essentiel du service est en
   plein jour, et le thème clair est le défaut assumé. La remise de
   design ne fournit AUCUNE valeur sombre alors qu'elle prévoit le
   sombre en surcharge système. Les valeurs ci-dessous sont donc
   dérivées ici et mesurées une par une, pas reprises d'ailleurs. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="clair"]) {
    --fond:#14120F; --surface:#1C1A16; --surface-2:#282420;
    --texte:#F7F5F2; --texte-doux:#C6BFB4; --texte-tertiaire:#9C9488;
    --ligne:#38332C; --ligne-forte:#4A443C;
    --signal:#6FB6E4; --signal-fonce:#8FC8EC; --signal-appuye:#A9D6F2;
    --signal-fond:#10293A; --signal-bord:#2C5A78;
    --signal-texte:#0A1620;
    --valide:#5FC08F; --valide-fond:#10281C; --valide-bord:#2C5A42;
    --alerte:#F0906A; --alerte-texte:#F0906A;
    --alerte-fond:#2E1811; --alerte-bord:#6B3B26;
    --alerte-texte-fonce:#F6C4AE;
    --ombre:0 40px 70px -34px rgba(0,0,0,.9);
  }
}
:root[data-theme="sombre"] {
  --fond:#14120F; --surface:#1C1A16; --surface-2:#282420;
  --texte:#F7F5F2; --texte-doux:#C6BFB4; --texte-tertiaire:#9C9488;
  --ligne:#38332C; --ligne-forte:#4A443C;
  --signal:#6FB6E4; --signal-fonce:#8FC8EC; --signal-appuye:#A9D6F2;
  --signal-fond:#10293A; --signal-bord:#2C5A78;
  --signal-texte:#0A1620;
  --valide:#5FC08F; --valide-fond:#10281C; --valide-bord:#2C5A42;
  --alerte:#F0906A; --alerte-texte:#F0906A;
  --alerte-fond:#2E1811; --alerte-bord:#6B3B26;
  --alerte-texte-fonce:#F6C4AE;
  --ombre:0 40px 70px -34px rgba(0,0,0,.9);
}

/* ---- Base ---------------------------------------------------- */

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--fond);color:var(--texte);
  font-family:var(--interface);font-size:var(--t-md);line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
/* L'ATTRIBUT `hidden` GAGNE, TOUJOURS.
   Il ne vaut qu'un `display:none` de la feuille par defaut du
   navigateur, donc n'IMPORTE quelle regle qui pose un `display` le bat.
   Trois fois en deux jours dans ce projet :

     le logo du magasin        `style="display:block"` en ligne
     la barre d'onglets        `display:grid`
     « Voir plus ancien »      `.ct-bouton{display:inline-flex}`

   A chaque fois le script disait « cache », la mesure confirmait
   `hidden === true`, et l'element restait a l'ecran. Une seule ligne
   ferme la classe entiere. */
[hidden]{display:none !important}

button,input,select,textarea{font:inherit;color:inherit}
button{border:0;background:none;cursor:pointer}
:focus-visible{outline:3px solid var(--signal);outline-offset:2px;border-radius:var(--r-sm)}
/* Sans cela, un navigateur mobile attend 300 ms avant de declencher le
   clic, au cas ou l'appui serait le premier d'un double-tap de zoom. Sur
   une borne, ce delai se lit comme une machine qui rame. */
button,a,input,select,textarea,[role=button],label{touch-action:manipulation}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* Le surlignage du navigateur est bleu systeme sur les six ecrans.
   Il ne coute rien de le faire aux couleurs du produit, et c'est le
   genre de detail qui separe un outil d'un gabarit. */
::selection{background:var(--signal);color:var(--signal-texte)}

.ct-titre{font-family:var(--titrage);font-weight:800;letter-spacing:-.03em;line-height:1.05}
/* Un titre de deux lignes casse par defaut la ou la largeur s'arrete,
   ce qui laisse un mot seul sur la seconde ligne une fois sur trois. */
h1,h2,.ct-titre{text-wrap:balance}
.ct-donnee{font-family:var(--donnee);font-variant-numeric:tabular-nums}
.ct-etiq{
  font-family:var(--donnee);font-size:var(--t-xs);font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--texte-tertiaire);
}

/* ---- Marque -------------------------------------------------- */

.ct-marque{display:inline-flex;align-items:center;gap:10px;text-decoration:none;color:inherit}
.ct-marque svg{display:block;flex:none}
.ct-marque .mot{font-family:var(--titrage);font-weight:800;font-size:var(--t-lg);letter-spacing:-.035em}

/* ---- Boutons ------------------------------------------------- */

.ct-bouton{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--e2);
  background:var(--signal);color:var(--signal-texte);
  border-radius:var(--r-md);padding:0 var(--e5);
  min-height:var(--cible-mini);font-weight:700;font-size:var(--t-md);
  transition:filter .12s ease,transform .08s ease;
}
.ct-bouton:hover{filter:brightness(1.06)}
.ct-bouton:active{transform:translateY(1px)}
.ct-bouton[disabled]{opacity:.45;pointer-events:none}
.ct-bouton--calme{background:var(--surface-2);color:var(--texte-doux);box-shadow:inset 0 0 0 1px var(--ligne)}
.ct-bouton--calme:hover{color:var(--texte);filter:none}
/* Au comptoir, tout ce qui se touche fait au moins 64 px. */
.ct-bouton--comptoir{min-height:var(--cible);padding:0 var(--e8);font-size:var(--t-lg)}

/* ---- Blocs --------------------------------------------------- */

.ct-carte{
  background:var(--surface);border:1px solid var(--ligne);
  border-radius:var(--r-lg);padding:var(--e5);box-shadow:var(--ombre);
}

.ct-jeton{
  display:inline-flex;align-items:center;gap:var(--e1);
  border-radius:var(--r-sm);padding:2px var(--e2);
  font-size:var(--t-xs);font-weight:700;letter-spacing:.02em;
}
.ct-jeton--allergene{background:var(--alerte-fond);color:var(--alerte)}
.ct-jeton--ok{background:var(--valide-fond);color:var(--valide)}
.ct-jeton--signal{background:var(--signal-fond);color:var(--signal)}


/* ---- Surfaces simulées et papier -----------------------------
   Ces valeurs ne suivent PAS le thème : elles représentent des
   objets physiques, l'écran d'une tablette de comptoir et une
   étiquette en papier. Un papier ne devient pas noir la nuit. */
:root{
  --ecran-chassis:#0A0908;
  --ecran-fond:#0D0B09;
  --ecran-ligne:#161310;
  --ecran-ligne-survol:#1D1915;
  --ecran-ligne-faite:#131110;
  --ecran-texte:#F5F0E6;
  --ecran-texte-2:#8E8578;
  --ecran-texte-3:#6E665B;
  --ecran-texte-4:#4A443C;
  --ecran-signal-fond:#3A2A11;
  --ecran-ok:#6FBE9C;
  --ecran-ok-fond:#14342A;
  --ecran-ok-texte:#0C1F19;

  --papier:#FBFAF7;
  --papier-encre:#14120F;
  --papier-texte-2:#5C5548;
  --papier-filet:#C9C2B4;
  --papier-surligne:#F6E2B4;

  /* Couleurs propres à la marque, fixes dans les deux thèmes, comme
     les couleurs de famille : ce sont des couleurs d'aliment. */
  --marque-papier:#E1901F;
  --marque-rabat:#A9640C;
  --marque-pain:#EBCEA4;
  --marque-garniture:#B4523C;
}

/* ---- Familles d'ingrédient -----------------------------------
   Fonctionnel, pas décoratif : au comptoir on reconnaît la famille
   à la couleur avant d'avoir lu le mot. Jamais SEULE porteuse de
   sens, le nom est toujours écrit à côté. */
:root{
  --f-pain:#C08A3E; --f-proteine:#B4523C; --f-fromage:#D8A828;
  --f-legume:#4E8C57; --f-sauce:#8A6FB0; --f-autre:var(--texte-tertiaire);
}
.ct-fam{
  width:34px;height:34px;flex:none;border-radius:var(--r-sm);
  display:grid;place-content:center;color:var(--surface);
}
.ct-fam[data-f="pain"]{background:var(--f-pain)}
.ct-fam[data-f="proteine"]{background:var(--f-proteine)}
.ct-fam[data-f="fromage"]{background:var(--f-fromage)}
.ct-fam[data-f="legume"]{background:var(--f-legume)}
.ct-fam[data-f="sauce"]{background:var(--f-sauce)}
.ct-fam[data-f="autre"]{background:var(--f-autre)}

/* Emplacement photo, dessiné maintenant, rempli quand les vraies
   photos arrivent. Le repli ne doit jamais donner l'impression
   d'une image cassée. */
.ct-photo{
  position:relative;aspect-ratio:4/3;border-radius:var(--r-md);
  background:var(--surface-2);overflow:hidden;display:grid;place-content:center;
}
.ct-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.ct-photo .repli{
  font-family:var(--titrage);font-weight:800;font-size:var(--t-2xl);
  color:var(--texte-tertiaire);letter-spacing:-.03em;
}

/* ==========================================================================
   LE RELIEF
   ==========================================================================
   Le defaut le plus visible du produit tenait en une phrase : TOUT
   ETAIT UNE CARTE. Une recette, un ingredient, un constat d'incoherence,
   une etape de montage portaient le meme fond blanc, le meme trait, le
   meme arrondi et la meme ombre.

   Or un trait, un fond, un arrondi et une ombre disent chacun « objet
   separe ». Depenses partout, ils ne disent plus rien : l'ecran devient
   une pile de rectangles egaux, et l'oeil n'a aucune raison de se poser
   quelque part plutot qu'ailleurs. C'est exactement ce qui donne a un
   outil son air de gabarit d'administration.

   D'ou trois niveaux, et pas un de plus :

     .ct-rangee   le defaut. Un filet, rien d'autre. Une liste de cent
                  recettes est une LISTE, pas cent objets.
     .ct-plaque   ce qu'on souleve. Une par ecran, au plus : la chose
                  qu'on est en train de faire.
     .ct-encart   ce qui interrompt. Un fond teinte, un bord a gauche,
                  pour ce qui reclame une decision.
   ========================================================================== */

.ct-rangee{
  display:grid;grid-template-columns:1fr auto;gap:var(--e3) var(--e5);
  align-items:center;
  padding:var(--e4) var(--e2);
  border-bottom:1px solid var(--ligne);
  transition:background var(--m-vif),box-shadow var(--m-vif);
}
.ct-rangee:last-child{border-bottom:0}
/* Le survol ne DEPLACE pas la rangee : dans une liste dense, une ligne
   qui bouge sous le curseur fait rater la ligne d'a cote. Il pose une
   teinte et un filet a gauche, qui indique aussi ou l'on est au clavier. */
.ct-rangee:hover,.ct-rangee:focus-within{
  background:var(--surface);
  box-shadow:inset 3px 0 0 var(--signal), 0 0 0 1px var(--ligne);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
}

.ct-plaque{
  background:var(--surface);border:1px solid var(--ligne-forte);
  border-radius:var(--r-lg);padding:var(--e6);
  box-shadow:0 1px 2px rgba(23,20,15,.05),0 12px 28px -18px rgba(23,20,15,.35);
}

.ct-encart{
  background:var(--surface);border:1px solid var(--ligne);
  border-left:3px solid var(--signal);
  border-radius:0 var(--r-md) var(--r-md) 0;padding:var(--e5);
}
.ct-encart[data-ton="alerte"]{border-left-color:var(--alerte);background:var(--alerte-fond)}
.ct-encart[data-ton="valide"]{border-left-color:var(--valide);background:var(--valide-fond)}

/* ---- LE CHIFFRE, EN TETE ------------------------------------------
   Sur les ecrans de gestion, la donnee EST le contenu. Elle se compose
   donc comme un titre : grande, en chasse fixe alignee sur la virgule,
   et sa legende dessous, petite. L'inverse de ce que faisait la liste
   des recettes, ou le prix et son etiquette avaient presque la meme
   taille et se lisaient comme deux mots quelconques. */
.ct-chiffre{
  display:flex;flex-direction:column;align-items:flex-end;gap:2px;
  font-family:var(--donnee);font-variant-numeric:tabular-nums;
  line-height:1;
}
.ct-chiffre b{font-size:var(--t-chiffre);font-weight:600;letter-spacing:-.02em}
.ct-chiffre--sm b{font-size:var(--t-chiffre-sm)}
.ct-chiffre span{
  font-size:var(--t-xs);font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--texte-tertiaire);
}
.ct-chiffre[data-ton="valide"] b{color:var(--valide)}
.ct-chiffre[data-ton="alerte"] b{color:var(--alerte)}

/* ---- LE TROU ------------------------------------------------------
   Une valeur inconnue s'ecrivait « ? », en gris, a la taille d'une
   etiquette. Trois « ? » de suite se lisaient comme de la ponctuation,
   et l'on passait devant sans voir qu'on ne connait pas le prix de
   revient de la recette.

   Un manque doit se lire comme un MANQUE : un trait vide, a la taille
   du chiffre qu'il remplace, dans le ton de ce qui reste a faire. */
.ct-trou{
  display:inline-block;min-width:2.2ch;height:.62em;
  border-bottom:2px dotted var(--alerte-bord);
  vertical-align:baseline;
}
.ct-chiffre .ct-trou{margin-bottom:.16em}

/* Le trou est dessine, donc muet. Ce qui se voit doit s'entendre :
   sans ce doublon, une synthese vocale lit la ligne « Brie, 4,00 euros,
   revient » et laisse croire que le cout vaut zero. */
.ct-visuellement-cache{
  position:absolute;width:1px;height:1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;
}

/* ---- Raccourcis entre les surfaces --------------------------------
   Les quatre pages se répondent : chacune annonce les trois autres.
   Une page utile qu'on ne trouve pas est une page qui n'existe pas. */
.ct-racc{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:var(--e3);margin:var(--e6) 0;
}
.ct-racc a{
  display:grid;gap:var(--e1);text-decoration:none;color:var(--texte);
  background:var(--surface);border:1px solid var(--ligne);border-radius:var(--r-md);
  padding:var(--e4) var(--e5);box-shadow:var(--ombre);
  position:relative;overflow:hidden;
  transition:border-color .14s ease,transform .12s ease;
}
.ct-racc a::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--signal);opacity:.3;transition:opacity .14s ease;
}
.ct-racc a:hover{border-color:var(--texte-tertiaire);transform:translateY(-2px)}
.ct-racc a:hover::before{opacity:1}
.ct-racc .k{
  font-family:var(--donnee);font-size:var(--t-xs);font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--signal);
}
.ct-racc .t{font-weight:700;font-size:var(--t-lg);letter-spacing:-.01em}
.ct-racc .d{font-size:var(--t-sm);color:var(--texte-doux);line-height:1.4}

/* ==========================================================================
   LA BARRE DES SURFACES INSTRUMENT
   ==========================================================================
   Le dossier de design la montre sombre, en chasse fixe capitale, avec le
   logo du PRODUIT et le nom du commerce en second : « GESTION · FUN & FOOD
   GOZÉE ». Elle porte la marque du produit et non celle du magasin, parce
   que c'est le produit qu'on revend au commerçant suivant.

   Elle est sombre alors que le corps est clair, et ce n'est pas une
   contradiction : le noir est permis « là où l'on ne lit rien et où l'on ne
   décide rien », ce qu'une barre de titre est exactement. Dès le corps de
   l'écran, où l'on saisit des prix et où l'on lit des allergènes, le fond
   redevient clair.
   ========================================================================== */
.barre-produit {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: var(--e4);
  padding: 14px var(--e5);
  /* Couleurs FIXES, pas des jetons : cette barre est un chrome sombre dans
     les deux themes, comme les en-tetes noirs de la borne. Avec
     `var(--texte)` en fond, le theme sombre la rendait CLAIRE et le texte
     blanc devenait illisible (1,09). */
  background: #17140F;
  color: #F7F5F2;                    /* 16,88 */
  flex-wrap: wrap;
}
.barre-produit .ou {
  font-family: var(--donnee);
  font-size: var(--t-xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #E7E2DB;
}
.barre-produit a {
  font-size: var(--t-sm); font-weight: 600;
  color: #F7F5F2; text-decoration: none;
  padding: 7px 12px; border-radius: var(--r-sm);
  border: 1px solid rgba(255,255,255,.28);
  min-height: var(--cible-mini);
  display: inline-flex; align-items: center;
}
.barre-produit a:hover { background: rgba(255,255,255,.14); }
.barre-produit a[aria-current="page"] { background: #F7F5F2; color: #17140F; border-color: #F7F5F2; }
.barre-produit .etat {
  margin-left: auto; display: flex; align-items: center; gap: var(--e2);
  font-family: var(--donnee); font-size: var(--t-xs);
  letter-spacing: .1em; text-transform: uppercase; color: #E7E2DB;
}
.barre-produit .pastille { width: 9px; height: 9px; border-radius: 50%; background: var(--valide); }
.barre-produit .pastille.hs { background: var(--alerte); }
@media (max-width: 640px) {
  .barre-produit { padding: 10px var(--e4); gap: var(--e3); }
  .barre-produit .ou { display: none; }
}

/* ==========================================================================
   LA COQUE D'ADMINISTRATION
   ==========================================================================
   Un seul lien, `/admin`, et une navigation qui reste au meme endroit d'une
   section a l'autre. Avant, six pages se partageaient une rangee plate de
   six boutons identiques : rien ne disait ou l'on etait, ni ce qui allait
   ensemble.

   POURQUOI LES SECTIONS RESTENT DES DOCUMENTS SEPARES
   Les cinq ecrans de gestion definissent chacun leurs propres `.msg`,
   `table`, `h1`, `main`, `.sous`, `.vide` : treize selecteurs se recouvrent.
   Les injecter dans une seule page les ferait se battre, et ce genre de
   bagarre ne fait pas d'erreur, elle fait un ecran legerement faux qu'on ne
   remarque qu'en production. La coque est donc partagee, le contenu non.
   ========================================================================== */
body.admin { padding-left: 236px; }

.coque-admin {
  position: fixed; inset: 0 auto 0 0; width: 236px; z-index: 50;
  background: #17140F; color: #F7F5F2;    /* chrome fixe, comme la barre */
  display: flex; flex-direction: column;
  overflow-y: auto;
}
.coque-admin .tete {
  display: flex; align-items: center; gap: 10px;
  padding: var(--e4) var(--e4) var(--e3);
}
.coque-admin .tete .ou {
  font-family: var(--donnee); font-size: var(--t-xs);
  letter-spacing: .16em; text-transform: uppercase; color: #B9B2A6;
}
.coque-admin nav { display: flex; flex-direction: column; padding: 0 10px 10px; gap: 2px; }
.coque-admin .groupe {
  font-family: var(--donnee); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: #8E877C;
  padding: var(--e4) 12px var(--e2);
}
.coque-admin a {
  /* L'icone, puis une COLONNE : le libelle et ce qu'on y fait. En ligne, le
     sous-titre devenait un deuxieme element de flex a cote du libelle, et
     les deux se coupaient au milieu d'un mot. */
  display: flex; align-items: flex-start; gap: 11px;
  padding: 10px 12px; border-radius: var(--r-sm);
  color: #F7F5F2; text-decoration: none;
  font-size: var(--t-sm); font-weight: 600;
  min-height: var(--cible-bureau);
}
.coque-admin a .libelle { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Les icones du menu : un trait, pas un aplat, et la couleur du texte. */
.coque-admin .ico, .onglets-admin .ico {
  flex: none; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.coque-admin a .ico { margin-top: 1px; opacity: .85; }
.coque-admin a[aria-current="page"] .ico { opacity: 1; color: var(--signal); }
.coque-admin .ouvrir-menu, .coque-admin .titre-ecran { display: none; }
.coque-admin a:hover { background: rgba(255,255,255,.10); }
.coque-admin a[aria-current="page"] { background: #F7F5F2; color: #17140F; }
.coque-admin a .quoi {
  /* 12 px pour une phrase descriptive est sous le plancher de lisibilite ;
     les etiquettes de donnee peuvent y rester, une phrase non. */
  display: block; font-weight: 400; font-size: var(--t-sm); color: #B9B2A6;
}
.coque-admin a[aria-current="page"] .quoi { color: #4A443C; }
.coque-admin .pied {
  margin-top: auto; padding: var(--e4);
  border-top: 1px solid rgba(255,255,255,.14);
  display: flex; align-items: center; gap: var(--e2);
  font-family: var(--donnee); font-size: var(--t-xs);
  letter-spacing: .08em; text-transform: uppercase; color: #B9B2A6;
}
/* Le bandeau qui rappelle a l'editeur qu'il est chez quelqu'un d'autre.
   Il vit tout en haut du document, hors de la coque, pour qu'aucun ecran ne
   puisse le pousser hors de vue. */
.bandeau-editeur {
  position: sticky; top: 0; z-index: 60;
  background: #6B3B08; color: #FFF0E4;
  padding: 9px 16px; font-size: 13px; font-weight: 600;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.bandeau-editeur a {
  color: #FFF0E4; text-decoration: underline; font-weight: 700;
  margin-left: auto; white-space: nowrap;
}

/* Qui est connecte, et par ou sortir. Pose par coque.js sur les six ecrans
   de gestion : une tablette partagee au comptoir a besoin des deux au meme
   moment, celui ou quelqu'un d'autre veut s'en servir. */
.coque-admin .qui {
  margin: auto 10px 0; padding: 10px 12px;
  border-top: 1px solid rgba(247,245,242,.14);
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
}
.coque-admin .qui-nom {
  font-size: 13px; font-weight: 600; color: #F7F5F2;
  overflow: hidden; text-overflow: ellipsis; max-width: 100%; white-space: nowrap;
}
.coque-admin .qui-sortir {
  font-size: 12px; font-weight: 600; color: #C6BFB4;
  background: rgba(255,255,255,.08); border: 1px solid rgba(247,245,242,.18);
  border-radius: 999px; padding: 7px 12px; min-height: var(--cible-mini);
}
.coque-admin .qui-sortir:hover { background: rgba(255,255,255,.16); color: #F7F5F2; }

.coque-admin .pastille { width: 9px; height: 9px; border-radius: 50%; background: var(--valide); }
.coque-admin .pastille.hs { background: var(--alerte); }

/* SOUS 900 PX, LA GESTION SE TIENT COMME UNE APPLICATION.
   Avant, la colonne devenait un bandeau qui defilait de cote : onze
   entrees sur une ligne, dont on ne voyait que trois, sans dire ou l'on
   etait. Maintenant : une barre en haut qui nomme l'ecran, une barre
   d'onglets en bas pour les quatre ecrans du quotidien, et « Menu » qui
   ouvre toute la liste en plein ecran, groupes et descriptions compris.
   Le tout est pose par coque.js. */
.onglets-admin { display: none; }
@media print { .onglets-admin, .coque-admin .ouvrir-menu { display: none !important; } }
@media (max-width: 900px) {
  body.admin { padding-left: 0; }
  body.admin.avec-onglets { padding-bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }
  .coque-admin {
    position: sticky; inset: auto; top: 0; width: auto;
    flex-direction: row; align-items: center;
    padding: 0 max(8px, env(safe-area-inset-right, 0px)) 0 max(8px, env(safe-area-inset-left, 0px));
    min-height: 56px; overflow: visible;
  }
  .coque-admin .tete { padding: 6px 0; flex: 1; min-width: 0; gap: 8px; }
  .coque-admin .tete .ou { display: none; }
  .coque-admin .tete #marque .mot { display: none; }
  .coque-admin .titre-ecran {
    display: block; font-family: var(--titrage); font-weight: 700; font-size: 18px;
    letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .coque-admin .ouvrir-menu {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: var(--cible-mini); height: var(--cible-mini); border-radius: var(--r-md);
    background: transparent; color: #F7F5F2; border: 0; cursor: pointer;
  }
  .coque-admin .ouvrir-menu:hover { background: rgba(255,255,255,.10); }
  .coque-admin .ouvrir-menu .ico { width: 24px; height: 24px; }
  .coque-admin nav, .coque-admin .qui { display: none; }
  .coque-admin .pied { margin: 0; padding: 0 6px; border: 0; flex: none; }
  .coque-admin .pied #etat { display: none; }

  /* Le menu ouvert : la coque prend tout l'ecran, et on y retrouve ce que
     la colonne montre sur un ordinateur. */
  body.menu-ouvert { overflow: hidden; }
  body.menu-ouvert .coque-admin {
    position: fixed; inset: 0; z-index: 70; flex-direction: column; align-items: stretch;
    overflow-y: auto; padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  body.menu-ouvert .coque-admin .tete { flex: none; min-height: 56px; }
  body.menu-ouvert .coque-admin nav { display: flex; flex-direction: column; padding: 0 10px 10px; }
  body.menu-ouvert .coque-admin a { min-height: var(--cible-mini); padding: 12px; }
  body.menu-ouvert .coque-admin .qui { display: flex; flex-direction: row; align-items: center;
    justify-content: space-between; margin: 0 10px; border-left: 0; border-top: 1px solid rgba(247,245,242,.14); }
  body.menu-ouvert .coque-admin .pied { position: absolute; top: 18px; right: 16px; }
  body.menu-ouvert .onglets-admin { display: none; }

  .onglets-admin {
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    background: var(--surface); border-top: 1px solid var(--ligne);
    padding: 6px max(6px, env(safe-area-inset-right, 0px)) calc(6px + env(safe-area-inset-bottom, 0px)) max(6px, env(safe-area-inset-left, 0px));
    box-shadow: 0 -10px 30px -20px rgba(23,20,15,.35);
  }
  .onglets-admin a, .onglets-admin button {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    min-height: 54px; padding: 4px 2px; border-radius: var(--r-md);
    color: var(--texte-tertiaire); text-decoration: none; background: none; border: 0;
    font: 600 11px/1.1 var(--interface); cursor: pointer;
  }
  .onglets-admin .ico { width: 24px; height: 24px; }
  .onglets-admin .libelle { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .onglets-admin a[aria-current="page"] { color: var(--signal); }
  .onglets-admin a[aria-current="page"] .ico { stroke-width: 2.2; }
  .onglets-admin a:active, .onglets-admin button:active { background: var(--surface-2); }
}

/* ==========================================================================
   LES LIENS
   ==========================================================================
   La charte ne donnait AUCUNE couleur aux liens. Ceux qu'aucune regle
   precise n'atteignait tombaient donc sur le bleu par defaut du navigateur,
   #0000EE, illisible sur le theme sombre : quatre d'entre eux mesuraient
   entre 1,78 et 1,99 dans les encarts d'alerte, la ou l'on dit justement au
   gerant ce qu'il lui reste a faire.

   `--signal` s'inverse avec le theme, donc la regle tient des deux cotes.
   `visited` prend la MEME couleur : distinguer un lien visite n'a pas de
   sens dans un back-office ou l'on repasse dix fois par jour au meme
   endroit, et la teinte violette du navigateur retombait dans le meme
   piege.
   ========================================================================== */
a { color: var(--signal); }
a:visited { color: var(--signal); }
a:hover { color: var(--signal-fonce); }

/* Le module de marque pose la couleur du mot EN LIGNE (`style="color:…"`),
   pour qu'il suive le jeton de texte partout ailleurs. Dans un chrome dont
   le fond est FIXE, ce jeton s'inverse et le mot disparait : en theme clair,
   « Comptoir » devenait #17140F sur #17140F, soit un contraste de 1,00, sur
   les six ecrans d'administration. Mesure, pas devine.

   D'ou le `!important` : il repond a un style EN LIGNE, pas a une autre
   regle. La regle vaut partout ou le fond est fixe et sombre. */
.coque-admin .mot,
.barre-produit .mot { color: #F7F5F2 !important; }

/* Sur telephone, la coque devient un bandeau qui defile horizontalement.
   L'entree courante peut donc naitre hors champ : sur « Reglages », on ne
   voyait que « Tableau de bord » et l'on croyait etre ailleurs. C'est
   `coque.js` qui la ramene dans le cadre. */

/* ==========================================================================
   LE PLANCHER TACTILE DES CHAMPS
   ==========================================================================
   Mesures a 390 px de large : les champs de formulaire tombaient a 41-42 px,
   deux a trois pixels sous le plancher de 44. Ce n'est pas un ecart visible,
   c'est un doigt qui rate une fois sur dix.

   Les cases a cocher et les boutons radio en sont EXCLUS : leur cible reelle
   est l'etiquette qui les entoure (mesuree a 304x98 sur les reglages), et
   leur donner 44 px de haut ferait un carre enorme a cote d'un texte normal.
   ========================================================================== */
@media (max-width: 900px) {
  input:not([type=checkbox]):not([type=radio]):not([type=hidden]),
  select,
  textarea {
    min-height: var(--cible-mini);
  }
}

/* Les liens du menu de gestion gardent la couleur du menu. Les regles
   generales ci-dessus (`a:visited`, `a:hover`) ont la meme force que
   `.coque-admin a` et viennent APRES : un ecran deja visite passait en bleu
   sur le fond noir, et le survol l'eteignait. */
.coque-admin a:link, .coque-admin a:visited, .coque-admin a:hover { color: #F7F5F2; }
.coque-admin a[aria-current="page"]:link, .coque-admin a[aria-current="page"]:visited { color: #17140F; }
.onglets-admin a:link, .onglets-admin a:visited, .onglets-admin a:hover { color: var(--texte-tertiaire); }
.onglets-admin a[aria-current="page"]:link, .onglets-admin a[aria-current="page"]:visited { color: var(--signal); }
