/* ============================================================================
   components.css — briques réutilisables.
   Tout est monochrome : la couleur n'entre que par les classes de statut.
   ========================================================================= */

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

.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--sp-2);
  min-height:var(--tap);
  padding:0 var(--sp-4);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  background:var(--s-2);
  color:var(--fg);
  font-size:var(--t-md);
  font-weight:550;
  letter-spacing:var(--ls-tight);
  white-space:nowrap;
  user-select:none;
  box-shadow:var(--lift-1);
  transition:background var(--d-1) var(--ease-io),
             border-color var(--d-1) var(--ease-io),
             color var(--d-1) var(--ease-io),
             opacity var(--d-1) var(--ease-io),
             transform var(--d-1) var(--ease-io);
}
.btn:hover:not(:disabled){background:var(--s-3);border-color:var(--line-strong)}
.btn:active:not(:disabled){background:var(--s-4);transform:translateY(.5px)}
.btn:disabled{opacity:.34;cursor:not-allowed;box-shadow:none}
.btn svg{width:17px;height:17px;stroke:currentColor;stroke-width:1.6}

/* Primaire : os sur noir. Le contraste maximal sans introduire de teinte —
   la couleur reste disponible pour le seul statut. */
.btn--primary{
  background:var(--fg);
  border-color:var(--fg);
  color:var(--on-accent);
  font-weight:600;
  box-shadow:none;
}
.btn--primary:hover:not(:disabled){background:var(--white);border-color:var(--white)}
.btn--primary:active:not(:disabled){background:var(--fg-2);border-color:var(--fg-2)}

/* Discret : sans fond ni filet, pour les actions de second rang. */
.btn--quiet{
  background:transparent;
  border-color:transparent;
  color:var(--fg-2);
  box-shadow:none;
}
.btn--quiet:hover:not(:disabled){background:var(--s-2);color:var(--fg);border-color:transparent}

.btn--danger:hover:not(:disabled){
  background:var(--err-soft);
  border-color:var(--err-line);
  color:var(--err);
}

.btn--sm{min-height:34px;padding:0 var(--sp-3);font-size:var(--t-sm)}
.btn--sm svg{width:15px;height:15px}
.btn--block{width:100%}

/* Bouton carré à icône seule. */
.btn--icon{
  width:var(--tap);
  min-width:var(--tap);
  padding:0;
}
.btn--icon.btn--sm{width:34px;min-width:34px}

/* Bouton rond translucide, posé par-dessus la vidéo de la caméra. */
.btn--round{
  width:46px;min-width:46px;height:46px;
  padding:0;
  border-radius:var(--r-pill);
  background:var(--glass);
  border-color:var(--glass-line);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
  backdrop-filter:blur(14px) saturate(1.3);
}
.btn--round:hover:not(:disabled){background:var(--glass-hover)}
.btn--round svg{width:20px;height:20px}
/* Torche allumée — remplace l'ancien basculement d'emoji 🔦/💡. */
.btn--round.is-on{
  background:var(--fg);
  border-color:var(--fg);
  color:var(--on-accent);
}

/* ----------------------------------------------------------------- Champs -- */

.field{
  width:100%;
  min-height:var(--tap);
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  background:var(--s-2);
  color:var(--fg);
  box-shadow:var(--inset-well);
  transition:border-color var(--d-1) var(--ease-io),
             background var(--d-1) var(--ease-io);
}
.field::placeholder{color:var(--fg-4)}
.field:hover:not(:disabled){border-color:var(--line-strong)}
.field:focus{border-color:var(--fg-3);background:var(--s-1)}
.field:focus-visible{box-shadow:var(--inset-well),var(--focus)}
.field:disabled{opacity:.4;cursor:not-allowed}

/* Le champ douchette : c'est là qu'atterrissent les scans, il doit être gros. */
.field--code{
  font-family:var(--font-mono);
  font-size:var(--t-input);
  letter-spacing:.02em;
  padding:var(--sp-4);
}

