/*
 * Feuille de style unique. Reprend les contraintes qui rendaient l'ancienne app
 * utilisable en service — base 20 px, cibles tactiles larges, pas de zoom — sans
 * son CDN Tailwind (une dependance reseau sur le WiFi d'un restaurant est un
 * point de panne de plus, pour du CSS qui tient en 150 lignes).
 */

:root {
  --bg: #f4f5f7;
  --card: #ffffff;
  --ink: #14181f;
  --ink-soft: #5b6472;
  --line: #dfe3e9;
  --accent: #1668e3;
  --ok: #1a7f45;
  --danger: #c02626;
  --warn: #a8620a;
  --radius: 12px;
  --tap: 56px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14181f;
    --card: #1e232c;
    --ink: #f2f4f7;
    --ink-soft: #9aa4b2;
    --line: #303743;
  }
}

* { box-sizing: border-box; }

/* L'attribut `hidden` DOIT gagner.
   La feuille de l'agent utilisateur pose `[hidden] { display: none }` avec la
   meme specificite qu'une classe : n'importe quelle regle de ce fichier posant
   un `display` -- `.screen { display: flex }` -- passe apres et l'annule en
   silence. Les trois ecrans se sont ainsi affiches empiles pendant que le code
   croyait n'en montrer qu'un, sans qu'aucun test le voie : le texte lu par les
   assertions etait bien la, simplement plus bas que le viewport. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font: 20px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
}

/* La page est une application, pas un document : elle tient dans la hauteur du
   telephone, et c'est la liste des plats qui defile A L'INTERIEUR.
   Ce que ca remplace : un pied de page `sticky`, dont tenait la position du
   bouton « Envoyer en caisse ». Un `sticky` est un pari sur le navigateur --
   Chromium garde bien le pied a l'ecran (mesure), d'autres le calent sur le
   viewport de MISE EN PAGE et il finit sous la barre d'outils. Sur une addition
   longue le bouton se retrouvait alors entierement hors de l'ecran, et sans
   remede : il etait deja au bas du document, aucun scroll n'allait plus loin.
   La mise en page ci-dessous ne fait plus ce pari -- le pied n'est pas dans la
   zone qui defile, donc rien ne peut l'en chasser.
   Les trois hauteurs sont un escalier de repli, de la plus fine a la plus
   grossiere : `dvh` (barres du navigateur deduites), `-webkit-fill-available`
   (iOS avant 15.4, meme resultat), `vh` (tout le reste, ou les deux coincident).
   Pas de `overflow: hidden` ici a dessein : si un cas extreme deborde quand
   meme, la page redevient un document qui defile plutot qu'un bouton
   inatteignable. */
html { height: 100%; }
body {
  height: 100vh;
  height: -webkit-fill-available;
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

.bar {
  /* Ne se laisse pas comprimer : son texte se chevaucherait au lieu de prendre
     simplement la place qu'il lui faut. */
  flex: none;
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: max(10px, env(safe-area-inset-top)) 14px 10px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}

.bar__title { font-weight: 700; font-size: 18px; }

.pill {
  font-size: 14px;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  white-space: nowrap;
}
.pill[data-state="open"]  { color: var(--ok);     border-color: currentColor; }
.pill[data-state="error"],
.pill[data-state="closed"] { color: var(--danger); border-color: currentColor; }
/* « injoignable depuis cette page » n'est pas une panne du restaurant : ni le
   rouge de l'alarme, ni le gris neutre qui se confondrait avec « — ». */
.pill[data-state="blocked"] { color: var(--warn); border-color: currentColor; }

/* Le bas de page est porte par chaque ecran (voir plus bas) : ici il ferait
   une bande morte SOUS le bouton d'envoi. */
main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 16px 14px 0;
}

.screen { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 16px; }
.screen--center { align-items: center; text-align: center; padding-top: 32px; }

/* Ces trois ecrans ne sont qu'une pile de contenu : ils defilent en entier. */
#screen-scan, #screen-pin, #screen-result {
  overflow-y: auto;
  padding-bottom: calc(20px + env(safe-area-inset-bottom));
}

.lead { margin: 8px 0; }
.muted { color: var(--ink-soft); }
.small { font-size: 15px; }

