/*
  STOVO — feuille de style de la PWA (lot 9a)
  =============================================
  Ce fichier reprend EXACTEMENT le <style> du dashboard actuel
  (livrables/sites-web/stovo/index.html), sans aucune modification de regle
  existante. Les regles ajoutees pour la coquille (barre de navigation,
  ecran "Parler", bascule d'onglets) sont regroupees a la fin, sous
  "Coquille PWA (lot 9a)", pour qu'on distingue clairement ce qui vient du
  dashboard de ce qui est nouveau.

  Monde clair « établi » depuis le 23/08/2026, aligné sur la vitrine
  (../DESIGN.md). Une retouche de jeton se fait aux deux endroits.
*/

/* DM Sans, variable, auto-hebergee (graisses 400 a 700), meme fichier que la
   vitrine (fonts/dm-sans-latin.woff2, copie dans app/fonts/). Pas d'Instrument
   Serif ici : le serif ne sert qu'au h1 de la vitrine, un h2 en serif dans
   l'app serait un deuxieme monde (DESIGN.md). */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/dm-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --brand: #0F766E;
  --brand-dark: #0F766E;
  --bg: #FFF8F1;
  --card: #FFFFFF;
  --border: #E3D6C5;
  --text: #1D1E1C;
  --muted: #615F5C;
  --muted-light: #8E8B87;

  --danger: #DC2626;
  --danger-bg: #fef2f2;
  --danger-border: #fecaca;
  --danger-text: #B91C1C;
  --warn: #A16207;
  --warn-bg: #FEF9C3;
  --warn-border: #FDE68A;
  --warn-text: #A16207;
  --ok: #0F766E;
  --ok-bg: #F0FDFA;
  --brand-light: #99F6E4;
  --brand-darker: #115E59;
  --muted-dark: #615F5C;

  --flamme: #FA5D00;
  --flamme-sombre: #C94A00;
  --fond-chaud: #FFF1E4;

  /* Lot A15 (R-2, 25/08/2026) : la couleur d'action au choix, cinq
     teintes (regle 10 de DESIGN.md, teal et vert exclus). --action et
     --action-sombre remplacent --flamme/--flamme-sombre sur tout ce qui
     est TOUCHABLE (boutons, liens, micro, onglet actif) ; --flamme reste
     reserve a l'identite (logotype "Stovo") et au decor (--fond-chaud,
     --shadow-chaude, INCHANGES par ce lot). Valeur par defaut = flamme,
     comme si aucun choix n'avait ete fait. */
  --action: #FA5D00;
  --action-sombre: #C94A00;

  --shadow-sm: 0 1px 2px rgba(29,30,28,.06);
  --shadow: 0 1px 2px rgba(29,30,28,.06);
  --shadow-chaude: rgba(250,166,0,.22) 6px 4px 24px, rgba(29,30,28,.05) 0 1px 2px;
  --radius: 20px;
}

/* Les cinq teintes de --action (lot A15, R-2). Un attribut data-couleur
   sur <html>, pose par reglages.js (choix immediat, memorise dans
   localStorage) ou par le script en tete d'index.html (avant le premier
   rendu, pour eviter le clignotement en flamme). "flamme" est explicite
   ici bien qu'identique au defaut de :root : un choix EXPLICITE de
   l'utilisateur doit pouvoir se relire dans la feuille de style, meme
   s'il ne change rien visuellement. */
html[data-couleur="flamme"] { --action: #FA5D00; --action-sombre: #C94A00; }
html[data-couleur="bleu"] { --action: #1D4ED8; --action-sombre: #1E40AF; }
html[data-couleur="prune"] { --action: #7E22CE; --action-sombre: #6B21A8; }
html[data-couleur="framboise"] { --action: #BE185D; --action-sombre: #9D174D; }
html[data-couleur="encre"] { --action: #1D1E1C; --action-sombre: #000000; }

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'DM Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  padding-bottom: 40px;
}

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 20px; }

/* ---------- En-tête ----------
   Monde clair (23/08/2026) : plus de bande teal, le header prend le fond de
   page. Le logotype "Stovo" en flamme fait office de marque (plus de boîte
   .logo ni de sous-titre dans le header, retirés de index.html). La classe
   .logo elle-même a disparu au lot "monde clair, suite" (23/08/2026) : son
   dernier usage (.login-brand .logo, l'écran de connexion) a été retiré en
   même temps que le pictogramme "S" (DESIGN.md, écran de connexion). */
header {
  background: var(--bg);
  padding: 18px 0 6px;
}
.header-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; }
.brand { display: flex; align-items: center; gap: 13px; }
/* Lot A15 (R-2, 25/08/2026) : le logotype reste en --flamme, JAMAIS en
   --action. C'est l'identite de Stovo (comme le mot "Stovo" en tete de la
   vitrine), pas un element touchable, il ne suit pas le choix de couleur. */
.brand h1 { font-size: 22px; font-weight: 700; letter-spacing: -.02em; line-height: 44px; color: var(--flamme); }
.brand p { font-size: 13.5px; opacity: .88; }
.header-actions { display: flex; align-items: center; gap: 8px; }
.updated { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Deux boutons a contour (Rafraichir, Deconnexion) : meme gabarit, meme
   comportement responsive. Mobile-first : icone seule (carre 44x44), le
   libelle (span.btn-label.sr-only) redevient visible a partir de 560px,
   l'aria-label reste pose dans les deux etats (nom accessible constant). */
.btn-refresh, .btn-reglages {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 44px; height: 44px; padding: 0;
  font-family: inherit; font-size: 14px; font-weight: 600; color: var(--text);
  background: var(--card); border: 1.5px solid var(--border); border-radius: 14px;
  cursor: pointer; transition: background .15s, transform .1s;
}
.btn-refresh svg, .btn-reglages svg { display: block; flex: 0 0 auto; }
.btn-refresh:hover, .btn-reglages:hover { background: var(--fond-chaud); }
.btn-refresh:active, .btn-reglages:active { transform: translateY(1px); }
@media (min-width: 560px) {
  .btn-refresh, .btn-reglages { width: auto; padding: 0 14px; justify-content: flex-start; }
  .btn-refresh .btn-label, .btn-reglages .btn-label {
    position: static; width: auto; height: auto; padding: 0; margin: 0;
    overflow: visible; clip: auto; white-space: nowrap; border: 0;
  }
}

/* ---------- KPI ---------- */
.kpis {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
  margin-top: 16px; margin-bottom: 8px;
}
.kpi {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px 18px; box-shadow: var(--shadow);
}
.kpi .k-label { font-size: 12px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; }
.kpi .k-value { font-size: 34px; font-weight: 700; line-height: 1.1; letter-spacing: -.03em; font-variant-numeric: tabular-nums; margin-top: 6px; color: var(--text); }
.kpi.danger .k-value { color: var(--danger); }
.kpi.warn .k-value { color: var(--warn); } /* --warn = --warn-text = #A16207 (4,9:1), reprise du 23/08 : l'ambre clair #CA8A04 essaye plus tot ne faisait que 2,9:1 */
.kpi .k-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

/* ---------- Bandeau valeur du stock (ROI) ---------- */
.stock-value {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 16px 20px; margin: 12px 0 0;
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 16px;
}
.stock-value .sv-label { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.stock-value .sv-amount { font-size: 30px; font-weight: 700; color: var(--text); line-height: 1.1; font-variant-numeric: tabular-nums; }
.stock-value .sv-sub { font-size: 12.5px; color: var(--muted); margin-left: auto; }
@media (max-width: 560px) { .stock-value .sv-sub { margin-left: 0; flex-basis: 100%; } }

/* ---------- Phrase de verdict (la réponse en un coup d'œil, avant tout scroll) ---------- */
.verdict { font-size: 15.5px; font-weight: 700; margin: 16px 2px 0; }
.verdict.v-ok { color: var(--brand-dark); }
.verdict.v-warn { color: var(--warn-text); }
.verdict.v-crit { color: var(--danger-text); }

/* ---------- Titres de section ---------- */
.section-title { font-size: 17px; font-weight: 700; letter-spacing: -.01em; margin: 30px 0 14px; display: flex; align-items: center; gap: 10px; }
.section-title .count {
  font-size: 12.5px; font-weight: 600; color: var(--muted);
  background: var(--card); border: 1px solid var(--border); padding: 2px 10px; border-radius: 999px;
}

/* ---------- Bloc réappro (priorité action) ---------- */
.reorder {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
}
.reorder-item {
  display: grid; grid-template-columns: 1fr auto; gap: 8px 16px; align-items: center;
  padding: 15px 20px; border-top: 1px solid var(--border);
}
.reorder-item:first-child { border-top: none; }
.reorder-item .ri-main { min-width: 0; }
.reorder-item .ri-name { font-weight: 700; font-size: 15px; }
.reorder-item .ri-detail { font-size: 13px; color: var(--muted); margin-top: 2px; }
.reorder-item .ri-right { text-align: right; white-space: nowrap; }
.reorder-item .ri-cover { font-size: 19px; font-weight: 700; }
.reorder-item .ri-cover.c-crit { color: var(--danger); }
.reorder-item .ri-cover.c-warn { color: var(--warn); }
.reorder-item .ri-coverlabel { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.reorder-item .ri-qty { font-size: 22px; font-weight: 700; color: var(--danger-text); font-variant-numeric: tabular-nums; cursor: help; }
.reorder-item .ri-warning { font-size: 12.5px; font-weight: 600; color: var(--danger-text); margin-top: 6px; }

/* ---------- Cartes produits ---------- */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 16px; }
.card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px; box-shadow: var(--shadow-sm);
}
.card .c-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.card .c-name { font-size: 15px; font-weight: 700; }
/* Héros de la carte : l'autonomie, l'info qui fait agir. Couleur selon l'urgence. */
.card .c-hero { font-size: 20px; font-weight: 700; line-height: 1.15; margin: 13px 0 2px; color: var(--text); }
.card .c-hero.h-crit { color: var(--danger); }
.card .c-hero.h-warn { color: var(--warn-text); }
.card .c-hero.h-ok { color: var(--ok); }
.card .c-hero.h-muted { color: var(--muted); font-weight: 700; font-size: 16px; }
/* Stock brut, rétrogradé en information secondaire */
.card .c-stockline { font-size: 13.5px; color: var(--muted); margin-bottom: 12px; }
.card .c-stockline b { color: var(--text); font-size: 15px; font-weight: 700; }
/* Détail (prix, valeur, conso, point de commande) : petit, gris, en pied de carte */
.card .c-detail { font-size: 12px; color: var(--muted); margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); line-height: 1.7; }
.card .c-detail b { color: var(--muted); font-weight: 700; }

/* jauge de niveau : repère du seuil au milieu (50%) */
.jauge { position: relative; height: 8px; background: var(--fond-chaud); border-radius: 999px; overflow: hidden; }
.jauge-fill { height: 100%; border-radius: 999px; background: var(--brand); }
.jauge-fill.is-low { background: var(--danger); }
.jauge-seuil { position: absolute; top: -2px; bottom: -2px; width: 2px; background: rgba(29,30,28,.35); }

/* badges / pills */
.badge { font-size: 12px; font-weight: 700; padding: 4px 10px; border-radius: 999px; white-space: nowrap; }
.badge.ok { color: var(--ok); background: var(--ok-bg); border: 1px solid var(--brand-light); }
.badge.danger { color: var(--danger-text); background: var(--danger-bg); border: 1px solid var(--danger-border); }
.badge.warn { color: var(--warn-text); background: var(--warn-bg); border: 1px solid var(--warn-border); }

/* ---------- Tableau des mouvements ---------- */
.table-wrap { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-sm); overflow: hidden; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 12px 18px; font-size: 14px; }
th { font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); background: var(--bg); font-weight: 700; }
/* Colonne "Mouvement" (3e colonne) : alignee a droite, jamais de retour a la ligne. */
th:nth-child(3), td:nth-child(3) { text-align: right; white-space: nowrap; }
tbody tr { border-top: 1px solid var(--border); }
tbody tr:hover { background: var(--fond-chaud); }
.pill { font-weight: 700; font-size: 13.5px; }
.pill.entree { color: var(--brand-dark); }
.pill.sortie { color: var(--text); } /* une sortie n'est pas une alerte, le signe moins suffit */
.src { font-size: 12px; color: var(--muted); }
/* Icone SVG en trait devant "vocal"/"manuel" (lot "monde clair, suite",
   23/08/2026), remplace les emoji 🎙️/⌨️ (dashboard.js, colonne Source). */
