/* Front du POC retail.
   Tactile d'abord : toute cible cliquable fait au moins 48 px de haut, parce
   qu'on tape dessus avec un doigt, debout, parfois les mains occupees. */

:root {
  --fond: #fbfbfa;
  --carte: #fff;
  --trait: #d8d6d1;
  --texte: #1c1a17;
  --discret: #6b6660;
  --accent: #1f5f4f;
  --accent-clair: #e7f1ee;
  --alerte: #a8331f;
  --alerte-clair: #fbeae7;
  --ok: #1f5f4f;
  --rayon: 8px;
  --cible: 48px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --fond: #171614; --carte: #201f1c; --trait: #3a3833; --texte: #ece9e3;
    --discret: #9b958c; --accent: #5fb89f; --accent-clair: #1d2e29;
    --alerte: #e98b76; --alerte-clair: #33201c;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--fond); color: var(--texte);
  -webkit-text-size-adjust: 100%;
}
h1 { font-size: 1.6rem; margin: 0 0 .25rem; }
h2 { font-size: 1.15rem; margin: 1.25rem 0 .5rem; }

/* ------------------------------------------------------------- connexion */
.plein {
  min-height: 100dvh; display: grid; place-items: center; padding: 1.5rem;
}
#form-connexion {
  width: 100%; max-width: 22rem; background: var(--carte);
  border: 1px solid var(--trait); border-radius: var(--rayon); padding: 1.5rem;
  display: grid; gap: .9rem;
}
.sous-titre { margin: 0 0 .5rem; color: var(--discret); }

/* ---------------------------------------------------------- page d'accueil
   Plus large que la carte de connexion (22 rem) parce qu'elle porte du texte a
   LIRE, pas des champs a remplir : une ligne de 22 rem casserait chaque phrase
   en quatre. Toutes les couleurs viennent des variables de theme, jamais d'une
   valeur litterale — un fond pose sans sa couleur de texte devient illisible en
   theme sombre. */
#accueil {
  width: 100%; max-width: 34rem; background: var(--carte); color: var(--texte);
  border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: 1.75rem 1.5rem;
}
#accueil-editeur {
  margin: 0 0 .75rem; font-size: .8rem; font-weight: 600;
  letter-spacing: .28em; color: var(--accent);
}
/* Marqueur de pile d'essai : teinte d'alerte, fond ET couleur de texte poses
   ensemble (un fond sans sa couleur de texte devient illisible en theme sombre). */
.pile-essai {
  margin: .5rem 0 .75rem; padding: .5rem .7rem;
  background: var(--alerte-clair); color: var(--alerte);
  border: 1px solid var(--alerte); border-radius: var(--rayon);
  font-size: .85rem; font-weight: 600;
}
#accueil-baseline em { font-style: normal; font-weight: 600; }
#accueil-fonctions {
  margin: 1.25rem 0; padding: 0; list-style: none;
  display: grid; gap: .6rem;
}
#accueil-fonctions li {
  padding-left: .9rem; border-left: 3px solid var(--accent-clair);
}
#accueil-fonctions strong { color: var(--accent); }
/* Cible tactile pleine largeur : c'est le seul geste de cet ecran. */
#btn-accueil-connexion { width: 100%; min-height: var(--cible); font-size: 1.05rem; }
#accueil-redirection, #accueil-acces { margin: .75rem 0 0; font-size: .92rem; }
#accueil-pied {
  margin: 1.5rem 0 0; padding-top: .9rem; border-top: 1px solid var(--trait);
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  font-size: .8rem; color: var(--discret);
}

/* Ouvrir une caisse : un bloc SECONDAIRE, visuellement en retrait du bouton de
   connexion. L'ecrasante majorite des arrivees sont des gens qui se connectent ;
   l'inscription ne doit pas leur disputer l'attention. */
