/* ============================================================================
   Charte Maison GDC — jetons et composants partagés
   Issu du gabarit terrain (23/08 → 02/09), étendu au client et à l'administration.
   La charte écrite : charte/CHARTE.md. Ce fichier en est la seule mise en œuvre.

   Deux règles pour qui édite ce fichier :
   1. AUCUN jeton existant n'est renommé — web/client/ et web/admin/ s'en servent déjà.
   2. Une couleur écrite en dur dans un composant est un bug : un composant se peint
      avec les jetons de thème, sinon il ne survit pas au passage salon → terrain.
   ========================================================================= */

:root{
  /* --- socle : les couleurs de la maison, identiques dans les deux thèmes --- */
  --encre:#14120F; --tiroir:#211D18; --tiroir-haut:#2C2721;
  --craie:#F5F1EA; --craie-2:#EDE7DC; --fumee:#9C9288; --or:#C4A06A; --or-sombre:#8E6F3E;

  /* Les trois signaux du terrain. Ils désignent l'état d'une chose, jamais une marque.
     souci = ça se rattrape (retard, écart, attente) ; casse = ça se facture (casse,
     manquant, échec). La distinction vient du quai, elle se tient partout ailleurs. */
  --conforme:#5A9E70; --souci:#D08A3E; --casse:#C05248;

  /* Variantes TEXTE des trois signaux + de l'or.
     Pourquoi elles existent : mesurées sur fond craie, --conforme donne 2,84:1,
     --souci 2,53:1, --casse 4,11:1 — sous le seuil AA de 4,5:1. Les valeurs nues
     restent excellentes en APLAT (fond de bouton, pastille, point) et ne changent pas.
     Règle : background → jeton nu ; color → jeton -txt. Jamais l'inverse. */
  --conforme-txt:#417251;   /* 4,97:1 sur craie */
  --souci-txt:#915C23;      /* 4,96:1 */
  --casse-txt:#AF463C;      /* 4,96:1 */
  --or-txt:#826334;         /* 4,93:1 — --or-sombre ne donne que 4,15:1, il reste aux aplats */

  /* --- les cinq familles d'états (D18) ---
     Une famille = une couleur, un développeur n'a jamais à en choisir une.
     commercial = or   : les trois seuls états où le CLIENT décide, et les seuls qui
                         parlent d'argent ; ils s'excluent dans le temps, donc jamais
                         deux pastilles or côte à côte.
     entrepôt   = gris : D20 les cache au client, c'est la cuisine interne — une couleur
                         qui n'appelle pas l'œil est la bonne réponse, pas un défaut.
     route      = bleu : la seule famille posée par une MACHINE (le traceur, D24), d'où
                         le seul froid de la palette. Et surtout : la route ne peut pas
                         être orange, D22 réserve l'orange au retard.
     client     = vert : le vert du bouton Conforme et du sceau de clôture — la promesse tenue.
     retour     = prune: la seule phase que personne n'attend, c'est de la comptabilité
                         après coup. Calme, jamais alarmante : un écart se dit en --casse
                         PAR-DESSUS la pastille, il ne change pas la couleur de famille. */
  --etat-commercial:#826334;
  --etat-entrepot:#5E564C;
  --etat-route:#2F5F82;
  --etat-client:#417251;
  --etat-retour:#6B5478;

  --filet:rgba(20,18,15,.12);
  --serif:"Bodoni Moda",Didot,"Times New Roman",serif;
  --sans:"IBM Plex Sans","Helvetica Neue",Arial,sans-serif;
  --mono:"IBM Plex Mono","SF Mono",Menlo,monospace;

  /* --- échelle typographique : six tailles, pas une de plus ---
     Toute taille hors de cette liste est un bug. Bodoni ne descend jamais sous --t-4
     (c'est un didone : ses déliés disparaissent en petit corps sur un écran sale). */
  --t-1:12px;   /* surtitres capitales, méta, légende de colonne */
  --t-2:14px;   /* texte secondaire, aide, mention */
  --t-3:16px;   /* CORPS — tout ce qu'on lit pour agir */
  --t-4:20px;   /* titre de feuille, nom d'article, champ de saisie */
  --t-5:26px;   /* h2, titre d'écran */
  --t-6:34px;   /* h1, ETA en grand (D22), grand compteur */

  /* --- espacements : une seule échelle, multiples de 4 ---
     Un écart qui n'est pas dans cette liste est un écart choisi au jugé. */
  --e-1:4px; --e-2:8px; --e-3:12px; --e-4:16px; --e-5:24px; --e-6:32px;

  --rayon:14px; --rayon-2:10px;
  --doigt:44px;            /* cible tactile minimale, sans exception */
  --bouton:56px;           /* décision au salon */
  --bouton-terrain:70px;   /* décision au terrain : il y a des gants (valeur du gabarit) */

  /* thème « salon » (client, administration) : clair */
  --fond:var(--craie); --fond-2:#FFFFFF; --texte:var(--encre); --texte-2:#5E564C; --accent:var(--or-sombre);
}

