/* =====================================================================
   VinoCash - Styles communs a toutes les pages (header, sidebar, modale).
   Inclus via <link rel="stylesheet" href="includes/app.css"> dans le
   <head>, AVANT le <style> propre a chaque page.

   Regle de bonne conduite : ce fichier ne doit contenir que ce qui est
   strictement identique sur toutes les pages (variables, structure du
   header/sidebar, squelette des modales). Toute personnalisation propre
   a une page (tailles de modale, marges, grilles specifiques, etc.) doit
   rester dans le <style> de cette page, APRES le <link> vers ce fichier,
   afin de pouvoir surcharger une propriete au besoin.
   ===================================================================== */

/* --- Couleur de l'interface -------------------------------------------
   TOUTE la couleur de l'application descend de --accent : boutons
   d'action, interrupteurs, fonds teintes, et jusqu'aux six tons de la
   barre laterale. Ces six-la etaient auparavant des hexadecimaux ecrits
   a la main, sans aucun rapport avec l'accent : on avait une barre
   bleue posee au-dessus de boutons bruns.

   Chaque poste peut changer cette couleur (Reglages > General >
   Apparence). Le script du <head> pose alors --accent en style inline
   sur <html> ; les color-mix() ci-dessous suivent d'eux-memes, sans
   qu'aucune autre regle n'ait a etre touchee.

   Les neutres, eux, restent des gris - a peine refroidis pour ne plus
   tirer sur le beige. Des gris qui se teinteraient de la couleur
   choisie rendraient l'ecran fatigant des que cette couleur est vive. */