#accueil-inscription {
  margin-top: 1.5rem; padding-top: 1.1rem;
  border-top: 1px solid var(--trait);
}
#accueil-inscription-titre { font-size: 1rem; margin: 0 0 .35rem; }
/* Un lien qui a la taille d'une cible tactile, sans la couleur d'un bouton
   primaire : c'est une action offerte, pas l'action attendue. */
.bouton-lien {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--cible); padding: 0 1.1rem;
  border: 1px solid var(--accent); border-radius: var(--rayon);
  background: var(--carte); color: var(--accent);
  text-decoration: none; font-weight: 600;
}
.bouton-lien:hover { background: var(--accent-clair); }

/* ---------------------------------------------------------------- entete */
#entete {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; flex-wrap: wrap;
  padding: 0 1rem; background: var(--carte); border-bottom: 1px solid var(--trait);
  position: sticky; top: 0; z-index: 5;
}
#entete nav { display: flex; gap: .25rem; }

/* Le menu est a l'EXTREME DROITE de l'en-tete, apres « Quitter » (#41). Un ecart
   franc et un trait les separent : sur tablette, un doigt qui vise ☰ ne doit pas
   tomber sur « Quitter » (et « Quitter » n'a pas de confirmation). */
.menu-zone {
  position: relative; display: flex; align-items: center;
  margin-left: 1.75rem; padding-left: 1.75rem;
  border-left: 1px solid var(--trait);
}

/* ---------------------------------------------------------------------------
 *  MENU DES ECRANS ADMINISTRATIFS
 *  Huit ecrans qu'on visite quelques fois par jour n'ont pas a occuper une ligne
 *  permanente au-dessus de l'ecran ou l'on passe la journee.
 * ------------------------------------------------------------------------ */
#btn-menu {
  min-height: var(--cible); min-width: var(--cible); border: 0;
  background: none; color: var(--texte); font-size: 1.35rem; cursor: pointer;
  line-height: 1;
}
#btn-menu:hover { background: var(--accent-clair); border-radius: var(--rayon); }
#menu-panneau {
  position: absolute; top: calc(100% + .2rem); right: 0; z-index: 30;
  max-width: calc(100vw - 1rem);
  display: flex; flex-direction: column; min-width: 14rem;
  /* Fond ET couleur de texte ensemble : la moitie d'une paire rend le panneau
     illisible des que le theme du systeme change. */
  background: var(--carte); color: var(--texte);
  border: 1px solid var(--trait); border-radius: var(--rayon);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  padding: .3rem;
}
#menu-panneau .onglet {
  text-align: left; border-bottom: 0; border-radius: var(--rayon);
  padding: 0 .9rem;
}
#menu-panneau .onglet:hover { background: var(--accent-clair); color: var(--texte); }
#menu-panneau .onglet.actif { color: var(--texte); background: var(--accent-clair); }

.onglet {
  min-height: var(--cible); padding: 0 1.1rem; border: 0; background: none;
  color: var(--discret); font-size: 1rem; font-weight: 600; cursor: pointer;
  border-bottom: 3px solid transparent;
}
.onglet.actif { color: var(--texte); border-bottom-color: var(--accent); }
.entete-droite { display: flex; align-items: center; gap: .9rem; }
.pastille {
  display: inline-block; min-width: 1.4rem; padding: 0 .35rem;
  background: var(--alerte); color: #fff; border-radius: 999px;
  font-size: .78rem; text-align: center;
}

/* ----------------------------------------------------------------- vues */
main { padding: 1rem; max-width: 84rem; margin: 0 auto; }
.vue { display: none; }
.vue.active { display: block; }
.colonnes { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; align-items: start; }
@media (max-width: 860px) { .colonnes { grid-template-columns: 1fr; } }

.barre { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; margin-bottom: 1rem; }

/* --------------------------------------------------------- formulaires */
label { display: grid; gap: .35rem; font-weight: 600; font-size: .9rem; }
label.gros { font-size: 1rem; }
input[type=text], input[type=email], input[type=password] {
  min-height: var(--cible); padding: 0 .8rem; font-size: 1.05rem;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--carte); color: var(--texte); width: 100%;
}
label.gros input { font-size: 1.5rem; font-variant-numeric: tabular-nums; }