/* Thème sombre de l'outil de terrain (nuit, quai, entrepôt).
   Il se pose EN DUR sur <html data-theme="terrain"> selon le dossier servi ; on ne
   lit jamais prefers-color-scheme : c'est le rôle qui décide, pas le téléphone. */
[data-theme="terrain"]{
  --fond:var(--encre); --fond-2:var(--tiroir); --texte:var(--craie); --texte-2:var(--fumee); --accent:var(--or);
  --filet:rgba(245,241,234,.13);
  /* sur fond encre, les signaux nus repassent AA — sauf --casse (4,04:1), éclairci ici */
  --conforme-txt:#5A9E70; --souci-txt:#D08A3E; --casse-txt:#E0776D; --or-txt:#C4A06A;
  --etat-commercial:#C4A06A;
  --etat-entrepot:#9C9288;
  --etat-route:#7FA8C9;
  --etat-client:#5A9E70;
  --etat-retour:#A897C0;
}

/* ---------------------------------------------------------------- socle ---- */
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
/* Le [hidden] natif doit gagner sur toute classe qui pose son propre display
   (.btn, .compteur, .frise...). Trouvé tardivement au terrain sur un élément resté
   visible ; corrigé globalement une bonne fois. */
[hidden]{display:none!important}
html,body{margin:0;padding:0;min-height:100%}
body{background:var(--fond);color:var(--texte);font-family:var(--sans);font-size:var(--t-3);line-height:1.45;
     -webkit-font-smoothing:antialiased;overscroll-behavior:none}
button{font:inherit;color:inherit;border:0;background:none;cursor:pointer}
/* Jamais outline:none, nulle part, pour aucune raison : Mathieu navigue son tableau
   au clavier depuis un bureau. */
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

h1,h2{font-family:var(--serif);font-weight:400;letter-spacing:-.01em;text-wrap:balance;margin:0}
h1{font-size:var(--t-6);line-height:1.12} h2{font-size:var(--t-5);line-height:1.2}
.sur{font-size:var(--t-1);letter-spacing:.2em;text-transform:uppercase;color:var(--texte-2);font-weight:600}
/* Un chiffre qui change (compteur, ETA qui descend, quantité qu'on tape) ne doit pas
   faire bouger ce qu'il y a autour : tabular-nums est obligatoire, pas décoratif. */
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* -------------------------------------------------------------- boutons ---- */
/* Un bouton dit ce qu'il fait, pas où il mène : « Demander un devis », pas « Continuer ».
   Un bouton désactivé CHANGE DE LIBELLÉ pour porter sa raison (« Photo requise ») ;
   jamais un bouton gris muet. */
.btn{min-height:var(--bouton);padding:0 18px;border-radius:var(--rayon);font-size:17px;font-weight:600;
     display:inline-grid;place-items:center;text-align:center;line-height:1.2;transition:transform .08s ease}