/* Select : flèche dessinée, la flèche native est illisible et hors système. */
.select{
  -webkit-appearance:none;
  appearance:none;
  width:100%;
  min-height:var(--tap);
  padding:0 var(--sp-8) 0 var(--sp-4);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  background-color:var(--s-2);
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23a9a8a4' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5 8 10.5 12 6.5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right var(--sp-3) center;
  background-size:16px;
  color:var(--fg);
  font-size:var(--t-md);
  font-weight:500;
  cursor:pointer;
  box-shadow:var(--lift-1);
  transition:border-color var(--d-1) var(--ease-io),background-color var(--d-1) var(--ease-io);
}
.select:hover:not(:disabled){background-color:var(--s-3);border-color:var(--line-strong)}
.select:disabled{opacity:.34;cursor:not-allowed}
.select option{background:var(--s-2);color:var(--fg)}

/* Variante pilule translucide, posée sur la vidéo. */
.select--glass{
  border-radius:var(--r-pill);
  background-color:var(--glass);
  border-color:var(--glass-line);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
  backdrop-filter:blur(14px) saturate(1.3);
  font-size:var(--t-sm);
}
.select--glass:hover:not(:disabled){background-color:var(--glass-hover)}

/* ------------------------------------------------------------- Marqueurs -- */

/* Pastille de statut : le point coloré des lignes d'historique. */
.dot{
  width:7px;height:7px;
  flex:none;
  border-radius:var(--r-pill);
  background:var(--fg-4);
}
.dot--ok{background:var(--ok)}
.dot--wrong{background:var(--wrong)}
.dot--err{background:var(--err)}

/* Point « prêt » qui respire doucement — l'appli attend un scan. */
.dot--live{
  background:var(--ok);
  animation:pulse-dot 2.4s var(--ease-io) infinite;
}
@keyframes pulse-dot{
  0%,100%{opacity:1;transform:scale(1)}
  50%{opacity:.35;transform:scale(.82)}
}

/* Badge numéro de tournée. */
.badge{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-width:26px;
  height:22px;
  padding:0 var(--sp-2);
  border:1px solid var(--line-strong);
  border-radius:var(--r-sm);
  background:var(--s-2);
  font-family:var(--font-mono);
  font-size:var(--t-xs);
  font-weight:600;
  color:var(--fg-2);
  /* Filet de sécurité : la troncature réelle se fait dans history.js, qui pose
     aussi le title avec la valeur complète. */
  max-width:11ch;
  overflow:hidden;
  white-space:nowrap;
}
.badge--ok{background:var(--ok-soft);border-color:var(--ok-line);color:var(--ok)}
.badge--wrong{background:var(--wrong-soft);border-color:var(--wrong-line);color:var(--wrong)}
.badge--err{background:var(--err-soft);border-color:var(--err-line);color:var(--err)}

/* Chip de filtre. */
.chip{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  height:32px;
  padding:0 var(--sp-3);
  border:1px solid var(--line);
  border-radius:var(--r-pill);
  background:var(--s-2);
  color:var(--fg-2);
  font-size:var(--t-sm);
  font-weight:500;
  white-space:nowrap;
  transition:background var(--d-1) var(--ease-io),
             color var(--d-1) var(--ease-io),
             border-color var(--d-1) var(--ease-io);
}
.chip:hover{background:var(--s-3);color:var(--fg)}
.chip[aria-pressed="true"]{
  background:var(--fg);
  border-color:var(--fg);
  color:var(--on-accent);
  font-weight:600;
}
.chip[aria-pressed="true"] .dot{background:var(--on-accent)}

/* ------------------------------------------------------------- Bandeaux --- */
/* Remplace les alert() du navigateur. Les textes sont repris mot pour mot ;
   seule la présentation change. */

.notice{
  display:flex;
  align-items:flex-start;
  gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--err-line);
  border-radius:var(--r-md);
  background:var(--err-soft);
  color:var(--fg);
  font-size:var(--t-sm);
  line-height:1.5;
}
.notice svg{width:17px;height:17px;margin-top:1px;stroke:var(--err);stroke-width:1.6}
.notice__body{flex:1;min-width:0;white-space:pre-line}
.notice__close{
  flex:none;margin:-2px -4px 0 0;
  width:26px;height:26px;
  display:grid;place-items:center;
  border-radius:var(--r-sm);
  color:var(--fg-3);
}
.notice__close:hover{background:rgba(255,255,255,.06);color:var(--fg)}
.notice__close svg{width:14px;height:14px;margin:0;stroke:currentColor}