.btn {
  min-height: var(--tap);
  padding: 0 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.btn--primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn--ghost   { background: transparent; }
.btn--xl      { min-height: 64px; font-size: 21px; }
.btn:disabled { opacity: .5; }

.manual { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.manual label { font-size: 16px; color: var(--ink-soft); }
.manual input {
  min-height: var(--tap);
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  font: inherit;
}

#video { width: 100%; border-radius: var(--radius); background: #000; }

.order-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 14px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.order-head__table { font-size: 26px; font-weight: 700; display: block; }
.order-head__meta  { font-size: 16px; color: var(--ink-soft); }
.order-head__total { font-size: 24px; font-weight: 700; white-space: nowrap; }

/* La liste des plats, et elle seule, absorbe la longueur de l'addition. */
.order-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.line {
  display: flex;
  gap: 12px;
  padding: 12px 14px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.line__qte  { font-weight: 700; min-width: 2.4em; font-variant-numeric: tabular-nums; }
.line__body { flex: 1; min-width: 0; }
.line__name { font-weight: 600; }
/* `pre-line` : les options arrivent deja separees par des sauts de ligne, au
   format que l'ancienne caisse imprime (« -2 X Sauce »). */
.line__comment { font-size: 16px; color: var(--ink-soft); white-space: pre-line; }
.line__total { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Hors de la zone qui defile : sa place est acquise, pas negociee. Le filet du
   haut est ce qui montre que la liste est coupee et qu'elle continue au-dessus. */
.footer {
  flex: none;
  display: flex;
  gap: 10px;
  padding: 12px 0 max(12px, env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  background: var(--bg);
}
.footer .btn { flex: 1; }
.footer .btn--primary { flex: 2; }

.result { font-size: 64px; line-height: 1; }
.result__title { font-size: 24px; margin: 4px 0; }
.result__detail { color: var(--ink-soft); margin: 0 0 12px; max-width: 34ch; white-space: pre-line; }

/* --------------------------------------------------- garde anti-doublon */
/* Un doublon en caisse est de l'argent encaisse en trop. Le bouton est donc
   eteint par defaut des qu'un ticket est deja parti, et il faut ecrire un mot
   pour le rallumer : un geste qu'on ne fait pas par inadvertance. */
.resend {
  border: 1px solid var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  border-radius: var(--radius);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.resend__head { margin: 0; font-weight: 700; color: var(--danger); }
.resend__warn { margin: 0; font-size: 16px; color: var(--ink); }
.resend__label { font-size: 16px; color: var(--ink-soft); }
.resend__label b { color: var(--ink); letter-spacing: .04em; }
.resend input {
  min-height: var(--tap);
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.resend input:focus-visible { outline: 2px solid var(--danger); outline-offset: 2px; }

/* Etat « deja envoye » du bouton principal : il reste lisible, mais il est
   visiblement hors service tant que le mot n'est pas ecrit. */
.btn--primary:disabled { background: var(--ink-soft); border-color: var(--ink-soft); }

/* Explication du « hors ligne ». Cachee tant que la caisse repond : elle ne
   sert qu'a la minute ou quelqu'un est bloque, et le reste du temps elle
   pousserait l'addition hors de l'ecran. */
/* Bornee a un tiers de l'ecran, et elle defile dans son coin au-dela : elle
   est longue -- trois causes, dont une qui demande une phrase entiere -- et sur
   un petit telephone elle mangeait toute la hauteur, jusqu'a repousser le
   bouton d'envoi hors de l'ecran. Soit exactement ce que la mise en page en
   haut de ce fichier existe pour empecher. */
.hint {
  flex: none;
  max-height: 30vh;
  max-height: 30dvh;
  overflow-y: auto;
  margin: 0;
  padding: 12px 16px;
  background: var(--warn-bg, #fff7ed);
  border-bottom: 1px solid var(--warn-line, #fed7aa);
  color: var(--warn-fg, #7c2d12);
  font-size: 14px;
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hint strong { font-size: 15px; }
.hint code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
}
.hint[hidden] { display: none !important; }

/* Pourquoi l'envoi ne peut pas partir, dit sous l'addition et avant le clic. */
.send-problem {
  margin: 0 16px 8px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--warn-bg, #fff7ed);
  border: 1px solid var(--warn-line, #fed7aa);
  color: var(--warn-fg, #7c2d12);
  font-size: 14px;
  line-height: 1.45;
}
.send-problem[hidden] { display: none !important; }

/* ── Code du restaurant ─────────────────────────────────────────────────────
   Demande une seule fois par telephone. Les touches sont a la taille du pouce
   (--tap) : ce code se tape debout, en salle, souvent d'une main. */
.pin__title { margin: 0; font-size: 22px; text-align: center; }
.pin__help { margin: 0; color: var(--ink-soft); text-align: center; font-size: 15px; }
.pin__dots {
  display: flex;
  gap: 14px;
  justify-content: center;
  min-height: 20px;
  margin: 4px 0 2px;
}
.pin__dot {
  width: 14px;
  height: 14px;
  border-radius: 999px;
  border: 2px solid var(--line);
}
.pin__dot--on { background: var(--ink); border-color: var(--ink); }
.pin__error { margin: 0; color: var(--danger); text-align: center; font-weight: 600; }
.pin__error[hidden] { display: none; }
.pin__pad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  max-width: 320px;
  width: 100%;
  margin: 0 auto;
}
.pin__key { min-height: var(--tap); font-size: 24px; font-weight: 600; }