.btn:active{transform:scale(.97)} .btn:disabled{opacity:.4}
.btn-large{width:100%;grid-column:1/-1}
[data-theme="terrain"] .btn{min-height:var(--bouton-terrain)}
.btn-or{background:var(--or);color:#231A0B} .btn-encre{background:var(--encre);color:var(--craie)}
.btn-fant{background:transparent;color:var(--texte);border:1.5px solid var(--filet)}
.btn-conforme{background:var(--conforme);color:#0B1A11}
.btn-souci{background:transparent;color:var(--souci-txt);border:1.5px solid var(--souci)}

/* ------------------------------------------------------------- surfaces ---- */
/* Pas de carte dans une carte : deux niveaux de bordure sur 375 px de large, c'est
   illisible. À l'intérieur, on sépare avec un filet horizontal. */
.carte{background:var(--fond-2);border:1px solid var(--filet);border-radius:var(--rayon);padding:var(--e-3) var(--e-4)}

/* -------------------------------------------------- pastille d'état (D18) ---- */
/* Information, jamais une commande : une pastille ne se clique pas.
   Le point coloré ne suffit jamais seul — le libellé porte la même information (AA). */
.etat{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;font-size:var(--t-1);
      font-weight:600;letter-spacing:.04em;background:var(--fond-2);border:1px solid var(--filet)}
.etat::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--texte-2);flex:0 0 auto}
.etat.commercial::before{background:var(--etat-commercial)}
.etat.entrepot::before{background:var(--etat-entrepot)}
/* corrigé : la route était sur --souci, ce qui la rendait indiscernable d'un retard (D22) */
.etat.route::before{background:var(--etat-route)}
.etat.client::before{background:var(--etat-client)}
.etat.retour::before{background:var(--etat-retour)}
.etat.alerte{border-color:var(--casse);color:var(--casse-txt)} .etat.alerte::before{background:var(--casse)}

/* ------------------------------------------------- frise d'étapes (D20) ---- */
/* Le suivi du client. Dix étapes au plus — celles que D20 autorise, jamais les dix-sept.
   L'étape en cours ne se saisit pas : elle vient de /api/commandes/{id}/suivi.
   Trois états, distingués par la FORME autant que par la couleur (pleine / anneau /
   vide) : sous une lampe jaune, la couleur seule ne suffit pas. */
.frise{list-style:none;margin:0;padding:0}
.frise li{position:relative;padding:0 0 var(--e-5) var(--e-5);color:var(--texte-2);font-size:var(--t-3)}
.frise li:last-child{padding-bottom:0}
.frise li::before{content:"";position:absolute;left:0;top:5px;width:12px;height:12px;border-radius:50%;
                  border:2px solid var(--filet);background:var(--fond);box-sizing:border-box}
/* le trait : plein au-dessus de l'étape en cours, pointillé en dessous — on voit le
   chemin parcouru et le chemin restant sans lire un mot */
.frise li::after{content:"";position:absolute;left:5px;top:19px;bottom:-2px;
                 border-left:2px dotted var(--filet)}
.frise li:last-child::after{display:none}
.frise li.faite{color:var(--texte)}
.frise li.faite::before{background:var(--etat-commercial);border-color:var(--etat-commercial)}
.frise li.faite::after{border-left:2px solid var(--texte-2)}
.frise li.en-cours{color:var(--texte);font-weight:600}   /* la seule ligne en gras de la frise */
.frise li.en-cours::before{background:var(--fond);border-color:var(--etat-commercial);border-width:2.5px}
/* la famille se pose en classe supplémentaire sur le <li> : .frise li.route.faite, etc. */
.frise li.commercial.faite::before{background:var(--etat-commercial);border-color:var(--etat-commercial)}
.frise li.entrepot.faite::before{background:var(--etat-entrepot);border-color:var(--etat-entrepot)}
.frise li.route.faite::before{background:var(--etat-route);border-color:var(--etat-route)}
.frise li.client.faite::before{background:var(--etat-client);border-color:var(--etat-client)}
.frise li.retour.faite::before{background:var(--etat-retour);border-color:var(--etat-retour)}
.frise li.commercial.en-cours::before{border-color:var(--etat-commercial)}
.frise li.entrepot.en-cours::before{border-color:var(--etat-entrepot)}
.frise li.route.en-cours::before{border-color:var(--etat-route)}
.frise li.client.en-cours::before{border-color:var(--etat-client)}
.frise li.retour.en-cours::before{border-color:var(--etat-retour)}
.frise small{display:block;font-family:var(--mono);font-variant-numeric:tabular-nums;
             font-size:var(--t-1);font-weight:400;color:var(--texte-2);margin-top:2px}