:root{
  --accent:#2e5798;

  --surface-0:#f3f4f6;
  --surface-1:#ffffff;
  --surface-2:#f8f9fb;
  --border:#e3e5ea;
  --radius:8px;
  --text:#21242a;
  --text-secondary:#565b63;
  --text-muted:#8b9099;

  /* Aplat tres pale de la couleur du theme, et la couleur elle-meme :
     survols de listes, pastilles, libelles mis en avant. */
  --bg-accent:color-mix(in srgb, var(--accent) 12%, #fff);
  --text-accent:var(--accent);

  --bg-success:#e4efe4;
  --text-success:#2f6b3a;
  --bg-danger:#f6e4e2;
  --text-danger:#a3372a;
  --bg-warning:#faf0d8;
  --text-warning:#8a6a10;

  /* Barre laterale, derivee de l'accent :
       fond   la couleur assombrie, pour rester en retrait du contenu
       survol la couleur elle-meme
       actif  la couleur eclaircie, un cran au-dessus du survol
     Les deux tons de texte sont cette meme couleur delavee de blanc. */
  --sidebar-bg:color-mix(in srgb, var(--accent) 84%, #000);
  --sidebar-survol:var(--accent);
  --sidebar-actif:color-mix(in srgb, var(--accent) 86%, #fff);
  --sidebar-texte:color-mix(in srgb, var(--accent) 20%, #fff);
  --sidebar-texte-discret:color-mix(in srgb, var(--accent) 38%, #fff);

  --sidebar-w:264px;
  --body-pad:14px;
}

/* Repli pour un navigateur sans color-mix (anterieur a 2023). La double
   declaration habituelle ne sert a rien ici : une variable accepte
   n'importe quel texte a l'analyse, et l'erreur n'apparait qu'au moment
   ou var() est lu - trop tard pour retomber sur la ligne precedente. Le
   fond de barre laterale deviendrait alors transparent, pas brun.
   Les valeurs ci-dessous sont les color-mix() calculees pour le bleu par
   defaut : sur ces navigateurs-la, le theme du poste n'a plus d'effet,
   mais l'application reste presentable. */
@supports not (color: color-mix(in srgb, #000 50%, #fff)){
  :root{
    --bg-accent:#e6ecf7;
    --text-accent:#2e5798;
    --sidebar-bg:#274a81;
    --sidebar-survol:#2e5798;
    --sidebar-actif:#4369a1;
    --sidebar-texte:#d5ddea;
    --sidebar-texte-discret:#afbfd8;
  }
}

/* --- Reset de base --- */
*{box-sizing:border-box;}
html, body{height:100%;}
body{
  margin:0; background:var(--surface-0); color:var(--text);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:14px; padding:var(--body-pad);
}
input,button,select{font-family:inherit; font-size:13px;}
button, a.primary, a.ghost, a.danger{
  border:0.5px solid var(--border); border-radius:var(--radius); background:var(--surface-1);
  color:var(--text); cursor:pointer; padding:8px 12px;
}
button:focus-visible{outline:2px solid var(--accent); outline-offset:1px;}
/* a.primary/a.ghost/a.danger : memes styles que les boutons, pour les
   liens de navigation entre pages (ex: "Nouvelle commande" -> page
   dediee, pas une modale) traites visuellement comme des boutons. */
a.primary, a.ghost, a.danger{text-decoration:none; display:inline-block; box-sizing:border-box;}
button.danger, a.danger{color:var(--text-danger);}
button.primary, a.primary{background:var(--accent); color:#fff; border-color:var(--accent); font-weight:500;}
button.ghost, a.ghost{background:transparent; border-color:transparent;}
h1,h2,h3,p{margin:0;}
.sr-only{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap;}

/* --- En-tete --- */
#header{
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
  padding:10px 14px; background:var(--surface-1); border-radius:var(--radius);
  margin-bottom:14px; gap:8px;
}
#header .left{display:flex; align-items:center; gap:14px; overflow:hidden; min-width:0;}
#header .center{display:flex; align-items:center; justify-content:center; gap:14px; min-width:0;}
#header .right{display:flex; align-items:center; justify-content:flex-end; gap:14px; min-width:0;}
#conn-badge{font-size:12px; padding:4px 10px; border-radius:var(--radius); background:var(--bg-success); color:var(--text-success); font-weight:500; white-space:nowrap;}
#conn-badge.offline{background:var(--bg-danger); color:var(--text-danger);}
#site-page-label{font-size:14px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
#site-page-label strong{font-weight:600;}
/* inline-flex plutot qu'un simple span : l'icone etait calee sur la
   ligne de base du texte, donc legerement plus basse que son centre. */
#vendor-label{display:inline-flex; align-items:center; gap:6px; font-size:13px; color:var(--text-secondary); white-space:nowrap; font-weight:700; cursor:pointer; border-radius:var(--radius); padding:3px 6px; margin:-3px -6px;}
#vendor-label:hover{background:var(--surface-2); color:var(--text);}
#vendor-label i{font-size:16px; line-height:1;}
#clock{font-size:13px; color:var(--text-muted); white-space:nowrap; font-weight:700;}

/* Bandeau d'avertissement apres un changement du mot de passe
   d'ouverture. Fixe et non defilant : un texte qui bouge attire l'oeil
   une fois puis devient illisible s'il tourne toute la journee. */
#bandeau-mot-de-passe{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  background:var(--bg-danger); color:var(--text-danger);
  border:0.5px solid rgba(163,55,42,0.25); border-radius:var(--radius);
  padding:9px 14px; margin-bottom:12px; font-size:13px; font-weight:500;
}
#bandeau-mot-de-passe i{margin-right:7px;}
#bandeau-mot-de-passe button{
  flex-shrink:0; font-size:12px; padding:6px 12px;
  background:var(--text-danger); color:#fff; border-color:var(--text-danger);
  font-weight:500;
}
#bandeau-mot-de-passe button:hover{filter:brightness(1.1);}

/* Poste non rattache a un site : etat anormal, present sur toutes les
   pages tant qu'un administrateur n'a pas enrole la machine. Teinte
   d'avertissement plutot que de danger - rien n'est casse, il manque
   une configuration - et bouton d'action a la couleur d'accent, comme
   tous les boutons d'action de l'application. */
#bandeau-poste{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  background:var(--bg-warning); color:var(--text-warning);
  border:0.5px solid rgba(138,106,16,0.25); border-radius:var(--radius);
  padding:9px 14px; margin-bottom:12px; font-size:13px; font-weight:500;
}
#bandeau-poste i{margin-right:7px;}
#bandeau-poste button{
  flex-shrink:0; font-size:12px; padding:6px 12px;
  background:var(--accent); color:#fff; border-color:var(--accent);
  font-weight:500;
}
#bandeau-poste button:hover{filter:brightness(1.1);}

/* Fermeture de session et changement de code : petits boutons
   utilitaires, volontairement discrets pour ne pas concurrencer
   visuellement les boutons d'action. */
#logout-btn{
  display:flex; align-items:center; justify-content:center;
  width:26px; height:26px; padding:0; flex:0 0 26px;
  background:transparent; border:0.5px solid transparent; border-radius:var(--radius);
  color:var(--text-muted); cursor:pointer; font-size:15px; line-height:1;
}
#logout-btn:hover{background:var(--surface-2); color:var(--text); border-color:var(--border);}

/* Bouton "Changer le code PIN" : libelle en clair plutot qu'une icone
   seule, dont la signification n'etait devinable qu'en survolant.
   Aligne sur le badge "En ligne" - meme taille de police, meme padding,
   meme rayon - pour que les deux extremites de l'en-tete se repondent. */
#pin-change-btn{
  display:inline-flex; align-items:center; white-space:nowrap;
  font-size:12px; font-weight:500; border-radius:var(--radius);
  /* Meme couleur que le bouton Encaisser : tous les boutons d'action de
     l'application partagent l'accent, sans code couleur secondaire. */
  background:var(--accent); border:1px solid var(--accent); color:#fff;
  cursor:pointer; font-family:inherit;
  /* Meme hauteur que le badge "En ligne" : meme taille de police et
     meme line-height "normal", mais 1 px de bordure en haut et en bas
     que le badge n'a pas - d'ou 3 px de padding vertical au lieu de 4.
     Mesure : les deux tombent a 24 px. */
  line-height:normal; padding:3px 10px;
}
#pin-change-btn:hover{filter:brightness(1.08);}

