/* 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); }

/* ---------------------------------------------------------------- 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; }
.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; }
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; }
.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;
}
.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, pour rester lisible quelle
   que soit la teinte choisie par le gerant. */
.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); }

/* 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; }

/* 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;
}
.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;
}