/* ------------------------------------------------ champ de saisie (D21) ---- */
/* Le <label> est TOUJOURS visible : un placeholder disparaît dès qu'on tape, et sur un
   formulaire d'adresse on ne sait plus ce qu'on remplit.
   La hauteur de 54 px et le corps de 17 px viennent du gabarit ; le corps ne descend
   JAMAIS sous 16 px, sinon iOS Safari zoome tout seul à la mise au point. */
.champ{margin-bottom:var(--e-4)}
.champ label{display:block;font-size:var(--t-1);letter-spacing:.16em;text-transform:uppercase;
             color:var(--texte-2);margin-bottom:7px;font-weight:600}
.champ input,.champ select,.champ textarea{
  width:100%;min-height:54px;border-radius:var(--rayon-2);background:var(--fond-2);color:var(--texte);
  border:1.5px solid var(--filet);padding:0 14px;font:inherit;font-size:17px}
.champ textarea{padding:14px;min-height:96px;line-height:1.4}
/* le focus clavier reste visible (charte §8, grille point 20) : on change la bordure,
   on ne retire jamais l'anneau — :focus-visible ci-dessus fait le reste */
.champ input:focus,.champ select:focus,.champ textarea:focus{border-color:var(--accent)}
/* Une bordure rouge muette ne dit pas quoi faire : .champ-erreur porte toujours une phrase. */
.champ.erreur input,.champ.erreur select,.champ.erreur textarea{border-color:var(--casse)}
.champ .aide{margin-top:var(--e-2);font-size:var(--t-2);color:var(--texte-2);line-height:1.35}
.champ .erreur-txt{margin-top:var(--e-2);font-size:var(--t-2);color:var(--casse-txt);font-weight:600}

/* ------------------------------------------------------------ bandeaux ---- */
/* Informe sans interrompre. Se place SOUS la barre de titre, jamais en flottant.
   Ne se ferme pas tant que la condition dure : un bandeau qu'on peut fermer alors que
   le problème persiste est un mensonge. */
.bandeau{padding:var(--e-2) var(--e-3);border-radius:var(--rayon-2);background:var(--fond-2);
         border:1px solid var(--filet);color:var(--texte-2);font-size:var(--t-2);line-height:1.4}
.bandeau b{color:var(--texte)}
/* ce qui se rattrape : retard annoncé (D29), devis qui expire, solde à J-10 */
.bandeau-souci{border-color:var(--souci);color:var(--souci-txt);background:var(--fond-2);
               background:color-mix(in srgb,var(--souci) 8%,var(--fond-2))}
/* quatre cas, et quatre seulement : position du camion perdue (D24), hors ligne avec
   des envois en attente (D31), alerte d'emballage non traitée (D16), écart au rapport (D8) */
.bandeau-alerte{border-color:var(--casse);color:var(--casse-txt);background:var(--fond-2);
                background:color-mix(in srgb,var(--casse) 8%,var(--fond-2));font-weight:600}
.bandeau-souci b,.bandeau-alerte b{color:inherit}

/* ----------------------------------------- ligne de tableau (D19/D23) ---- */
/* Ce n'est PAS un <table> : un tableau HTML ne se réduit pas proprement à 375 px, et
   Mathieu ouvrira ce tableau depuis son téléphone.
   Le liseré gauche porte la famille d'état : la couleur se lit sans lire le texte. */
.ligne-tableau{display:grid;align-items:center;gap:var(--e-3);
               grid-template-columns:1.6fr 1.6fr .9fr auto .8fr 1.2fr auto;
               min-height:var(--bouton);padding:var(--e-2) var(--e-3);
               border-bottom:1px solid var(--filet);border-left:3px solid transparent;
               background:var(--fond-2);font-size:var(--t-2)}