/* Champ article de la caisse (#41) : le geste principal de l'ecran. Pleine
   largeur de sa colonne, haut, gros caracteres. */
#scan {
  display: block; width: 100%; box-sizing: border-box;
  min-height: 4rem; padding: 0 1rem; font-size: 1.75rem;
  border: 2px solid var(--trait); border-radius: var(--rayon);
  background: var(--carte); color: var(--texte);
}
#scan:focus-visible { border-color: var(--accent); }
.carte > label.gros[for="scan"] { font-size: 1.1rem; font-weight: 600; display: block; margin-bottom: .4rem; }
input:focus-visible, button:focus-visible {
  outline: 3px solid var(--accent); outline-offset: 1px;
}

button, .bouton-fichier {
  min-height: var(--cible); padding: 0 1.2rem; font-size: 1rem; font-weight: 600;
  border-radius: var(--rayon); border: 1px solid var(--trait); cursor: pointer;
  background: var(--carte); color: var(--texte);
  display: inline-flex; align-items: center; justify-content: center;
}
button.primaire, .bouton-fichier.primaire {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
button:disabled { opacity: .45; cursor: not-allowed; }
button.lien {
  border: 0; background: none; color: var(--discret); min-height: var(--cible);
  padding: 0; text-decoration: underline;
}
.actions { display: flex; gap: .75rem; flex-wrap: wrap; margin-top: 1rem; }
.interrupteur { display: flex; flex-direction: row; align-items: center; gap: .5rem; font-weight: 500; }
.interrupteur input { width: 1.15rem; height: 1.15rem; }

/* -------------------------------------------------------------- tableaux */
table { width: 100%; border-collapse: collapse; background: var(--carte); }
th, td { text-align: left; padding: .6rem .7rem; border-bottom: 1px solid var(--trait); }
th { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--discret); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tbody tr.cliquable { cursor: pointer; }
tbody tr.cliquable:hover { background: var(--accent-clair); }
tr.sous-objectif td { background: var(--alerte-clair); }

.total-bloc {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: .9rem .7rem; border-bottom: 2px solid var(--texte);
  font-size: 1.15rem;
}
.total-bloc strong { font-size: 1.7rem; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- verdict */
.verdict { padding: .8rem 1rem; border-radius: var(--rayon); margin-bottom: 1rem; font-weight: 600; }
.verdict.ok { background: var(--accent-clair); color: var(--ok); }
.verdict.ecart { background: var(--alerte-clair); color: var(--alerte); }
.verdict ul { margin: .5rem 0 0; padding-left: 1.2rem; font-weight: 400; }

#relecture { margin-top: 1.5rem; border-top: 1px solid var(--trait); padding-top: 1rem; }
#relecture-photo {
  width: 100%; border: 1px solid var(--trait); border-radius: var(--rayon); background: var(--carte);
}
#camera { width: 100%; max-width: 22rem; border-radius: var(--rayon); margin-top: .75rem; }

#conseil {
  margin-top: 1.5rem; padding: 1rem 1.2rem; background: var(--carte);
  border: 1px solid var(--trait); border-left: 4px solid var(--accent);
  border-radius: var(--rayon);
}
#conseil-texte { font-size: 1.05rem; }

/* --------------------------------------------------------------- divers */
.erreur { color: var(--alerte); font-weight: 600; }
.ok { color: var(--ok); font-weight: 600; }
.aide, .discret { color: var(--discret); font-size: .875rem; }
.aide { max-width: 34rem; }
[hidden] { display: none !important; }

/* =====================================================================
   POS retail : grille de caisse, tuiles, pave numerique, dialogues.
   Ajoute a l'etape « vrai POS ». Tout reste tactile d'abord : aucune cible
   cliquable sous 48 px, et les tuiles montent a 96 px parce qu'on les touche
   vite et sans regarder.
   ===================================================================== */