/* Le bouton se colle au nom du vendeur plutot que de subir
   l'espacement de 14px de la zone centrale. */
#header .center{gap:8px;}

/* --- Structure generale ---
   L'application tient dans un cadre de la hauteur exacte de la fenetre :
   le document lui-meme ne defile jamais. Seul le contenu de #main defile,
   ce qui laisse la barre laterale et l'en-tete a l'ecran quelle que soit
   la longueur de la page - sur une caisse, le menu et le nom du vendeur
   doivent rester accessibles sans avoir a remonter.

   Une page qui a besoin d'un decoupage plus fin (deux colonnes defilant
   separement, liste a en-tete fige, etc.) surcharge #main - et au besoin
   #content-area - dans son propre <style>, charge apres ce fichier. */
html, body{overflow:hidden;}
#app-shell{display:flex; align-items:stretch; height:calc(100vh - 2*var(--body-pad));}
#content-area{flex:1; min-width:0; display:flex; flex-direction:column; height:100%; overflow:hidden;}
/* L'en-tete et les bandeaux d'alerte font partie du cadre fixe : ils ne
   defilent pas et ne doivent pas non plus se laisser ecraser par un
   contenu trop long (comportement par defaut d'un enfant de flex). */
#header, #bandeau-poste, #bandeau-mot-de-passe{flex-shrink:0;}
#main{flex:1; min-height:0; overflow-y:auto;}