/* Pile de notifications, en bas d'écran. */
.toaster{
  position:fixed;
  left:50%;
  bottom:calc(var(--sp-5) + env(safe-area-inset-bottom));
  transform:translateX(-50%);
  z-index:var(--z-toast);
  display:flex;
  flex-direction:column;
  gap:var(--sp-2);
  width:min(440px,calc(100vw - var(--sp-8)));
  pointer-events:none;
}
.toast{
  pointer-events:auto;
  display:flex;
  align-items:center;
  gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line-strong);
  border-radius:var(--r-md);
  background:var(--s-2);
  box-shadow:var(--lift-3);
  font-size:var(--t-sm);
  animation:toast-in var(--d-3) var(--ease) both;
}
.toast svg{width:16px;height:16px;stroke:var(--fg-2);stroke-width:1.6}
.toast--ok svg{stroke:var(--ok)}
.toast--err{border-color:var(--err-line)}
.toast--err svg{stroke:var(--err)}
.toast.is-leaving{animation:toast-out var(--d-2) var(--ease-io) both}
@keyframes toast-in{
  from{opacity:0;transform:translateY(10px) scale(.97)}
  to{opacity:1;transform:none}
}
@keyframes toast-out{
  from{opacity:1;transform:none}
  to{opacity:0;transform:translateY(6px) scale(.98)}
}

/* --------------------------------------------------------------- Feuille -- */
/* Panneau glissant : latéral sur desktop, feuille par le bas sur téléphone. */

.sheet{
  position:fixed;
  inset:0;
  z-index:var(--z-sheet);
  display:grid;
}
.sheet__scrim{
  position:absolute;
  inset:0;
  background:var(--scrim);
  -webkit-backdrop-filter:blur(2px);
  backdrop-filter:blur(2px);
  animation:fade-in var(--d-2) var(--ease-io) both;
}
.sheet__panel{
  position:relative;
  display:flex;
  flex-direction:column;
  min-height:0;
  background:var(--s-1);
  border:1px solid var(--line);
  box-shadow:var(--lift-3);
  animation:sheet-up var(--d-3) var(--ease) both;
}
.sheet__head{
  display:flex;
  align-items:center;
  gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5);
  border-bottom:1px solid var(--line);
}
.sheet__title{
  flex:1;min-width:0;
  font-size:var(--t-lg);
  font-weight:600;
  letter-spacing:var(--ls-tight);
}
.sheet__tools{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-5);
  border-bottom:1px solid var(--line);
}
.sheet__body{
  flex:1;
  min-height:0;
  overflow-y:auto;
  overscroll-behavior:contain;
}
.sheet__foot{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  padding:var(--sp-3) var(--sp-5) calc(var(--sp-3) + env(safe-area-inset-bottom));
  border-top:1px solid var(--line);
}

@media (max-width:719px){
  .sheet{align-items:end}
  .sheet__panel{
    max-height:88vh;
    border-radius:var(--r-xl) var(--r-xl) 0 0;
    border-bottom:0;
  }
  /* Poignée de préhension — repère tactile en haut de la feuille. */
  .sheet__panel::before{
    content:"";
    position:absolute;
    top:var(--sp-2);left:50%;
    transform:translateX(-50%);
    width:38px;height:4px;
    border-radius:var(--r-pill);
    background:var(--line-strong);
  }
  .sheet__head{padding-top:var(--sp-5)}
}
@media (min-width:720px){
  .sheet{justify-items:end}
  .sheet__panel{
    width:min(560px,100vw);
    height:100%;
    border-radius:0;
    border-right:0;
    animation-name:sheet-in;
  }
}

@keyframes fade-in{from{opacity:0}to{opacity:1}}
@keyframes sheet-up{
  from{opacity:0;transform:translateY(24px)}
  to{opacity:1;transform:none}
}
@keyframes sheet-in{
  from{opacity:0;transform:translateX(24px)}
  to{opacity:1;transform:none}
}

/* ------------------------------------------------------------ État vide --- */

.empty{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--sp-3);
  padding:var(--sp-10) var(--sp-5);
  text-align:center;
  color:var(--fg-3);
  font-size:var(--t-sm);
}
.empty svg{width:26px;height:26px;stroke:var(--fg-4);stroke-width:1.4}