.carte {
  background: var(--carte);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  padding: 1rem;
}
.carte > h2:first-child { margin-top: 0; }

/* Trois zones : le ticket, la saisie, les tuiles. Le ticket reste a gauche
   parce que c'est ce que le client regarde. */
.caisse-grille {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1.1fr 0.85fr 1.15fr;
  align-items: start;
}
@media (max-width: 1240px) {
  .caisse-grille { grid-template-columns: 1fr 1fr; }
  .caisse-grille > .tuiles-zone { grid-column: 1 / -1; }
}
@media (max-width: 820px) {
  .caisse-grille { grid-template-columns: 1fr; }
}

.ticket-zone .total-bloc { margin-top: .5rem; }
button.gros { min-height: 60px; font-size: 1.1rem; flex: 1; }

/* Une quantite cliquable : c'est la correction la plus fréquente. */
td.modifiable {
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
td.modifiable:hover { background: var(--accent-clair); }

/* ------------------------------------------------------ pave numerique --- */
#pave { margin-top: 1rem; border-top: 1px solid var(--trait); padding-top: .9rem; }

/* ---------------------------------------------------------------------------
 *  MODES DU PAVE
 *  Le mode actif se voit, parce que taper 20 en croyant regler une quantite
 *  alors qu'on applique une remise est une erreur qu'aucun message ne rattrape
 *  apres l'encaissement.
 * ------------------------------------------------------------------------ */
.pave-modes { display: flex; gap: .3rem; margin-bottom: .6rem; }
.mode-pave {
  flex: 1; min-height: 2.4rem; cursor: pointer;
  background: var(--carte); color: var(--discret);
  border: 1px solid var(--trait); border-radius: var(--rayon);
  font-size: 1rem; font-weight: 600;
}
.mode-pave.actif {
  background: var(--accent-clair); color: var(--texte);
  border-color: var(--accent);
}
#remise-motif-bloc { display: block; margin: .5rem 0 .2rem; }

/* La ligne sur laquelle agit le pave. Sans ce reperage, taper une quantite
   reviendrait a l'appliquer a une ligne devinee. */
tr.ligne-visee > td {
  background: var(--accent-clair); color: var(--texte);
}
tr.ligne-visee > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* Une remise s'ECRIT sur la ligne : un prix plus bas sans explication fait
   douter le client et ne se relit pas six mois plus tard. */
.etiquette-remise {
  display: inline-block; padding: 0 .35rem; border-radius: 999px;
  background: var(--alerte); color: #fff; font-size: .75rem; font-weight: 700;
}
.prix-barre { color: var(--discret); text-decoration: line-through; }
.pave-entete {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: .5rem; margin-bottom: .5rem; min-height: 1.5rem;
}
.pave-entete strong { font-size: 1.05rem; }
#pave-ecran {
  display: block; width: 100%;
  padding: .6rem .8rem; margin-bottom: .5rem;
  background: var(--fond); border: 1px solid var(--trait); border-radius: var(--rayon);
  font-size: 2rem; font-variant-numeric: tabular-nums; text-align: right;
  line-height: 1.2;
}
.pave-calcul {
  margin: 0 0 .6rem; padding: .5rem .7rem;
  background: var(--accent-clair); color: var(--accent);
  border-radius: var(--rayon); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* Refus de touche : la MEME ligne que le calcul, en couleur d'alerte. Avaler une
   touche en silence a deja coute une pesee fausse (125 g lu 12 kg). */
.pave-calcul.pave-alerte {
  background: var(--alerte-clair); color: var(--alerte);
}
.pave-touches {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem;
}
.touche {
  min-height: 58px; font-size: 1.35rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.touche:active { background: var(--accent-clair); }
.pave-actions { display: flex; gap: .5rem; margin-top: .5rem; }
.pave-actions button { flex: 1; }

/* -------------------------------------------------------------- tuiles --- */
.grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: .6rem;
}
.tuile {
  min-height: 96px; padding: .7rem;
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  gap: .15rem; text-align: left;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  cursor: pointer; overflow: hidden;
}
.tuile-nom {
  font-weight: 600; font-size: 1rem; line-height: 1.25;
  /* Un libelle long ne doit pas deformer la grille. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.tuile-prix { font-size: 1.2rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.tuile-sous { font-size: .78rem; opacity: .75; }

/* Categorie : la couleur vient de la base, posee en JS apres validation du
   format #rrggbb. Le texte est blanc (avec une ombre) ou noir (sans), choisi
   par contraste cote serveur -- le JS pose alors color et text-shadow. Le blanc
   reste la valeur de repli d'un catalogue garde en cache. */
.tuile-categorie {
  color: #fff; border-color: transparent;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .45);
}
.tuile-categorie .tuile-sous { opacity: .9; }

.tuile-article { background: var(--carte); color: var(--texte); }
.tuile-article:hover { border-color: var(--accent); }
/* Un article au poids se distingue d'un coup d'oeil : il ouvre le pave au lieu
   de tomber directement au ticket. */
.tuile-poids {
  border-left: 5px solid var(--accent);
  background: var(--accent-clair);
}

/* ----------------------------------------------------------- catalogue --- */
.puce {
  display: inline-block; width: 1.1rem; height: 1.1rem;
  border-radius: 4px; border: 1px solid var(--trait);
}
td.actions-cellule { white-space: nowrap; }
td.actions-cellule button { margin-right: .6rem; }
button.lien.danger { color: var(--alerte); }

/* ----------------------------------------------------------- dialogues --- */
dialog {
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--carte); color: var(--texte);
  padding: 0; max-width: 30rem; width: calc(100% - 2rem);
}
dialog::backdrop { background: rgba(0, 0, 0, .45); }
dialog form { padding: 1.25rem; display: grid; gap: .9rem; }
dialog h2 { margin: 0; font-size: 1.2rem; }
dialog fieldset {
  border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: .7rem .9rem; display: grid; gap: .5rem;
}
dialog legend { font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: var(--discret); }
dialog select, dialog input[type=number], dialog input[type=color] {
  min-height: var(--cible); padding: 0 .6rem; font-size: 1.05rem;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--carte); color: var(--texte); width: 100%;
}
dialog input[type=color] { padding: .2rem; cursor: pointer; }
dialog .actions { margin-top: .25rem; }
dialog .actions button { flex: 1; }

