/* ═══════════════════════════════════════════════════════════════════
   JALON — EXTENSION TERRAIN DU SYSTÈME DE DESIGN

   Première interface mobile de la suite. Le système commun a été conçu
   pour des consoles de bureau ; il faut l'étendre une fois, proprement,
   plutôt que semer des styles isolés dans ce module.

   Ces jetons ont vocation à rejoindre le système commun — d'autres
   interfaces terrain suivront, à commencer par le SAV et les relevés de
   compteurs. Ils vivent ici en attendant cette promotion, qui touche un
   fichier partagé par des consoles en production et se décide de jour.

   L'USAGE QUI DICTE CHAQUE VALEUR

   Le chauffeur manipule l'appareil DEBOUT, D'UNE MAIN, souvent avec des
   bacs dans l'autre, en plein soleil dakarois, sur un téléphone d'entrée
   de gamme. Rien ici n'est une préférence esthétique.
   ═══════════════════════════════════════════════════════════════════ */

:root{
  /* L'interface est CLAIRE, et le dit. Sans cette déclaration, le
     navigateur d'un téléphone en thème sombre assombrit la page de
     force : les contrastes mesurés sont contournés, la couleur du
     client est faussée, et l'écran devient illisible en plein
     soleil — exactement l'usage visé. */
  color-scheme: only light;
}

:root{
  /* Cibles tactiles. 44 px est le minimum ; une action décisive mérite
     davantage, parce qu'on la vise en marchant. */
  --cible:44px; --cible-l:56px;

  /* Lisibilité en extérieur. Le corps de texte monte de 13 à 16 px :
     plein soleil sur un écran bon marché, et c'est aussi ce qui évite
     que le navigateur zoome tout seul à la saisie. */
  --t-terrain:16px; --t-terrain-l:19px; --t-terrain-num:32px;

  /* Densité réduite : une information par ligne, jamais de tableau. */
  --s-terrain:16px; --s-terrain-l:22px;

  /* Zone du pouce : les actions décisives sont en bas, jamais en haut,
     et au-dessus de la barre système du téléphone. */
  --pouce:calc(env(safe-area-inset-bottom, 0px) + 12px);

  /* ÉTATS RÉSEAU. Le hors ligne est un ÉTAT NORMAL, pas une erreur : il
     ne prend donc ni l'ambre ni le rouge, réservés à ce qui ne va pas.
     Un chauffeur en zone blanche travaille normalement. */
  --hors-ligne:#5A7180; --hors-ligne-bg:#EFF1F2; --hors-ligne-t:#3E4F59;
  --en-attente:#1D6F8B; --en-attente-bg:#E6F1F5;
}

/* ── Ossature ─────────────────────────────────────────────────────── */

/* [hidden] pose display:none, mais n'importe quelle règle de composant
   qui déclare display:block le supplante — et un champ censé être caché
   s'affiche. C'est arrivé au motif de forçage, visible sur un contrôle
   conforme. Ce filet doit précéder tout le reste. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);
  font-family:'IBM Plex Sans',system-ui,sans-serif;font-size:var(--t-terrain);
  line-height:1.5;-webkit-tap-highlight-color:transparent}

.jln-ecran{display:none;min-height:100dvh;flex-direction:column}
.jln-ecran[aria-current="page"]{display:flex}

/* En-tête : la marque du client, et l'état du réseau en permanence. */
.jln-tete{position:sticky;top:0;z-index:5;display:flex;align-items:center;
  gap:var(--s3);padding:var(--s3) var(--s4);background:var(--card);
  border-bottom:1px solid var(--line);min-height:var(--cible)}
.jln-tete img{height:26px;width:auto}
.jln-tete b{font-size:var(--t-terrain);font-weight:600}
.jln-tete small{display:block;color:var(--ink-3);font-size:var(--t-sm)}

.jln-corps{flex:1;padding:var(--s4);padding-bottom:calc(var(--cible-l) + var(--pouce) + var(--s5))}

/* ── L'état du réseau, lisible en permanence ──────────────────────── */
.jln-reseau{margin-left:auto;display:flex;align-items:center;gap:6px;
  padding:5px 11px;border-radius:999px;font-size:var(--t-sm);font-weight:600;
  background:var(--go-bg);color:#2C6B00}
.jln-reseau[data-etat="hors-ligne"]{background:var(--hors-ligne-bg);color:var(--hors-ligne-t)}
.jln-reseau[data-etat="en-attente"]{background:var(--en-attente-bg);color:var(--en-attente)}
.jln-reseau .pastille{width:8px;height:8px;border-radius:50%;background:currentColor}

/* ── Une information par ligne ────────────────────────────────────── */
.jln-arret{display:flex;align-items:center;gap:var(--s3);width:100%;
  min-height:var(--cible-l);padding:var(--s3) var(--s4);margin-bottom:8px;
  background:var(--card);border:1px solid var(--line);border-radius:10px;
  text-align:left;font:inherit;color:inherit}
.jln-arret .rang{flex:none;width:30px;height:30px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--entite-bg);color:var(--entite-d);
  font-family:'IBM Plex Mono',monospace;font-size:var(--t-sm);font-weight:600}