/* --- Barre laterale --- */
#sidebar{
  width:250px; flex-shrink:0; background:var(--sidebar-bg); color:var(--sidebar-texte);
  display:flex; flex-direction:column; border-radius:var(--radius);
  margin-right:14px; padding:14px 10px; transition:width 0.15s ease;
  overflow-y:auto;
}
#sidebar.collapsed{width:64px;}
#sidebar .brand{display:flex; align-items:center; gap:10px; padding:8px 8px 20px; color:#fff; font-weight:600; font-size:20px; white-space:nowrap; overflow:hidden; cursor:pointer;}
#sidebar .brand i{font-size:26px;}
#sidebar nav{flex:1; display:flex; flex-direction:column; gap:2px;}

.nav-item{
  display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:6px;
  color:var(--sidebar-texte); cursor:pointer; font-size:13px; white-space:nowrap; overflow:hidden;
  border:none; background:transparent; width:100%; text-align:left;
  text-decoration:none; box-sizing:border-box;
}
.nav-item i{font-size:17px; flex-shrink:0; width:18px; text-align:center;}
.nav-item:hover{background:var(--sidebar-survol); color:#fff;}
.nav-item.active{background:var(--sidebar-actif); color:#fff; font-weight:500;}
.nav-item.disabled{opacity:0.5; cursor:default;}
.nav-item.disabled:hover{background:transparent; color:var(--sidebar-texte);}

/* Sous-menu deroulant (ex: Réglages > Utilisateurs) */
.nav-group{display:flex; flex-direction:column;}
.nav-group-toggle{justify-content:flex-start;}
.submenu-chevron{margin-left:auto; font-size:14px !important; transition:transform 0.15s;}
.nav-group.open .submenu-chevron{transform:rotate(180deg);}
.submenu{display:none; flex-direction:column; gap:2px; margin:2px 0 2px 20px; padding-left:8px; border-left:1px solid rgba(255,255,255,0.15);}
.submenu.open{display:flex;}
.submenu-item{font-size:12.5px; padding:7px 10px;}
#sidebar.collapsed .submenu{display:none !important;}
#sidebar.collapsed .label, #sidebar.collapsed .brand-text{display:none;}

#sidebar-collapse-btn{
  display:flex; align-items:center; gap:10px; padding:9px 10px; margin-top:auto;
  border:none; background:transparent; color:var(--sidebar-texte-discret); cursor:pointer; font-size:12px;
  /* Filet en blanc translucide plutot qu'en bleu fixe : il se pose sur
     le fond quelle que soit la couleur du theme, comme celui du
     sous-menu juste au-dessus. */
  border-top:1px solid rgba(255,255,255,0.18); padding-top:14px; white-space:nowrap; overflow:hidden;
}
#sidebar-collapse-btn:hover{color:#fff;}

#sidebar-version{
  text-align:center; font-size:10.5px; font-weight:700; color:var(--sidebar-texte-discret); opacity:0.7;
  padding:6px 10px 2px; white-space:nowrap; overflow:hidden; cursor:pointer;
}
#sidebar-version:hover{opacity:1; text-decoration:underline;}
#sidebar.collapsed #sidebar-version{display:none;}

/* --- Modale changelog (historique des commits, cf. sidebar-version) --- */
#overlay-changelog .modal{max-width:560px;}
#changelog-list{max-height:60vh; overflow-y:auto; margin-top:4px;}
.changelog-entry{
  display:flex; gap:10px; align-items:baseline; padding:6px 0; font-size:12.5px;
  border-bottom:0.5px solid var(--border);
}
.changelog-entry:last-child{border-bottom:none;}
.changelog-version{
  flex-shrink:0; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color:var(--text-secondary); font-weight:500;
}
.changelog-hash{
  flex-shrink:0; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color:var(--text-muted); background:var(--surface-2); border-radius:4px; padding:1px 6px;
}
.changelog-message{color:var(--text);}

/* Animation "pour le fun" au clic sur le logo */
@keyframes brand-icon-spin{ from{transform:rotate(0deg);} to{transform:rotate(360deg);} }
.brand-icon-spin{ animation: brand-icon-spin 0.6s ease; display:inline-block; }