.src-ligne { display: inline-flex; align-items: center; gap: 5px; }
.src-ligne svg { width: 13px; height: 13px; flex: 0 0 auto; display: block; }
/* étiquette des mouvements de régularisation (motif), pour les distinguer d'une vente */
.tag-motif { font-size: 11px; font-weight: 700; color: var(--muted); background: var(--fond-chaud); border: 1px solid var(--border); padding: 1px 8px; border-radius: 999px; margin-left: 7px; vertical-align: middle; }
.tag-auto { font-size: 10.5px; font-weight: 700; color: var(--brand-dark); background: var(--ok-bg); border: 1px solid var(--brand-light); padding: 0 7px; border-radius: 999px; vertical-align: middle; cursor: help; }
.tag-fixe { font-size: 10.5px; font-weight: 700; color: var(--muted); background: var(--fond-chaud); border: 1px solid var(--border); padding: 0 7px; border-radius: 999px; vertical-align: middle; cursor: help; }

/* ---------- États ---------- */
.state { padding: 38px; text-align: center; color: var(--muted); }
.state.error { color: var(--danger); }

footer { margin-top: 36px; font-size: 12.5px; color: var(--muted); text-align: center; line-height: 1.6; }

/* ---------- Mobile ---------- */
@media (max-width: 900px) { .kpis { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) {
  .kpi .k-value { font-size: 26px; }
  .brand h1 { font-size: 21px; }
  th:nth-child(4), td:nth-child(4) { display: none; }
  th, td { padding: 11px 12px; }
  td:first-child { font-size: 13px; }
}

/* =====================================================================
   Coquille PWA (lot 9a) — tout ce qui suit est nouveau, rien ci-dessus
   n'a ete modifie par rapport au dashboard actuel.
   ===================================================================== */

/* Laisse de la place en bas pour la barre de navigation fixe (+ l'encoche
   iPhone via env(safe-area-inset-bottom), actif grace a viewport-fit=cover). */
body { padding-bottom: calc(78px + env(safe-area-inset-bottom)); }

/* Bascule d'ecran : un seul des deux ecrans visible a la fois. */
.ecran { display: none; }
.ecran.ecran-actif { display: block; }

/* Ecran "Parler" (placeholder, lot 9a) : centre verticalement et horizontalement. */
.parler-page {
  min-height: calc(100vh - 78px - env(safe-area-inset-bottom));
  min-height: calc(100dvh - 78px - env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.parler-centre { text-align: center; max-width: 340px; width: 100%; }
/* A-6 (audit accessibilité 31/07) : sur grand écran, 340px bride tout le
   panneau de réception/sortie et l'inventaire (noms de produits tronqués). */
@media (min-width: 700px) { .parler-centre { max-width: 640px; } }
/* Repos (disabled) : décor seulement (icône --muted-light, §1 de DESIGN.md).
   L'icône SVG (index.html) remplace l'emoji 🎙️ ; sa taille est fixée par
   .btn-micro svg ci-dessous, indépendamment du reste du bouton. */
.btn-micro {
  width: 90px; height: 90px; border-radius: 999px;
  background: var(--card); border: 2px solid var(--border); color: var(--muted-light);
  display: grid; place-items: center; margin: 24px auto 8px;
  cursor: not-allowed;
}
.btn-micro svg { width: 36px; height: 36px; display: block; }
.parler-texte { color: var(--muted); font-size: 12.5px; }

/* =====================================================================
   Micro on-device (lot 11a) — activé par parler.js seulement si l'API
   SpeechRecognition existe (le style "grisé" ci-dessus reste tant qu'il
   est disabled : progressive enhancement, additif seulement).
   ===================================================================== */

/* Actif : disque flamme (audit --brand §2bis, monde clair 23/08/2026) —
   c'est l'action de l'écran, au même titre que .matin-copier ou
   .btn-reception-primaire. */
.btn-micro:not(:disabled) {
  background: var(--action); border-color: var(--action); color: #fff;
  box-shadow: 0 1px 4px rgba(250,93,0,.25);
  cursor: pointer; transition: background .15s, transform .1s, box-shadow .15s;
}
.btn-micro:not(:disabled):hover { background: var(--action-sombre); border-color: var(--action-sombre); }
.btn-micro:not(:disabled):active { transform: translateY(1px); }

/* État "en écoute" : pulsation discrète pour montrer que le micro capte.
   Correctif contraste du 01/08 : --danger-text donne ~5,9:1, au moins aussi
   visible que le repos. Fond et pulsation inchangés par ce lot : c'est un
   ÉTAT (pas une action), il ne suit pas le passage à la flamme ci-dessus. */
.btn-micro.ecoute {
  background: var(--danger-bg); border-color: var(--danger-text); color: var(--danger-text);
  box-shadow: none;
  animation: pulse-micro 1.4s ease-in-out infinite;
}
@keyframes pulse-micro {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, .25); }
  50% { box-shadow: 0 0 0 12px rgba(220, 38, 38, 0); }
}

/* Zone d'état du micro (écoute / erreur / indisponibilité), sous le bouton. */
.parler-etat { font-size: 12.5px; color: var(--muted); margin-top: 6px; min-height: 16px; }

/* =====================================================================
   Écran « Parler » au clavier (lot 10b) — message du bot, formulaire de
   déclaration, boutons Oui/Non de confirmation.
   ===================================================================== */

/* Dernière réponse renvoyée par pwa-api (ou message d'accueil par défaut). */
.parler-reponse {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: 18px 20px; margin-bottom: 16px;
  font-size: 15px; color: var(--text); text-align: left; line-height: 1.45;
}

/* Boutons Oui/Non (monde clair, 23/08/2026) : le couple flamme/contour de la
   démo jouable de la vitrine (index.html racine, section du compteur). Oui
   = bouton flamme avec coche SVG (c'est le "Oui" de tout Stovo) ; Non =
   bouton à contour, texte seul (refuser n'est pas une erreur, plus de rouge). */
.parler-confirmation { display: flex; gap: 12px; margin-bottom: 16px; }
.btn-confirmation {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: inherit; font-size: 19px; font-weight: 700; white-space: nowrap;
  min-height: 46px; padding: 0 16px; border-radius: 14px; cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
}
.btn-confirmation svg { flex: 0 0 auto; }
.btn-confirmation:active { transform: translateY(1px); }
.btn-confirmation:disabled { opacity: .6; cursor: wait; }
.btn-oui { background: var(--action); border: none; color: #fff; box-shadow: 0 1px 4px rgba(250,93,0,.25); }
.btn-oui:hover { background: var(--action-sombre); }
.btn-non { background: var(--card); border: 1.5px solid var(--border); color: var(--text); font-size: 17px; }
.btn-non:hover { background: var(--fond-chaud); }

/* Choix numéroté (lot A10-6, 23/08/2026 ; poli au lot A10-6b, 23/08/2026,
   après critique Impeccable) : « Tu veux dire 1) A ou 2) B ? » Un bouton par
   candidat (pastille numéro + nom), un dernier bouton « Aucun de ceux-là »,
   empilés (colonne), toute la largeur, 4 candidats maximum. Style à contour
   comme .btn-non : un choix n'écrit rien en base (§6 du plan A10, c'est
   toujours le "oui" qui écrit), ce n'est pas l'action pleine en flamme.
   Aucun jeton neuf, uniquement ceux déjà posés ailleurs dans ce fichier. */
.parler-choix { display: flex; flex-direction: column; gap: 12px; margin-bottom: 16px; }
.btn-choix {
  /* align-items:flex-start (pas center) : un nom de produit long peut passer
     sur deux lignes (ex. « Coca zéro sucre 33 cl bouteille verre » à 320 px),
     et la pastille doit rester collée à la PREMIÈRE ligne, jamais flotter au
     milieu du bloc (constaté à la capture 320 px du lot A10-6). */
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  min-height: 44px; padding: 7.5px 16px 7.5px 12px; border-radius: 14px;
  font-family: inherit; font-size: 15px; font-weight: 600; text-align: left;
  color: var(--text); background: var(--card); border: 1.5px solid var(--border);
  cursor: pointer; transition: background .15s, border-color .15s, transform .1s;
}
/* Pastille numéro (lot A10-6b) : disque encre, chiffre blanc (16,4:1 sur
   --text, comme --encre sur blanc, balayage à zéro échec), remplace l'ancien
   « 1) » en tête de texte. Hauteur totale du bouton : 7,5 (padding) + 28
   (pastille) + 7,5 (padding) + 3 (les deux filets de 1,5px) = 46px, la même
   hauteur que #btn-oui/#btn-non (corrigé après relecture du Jarvis : les
   9px d'origine donnaient 48px, l'arithmétique de la consigne n'incluait
   pas les 3px de filet). */
.btn-choix__num {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 999px;
  background: var(--text); color: #fff; font-size: 15px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  display: inline-flex; align-items: center; justify-content: center;
}
/* padding-top:4px fait tomber le centre de la PREMIÈRE ligne du nom (20px
   d'interligne) sur le centre de la pastille de 28px : le padding-top du
   bouton s'ajoute de façon identique aux deux (pastille et nom), il
   s'annule dans l'écart entre leurs centres, donc ce padding-top:4px reste
   correct même après le changement de padding du bouton (9px -> 7,5px).
   Mesuré à la capture, écart 0px (voir le compte rendu du lot A10-6b). */
.btn-choix__nom { font-size: 15px; font-weight: 600; line-height: 20px; padding-top: 4px; }
.btn-choix:hover { background: var(--fond-chaud); }
.btn-choix:active { transform: translateY(1px); }
.btn-choix:disabled { opacity: .6; }
/* État pressé pendant l'appel (lot A10-6b, §1.2) : « en train d'être dite »,
   même dessin que la démo jouable de la vitrine (DESIGN.md, « La carte du
   compteur »). Posé/retiré par gererClicChoix (parler.js), jamais figé dans
   le HTML de base. */
.btn-choix.est-choisi { background: var(--fond-chaud); border-color: var(--text); }

/* « Aucun de ceux-là » (lot A10-6b, §1.4) : refuser n'est pas une erreur, pas
   de rouge, texte seul sans contour, dernier bouton de la zone, se cache
   avec elle. Se désactive comme les candidats quand un AUTRE bouton de la
   zone est en cours d'appel (même mécanique dans gererClicChoix). Rendu
   seulement si l'appelant fournit un vrai rappel `surAucun` (parler.js). */
.btn-choix-aucun {
  width: 100%; min-height: 44px; background: transparent; border: none;
  color: var(--muted); font-family: inherit; font-size: 14px; font-weight: 600;
  text-align: center; cursor: pointer; border-radius: 14px;
}
.btn-choix-aucun:hover { background: var(--fond-chaud); }
.btn-choix-aucun:disabled { opacity: .6; }

/* Champ texte (lot saisie multiligne, 23/08/2026) : un <textarea> qui montre
   toute la phrase, au lieu d'un <input> qui la fait defiler hors du cadre.
   Bouton Envoyer cale en bas (align-items: flex-end) pour rester sur la
   ligne de base de la derniere ligne du texte. */
.parler-form { display: flex; align-items: flex-end; gap: 10px; }
.parler-form textarea {
  display: block; flex: 1; min-width: 0; font-family: inherit; font-size: 15px;
  line-height: 1.4; padding: 11px 13px; resize: none; overflow-y: auto;
  /* 2 lignes au repos, 5 lignes maximum : au-dela, defilement interne.
     ajusterHauteurChamp() (parler.js) fait foi partout (Safari iOS ne gere
     pas encore field-sizing), field-sizing est une amelioration progressive
     pour les navigateurs qui le supportent deja (Chrome). */
  min-height: calc(2 * 1.4em + 22px + 2px);
  max-height: calc(5 * 1.4em + 22px + 2px);
  field-sizing: content;
  border: 1px solid var(--border); border-radius: 10px; background: var(--card); color: var(--text);
  transition: border-color .15s;
}
.parler-form textarea:focus { border-color: var(--text); }
.parler-form textarea:disabled { opacity: .7; }
/* Bouton à contour (action secondaire, audit --brand §2bis) : Envoyer n'est
   plus la seule action de l'écran depuis le micro et les modes réception/
   sortie/inventaire, il redevient un bouton comme les autres. */
.btn-envoyer {
  font-family: inherit; font-size: 15px; font-weight: 700; white-space: nowrap;
  min-height: 44px; padding: 0 18px; border: 1.5px solid var(--border); border-radius: 14px;
  background: var(--card); color: var(--text); cursor: pointer;
  transition: background .15s, transform .1s;
}
.btn-envoyer:hover { background: var(--fond-chaud); }
.btn-envoyer:active { transform: translateY(1px); }
.btn-envoyer:disabled { opacity: .7; cursor: wait; }

/* =====================================================================
   Import catalogue .xlsx (lot 12a) — bouton secondaire sous le formulaire
   de déclaration, sobre (l'action principale reste "Envoyer").
   ===================================================================== */
.btn-import {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 12px; min-height: 44px;
  font-family: inherit; font-size: 14px; font-weight: 600;
  padding: 11px 16px; border: 1px dashed var(--border); border-radius: 14px;
  background: var(--card); color: var(--muted); cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
}
.btn-import svg { flex: 0 0 auto; }
.btn-import:hover { background: var(--fond-chaud); border-color: var(--border); color: var(--text); }
.btn-import:active { transform: translateY(1px); }
.btn-import:disabled { opacity: .7; cursor: wait; }

/* =====================================================================
   Photo du bon de livraison (lot P-3) — dans le panneau de réception.
   Même sobriété que le bouton d'import : l'action principale de l'écran
   reste "Ajouter" (dicter une ligne), la photo est une autre façon de
   remplir la même liste, pas un geste concurrent.
   ===================================================================== */
.btn-photo-bl {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 12px; min-height: 44px;
  font-family: inherit; font-size: 14px; font-weight: 600;
  padding: 11px 16px; border: 1px dashed var(--border); border-radius: 14px;
  background: var(--card); color: var(--muted); cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
}
.btn-photo-bl svg { flex: 0 0 auto; }
.btn-photo-bl:hover { background: var(--fond-chaud); border-color: var(--border); color: var(--text); }
.btn-photo-bl:active { transform: translateY(1px); }
.btn-photo-bl:disabled { opacity: .7; cursor: wait; }

/* Journal de lecture de la photo : le libellé du papier en face du produit
   retenu. Volontairement discret mais lisible : c'est un outil de contrôle,
   pas une décoration. Monde clair (23/08/2026) : la bande teal à gauche
   disparaît, fond --bg (plus de #fafafa). */
.reception-lecture {
  margin-top: 12px; padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px; background: var(--bg);
}
.lecture-titre {
  margin: 0 0 8px; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; color: var(--muted);
}
.lecture-item {
  margin: 0 0 4px; font-size: 13px; line-height: 1.45;
  display: flex; flex-wrap: wrap; align-items: baseline;
}
.lecture-item:last-child { margin-bottom: 0; }
.lecture-source { color: var(--muted); word-break: break-word; }
.lecture-fleche { color: var(--muted); }
/* La cible est une VALEUR (le nom + la quantité retenus), pas un état :
   passe en encre (audit --brand §2bis), comme .ri-qte/.reception-total
   ci-dessous. */
.lecture-cible { font-weight: 700; color: var(--text); }

/* =====================================================================
   Mode réception multi-produits (N1, lots FR-4 + FR-5) — écran de
   contrôle : bouton d'entrée, liste vivante, actions de clôture,
   bannière de reprise. Reprend les tokens existants (--brand, --border…).
   ===================================================================== */

/* Bouton d'entrée en réception : à contour (audit --brand §2bis, monde
   clair 23/08/2026), icône SVG (carton/cercle-moins/liste cochée selon le
   mode, index.html) devant le libellé. Survol --fond-chaud, plus de
   #ccfbf1. */
.btn-reception-demarrer {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 12px; min-height: 44px;
  font-family: inherit; font-size: 14.5px; font-weight: 700;
  padding: 12px 16px; border: 1.5px solid var(--border); border-radius: 14px;
  background: var(--card); color: var(--text); cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
}
.btn-reception-demarrer svg { flex: 0 0 auto; }
.btn-reception-demarrer:hover { background: var(--fond-chaud); }
.btn-reception-demarrer:active { transform: translateY(1px); }

/* Panneau de la réception en cours (la liste vivante). */
.reception-panneau {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: 14px 16px; margin-bottom: 16px; text-align: left;
}
.reception-entete { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.reception-titre { font-size: 16px; font-weight: 700; color: var(--text); }
/* Un compteur de lignes est une VALEUR, pas un état (audit --brand §2bis). */
.reception-total { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; }

.reception-liste { display: flex; flex-direction: column; gap: 6px; }
.reception-vide { color: var(--muted); font-size: 13.5px; padding: 8px 2px; }

/* Une ligne : nom à gauche, quantité, croix de suppression à droite. */
.reception-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 10px; background: var(--card);
}
.ri-nom { flex: 1; min-width: 0; font-size: 14.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ri-qte { font-size: 14.5px; font-weight: 700; color: var(--text); white-space: nowrap; }
.ri-retirer {
  position: relative;
  flex: none; width: 28px; height: 28px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--danger-border); background: var(--danger-bg); color: var(--danger-text);
  font-size: 14px; line-height: 1; display: grid; place-items: center;
  transition: background .12s, transform .1s;
}
.ri-retirer:hover { background: #fee2e2; }
.ri-retirer:active { transform: translateY(1px); }
/* Zone tactile agrandie à 44x44 px (A-5, audit accessibilité 31/07) : ce
   bouton supprime une ligne de réception/sortie en cours, usage réel debout
   une main. Le pseudo-élément agrandit la cible sans changer la taille
   visible du bouton (28x28 px). */
.ri-retirer::after {
  content: ""; position: absolute;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px;
}

/* Flash bref quand une ligne vient d'être fusionnée (dictée à nouveau). */
.reception-item.fusionnee { animation: flash-fusion 1s ease-out 1; }
@keyframes flash-fusion {
  0% { background: var(--ok-bg); border-color: var(--brand-light); }
  100% { background: var(--card); border-color: var(--border); }
}

/* Lot S-5 (chantier mode sortie) : ligne dont la sortie dictée dépasse le
   stock connu (stockApres < 0). Avertissement NON BLOQUANT (§Q1 du plan) :
   la ligne reste valide et validable, elle est juste signalée. Mêmes
   variables que .reception-inconnus juste en dessous, aucune couleur neuve. */
.reception-item.alerte { border-color: var(--warn-border); background: var(--warn-bg); }

/* Produits dictés hors catalogue : signalés en orange, exclus du lot. */
.reception-inconnus {
  margin-top: 10px; padding: 9px 11px; border-radius: 10px;
  background: var(--warn-bg); border: 1px solid var(--warn-border); color: var(--warn-text);
  font-size: 13px; line-height: 1.4;
}

/* Actions de clôture : Valider (bouton flamme, c'est le "Oui" du mode) +
   Abandonner (contour, survol rouge gardé : abandonner une saisie est
   destructif, audit --brand §2bis). */
.reception-actions { display: flex; gap: 12px; margin-top: 14px; }
.btn-reception-primaire {
  flex: 1; display: inline-flex; align-items: center; justify-content: center;
  font-family: inherit; font-size: 19px; font-weight: 700; white-space: nowrap;
  min-height: 46px; padding: 0 16px; border: none; border-radius: 14px;
  background: var(--action); color: #fff; cursor: pointer;
  box-shadow: 0 1px 4px rgba(250,93,0,.25);
  transition: background .15s, transform .1s, opacity .15s;
}
.btn-reception-primaire:hover { background: var(--action-sombre); }
.btn-reception-primaire:active { transform: translateY(1px); }
.btn-reception-primaire:disabled { opacity: .5; cursor: not-allowed; }
.btn-reception-secondaire {
  font-family: inherit; font-size: 14px; font-weight: 600; min-height: 44px;
  padding: 12px 16px; border: 1.5px solid var(--border); border-radius: 14px;
  background: var(--card); color: var(--muted); cursor: pointer;
  transition: background .15s, color .15s, border-color .15s, transform .1s;
}
.btn-reception-secondaire:hover { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-text); }
.btn-reception-secondaire:active { transform: translateY(1px); }
.btn-reception-secondaire:disabled { opacity: .6; cursor: wait; }

/* Bannière de reprise (une réception oubliée remonte au chargement). */
.reception-reprise {
  background: var(--warn-bg); border: 1px solid var(--warn-border); border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 16px; text-align: left;
}
.reception-reprise-texte { font-size: 14px; font-weight: 600; color: var(--warn-text); margin-bottom: 10px; }
.reception-reprise-actions { display: flex; gap: 12px; }
.reception-reprise-actions .btn-reception-primaire { flex: 1; }

/* Barre de navigation, fixee en bas (style app mobile).
   Passee a 4 onglets le 25/07 (ajout de « Aide ») : les colonnes sont
   resserrees (max-width, padding, taille du libelle) et les libelles ne se
   coupent plus sur deux lignes, pour tenir sur la largeur d'un telephone. */
.nav-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; justify-content: space-around;
  background: var(--card); border-top: 1px solid var(--border);
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  box-shadow: 0 -2px 10px rgba(29,30,28,.05);
}
.nav-item {
  flex: 1; max-width: 130px; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: none; border: none; padding: 8px 2px; border-radius: 12px;
  font-family: inherit; color: var(--muted); cursor: pointer;
  transition: color .15s;
}
.nav-item .nav-icone { display: flex; align-items: center; justify-content: center; }
.nav-item .nav-label {
  font-size: 11px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
/* Reprise du 23/08 : la couleur d'action reste sur l'icone (decorative, hors
   seuil de contraste) ; le libelle actif passe en encre pour rester lisible
   (la flamme sur blanc a 11px gras ne fait que ~3,17:1, sous le seuil AA).
   Lot A15 (R-2, 25/08) : --flamme -> --action, c'est "l'onglet qu'on peut
   toucher" au sens du brief, donc suit le choix de couleur. */
.nav-item.actif .nav-icone { color: var(--action); }
.nav-item.actif .nav-label { color: var(--text); font-weight: 700; }
.nav-item:active { transform: translateY(1px); }

/* Bannière « nouvelle version prête » (lot A6, 25/08/2026). Choix n°5 de
   l'Architecte : jamais automatique, jamais en pleine session sans ce
   bandeau. Fixée juste AU-DESSUS de la nav (même 78px que body
   padding-bottom ci-dessus, ligne 254 : la nav mesure cette hauteur), pour
   ne jamais recouvrir une saisie en cours (le champ de "Parler" est plus
   haut dans le flux, jamais coincé contre la nav). Bouton réutilise
   .btn-reception-primaire (flamme + blanc déjà audité, §2bis) : .maj-bouton
   ne fait qu'ajuster sa taille dans ce contexte plus étroit. */
.maj-bandeau {
  position: fixed; left: 0; right: 0; z-index: 55;
  bottom: calc(78px + env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  background: var(--card); border-top: 1px solid var(--border);
  padding: 12px 16px;
  box-shadow: 0 -2px 10px rgba(29,30,28,.08);
}
.maj-texte { font-size: 14px; font-weight: 600; color: var(--text); margin: 0; }
/* Cible tactile : le gabarit de .btn-reception-primaire (46px, deja >= 44px,
   regle des lots A1/A2) n'est PAS retaille ici, seule sa largeur est
   contrainte pour cohabiter avec le texte dans la banniere. */
.maj-bandeau .maj-bouton { flex: 0 0 auto; }

/* =====================================================================
   Connexion (lot 9b) — écran de login.
   Le bouton d'engrenage de l'en-tête (.btn-reglages, ouvre l'écran Réglages
   depuis le lot A4, 24/08/2026 — la déconnexion a quitté l'en-tête pour ce
   nouvel écran) est stylé avec .btn-refresh plus haut (section En-tête,
   monde clair) : une seule règle pour les deux boutons à contour de
   l'en-tête, pas de redéfinition ici.
   ===================================================================== */

/* Correctif d'affichage (11/07) : l'attribut `hidden` doit TOUJOURS
   l'emporter. Sans ce !important, la regle .ecran-login { display:flex }
   ci-dessous annulait le hidden -> l'ecran de connexion restait visible
   apres login et le dashboard s'empilait en dessous (il fallait defiler). */
[hidden] { display: none !important; }

/* Écran de connexion (monde clair, 23/08/2026) : centré, sobre, plein écran
   sur --bg (le dégradé teal disparaît). Référence : maquettes/compte-et-
   reglages/apercu-Connexion.png (DESIGN.md, "L'app"). */
.ecran-login {
  min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px; background: var(--bg);
}
/* Le mot Stovo, logotype flamme, posé AU-DESSUS de la carte (pas de
   pictogramme) : même gabarit que .brand h1 de l'en-tête et .logo de la
   vitrine (DM Sans 700, 22px, -.02em). Lot A15 (R-2, 25/08/2026) : reste en
   --flamme comme .brand h1 ci-dessus, c'est l'identité, pas --action. */
.login-logo {
  font-size: 22px; font-weight: 700; letter-spacing: -.02em; line-height: 44px;
  color: var(--flamme); margin-bottom: 4px;
}
.login-carte {
  width: 100%; max-width: 380px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-sm);
  padding: 32px 28px;
}
/* Titre et sous-titre alignés à gauche comme la carte (maquettes/compte-et-
   reglages/apercu-Connexion.png), à l'inverse de l'ancien centrage teal. */
.login-carte h1 { font-size: 26px; font-weight: 700; letter-spacing: -.02em; color: var(--text); }
.login-soustitre { font-size: 15px; color: var(--muted); margin: 6px 0 26px; }

/* Lot A4 (24/08/2026) : le sélecteur était ID-spécifique à #form-login (lot
   9b), donc IGNORAIT les 3 nouveaux formulaires du mot de passe perdu
   (#form-code-demande, #form-code-saisie) et de son changement connecté
   (#form-changer-mdp) — repéré à la relecture des premières captures
   (champs rendus avec le style par défaut du navigateur). `.login-carte`
   est le conteneur COMMUN à toutes ces cartes (voir index.html), qu'elles
   vivent dans un `.ecran-login` (avant connexion) ou dans un `.ecran`
   classique (#ecran-changer-mdp, connecté) : un seul sélecteur suffit. */
.login-carte form { display: flex; flex-direction: column; gap: 6px; }
.login-carte form label { font-size: 13.5px; font-weight: 600; color: var(--muted); margin-top: 10px; }
.login-carte form input {
  font-family: inherit; font-size: 15px; padding: 11px 13px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--card); color: var(--text);
  transition: border-color .15s;
}
.login-carte form input:focus { border-color: var(--text); }
/* Champ du code reçu (planche Code2Saisie) : grand, centré, chiffres
   alignés (tabular-nums), pour qu'un code à 6 chiffres se lise d'un coup
   d'œil — reprend l'esprit de la maquette sans copier ses valeurs exactes. */
#recup-code {
  font-size: 26px; font-weight: 700; letter-spacing: .14em; text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Bouton flamme, pleine largeur : c'est le "Oui" de cet écran (audit --brand,
   §2bis, comme .matin-copier et .btn-reception-primaire). */