.jln-arret .nom{flex:1;min-width:0;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jln-arret .sous{display:block;font-weight:400;font-size:var(--t-sm);color:var(--ink-3)}
.jln-arret[data-fait="livre"]{background:var(--go-bg);border-color:transparent}
.jln-arret[data-fait="livre"] .rang{background:#D6F0BE;color:#2C6B00}
.jln-arret[data-fait="echec"]{background:var(--late-bg);border-color:transparent}
.jln-arret[data-sans-point="oui"] .sous{color:var(--warn-t)}

/* ── Bandeau de position, en tête de l'arrêt, avant tout le reste ── */
.jln-position{display:flex;gap:var(--s3);align-items:flex-start;
  padding:var(--s4);border-radius:10px;margin-bottom:var(--s4);
  background:var(--go-bg);color:#2C6B00;font-weight:600}
.jln-position[data-controle="force"]{background:var(--late-bg);color:#8E2A1F}
.jln-position[data-controle="non_controle"],
.jln-position[data-controle="sans_point"]{background:var(--hors-ligne-bg);color:var(--hors-ligne-t)}
.jln-position p{margin:4px 0 0;font-weight:400;font-size:var(--t-sm)}

/* ── Compteurs : gros chiffres, grosses cibles ────────────────────── */
.jln-compteur{display:flex;align-items:center;justify-content:space-between;
  gap:var(--s3);padding:var(--s3) var(--s4);background:var(--card);
  border:1px solid var(--line);border-radius:10px;margin-bottom:8px}
.jln-compteur .libelle{font-weight:600}
.jln-compteur .reglage{display:flex;align-items:center;gap:var(--s3)}
.jln-compteur output{min-width:2.5ch;text-align:center;
  font-family:'IBM Plex Mono',monospace;font-size:var(--t-terrain-num);font-weight:600;
  font-variant-numeric:tabular-nums}
.jln-pas{width:var(--cible);height:var(--cible);border-radius:50%;
  border:1px solid var(--line-2);background:var(--card);color:var(--ink);
  font-size:22px;line-height:1}
.jln-pas:active{background:var(--entite-bg)}

/* ── Champs ───────────────────────────────────────────────────────── */
.jln-champ{display:block;margin-bottom:var(--s4)}
.jln-champ span{display:block;font-weight:600;margin-bottom:6px}
.jln-champ small{display:block;color:var(--ink-3);font-size:var(--t-sm);margin-top:6px}
.jln-champ input,.jln-champ select,.jln-champ textarea{
  width:100%;min-height:var(--cible);padding:11px var(--s3);
  border:1px solid var(--line-2);border-radius:8px;background:var(--card);
  font:inherit;color:var(--ink)}
.jln-champ input:focus,.jln-champ select:focus,.jln-champ textarea:focus{
  outline:2px solid var(--entite);outline-offset:1px}

/* ── Signature ────────────────────────────────────────────────────── */
.jln-signature{position:relative;height:190px;background:var(--card);
  border:1px dashed var(--line-2);border-radius:10px;overflow:hidden}
.jln-signature canvas{width:100%;height:100%;display:block;touch-action:none}
.jln-signature .invite{position:absolute;inset:0;display:flex;
  align-items:center;justify-content:center;color:var(--ink-3);pointer-events:none}
.jln-signature[data-signe="oui"] .invite{display:none}

/* ── Zone du pouce : l'action décisive, toujours en bas ───────────── */
.jln-actions{position:fixed;left:0;right:0;bottom:0;z-index:6;
  display:flex;gap:var(--s3);padding:var(--s3) var(--s4) var(--pouce);
  background:var(--card);border-top:1px solid var(--line)}
.jln-bouton{flex:1;min-height:var(--cible-l);border:0;border-radius:10px;
  font:inherit;font-size:var(--t-terrain);font-weight:600;
  background:var(--entite);color:var(--entite-sur)}
.jln-bouton[data-role="second"]{flex:0 0 auto;padding:0 var(--s5);
  background:var(--card);color:var(--ink);border:1px solid var(--line-2)}
.jln-bouton:disabled{opacity:.45}
.jln-bouton:active{filter:brightness(.94)}

/* ── Écran vide : une invitation à agir, pas un constat ───────────── */
.jln-vide{padding:var(--s6) var(--s4);text-align:center;color:var(--ink-2)}
.jln-vide b{display:block;font-size:var(--t-terrain-l);margin-bottom:var(--s2)}

/* ── Signature de produit, discrète et permanente ─────────────────── */
.jln-signature-produit{padding:var(--s5) var(--s4);text-align:center;
  color:var(--ink-3);font-size:var(--t-sm)}

/* Ce qui bouge à l'écran signifie qu'une donnée a changé — règle
   d'immobilité du système commun. Rien d'autre n'est animé. */
@media (prefers-reduced-motion:no-preference){
  .jln-reseau{transition:background-color .2s,color .2s}
}

/* ── Plusieurs tournées dans la journée ─────────────────────────────
   Une vague du matin, une de l'après-midi : le chauffeur choisit. La
   carte porte la même cible tactile que le reste — on la touche debout,
   d'une main, parfois avec des gants. */
.jln-tournee{display:flex;align-items:center;gap:var(--s3);width:100%;
  min-height:var(--cible-l);padding:var(--s4);margin-bottom:10px;
  background:var(--card);border:1px solid var(--line);border-radius:10px;
  text-align:left;font:inherit;color:inherit}
.jln-tournee .quoi{flex:1;min-width:0;font-weight:600}
.jln-tournee .sous{display:block;font-weight:400;font-size:var(--t-sm);color:var(--ink-3)}
.jln-tournee .compte{flex:none;font-family:'IBM Plex Mono',monospace;
  font-size:var(--t-sm);color:var(--ink-2)}
.jln-tournee[data-etat="close"]{background:var(--go-bg);border-color:transparent}
.jln-tournee[aria-current="true"]{border-color:var(--entite);border-width:2px}

/* Barre d'actions de la tournée : deux liens, pas deux boutons pleins —
   ce ne sont pas les gestes du métier, ils ne doivent pas peser autant
   que « Valider la livraison ». */
.jln-barre-tournee{display:flex;gap:var(--s4);padding:0 0 8px}
.jln-lien{background:none;border:0;padding:8px 0;font:inherit;
  font-size:var(--t-sm);font-weight:600;color:var(--entite-d);
  text-decoration:underline;text-underline-offset:3px;min-height:var(--cible)}
.jln-lien.fort{margin-left:auto}
.jln-note-sequence{margin:0 0 12px;font-size:var(--t-sm);color:var(--ink-2)}

/* La proposition du prochain arrêt. C'est ELLE le chemin normal : un
   geste pour suivre l'ordre prévu, et la liste juste en dessous pour en
   choisir un autre. Rien à réorganiser, rien à justifier. */
.jln-prochain{padding:var(--s4);margin-bottom:var(--s4);border-radius:12px;
  background:var(--entite-bg);border:1px solid var(--entite)}
.jln-prochain .quoi{margin:0 0 var(--s3)}
.jln-prochain .k{display:block;font-size:var(--t-sm);font-weight:600;
  text-transform:uppercase;letter-spacing:.04em;color:var(--entite-d)}
.jln-prochain b{display:block;font-size:var(--t-l);line-height:1.25;margin-top:2px}
.jln-prochain .sous{display:block;font-size:var(--t-sm);color:var(--ink-2);margin-top:2px}
.jln-prochain .autre{margin:var(--s3) 0 0;font-size:var(--t-sm);color:var(--ink-2)}
.jln-prochain .jln-bouton{width:100%}

/* L'avancement se lit sous le titre, donc du même bord que lui :
   centré, il donnait l'impression d'un pied de page. */
#tournee-avancement{text-align:left;padding:0}

/* L'arrêt proposé se retrouve dans la liste sans la dominer. */
.jln-arret[data-prochain="oui"]{border-color:var(--entite)}

/* Une tournée libre se distingue de la sienne : on ne la « rouvre »
   pas, on la PREND, et ce n'est pas le même geste. */
.jln-tournee[data-libre="oui"]{border-style:dashed}
.jln-tournee[data-libre="oui"] .compte{font-weight:600;color:var(--entite-d)}
.jln-tournee[data-libre="oui"]:disabled{opacity:.6}

/* Ce qui vient de se passer. Ton neutre : une tournée prise par un
   collègue n'est pas une erreur du chauffeur. */
.jln-avis{margin:0 0 var(--s4);padding:var(--s3) var(--s4);border-radius:10px;
  background:var(--en-attente-bg);color:var(--en-attente);font-size:var(--t-sm)}

/* ── Le scan des bacs ────────────────────────────────────────────────
   Le scan nourrit le compteur, il ne le remplace pas : des bacs marqués
   et des bacs non marqués coexisteront pendant des mois. */
.jln-scan{margin:-4px 0 12px}
.jln-scan .jln-bouton{width:100%}
.codes{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.jln-code{display:inline-flex;align-items:center;gap:6px;
  padding:6px 6px 6px 10px;border-radius:999px;
  background:var(--entite-bg);color:var(--entite-sur);
  font-family:'IBM Plex Mono',monospace;font-size:var(--t-sm)}
.jln-code button{width:26px;height:26px;flex:none;border:0;border-radius:50%;
  background:rgba(0,0,0,.08);color:inherit;font:inherit;line-height:1;padding:0}

/* Le viseur. Cadre au centre : sans repère, on promène le téléphone
   au-dessus du bac sans savoir où viser. */
.jln-viseur{position:relative;width:100%;aspect-ratio:4/3;border-radius:12px;
  overflow:hidden;background:#0b0f0d;margin-bottom:var(--s4)}
.jln-viseur video{width:100%;height:100%;object-fit:cover}
.jln-viseur .cadre{position:absolute;inset:18% 22%;border:3px solid #fff;
  border-radius:12px;box-shadow:0 0 0 100vmax rgba(0,0,0,.35)}

/* La version, discrète, et la sortie de secours à côté. */
.jln-signature-produit .jln-lien{display:inline-block;margin-left:10px;
  min-height:0;padding:0;font-size:inherit}