/* ------------------------------------------------- roles et enrichissement --- */

/* Le role en vigueur, toujours visible : en demonstration, on doit pouvoir dire
   d'un coup d'oeil sous quelle identite on est en train de cliquer. */
.badge {
  padding: .2rem .6rem; border-radius: 999px;
  font-size: .75rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; border: 1px solid var(--trait);
}
.badge-gerant { background: var(--accent); color: #fff; border-color: var(--accent); }
.badge-caissier { background: var(--accent-clair); color: var(--accent); }
/* Articles crees en caisse en attente du gerant : une alerte, donc la couleur
   de la pastille des factures, et un bouton qui mene a la file. */
.badge-alerte { background: var(--alerte); color: #fff; border-color: var(--alerte); cursor: pointer; }

/* Catalogue vu par un caissier : la colonne des categories est masquee, la
   liste des articles reprend toute la largeur au lieu d'une demi-colonne. */
.colonnes.une-seule { grid-template-columns: 1fr; }
/* File de validation : separee du reste du catalogue, comme une alerte. */
#file-a-valider { border-left: 4px solid var(--alerte); padding-left: .8rem; margin-bottom: 1.2rem; }
#art-historique { margin: .6rem 0; }
#art-historique table { font-size: .85rem; }

/* Code-barres inconnu : la proposition de creation. Bordure accentuee, parce que
   c'est une invitation a agir, pas un message d'erreur. */
#article-inconnu {
  margin-top: .9rem; padding: .9rem 1rem;
  background: var(--accent-clair);
  border: 1px solid var(--accent); border-left-width: 5px;
  border-radius: var(--rayon);
}
#article-inconnu strong { display: block; font-size: 1.05rem; margin-bottom: .3rem; }
#inconnu-champs {
  display: grid; grid-template-columns: auto 1fr; gap: .25rem .8rem;
  margin: .6rem 0;
}
#inconnu-champs dt { font-size: .8rem; color: var(--discret); }
#inconnu-champs dd { margin: 0; font-weight: 600; }
#inconnu-source { margin: .5rem 0 0; font-size: .8rem; }