.btn-login {
  margin-top: 20px; width: 100%;
  font-family: inherit; font-size: 19px; font-weight: 700;
  min-height: 46px; padding: 0 16px; border: none; border-radius: 14px;
  background: var(--action); color: #fff; cursor: pointer;
  box-shadow: 0 1px 4px rgba(250,93,0,.25);
  transition: background .15s, transform .1s;
}
.btn-login:hover { background: var(--action-sombre); }
.btn-login:active { transform: translateY(1px); }
.btn-login:disabled { opacity: .7; cursor: wait; }

.login-erreur {
  margin-top: 14px; padding: 10px 14px; border-radius: 10px;
  font-size: 13.5px; font-weight: 600;
  color: var(--danger-text); background: var(--danger-bg); border: 1px solid var(--danger-border);
}

@media (max-width: 420px) {
  .login-carte { padding: 26px 20px; }
}

/* =====================================================================
   Écran du matin (brique 1) — bandeau de brief en tête du tableau de
   bord, construit à partir de chiffres DEJA calcules par dashboard.js
   (lecture seule). Il chevauche le bas de l'en-tete comme le faisaient
   les KPI ; ceux-ci passent donc SOUS lui (.matin + .kpis) et ne
   remontent plus dans l'en-tete. Additif : aucune regle ci-dessus n'est
   modifiee.
   ===================================================================== */
