/* ============================================================
   COMPOSANTS PARTAGÉS — préfixe .ui-
   ------------------------------------------------------------
   Chargé APRÈS theme.css / themes.css et AVANT le CSS de chaque vue.
   Cet ordre est délibéré : une règle de vue qui survit gagne encore.
   Retirer une règle de vue ne peut donc que RÉVÉLER la règle partagée,
   jamais entrer en conflit avec elle.

   Chaque règle liste ses ALIAS historiques (#toast, #viewnav…) pour que
   le HTML existant continue de fonctionner sans être touché. Le
   renommage des balises est la toute dernière étape, composant par
   composant — un alias qui vit coûte moins cher qu'un renommage qui
   casse.

   ⚠️ BREAKPOINTS. Ils ne peuvent pas être des tokens
      (`@media (min-width: var(--bp))` n'existe pas). Valeurs du projet :
        1000px  caisse : ticket en rail droit / en feuille inférieure
         819px  caisse : bascule 2 colonnes → 1 colonne (historique)
         760px  en-tête : libellés de navigation masqués
         640px  timeline : graduations 5 min masquées
         600px  horloge réduite · grilles 1 → N colonnes
         520px  formulaires 2 → 1 colonne
         440px  horloge masquée
   ============================================================ */


/* ============================================================
   RACINE — taille de base pilotée par le thème
   ------------------------------------------------------------
   Toutes les tailles du projet sont en rem : changer --font-scale suffit
   donc à agrandir TOUTE l'interface. C'est ce qui permet au pack
   « Kiosque » (écran lu de loin) d'exister en une ligne, au lieu de
   réécrire les ~68 tailles de police du projet.
   Cette règle n'était déclarée que dans caisse.css : les 4 autres pages
   dépendaient du réglage du navigateur.
   ============================================================ */
html { font-size: calc(16px * var(--font-scale, 1)); }


/* ============================================================
   ANIMATIONS PARTAGÉES
   ------------------------------------------------------------
   ⚠️ Il existait TROIS `@keyframes pulse` concurrents dans le projet,
   avec des effets DIFFÉRENTS : opacité en caisse et chez le livreur,
   ombre d'urgence en cuisine. Aucun bug aujourd'hui (aucune page ne
   charge deux de ces fichiers), mais les réunir naïvement ici aurait
   donné au ticket cuisine l'animation d'opacité — le clignotement
   d'urgence du pizzaïolo serait mort en silence.
   D'où trois familles distinctes et nommées.
   ============================================================ */

/* Simple battement d'opacité — badges « en retard », compteurs. */
@keyframes ui-pulse-opacity { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

/* Halo d'urgence des CARTES (caisse, livreur) : anneau 1px, sans décalage.
   Le RAYON du halo vient de --urg-glow : calibré pour du fond sombre, il se lit
   comme de la saleté sur du blanc. Les packs clairs le réduisent ou l'annulent,
   et compensent par un anneau plus épais (--urg-ring). */
@keyframes ui-pulse-urg {
  0%, 100% { box-shadow: 0 0 0 var(--urg-ring-card) var(--urg), 0 0 var(--urg-glow) color-mix(in srgb, var(--urg) 32%, transparent); }
  50%      { box-shadow: 0 0 0 var(--urg-ring-card) var(--urg), 0 0 calc(var(--urg-glow) * 1.5) color-mix(in srgb, var(--urg) 60%, transparent); }
}
@keyframes ui-pulse-urg-soft {
  0%, 100% { box-shadow: 0 0 0 var(--urg-ring-card) var(--urg), 0 0 calc(var(--urg-glow) * 0.6) color-mix(in srgb, var(--urg) 16%, transparent); }
  50%      { box-shadow: 0 0 0 var(--urg-ring-card) var(--urg), 0 0 calc(var(--urg-glow) * 0.9) color-mix(in srgb, var(--urg) 30%, transparent); }
}

/* Halo d'urgence des TICKETS cuisine. Volontairement DIFFÉRENT : anneau
   2px et ombre portée décalée de 6px, parce que la carte est plus grande
   et lue à 2 m sur la tablette murale. Ne pas « unifier » avec le halo
   des cartes : ce n'est pas un doublon, c'est un réglage. */
@keyframes ui-pulse-ticket {
  0%, 100% { box-shadow: 0 0 0 var(--urg-ring) var(--urg), 0 6px calc(var(--urg-glow) * 1.1) color-mix(in srgb, var(--urg) 34%, transparent); }
  50%      { box-shadow: 0 0 0 var(--urg-ring) var(--urg), 0 6px calc(var(--urg-glow) * 1.5) color-mix(in srgb, var(--urg) 60%, transparent); }
}
@keyframes ui-pulse-ticket-soft {
  0%, 100% { box-shadow: 0 0 0 var(--urg-ring) var(--urg), 0 6px calc(var(--urg-glow) * 0.7) color-mix(in srgb, var(--urg) 16%, transparent); }
  50%      { box-shadow: 0 0 0 var(--urg-ring) var(--urg), 0 6px calc(var(--urg-glow) * 1.0) color-mix(in srgb, var(--urg) 32%, transparent); }
}


/* ============================================================
   NAVIGATION D'EN-TÊTE (viewnav)
   ------------------------------------------------------------
   Ces règles étaient INJECTÉES AU RUNTIME par js/viewnav.js, donc
   invisibles à toute recherche dans css/. Elles habillaient les boutons
   autour de `var(--cream)` — un nom qui veut dire « clair » : sur un
   pack de thème clair, on aurait eu du texte clair sur fond clair, sans
   qu'aucun grep ne puisse le signaler. Sorties du JS pour cette raison.
   ============================================================ */
.ui-viewnav, #viewnav {
  display: flex; align-items: center; gap: var(--sp-2);
  flex-shrink: 0; margin-left: var(--sp-1);
}
.ui-viewnav .vn-btn, #viewnav .vn-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px; white-space: nowrap;
  /* 28px de haut : on change de poste au doigt, sur une tablette de comptoir.
     Le plancher « ailleurs » du contrat de tokens tient largement dans un
     en-tête de 60px. */
  min-height: var(--tap-min-sm);
  font-size: var(--fs-sm); font-weight: var(--fw-bold);
  text-decoration: none; cursor: pointer;
  /* --text et non --cream : le crème est une couleur CLAIRE par définition,
     elle aurait donné du texte clair sur fond clair dès le premier thème clair. */
  color: var(--text); background: var(--surface-3);
  border: 1px solid var(--border); border-radius: var(--r-pill);
  padding: 5px 11px; transition: background var(--dur-fast);
}
.ui-viewnav .vn-btn:active, #viewnav .vn-btn:active { background: var(--brand); color: var(--on-brand); }
/* « Quitter » : rouge ADOUCI, jamais alarmant — c'est une action banale, pas un
   danger. L'ancienne valeur (#eb9b8f) était un rouge délavé calculé pour du fond
   sombre ; le mélange reproduit l'intention en suivant le thème. */