/* Code releve a l'inventaire, ou d'un article inactif (#60). Meme invitation a
   agir que le code inconnu. Chaque ligne porte son propre fond ET sa couleur de
   texte : un fond pose seul devient illisible en theme sombre. */
#a-traiter-scan {
  margin-top: .9rem; padding: .9rem 1rem;
  background: var(--accent-clair); color: var(--texte);
  border: 1px solid var(--accent); border-left-width: 5px;
  border-radius: var(--rayon);
}
#a-traiter-scan > strong { display: block; font-size: 1.05rem; margin-bottom: .3rem; }
.at-ligne {
  background: var(--carte); color: var(--texte);
  border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: .7rem .9rem; margin: .6rem 0;
}
.at-ligne > p { margin: 0 0 .3rem; }
.at-ligne .actions { margin-top: .5rem; }
.at-zone input[type="search"] { width: 100%; min-height: var(--cible); margin-top: .5rem; }
.at-form { display: grid; gap: .5rem; margin-top: .6rem; max-width: 30rem; }
.at-form label { display: grid; gap: .2rem; }
.at-form input, .at-form select { min-height: var(--cible); }

/* Un champ verrouille doit SE VOIR verrouille : l'EAN vient de la douchette, on
   ne veut pas laisser croire qu'il est modifiable. */
input[readonly] {
  background: var(--fond); color: var(--discret); cursor: not-allowed;
}

/* ------------------------------------------- paiement et cloture --- */

/* L'etape de paiement. Le total domine l'ecran : c'est le dernier moment ou le
   caissier et le client regardent le meme chiffre. */
.paiement { padding: 1.5rem; text-align: center; }
.paiement-libelle { margin: 0; color: var(--discret); text-transform: uppercase;
  font-size: .78rem; letter-spacing: .06em; }
#paiement-total {
  display: block; font-size: 3rem; font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums; margin: .25rem 0 1rem;
}
/* Le montant en especes, si l'arrondi le change : lisible d'un coup d'oeil, sans
   rivaliser avec le total (c'est une precision, pas un second total). */
.paiement-especes { margin: -.5rem 0 1rem; font-size: 1.15rem; font-weight: 600;
  font-variant-numeric: tabular-nums; }
.paiement-choix {
  display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin-bottom: 1rem;
}
.moyen {
  min-height: 72px; font-size: 1.05rem; font-weight: 700;
  background: var(--accent); color: #fff; border-color: var(--accent);
}
.moyen:active { opacity: .85; }
.moyen[data-moyen="autre"] {
  background: var(--carte); color: var(--texte); border-color: var(--trait);
}

/* Le mode d'operation. Volontairement PLUS DISCRET que les moyens de paiement
   (pas de fond plein, hauteur moindre) : le geste principal de cet ecran reste
   l'encaissement, le mode n'est qu'un etat qu'on corrige a l'occasion. Mais il
   est toujours visible, parce qu'il est colle d'une vente a la suivante et
   qu'un oubli de bascule produit une ventilation de TVA fausse. */
.mode-operation { margin-bottom: .5rem; }
.mode {
  min-height: 52px; font-size: .95rem; font-weight: 600;
  background: var(--carte); color: var(--discret); border-color: var(--trait);
}
/* L'etat actif se lit sur aria-pressed, pas sur une classe : l'attribut porte
   deja l'information pour un lecteur d'ecran, une classe la dupliquerait. */