/* Reprise du 23/08/2026 : grille nommee pour placer "Copier la liste" en
   haut a droite (bureau) / pleine largeur SOUS la liste (telephone), sans
   changer l'ordre du DOM (accessibilite, voir index.html). */
.matin {
  position: relative; z-index: 2;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-chaude); padding: 18px 20px 8px; margin-top: 10px;
}
/* Plus de bande de couleur a gauche (monde clair, 23/08/2026) : l'etat se lit
   dans la couleur de .matin-resume et son symbole (● ▲ ■), pas la bordure. */

/* Wrapper qui porte la grille (voir le commentaire de index.html) : #matin
   lui-meme reste un simple conteneur visuel, dashboard.js pose un
   style.display inline dessus pour le montrer/le masquer sans jamais
   toucher a sa mise en page interne. */
.matin-corps {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "head bouton" "resume resume" "liste liste";
  column-gap: 12px;
}

.matin-head { grid-area: head; display: flex; align-items: center; }
/* Correctif du 01/08/2026 (mesure Playwright) : "Ce matin" devient un <h2>
   (voir index.html) pour rendre a la section son titre de niveau. Le <h2>
   ne fait qu'envelopper le bouton, il ne doit imposer ni marge ni taille de
   police a lui : c'est toujours .matin-titre (le <span> a l'interieur) qui
   pilote l'apparence. */