.ui-viewnav .vn-logout, #viewnav .vn-logout {
  border-color: color-mix(in srgb, var(--brand) 50%, transparent);
  color: color-mix(in srgb, var(--brand) 42%, var(--text));   /* ≈ #ec9788, l'ancien #eb9b8f */
}
.ui-viewnav .vn-ico, #viewnav .vn-ico { font-size: var(--fs-base); line-height: 1; }
@media (max-width: 760px) {
  .ui-viewnav .vn-label, #viewnav .vn-label { display: none; }
  .ui-viewnav .vn-btn, #viewnav .vn-btn { padding: 6px 9px; }
}
/* Sous 430px (téléphone), l'en-tête débordait : les libellés étaient déjà
   masqués mais la barre de navigation gardait `flex-shrink: 0` et poussait la
   page en défilement HORIZONTAL — le pire défaut possible sur un écran de
   livreur tenu à une main. On resserre au lieu de laisser déborder. */
@media (max-width: 430px) {
  .ui-viewnav, #viewnav { gap: 4px; margin-left: 0; }
  .ui-viewnav .vn-btn, #viewnav .vn-btn { padding: 6px 7px; }
}

/* Bulle d'aide iOS « Ajouter à l'écran d'accueil » (le plein écran n'y existe pas). */
#vn-fshint {
  position: fixed; top: 14px; left: 50%; transform: translate(-50%, -14px);
  max-width: min(92vw, 420px); z-index: var(--z-hint); pointer-events: none;
  background: var(--surface-3); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 11px 15px; font-size: var(--fs-md); line-height: var(--lh-normal);
  text-align: center; box-shadow: var(--sh-3);
  opacity: 0; transition: opacity var(--dur-slow), transform var(--dur-slow);
}
#vn-fshint.show { opacity: 1; transform: translate(-50%, 0); }
#vn-fshint b { color: var(--text-strong); }


/* ============================================================
   ÉTAT DE CONNEXION
   ------------------------------------------------------------
   Était écrit en `style.cssText` depuis le JS, avec des rgba() en dur :
   impossible à retoucher par un pack de thème.
   ============================================================ */
.ui-conn {
  font-size: var(--fs-xs); font-weight: var(--fw-bold);
  padding: 3px 7px; border-radius: var(--r-pill);
}
.ui-conn.is-online     { background: var(--ok-dim);      color: var(--ok-text); }
.ui-conn.is-offline    { background: var(--danger-dim);  color: var(--danger-text); }
.ui-conn.is-connecting { background: var(--warn-dim);    color: var(--warn-text); }
/* Variante du livreur : badge LIBELLÉ (« 🔴 Hors ligne »), et EFFACÉ quand tout va
   bien — en ligne est l'état normal, il n'a pas à faire de bruit visuel. */
.ui-conn--wide { padding: 3px 9px; letter-spacing: 0.5px; }
.ui-conn--wide.is-online { display: none; }


/* ============================================================
   TOAST
   ------------------------------------------------------------
   Quatre copies identiques, à un détail près : la caisse limitait la
   largeur et laissait le texte revenir à la ligne, les trois autres
   forçaient `nowrap`. On généralise le comportement de la caisse : les
   messages de conflit d'écriture sont longs (« ⚠️ 2 déjà modifiées sur
   un autre poste · 1 non enregistré (réseau ?) — 1 parti ») et
   débordaient de l'écran sur le téléphone du livreur.
   ============================================================ */
.ui-toast, #toast {
  position: fixed; bottom: 24px; left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
  padding: 12px 20px; border-radius: var(--r-pill);
  font-size: var(--fs-md); font-weight: var(--fw-medium);
  z-index: var(--z-toast);
  transition: transform var(--dur-slow) var(--ease-spring);
  max-width: min(92vw, 560px); text-align: center;
  box-shadow: var(--sh-2);
}
.ui-toast.show, #toast.show       { transform: translateX(-50%) translateY(0); }
/* Le FOND vient de la règle de base (--surface) : la bordure garde la couleur
   vive, le texte prend la variante lisible. `.ui-toast.error` porte TOUS les
   messages d'erreur des 5 vues — il était à 3,87 sur le thème de production. */
.ui-toast.success, #toast.success { border-color: var(--ok);     color: var(--ok-text); }
.ui-toast.error, #toast.error     { border-color: var(--danger); color: var(--danger-text); }


/* ============================================================
   BARRE DE DÉFILEMENT (3 copies identiques)
   ============================================================ */
::-webkit-scrollbar       { width: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