.mode[aria-pressed="true"] {
  background: var(--carte); color: var(--texte);
  border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent);
}
.mode:active { opacity: .85; }
.mode-taux {
  margin: 0 0 1rem; min-height: 1.2em;
  font-variant-numeric: tabular-nums; color: var(--discret);
}

/* L'avertissement fiscal. Visible, pas dissimule en note de bas de page : c'est
   la limite la plus importante a comprendre de tout cet ecran. */
.avertissement {
  max-width: none; padding: .8rem 1rem; border-radius: var(--rayon);
  background: var(--alerte-clair); border-left: 4px solid var(--alerte);
  color: var(--texte);
}
#z-empreinte { word-break: break-all; font-family: ui-monospace, monospace; font-size: .75rem; }
#detail-z { margin-top: 1.5rem; }
#table-clotures td:nth-child(6) { font-family: ui-monospace, monospace; font-size: .8rem; }

/* ------------------------------------- session de caisse et stock --- */

/* Bandeau de session : toujours visible pendant le service. Ce que la caissiere
   doit pouvoir lire sans reflechir, c'est ce qui devrait etre dans le tiroir. */
.bandeau {
  display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap;
  padding: .7rem 1rem; margin-bottom: 1rem;
  background: var(--accent-clair); color: var(--texte);
  border: 1px solid var(--accent); border-left: 5px solid var(--accent);
  border-radius: var(--rayon);
  font-variant-numeric: tabular-nums;
}
.bandeau button { margin-left: auto; min-height: 44px; }
.bandeau strong { font-weight: 700; }

#session-fermee { max-width: 30rem; margin: 2rem auto; text-align: center; }
#session-fermee form { display: grid; gap: 1rem; margin-top: 1rem; }
#session-fermee .gros input { font-size: 2rem; text-align: center; }

#resultat-fermeture { max-width: 44rem; margin: 1.5rem auto; }
#table-rapprochement td:last-child { font-weight: 700; }

/* Une etiquette en ligne dans une barre d'outils, pour le champ de date. */
label.inline {
  display: flex; flex-direction: row; align-items: center; gap: .5rem;
  font-weight: 600; font-size: .9rem;
}
label.inline input {
  min-height: var(--cible); padding: 0 .6rem;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--carte); color: var(--texte); font-size: 1rem; width: auto;
}

#extrait { margin-top: 1.5rem; }
#table-extrait { font-variant-numeric: tabular-nums; }

/* =====================================================================
   IMPRESSION — ticket de caisse et rapport Z
   ===================================================================== */

/* A l'ecran, le bloc d'impression n'existe pas. */
#impression { display: none; }

/* Zone de remboursement : le champ de quantite doit rester petit dans un
   tableau, contrairement aux champs de formulaire en pleine largeur. */
#remb-lignes input {
  width: 6.5rem; min-height: 40px; padding: 0 .4rem;
  text-align: right; font-variant-numeric: tabular-nums;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--carte); color: var(--texte);
}
#remb-lignes { margin-bottom: .5rem; }
.interrupteur span { font-weight: 400; }
#msg-caisse button { margin-left: .75rem; }