.matin-titre-h2 { margin: 0; font-size: inherit; font-weight: inherit; line-height: inherit; }
.matin-titre { font-size: 18px; font-weight: 700; white-space: nowrap; }
/* Bouton flamme : la seule action de l'ecran Pilotage (audit --brand, §2bis).
   19px/46px, meme regime que les boutons flamme de la vitrine (DESIGN.md :
   "texte large au sens WCAG, 3,2:1 suffit") : a 14px (premiere version du
   23/08), le blanc sur --flamme ne faisait que 3,17:1, sous le seuil AA. */
.matin-copier {
  grid-area: bouton; align-self: start;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: inherit; font-size: 19px; font-weight: 700; white-space: nowrap;
  padding: 0 18px; border-radius: 14px; border: none;
  background: var(--action); color: #fff; cursor: pointer;
  box-shadow: 0 1px 4px rgba(250,93,0,.25);
  transition: background .15s, transform .1s;
  min-height: 46px;
}
.matin-copier:hover { background: var(--action-sombre); }
.matin-copier:active { transform: translateY(1px); }

.matin-resume { grid-area: resume; font-size: 14.5px; font-weight: 600; margin-top: 5px; }
.matin.matin-ok .matin-resume { color: var(--brand-dark); }
.matin.matin-warn .matin-resume { color: var(--warn-text); }
.matin.matin-crit .matin-resume { color: var(--danger-text); }

/* Correctif du 01/08/2026 : #matin-liste devient une vraie <ul> (voir
   index.html) pour qu'un lecteur d'ecran annonce "liste de N elements" au
   lieu d'un simple bloc. list-style retire les puces (les <li> heritent de
   "none") ; margin/padding remis a zero explicitement en plus du reset
   global "* { margin:0; padding:0; }" deja present en tete de fichier, par
   robustesse si ce reset venait a changer. Le reste (grid-template-columns,
   grid-column, le bloc @media plus bas) n'est PAS touche : .matin-item
   garde exactement le meme rendu, seule sa balise change (div -> li). */
.matin-liste { grid-area: liste; list-style: none; margin: 13px 0 0; padding: 0; }
/* Monde clair (23/08/2026) : la couverture (.mi-cov) passe sur sa propre
   ligne A TOUTES LES LARGEURS (grid-column:1/-1 ci-dessous), comme sur la
   planche bureau. La grille ne garde donc que 2 colonnes (nom, quantite) ;
   l'ancienne 3e colonne "auto" ne servait qu'a l'etat replie mobile, deplace
   ici a demeure. Le correctif du 01/08/2026 (nom qui se compresse, cf.
   min-width:0 sur .mi-nom) reste inchange. */