/* --- Squelette des modales ---
     Pas de fermeture au clic exterieur : uniquement via un bouton explicite.
     max-width/padding/marges specifiques restent dans le <style> de
     chaque page si elles different du defaut ci-dessous. --- */
/* Le voile part du bord droit de la barre laterale et couvre tout le
   reste de l'ecran. `--sidebar-w` vaut toujours la largeur de la barre
   PLUS sa marge droite (264px, 78px repliee - voir toggleSidebar dans
   app.js) : le voile suit donc le repli sans regle supplementaire.

   Coins arrondis comme la barre laterale et les cartes. */
.overlay{
  position:fixed; top:0; right:0; bottom:0; left:var(--sidebar-w);
  border-radius:var(--radius);
  background:rgba(25,28,34,0.45); display:none;
  align-items:center; justify-content:center; z-index:50; padding:16px; transition:left 0.15s ease;
}
.overlay.open{display:flex;}
.modal{background:var(--surface-1); border-radius:12px; max-width:420px; width:100%; padding:18px; max-height:85vh; overflow-y:auto;}
.modal h3{font-size:15px; margin-bottom:12px;}
.modal-error{display:none; color:var(--text-danger); font-size:12px; margin-top:10px;}
.modal-actions{display:flex; gap:8px; margin-top:16px; justify-content:flex-end;}

/* Titre de modale + croix de fermeture sur la meme ligne (meme action que
   le bouton Annuler) - a utiliser a la place de <h3> seul quand une modale
   a besoin d'une croix explicite. */
/* --- Saisie du code d'identification du vendeur ---
   Au-dessus de TOUTES les autres fenetres (les plus hautes de
   l'application montent a 80). Le pave numerique s'ouvre desormais
   PAR-DESSUS une fenetre deja ouverte - la demande d'autorisation
   administrateur arrive alors que celle du remboursement est encore la -
   et a z-index egal, c'est l'element le plus bas dans la page qui gagne.
   Le pave vit dans header.php, donc tout en haut : il passait dessous,
   et l'ecran semblait ne rien demander. */
#overlay-vendor-pin{z-index:90;}
/* Modale volontairement etroite : elle ne contient qu'un pave numerique,
   une largeur de modale standard donnait un bloc disproportionne. */
#overlay-vendor-pin .modal{max-width:284px; padding:16px;}
#overlay-vendor-pin .modal h3{font-size:14px; margin-bottom:2px; text-align:center;}
#overlay-vendor-pin .modal-actions{margin-top:12px; justify-content:center;}
#overlay-vendor-pin .modal-actions button{font-size:12px;}

/* Ligne d'etape, affichee uniquement lors d'un changement de code
   ("Code actuel", "Nouveau code", "Confirmer le nouveau code"). */
#pin-sous-titre{
  display:none; text-align:center; font-size:12px;
  color:var(--text-secondary); margin-top:4px;
}

#pin-dots{
  display:flex; justify-content:center; gap:10px;
  margin:12px 0 10px; min-height:12px;
}
.pin-dot{
  width:10px; height:10px; border-radius:50%;
  border:1.5px solid var(--border); background:transparent;
}
.pin-dot.rempli{background:var(--accent); border-color:var(--accent);}

/* Choix de l'administrateur qui autorise une action reservee. Empile
   plutot qu'en grille comme le pave : ce sont des noms, de longueur
   variable, et ils se lisent de haut en bas. */
#pin-choix{display:flex; flex-direction:column; gap:6px;}
#pin-choix button{
  width:100%; text-align:left; padding:10px 12px; font-size:13px;
  background:var(--surface-2); border:0.5px solid var(--border);
  border-radius:var(--radius); cursor:pointer; color:var(--text);
}
#pin-choix button:hover{background:var(--bg-accent);}
#pin-choix .vide{font-size:12px; color:var(--text-muted); text-align:center; padding:8px 0;}