@media print {
  /*
     Tout dispraait sauf l'imprime. `body > *` cible les sections de premier
     niveau (entete, main, dialogues) : les masquer suffit, inutile de lutter
     avec chaque descendant.
  */
  body > * { display: none !important; }
  #impression { display: block !important; }

  /* Marges minimales : une imprimante thermique n'en a pas, et sur A4 une marge
     de 6 mm evite que le bord soit rogne. */
  @page { margin: 6mm; }

  html, body {
    background: #fff !important; color: #000 !important;
    margin: 0; padding: 0;
  }

  #impression {
    /* Monospace : c'est ce qui aligne les montants en colonne sur un ticket,
       comme le fait une imprimante de caisse. */
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    color: #000;
  }

  /* --- ticket de caisse : 72 mm, soit un rouleau 80 mm moins ses marges --- */
  #impression.imp-ticket { width: 72mm; font-size: 9pt; line-height: 1.35; }
  /* --- rapport Z : toute la largeur disponible --- */
  #impression.imp-z { width: 100%; font-size: 10pt; line-height: 1.5; }

  .imp-titre {
    text-align: center; font-weight: 700; font-size: 1.15em;
    text-transform: uppercase; letter-spacing: .05em;
  }
  .imp-centre { text-align: center; }
  .imp-section { font-weight: 700; margin-top: .3em; }

  /* Un filet de separation, dessine par une bordure plutot que par une rangee de
     tirets : le rendu est net quelle que soit la largeur du papier. */
  .imp-trait {
    border-top: 1px dashed #000;
    margin: 1.2mm 0; height: 0; overflow: hidden;
  }

  .imp-paire { display: flex; justify-content: space-between; gap: 2mm; }
  .imp-paire > span:last-child { white-space: nowrap; font-variant-numeric: tabular-nums; }
  .imp-detail { font-size: .9em; }
  .imp-total { font-weight: 700; font-size: 1.25em; }

  .imp-empreinte { font-size: .7em; word-break: break-all; }
  .imp-mention {
    font-size: .75em; text-align: center; font-style: italic;
    /* La mention de non-valeur fiscale ne doit jamais se retrouver seule sur une
       deuxieme page, detachee du document qu'elle qualifie. */
    break-inside: avoid; page-break-inside: avoid;
  }
}

/* Bandeau de reveil de la base : visible mais non bloquant. Il apparait en haut
   de la zone applicative pendant les ~15 s de sortie de veille du cluster. */
.bandeau-reveil {
  margin: 0 0 1rem; padding: .7rem 1rem;
  background: var(--alerte-clair); color: var(--texte);
  border: 1px solid var(--alerte); border-left: 5px solid var(--alerte);
  border-radius: var(--rayon); font-weight: 600;
}

/* Resultats de la recherche d'article par libelle. Une ligne = un article, son
   prix et un bouton d'action, assez large pour un doigt sur ecran tactile. */
.liste-resultats {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  max-height: 16rem;
  overflow-y: auto;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--carte);
  color: var(--texte);
}
.liste-resultats li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--trait);
}
.liste-resultats li:last-child { border-bottom: none; }
.liste-resultats li strong { flex: 0 1 auto; }
.liste-resultats li span { flex: 1 1 auto; }
.liste-resultats li button { flex: 0 0 auto; min-height: var(--cible); }

/* Pile et version servies, dans l'en-tete. Discret par defaut, voyant quand le
   front et l'API ne sont pas a la meme version — ce cas-la doit se remarquer. */
.badge-pile {
  font-size: 0.8rem;
  padding: 0.15rem 0.45rem;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  color: var(--discret);
  cursor: help;
}
.badge-pile.desaccord {
  color: var(--alerte);
  border-color: var(--alerte);
}

/* Une ligne d'inventaire dont le compte ne tombe pas sur le stock theorique.
   Teintee, PAS rouge vif : un ecart est le resultat NORMAL d'un inventaire, pas
   une anomalie. Ce qui doit sauter aux yeux, c'est sa valeur en euros, et c'est
   le tri de la table qui s'en charge (les plus gros ecarts en premier). */
tr.ligne-ecart { background: var(--alerte-clair); }
tr.ligne-ecart td { font-weight: 500; }

/* Avertissement de securite des comptes (#58) : meme teinte que la pile
   d'essai, fond ET couleur de texte poses ensemble pour le theme sombre. */
.avertissement {
  padding: .5rem .7rem; max-width: 46rem;
  background: var(--alerte-clair); color: var(--alerte);
  border: 1px solid var(--alerte); border-radius: var(--rayon);
  font-weight: 600;
}
#securite-comptes .colonnes { grid-template-columns: repeat(3, minmax(0, 1fr)); }