.matin-item {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 14px; align-items: baseline;
  padding: 11px 0; border-top: 1px solid var(--border);
}
.matin-item:first-child { border-top: none; }
.mi-nom { font-weight: 700; font-size: 15px; color: var(--text); min-width: 0; overflow-wrap: break-word; }
.mi-qte { font-weight: 700; font-size: 15px; color: var(--danger-text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.mi-qte-label { font-weight: 600; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.mi-cov { font-size: 13px; color: var(--muted); white-space: normal; grid-column: 1 / -1; }
.mi-cov.urgent { color: var(--danger-text); font-weight: 700; }

/* Bandeau repliable : le chevron + le titre forment un bouton qui plie/deplie
   la liste. L'etat est memorise (localStorage) entre les sessions. */
.matin-toggle {
  display: flex; align-items: center; gap: 8px;
  background: none; border: none; padding: 0; margin: 0;
  font-family: inherit; color: inherit; cursor: pointer; text-align: left;
  /* Cible tactile 44px (mesure Playwright du 01/08/2026, le bouton mesurait
     103x22px). min-height agit directement sur le bouton, pas sur la ligne :
     align-items:center (deja present) garde le titre centre dans cette
     hauteur, sans changer sa largeur ni son texte. */
  min-height: 44px;
}
/* Une compensation en marge negative a ete essayee ici sur l'etat "rien a
   commander", puis retiree apres mesure (01/08/2026) : elle partait de l'idee
   qu'il fallait annuler la croissance de la ligne, alors que min-height:44px
   s'applique au bouton dans TOUS les etats et que cette hauteur est
   precisement ce qui rend la cible tactile conforme. Mesure a l'appui : avec
   la compensation, le titre remontait a 18px du haut du bandeau contre 29px
   dans l'etat normal, et la zone cliquable empietait de 11px dans le padding
   de la carte. Sans elle, les deux etats sont alignes au pixel pres. */
.matin-chevron { display: inline-flex; color: var(--muted); transition: transform .15s; }
.matin-chevron svg { display: block; }
.matin.replie .matin-chevron { transform: rotate(-90deg); }
.matin.replie .matin-liste { display: none; }

/* Sous 560px (reprise du 23/08/2026) : une seule colonne, le bouton "Copier
   la liste" redescend sur sa propre ligne pleine largeur, sous la liste (on
   lit, puis on copie). [hidden] reste "display:none !important" (regle
   globale plus bas) : si rien n'est a commander, la ligne "bouton" ne
   reserve aucun espace, la grille se referme normalement. */
@media (max-width: 560px) {
  .matin-corps { grid-template-columns: 1fr; grid-template-areas: "head" "resume" "liste" "bouton"; }
  .matin-copier { width: 100%; justify-content: center; margin: 4px 0 10px; }
}

/* Inventaire regroupe par etat, en sections depliables (element <details>
   natif : accessible, pas de JS pour le pli lui-meme ; l'etat ouvert est juste
   memorise cote JS pour survivre au rafraichissement). */
.inv-groupes { display: flex; flex-direction: column; gap: 12px; }
.inv-sommaire {
  cursor: pointer; list-style: none; -webkit-user-select: none; user-select: none;
  display: flex; align-items: center; gap: 9px;
  font-size: 15px; font-weight: 700; padding: 8px 2px; min-height: 44px;
}
.inv-sommaire::-webkit-details-marker { display: none; }
/* Chevron dessine en CSS (monde clair, 23/08/2026) : un carre de 8px, deux
   bordures visibles, tourne a 45deg au repos (pointe a droite, comme ▸) puis
   encore 90deg de plus une fois ouvert (pointe vers le bas, comme ▾). */
.inv-sommaire::before {
  content: ''; width: 8px; height: 8px; flex: 0 0 auto;
  border-right: 1.8px solid var(--muted); border-bottom: 1.8px solid var(--muted);
  transform: rotate(-45deg); transition: transform .15s;
}
.inv-groupe[open] > .inv-sommaire::before { transform: rotate(45deg); }
.inv-sym-commander { color: var(--danger); }
.inv-sym-surveiller { color: var(--warn); }
.inv-sym-stock { color: var(--brand-dark); }
.inv-groupe > .grid { margin-top: 12px; }

/* ---------- Onglet « Stock » (QW-C, 18/07/2026) ----------
   Liste compacte (des lignes, pas des cartes) + recherche a la frappe.
   Chaque ligne est un <details> natif : sommaire = ligne compacte,
   contenu = detail replie (chiffres deja calcules par dashboard.js). */
.stock-page { padding-top: 22px; }
.stock-recherche {
  width: 100%; padding: 12px 15px; font-size: 15px;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); color: var(--text);
  box-shadow: var(--shadow-sm);
  margin-bottom: 14px;
}
.stock-recherche:focus { border-color: var(--text); }
.stock-liste {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
  padding: 2px 14px;
}
.stock-ligne { border-top: 1px solid var(--border); }
.stock-ligne:first-child { border-top: none; }
.stock-sommaire {
  cursor: pointer; list-style: none; -webkit-user-select: none; user-select: none;
  display: grid; grid-template-columns: 1fr auto auto;
  gap: 12px; align-items: center; padding: 11px 2px;
}
.stock-sommaire::-webkit-details-marker { display: none; }
.sl-nom { font-weight: 700; font-size: 14.5px; }
.sl-stock { font-size: 13.5px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.sl-stock b { color: var(--text); }
.stock-detail { padding: 0 2px 12px; font-size: 12.5px; color: var(--muted); line-height: 1.7; }

/* ---------- Onglet « Aide » (25/07/2026) ----------
   Le mode d'emploi dans l'app. Trois sections depliables (<details> natif,
   comme l'inventaire du dashboard et les lignes de l'onglet Stock), avec des
   exemples cliquables qui recopient la phrase dans l'ecran « Parler ».
   Aucune couleur nouvelle : on reutilise les variables de la charte. */
.aide-page { padding-top: 22px; padding-bottom: 30px; }
.aide-intro { font-size: 14px; color: var(--muted); margin: -6px 0 16px; }

.aide-section {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
  margin-bottom: 12px; overflow: hidden;
}
.aide-sommaire {
  cursor: pointer; list-style: none; -webkit-user-select: none; user-select: none;
  display: flex; align-items: center; gap: 11px;
  padding: 15px 16px; font-weight: 700; font-size: 15.5px;
}
.aide-sommaire::-webkit-details-marker { display: none; }
/* Icone SVG en trait (lot "monde clair, suite", 23/08/2026) : remplace
   l'emoji. Decorative (aria-hidden dans aide.js), couleur --muted-light
   comme .aide-geste-icone ci-dessous (regle 3 de DESIGN.md : le titre en
   gras a cote porte deja le sens, l'icone n'est qu'un repere visuel). */
.aide-icone { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; color: var(--muted-light); }
.aide-icone svg { width: 22px; height: 22px; display: block; }
/* Chevron a droite, tourne quand la section est ouverte. */
.aide-titre { flex: 1; }
.aide-sommaire::after {
  content: '▾'; color: var(--muted); font-size: 13px;
  transition: transform .15s;
}
.aide-section[open] > .aide-sommaire::after { transform: rotate(180deg); }
.aide-section[open] > .aide-sommaire { border-bottom: 1px solid var(--border); }
.aide-contenu { padding: 4px 16px 16px; }

.aide-texte { font-size: 14px; color: var(--text); line-height: 1.65; margin: 12px 0; }
.aide-texte b { font-weight: 700; }

.aide-defs { margin: 12px 0; }
/* display:flex ajoutee (lot "monde clair, suite") : seules les 4 defs de
   "Comprendre Stovo" portent une icone (aide.js), les autres <dt> n'ont
   simplement rien a aligner et le flex ne change rien pour eux. */
.aide-defs dt { display: flex; align-items: center; gap: 7px; font-weight: 700; font-size: 13.5px; margin-top: 12px; }
.aide-defs dt:first-child { margin-top: 0; }
.aide-defs dd { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin: 2px 0 0; }

/* Listes a puces DANS une section. Classe volontairement distincte du
   conteneur #aide-liste : sinon tout l'ecran heriterait du retrait. */
.aide-puces { margin: 12px 0; padding-left: 20px; font-size: 14px; line-height: 1.7; }

/* Un geste = un bloc encadre : ce qu'il fait, des exemples, une note. */
.aide-geste {
  border-top: 1px solid var(--border);
  padding: 16px 0 4px;
}
.aide-geste:first-of-type { border-top: none; }
.aide-geste-titre { display: flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 700; margin-bottom: 5px; }
.aide-geste-quoi { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin-bottom: 10px; }
/* Icone decorative devant le titre d'un geste ou d'une astuce (couleur
   --muted-light, regle 3 de DESIGN.md : le titre en gras a cote porte deja
   le sens). Reutilisee aussi devant les 4 defs "Comprendre Stovo" (aide.js),
   d'ou une classe generique plutot que ".aide-geste-titre .icone". */
.aide-geste-icone { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; color: var(--muted-light); }
.aide-geste-icone svg { width: 20px; height: 20px; display: block; }

.aide-exemples { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 9px; }
/* L'exemple est un BOUTON : le taper recopie la phrase dans l'ecran Parler
   (aide.js), il doit donc se voir comme cliquable. Reprise du 23/08/2026
   (audit --brand §2bis) : bouton a contour, sur le modele des trois phrases
   proposees de la demo jouable de la vitrine (.compteur__phrase) — plus de
   teal, l'italique et les guillemets restent. */
.aide-exemple {
  font-family: inherit; font-size: 13px; font-style: italic;
  color: var(--text); background: var(--card);
  border: 1.5px solid var(--border); border-radius: 14px;
  min-height: 44px; padding: 12px 16px; cursor: pointer; text-align: left;
  transition: background .15s, border-color .15s;
}
.aide-exemple::before { content: '« '; font-style: normal; }
.aide-exemple::after { content: ' »'; font-style: normal; }
.aide-exemple:hover { background: var(--fond-chaud); border-color: var(--text); }
.aide-exemple:active { transform: translateY(1px); }

.aide-note {
  font-size: 12.5px; color: var(--muted); line-height: 1.6;
  border-left: 2px solid var(--border); padding-left: 10px;
}

/* Une astuce = un encadre plein, pour trancher visuellement avec les gestes. */
.aide-astuce {
  background: var(--bg); border-radius: 12px;
  padding: 13px 14px; margin-bottom: 11px;
}
.aide-astuce-titre { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; margin-bottom: 2px; }
.aide-astuce .aide-texte { margin: 4px 0 0; font-size: 13.5px; }

/* ===================== Inventaire complet guidé (CM-C, 25/07/2026) =====================
   Réutilise volontairement les classes de la réception (.reception-panneau,
   .reception-actions, .btn-reception-*) : même mécanique, même langage visuel.
   Seuls les éléments propres au parcours produit-par-produit sont stylés ici. */

.inventaire-panneau {
  margin-top: 14px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
}

/* Le nom du produit à compter : c'est LE point d'attention de l'écran, donc
   l'élément le plus gros. C'est lui qui dispense de répéter le nom à la voix. */
.inventaire-nom {
  margin: 10px 0 4px;
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.2;
}

.inventaire-stock,
.inventaire-deja,
.inventaire-total {
  margin: 2px 0;
  font-size: 0.92rem;
  opacity: 0.75;
}

.inventaire-deja:empty { display: none; }

.inventaire-aveugle {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 0 6px;
  font-size: 0.9rem;
  opacity: 0.85;
  cursor: pointer;
}

.inventaire-recap {
  margin: 8px 0 14px;
  line-height: 1.5;
}

/* Lot P-3 (chantier PILOTAGE, 26/07/2026) : bandeau "pilotage en pause",
   affiche sous le verdict quand aucune sortie n'est declaree depuis
   GESTE_VIVANT_JOURS. Reutilise .card pour la boite (deja stylee). */
.bandeau-pilotage { margin: 10px 0 2px; }
.bandeau-pilotage .bp-titre { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
.bandeau-pilotage .bp-texte { font-size: 13.5px; color: var(--muted); margin-bottom: 8px; line-height: 1.5; }
/* Bouton a contour (action secondaire, audit --brand §2bis). */
.bandeau-pilotage .bp-bouton {
  font-family: inherit; font-size: 13px; font-weight: 600; min-height: 44px;
  padding: 0 16px; border-radius: 14px; border: 1.5px solid var(--border);
  background: var(--card); color: var(--text); cursor: pointer;
  transition: background .15s, transform .1s;
}
.bandeau-pilotage .bp-bouton:hover { background: var(--fond-chaud); }
.bandeau-pilotage .bp-bouton:active { transform: translateY(1px); }

/* Lot P-5 (chantier PILOTAGE, 26/07/2026) : phrase de synthese du stock
   dormant, sous le bloc "Valeur du stock". */
.dormant-resume {
  font-size: 12.5px;
  color: var(--muted);
  margin: -2px 0 8px;
  padding: 0 2px;
}

/* ---------- Chantier C1 (26/07/2026) : demarque valorisee "Ce que tu as
   jete" ---------- Rendu par app/pertes.js (calculerDemarque + rendreDemarque),
   injecte dans #pertes-contenu, lui-meme a l'interieur du <details
   class="inv-groupe"> dedie (voir index.html) : le chevron et le style du
   sommaire sont deja herites de .inv-groupe/.inv-sommaire, rien a refaire ici.
   Marge propre a CE <details> (id, pas la classe .inv-groupe partagee) : il
   vit hors de #inv-grid/.inv-groupes (qui donne le gap de 12px entre les 3
   groupes d'inventaire), donc sans cette marge il serait colle au bloc du
   dessus (reappro, souvent masque) et au dessous. */
#pertes-groupe { margin: 18px 0 6px; }
.pertes-vide { padding: 10px 2px 4px; color: var(--muted); font-size: 14px; }

.pertes-total { font-size: 26px; font-weight: 700; color: var(--text); margin: 10px 0 8px; line-height: 1.15; }
.pertes-total .pertes-partiel { font-size: 13px; font-weight: 600; color: var(--muted); margin-left: 4px; }

.pertes-motifs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.pertes-motif {
  display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600;
  background: var(--warn-bg); border: 1px solid var(--warn-border); color: var(--warn-text);
  padding: 5px 12px; border-radius: 999px;
}
.pertes-motif .pm-nom { text-transform: capitalize; }
.pertes-motif .pm-montant { font-weight: 700; }

.pertes-liste { margin-top: 2px; }
.pertes-ligne {
  display: grid; grid-template-columns: 1fr auto; gap: 8px 16px; align-items: center;
  padding: 12px 2px; border-top: 1px solid var(--border);
}
.pertes-ligne:first-child { border-top: none; }
.pertes-ligne .pp-main { min-width: 0; }
.pertes-ligne .pp-nom { font-weight: 700; font-size: 14.5px; }
.pertes-ligne .pp-detail { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.pertes-ligne .pp-right { text-align: right; white-space: nowrap; font-size: 15px; font-weight: 700; }
.pertes-ligne .pp-sansprix { font-size: 12.5px; color: var(--muted); font-weight: 500; font-style: italic; }

.pertes-note { font-size: 12.5px; color: var(--muted); margin-top: 10px; }
.pertes-methode { font-size: 11.5px; color: var(--muted); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }

/* ---------- Chantier C2 « les exports » (lot C2-3, 22/08/2026) ----------
   Même famille que #pertes-groupe juste au-dessus : un <details
   class="inv-groupe"> qui vit hors de #inv-grid/.inv-groupes, donc la même
   marge propre est nécessaire (sinon collé au tableau des mouvements et au
   pied de page). Le chevron et le style du sommaire sont déjà hérités de
   .inv-groupe/.inv-sommaire, rien à refaire ici. */
#export-groupe { margin: 18px 0 6px; }
.export-contenu { padding-top: 4px; }
.export-intro { font-size: 13.5px; color: var(--muted); margin: 4px 0 12px; }
.export-actions { display: flex; flex-direction: column; gap: 10px; }

/* Bouton a contour (action secondaire, audit --brand §2bis, 23/08/2026) : un
   export est un geste rare, pas l'action principale de l'écran. Hauteur mini
   44 px (cible tactile, règle A1-A4). */
.btn-export {
  font-family: inherit; font-size: 14.5px; font-weight: 600;
  min-height: 44px; padding: 12px 16px; border: 1.5px solid var(--border); border-radius: 14px;
  background: var(--card); color: var(--text); cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
}
.btn-export:hover { background: var(--fond-chaud); }
.btn-export:active { transform: translateY(1px); }
.btn-export:disabled { opacity: .6; cursor: wait; }

/* Message d'état sous les boutons (aria-live="polite" dans index.html) :
   "Préparation du fichier…", puis le compte de lignes, ou une erreur. */
.export-etat { font-size: 13px; color: var(--muted); margin: 10px 0 0; }
.export-etat.est-erreur { color: var(--danger); font-weight: 600; }

/* Mention légale répétée à l'écran (règle C1 : la méthode s'affiche avec le
   chiffre), même style que .pertes-methode juste au-dessus. */
.export-mention { font-size: 11.5px; color: var(--muted); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }

/* =====================================================================
   Accessibilité (lot A1, audit Impeccable du 31/07/2026).
   ===================================================================== */

/* A-9 : l'avertissement "prix d'achat, pas une valorisation comptable"
   sortait du `title` (invisible sur mobile) vers un paragraphe statique,
   sous le bandeau "Valeur du stock". Discret : ce n'est pas l'info
   principale de l'écran, juste le garde-fou qui évite un contresens. */
.sv-avertissement {
  font-size: 12.5px; color: var(--muted);
  margin: -4px 0 8px; padding: 0 2px;
}

/* A-7 : aucune règle prefers-reduced-motion n'existait alors que la
   pulsation du micro en écoute (pulse-micro) tourne en boucle infinie.
   Le micro reste reconnaissable sans le mouvement (fond --danger-bg et
   bordure --danger-border déjà posés par .btn-micro.ecoute ci-dessus) :
   seule l'animation disparaît, jamais le changement de couleur.
   Correctif A-7 bis (31/07/2026) : la première version neutralisait TOUTES
   les transitions du site (`* { transition-duration: 0.01ms !important; }`),
   un motif explicitement dénoncé par le référentiel Impeccable car il
   détruit aussi le retour d'information utile (un bouton qui change de
   couleur au clic, par exemple). Un utilisateur qui demande moins de
   mouvement veut supprimer le DÉPLACEMENT et les boucles, pas les fondus.
   La règle ci-dessous cible donc uniquement : les deux animations en
   boucle, et le tassement `translateY(1px)` au clic des boutons (état
   `:active`) + le survol `.card:hover` (`translateY(-1px)`). Les
   transitions de `background`, `border-color`, `color`, `opacity` et
   `box-shadow` restent actives partout, aucune n'est touchée ici. */
@media (prefers-reduced-motion: reduce) {
  .btn-micro.ecoute { animation: none; }
  .reception-item.fusionnee { animation: none; }
  .btn-refresh:active,
  .btn-envoyer:active,
  .btn-login:active,
  .btn-import:active,
  .btn-photo-bl:active,
  .btn-confirmation:active,
  .btn-choix:active,
  .btn-reception-primaire:active,
  .btn-reception-secondaire:active,
  .btn-reception-demarrer:active,
  .ri-retirer:active,
  .matin-copier:active,
  .aide-exemple:active,
  .nav-item:active,
  .btn-micro:not(:disabled):active,
  .btn-reglages:active,
  .reglages-btn-mailto:active,
  .reglages-pastille:active {
    transform: none;
  }
}

/* =====================================================================
   Accessibilité (lot A2, seconde passe du 31/07/2026).
   ===================================================================== */

/* A2-7 : le fichier ne posait aucun style de focus clavier, et trois champs
   supprimaient activement l'anneau du navigateur (`outline: none`, retire
   ci-dessus sur .parler-form textarea, #form-login input, .stock-recherche).
   Cette regle unique le remplace pour TOUT element focusable au clavier,
   sans reintroduire d'anneau au clic souris (`:focus-visible` ne se
   declenche pas dans ce cas dans les navigateurs modernes). */
:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* A2-8 : titre <h1> reserve aux technologies d'assistance sur l'ecran
   « Parler », qui n'a aucun titre visible (son message d'accueil dans
   .parler-reponse en tient lieu a l'ecran). Retire visuellement mais reste
   lisible au clavier/lecteur d'ecran. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* =====================================================================
   Lot A4 (24/08/2026) : mot de passe perdu (écrans avant connexion) et
   écran Réglages (compte, contact, version). Aucun jeton neuf : uniquement
   ceux déjà posés ailleurs dans ce fichier. Le teal n'apparaît qu'une fois
   (.pastille-validee, l'écran "Fait") : règle 10 de DESIGN.md, il reste
   réservé aux états, jamais à un bouton ou un lien.
   ===================================================================== */

/* Lien centré sous un formulaire de .ecran-login ("Mot de passe oublié ?",
   "Renvoyer un code") : même couleur d'action que le reste de l'app, cible
   tactile 44px. */
.login-lien-centre { display: flex; justify-content: center; margin-top: 14px; }
.login-lien-centre a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 15px; font-weight: 600; color: var(--text);
  text-decoration: underline; text-underline-offset: 3px;
}
.login-lien-centre a:hover { color: var(--muted); }
/* Grisé pendant le compte à rebours des 60 s de "Renvoyer un code"
   (recuperation.js, Supabase refuse un 2e envoi avant une minute) : plus de
   couleur d'action tant que le clic ne fait rien, curseur par défaut. */
.login-lien-centre a.lien-recup-inactif {
  color: var(--muted); text-decoration: none; cursor: default;
}

/* Lien de retour ("← Connexion", "← Réglages"...), au-dessus d'une carte de
   .ecran-login ou de .reglages-page. Cible tactile 44px comme les autres
   liens/boutons de navigation de l'app. */
.login-retour { padding: 12px 12px 0; }
.lien-retour {
  display: inline-flex; align-items: center; gap: 4px; min-height: 44px;
  padding: 0 8px; color: var(--text); text-decoration: none;
  font-size: 15px; font-weight: 600;
}
.lien-retour svg { flex: 0 0 auto; }
.lien-retour:hover { color: var(--muted); }

/* Note sous le formulaire de "Recevoir un code" (planche Code1Demande). */
.login-note { font-size: 14px; color: var(--muted); margin-top: 16px; line-height: 1.5; text-align: center; }

/* Champ en état d'erreur (planche Code2Erreur, écran "Nouveau mot de passe") :
   bordure en encre plutôt qu'un rouge d'alerte classique, le bloc d'alerte
   juste en dessous (.login-erreur, déjà stylé) porte la couleur du message. */
#form-code-saisie input.champ-erreur { border-color: var(--text); }

/* Pastille "validé" de l'écran "Fait" (planche Code3Fait) : blanc sur --ok
   mesuré à 5,47:1 (balayage-contrastes.mjs), largement au-dessus du seuil
   même à 15px — pas besoin d'un texte large ici, contrairement à la flamme. */
.pastille-validee {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 36px; padding: 6px 14px; margin-bottom: 4px;
  border-radius: 999px; background: var(--ok); color: #fff;
  font-size: 15px; font-weight: 600;
}

/* ---------- Écran Réglages ---------- */
.reglages-page { padding-top: 8px; padding-bottom: 30px; max-width: 480px; }
.reglages-page-etroite { max-width: 420px; }
.reglages-page .section-title { margin-top: 4px; }

.reglages-carte { display: flex; flex-direction: column; gap: 4px; margin-top: 18px; }
.reglages-soustitre { font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.reglages-email { font-size: 15px; font-weight: 600; color: var(--text); margin: 6px 0 10px; }
.reglages-separateur { height: 1px; background: var(--border); margin: 4px 0; }

/* Une ligne de compte = un bouton pleine largeur (icône, texte, chevron
   optionnel) : même esprit que .aide-geste-titre mais cliquable. */
.reglages-ligne {
  display: flex; align-items: center; gap: 12px; width: 100%;
  min-height: 52px; padding: 4px 0; border: none; background: none;
  font-family: inherit; font-size: 17px; font-weight: 600; color: var(--text);
  text-align: left; cursor: pointer;
}
.reglages-ligne-icone {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 999px;
  background: var(--fond-chaud); color: var(--action);
}
.reglages-ligne-texte { flex: 1 1 auto; }
.reglages-chevron { flex: 0 0 auto; color: var(--muted-light); }

/* Carte "Une question, un souci ?" : fond chaud plein (comme la planche
   Main), pas de bordure — se distingue visuellement de la carte "Mon compte"
   juste au-dessus. */
.reglages-contact {
  background: var(--fond-chaud); border-radius: var(--radius);
  padding: 22px 20px; margin-top: 16px;
  display: flex; flex-direction: column; gap: 14px;
}
.reglages-contact-texte { font-size: 16px; color: var(--text); line-height: 1.5; margin: 0; }
/* Bouton flamme pleine largeur pour "Écrire à Corentin" : c'est un <a> (lien
   mailto, pas un bouton de formulaire), donc son style est écrit ici plutôt
   que de réutiliser .btn-login (qui suppose display:block via un <button>
   natif — un <a> reste "inline" par défaut et ignorerait sa largeur/hauteur
   sans ce display explicite). */
.reglages-btn-mailto {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 50px; padding: 12px 20px;
  background: var(--action); color: #fff; text-decoration: none;
  font-family: inherit; font-size: 19px; font-weight: 700; border-radius: 14px;
  box-shadow: 0 1px 4px rgba(250,93,0,.25);
  transition: background .15s, transform .1s;
}
.reglages-btn-mailto:hover { background: var(--action-sombre); }
.reglages-btn-mailto:active { transform: translateY(1px); }
.reglages-adresse-ligne { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.reglages-adresse { font-size: 15px; color: var(--text); word-break: break-all; }

.reglages-version { font-size: 13px; color: var(--muted); margin-top: 22px; line-height: 1.5; }
.reglages-version a { color: var(--muted); }

/* ---------- Écran "Changer mon mot de passe" ---------- */
/* Un seul élément pour le succès ET l'échec (reglages.js bascule la classe) :
   même patron que .export-etat (dashboard.js/export). */
.changer-mdp-message {
  margin-top: 14px; padding: 10px 14px; border-radius: 10px;
  font-size: 13.5px; font-weight: 600;
  color: var(--ok); background: var(--ok-bg); border: 1px solid var(--brand-light);
}
.changer-mdp-message.est-erreur {
  color: var(--danger-text); background: var(--danger-bg); border-color: var(--danger-border);
}

/* =====================================================================
   Lot A15 (R-2, 25/08/2026) : la carte « Couleur de Stovo », en tête de
   l'écran Réglages (au-dessus de « Mon compte »). Planche source :
   maquettes/compte-et-reglages/ReglagesPrune.dc.html. Le nuancier et
   l'aperçu sont RENDUS par reglages.js (via app/couleur_logique.js,
   module pur), ce fichier ne pose que leur style.
   ===================================================================== */

/* Même gabarit que .reglages-carte (padding 22px 20px, marge du haut
   18px, comme la planche), mais un gap plus large (14px au lieu de 4px) :
   cette carte empile 4 blocs distincts (étiquette, texte, nuancier,
   aperçu) plutôt que des lignes de compte serrées. */
.reglages-couleur { padding: 22px 20px; display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
.reglages-couleur-texte { font-size: 15px; line-height: 1.5; color: var(--muted); }

.reglages-nuancier { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
/* Vrai <button> (accessibilité, brief §6) : cible 44px, libellé toujours
   visible sous le disque (jamais la pastille seule). */
.reglages-pastille {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  min-height: 44px; padding: 6px 0;
  font-family: inherit; font-size: 13px; font-weight: 500; color: var(--muted);
  background: none; border: none; cursor: pointer;
  transition: color .15s, transform .1s;
}
.reglages-pastille-disque {
  width: 44px; height: 44px; border-radius: 999px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center; color: #fff;
}
/* Les CINQ couleurs du nuancier sont FIXES (chaque pastille montre
   toujours sa propre teinte, contrairement à --action qui n'en active
   qu'une à la fois sur <html>) : mêmes valeurs que les cinq blocs
   html[data-couleur] plus haut (section :root), dupliquées ici avec la
   même raison — un changement de teinte se fait aux DEUX endroits. */
.reglages-pastille[data-teinte="flamme"] .reglages-pastille-disque { background: #FA5D00; }
.reglages-pastille[data-teinte="bleu"] .reglages-pastille-disque { background: #1D4ED8; }
.reglages-pastille[data-teinte="prune"] .reglages-pastille-disque { background: #7E22CE; }
.reglages-pastille[data-teinte="framboise"] .reglages-pastille-disque { background: #BE185D; }
.reglages-pastille[data-teinte="encre"] .reglages-pastille-disque { background: #1D1E1C; }
/* Sélection : anneau blanc + encre autour du disque (planche), libellé en
   gras + encre (comme .nav-item.actif .nav-label, même logique). La coche
   SVG (rendue par couleur_logique.js) est blanche sur les cinq teintes :
   flamme ne tient que 3,17:1 en blanc, mais c'est un pictogramme, pas du
   texte courant (DESIGN.md, règle 10) ; les quatre autres teintes tiennent
   toutes le 4,5:1 (balayé au rapport de passation). */
.reglages-pastille.est-choisi { color: var(--text); font-weight: 700; }
.reglages-pastille.est-choisi .reglages-pastille-disque {
  box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px var(--text);
}
.reglages-pastille:active { transform: translateY(1px); }

/* L'aperçu : le bouton Oui « tel qu'il sera », dans la teinte courante —
   il réutilise .btn-confirmation.btn-oui déjà stylé plus haut (donc suit
   --action automatiquement, aucune couleur à dupliquer ici). C'est un
   <span>, pas un <button> : aria-hidden (brief §5), pointer-events:none
   en renfort pour qu'aucun clic ne lui donne l'air actif, et la légende
   à côté porte tout le sens pour un lecteur d'écran. */
.reglages-apercu { display: flex; align-items: center; gap: 10px; padding-top: 4px; flex-wrap: wrap; }
.reglages-apercu-bouton { flex: 0 0 auto; pointer-events: none; }
.reglages-apercu-texte { font-size: 14px; line-height: 1.5; color: var(--muted); margin: 0; flex: 1 1 200px; min-width: 0; }