#pin-pad{
  display:grid; grid-template-columns:repeat(3, 1fr); gap:6px;
}
#pin-pad button{
  height:42px; font-size:16px; font-weight:500;
  background:var(--surface-2); border:0.5px solid var(--border);
  border-radius:var(--radius); cursor:pointer; color:var(--text);
}
#pin-pad button:hover{background:var(--bg-accent);}
#pin-pad button.pin-secondaire{color:var(--text-secondary); font-size:15px;}
#pin-pad button.primary{background:var(--accent); color:#fff; border-color:var(--accent); font-size:15px;}

.modal-header-row{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:12px;}
.modal-header-row h3{margin-bottom:0;}
.modal-close{
  width:26px; height:26px; border-radius:6px; flex-shrink:0;
  border:0.5px solid var(--border); background:var(--surface-1); color:var(--text-muted);
  display:inline-flex; align-items:center; justify-content:center; cursor:pointer; padding:0; font-size:14px;
}
.modal-close:hover{background:var(--surface-2); color:var(--text);}

/* --- Interrupteur actif/inactif (reutilisable sur toute page) ---
     Taille unique dans toute l'application : celle qui etait jusqu'ici
     propre a l'ecran Articles (22x13). L'ancienne mesure commune, 32x18,
     rendait l'interrupteur plus voyant que la donnee qu'il commande.
     La classe .small qui portait cette variante n'existe plus. */
.switch{position:relative; display:inline-block; width:22px; height:13px; flex-shrink:0;}
.switch input{opacity:0; width:0; height:0;}
.switch .slider{
  position:absolute; cursor:pointer; inset:0; background:var(--border);
  border-radius:13px; transition:background 0.15s ease;
}
.switch .slider::before{
  content:""; position:absolute; height:9px; width:9px; left:2px; top:2px;
  background:#fff; border-radius:50%; transition:transform 0.15s ease;
  box-shadow:0 1px 2px rgba(0,0,0,0.25);
}
.switch input:checked + .slider{background:var(--accent);}
.switch input:checked + .slider::before{transform:translateX(9px);}
.switch input:focus-visible + .slider{outline:2px solid var(--accent); outline-offset:2px;}

/* --- Barre de filtres des ecrans de consultation ---
     Partagee par Tickets, Paiements, Cheques cadeaux, Avoirs, Devis et
     Mouvements de stock : ce sont des vues du meme sujet, elles doivent se
     ressembler.

     Definie ici et non dans chaque page : les cinq copies etaient
     identiques, et la premiere retouche demandee aurait du etre faite cinq
     fois. Ne restent reglees page par page que la largeur minimale des
     champs (les libelles n'ont pas la meme longueur partout) et, sur
     Mouvements de stock, la marge basse.

     Sans fond : la barre se pose sur le fond de page plutot que de former
     un bloc clair de plus au-dessus des cartes de totaux et de la liste,
     qui en portent deja un. Le filet suffit a delimiter la zone. */
#filtres{
  display:flex; flex-wrap:wrap; gap:10px; align-items:flex-end;
  border:0.5px solid var(--border); border-radius:var(--radius);
  padding:12px; margin-bottom:14px;
}
.filtre{display:flex; flex-direction:column; gap:4px;}
/* Libelles en gras : a 11 pixels et en capitales, la graisse est ce qui
   les rend lisibles d'un coup d'oeil au-dessus de leur champ. */
.filtre label{
  font-size:11px; font-weight:600; color:var(--text-secondary);
  text-transform:uppercase; letter-spacing:0.02em;
}
#filtres-raccourcis{display:flex; gap:6px; margin-left:auto;}
#filtres-raccourcis button{font-size:12px; padding:6px 10px;}

/* --- Modale de selection du vendeur (partagee : accueil.php + caisse.php,
     HTML mutualise dans includes/vendor-modal.php) --- */
.vendor-grid{display:grid; grid-template-columns:repeat(2,1fr); gap:8px;}
.vendor-grid button{padding:14px; font-size:14px; font-weight:500;}