.ligne-tableau .mono,.ligne-tableau time{font-family:var(--mono);font-variant-numeric:tabular-nums}
.ligne-tableau b{font-size:var(--t-3);font-weight:600}
.ligne-tableau small{display:block;color:var(--texte-2);font-size:var(--t-1)}
.ligne-tableau.commercial{border-left-color:var(--etat-commercial)}
.ligne-tableau.entrepot{border-left-color:var(--etat-entrepot)}
.ligne-tableau.route{border-left-color:var(--etat-route)}
.ligne-tableau.client{border-left-color:var(--etat-client)}
.ligne-tableau.retour{border-left-color:var(--etat-retour)}
/* l'alerte S'AJOUTE à l'état, elle ne le remplace pas : le liseré de famille ne bouge pas */
.ligne-tableau.avec-alerte b::before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;
                                     background:var(--casse);margin-right:6px;vertical-align:middle}
/* Sous 700 px la ligne se replie en deux niveaux, mais on ne cache JAMAIS l'état. */
@media (max-width:700px){
  .ligne-tableau{grid-template-columns:1fr auto;gap:var(--e-1) var(--e-2);padding:var(--e-3)}
  .ligne-tableau .repli{grid-column:1/-1;color:var(--texte-2);font-size:var(--t-2)}
}

/* -------------------------------------------------- compteur de tête (D9) ---- */
/* La ligne collante en haut d'une liste : « 12 / 40 contrôlés ».
   Règle de la maison : jamais un nombre nu sans son type — « 40 pièces », « code
   Rentman 1085 », jamais « 40 » ni « 1085 » seuls. */
.compteur-tete{position:sticky;top:0;z-index:5;background:var(--fond);
               display:flex;align-items:center;justify-content:space-between;gap:var(--e-3);
               padding:var(--e-3) var(--e-4);border-bottom:1px solid var(--filet);
               font-family:var(--mono);font-variant-numeric:tabular-nums;
               font-size:13px;color:var(--texte-2);letter-spacing:.03em}
.compteur-tete b{color:var(--texte);font-weight:600}

/* ------------------------------------------- choisir son mot de passe ---- */
/* Le voile de la PREMIÈRE CONNEXION (commun/mot-de-passe.js). Il vit ici et pas
   dans les trois feuilles des trois applications : c'est le même écran qui
   s'ouvre à la porte, dans l'espace client et sur le tableau, et trois copies
   auraient fini par ne plus se ressembler.
   Ses champs portent leurs propres classes (.mdp-champ) : /entree.css écrit
   « .champ span » là où charte.css écrit « .champ label », et un écran commun
   ne peut pas dépendre de laquelle des deux feuilles est chargée. */
.mdp-voile{position:fixed;inset:0;z-index:200;background:var(--fond);
           display:grid;place-items:center;padding:var(--e-4);overflow:auto}
.mdp-boite{width:100%;max-width:420px}
.mdp-sur{font-size:var(--t-1);letter-spacing:.18em;text-transform:uppercase;color:var(--texte-2)}
.mdp-titre{font-family:var(--serif);font-weight:400;font-size:26px;line-height:1.2;
           margin:6px 0 10px}
.mdp-sous{font-size:15px;line-height:1.45;color:var(--texte-2);margin-bottom:var(--e-4)}
.mdp-champ{display:block;margin-bottom:14px}
.mdp-champ label{display:block;font-size:12px;letter-spacing:.1em;text-transform:uppercase;
                 color:var(--texte-2);margin-bottom:7px;font-weight:600}
.mdp-champ input{width:100%;min-height:54px;border-radius:var(--rayon-2);
                 background:var(--fond-2);color:var(--texte);border:1.5px solid var(--filet);
                 padding:0 14px;font:inherit;font-size:17px}
.mdp-champ input:focus{border-color:var(--accent)}
.mdp-ok{margin-top:6px}
/* L'erreur se lit SOUS le bouton : c'est là que l'œil revient après avoir
   appuyé, pas en haut de l'écran. */
.mdp-erreur:empty{display:none}
.mdp-erreur{margin-top:var(--e-3);font-size:14px;font-weight:600;color:var(--casse-txt)}
/* La meme ligne dit aussi que c'est fait : une reussite muette laisse la main
   sur le bouton, a se demander si on a appuye. */
.mdp-erreur.bien{color:var(--conforme-txt)}

/* ---------------------------------------------------------- mouvement ---- */
/* Concerne la montée de la feuille du bas, la barre de progression, le scale(.97) des
   boutons, et le glissement du camion sur la carte (D22). */
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
