/*
 * Système de design repris des maquettes UX (maquettes_ux.html).
 *
 * Les jetons de couleur, les composants (card, tag, field, alert, kpi, tabs,
 * mono-sim, jauge…) et leurs dimensions sont conservés à l'identique : c'est ce
 * qui garantit que l'application ressemble à ce qui a été validé, et non à une
 * réinterprétation.
 */

:root{
  --bleu:#1f6f8b; --bleu-fonce:#144d61; --bleu-clair:#e8f2f6;
  --gris:#f4f6f8; --bord:#d8dee3; --texte:#1f2933; --texte2:#6b7885;
  --vert:#2e7d52; --vert-clair:#e6f4ec;
  --orange:#c77700; --orange-clair:#fdf3e2;
  --rouge:#c0392b; --rouge-clair:#fdeceb;
  --radius:6px;
}
*{box-sizing:border-box}
body{margin:0;font:14px/1.5 -apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:var(--texte);background:#fff}
h1,h2,h3,h4{margin:0 0 .6em;font-weight:600;line-height:1.25}
h1{font-size:20px} h2{font-size:17px} h3{font-size:15px} h4{font-size:13px}
a{color:var(--bleu);text-decoration:none}
a:hover{text-decoration:underline}
code{font:12px/1.4 ui-monospace,Menlo,Consolas,monospace;background:var(--gris);padding:1px 5px;border-radius:3px}

/* ---------- Structure ---------- */
.wrap{display:flex;min-height:100vh}
/* En colonne : la pastille du compte se colle en bas par `margin-top:auto`. */
.side{width:250px;flex:0 0 250px;background:var(--bleu-fonce);color:#cfe3ea;padding:18px 0;position:sticky;top:0;height:100vh;overflow:auto;display:flex;flex-direction:column}
.side .brand{padding:0 18px 16px;border-bottom:1px solid rgba(255,255,255,.13);margin-bottom:12px}
.side .brand b{color:#fff;font-size:16px;display:block}
.side .brand span{font-size:11px;opacity:.7}
.side .grp{padding:14px 18px 5px;font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;opacity:.55}
/* `flex` et non `block` : le picto et le mot tiennent sur la meme ligne de base,
   et un libelle qui passe a la ligne s'aligne sous le texte, pas sous l'icone. */
.side a{display:flex;align-items:center;gap:9px;width:100%;text-align:left;color:#cfe3ea;padding:8px 18px;border-left:3px solid transparent;text-decoration:none}
.side a:hover{background:rgba(255,255,255,.07);color:#fff;text-decoration:none}
.side a.on{background:rgba(255,255,255,.12);color:#fff;border-left-color:#7fc4dd;font-weight:600}
/* Les ecrans non developpes ne paraissent plus dans le menu : ils occupaient des
   lignes grisees et inertes, la moitie du menu d'un compte production. Le style
   part avec eux — le garder ferait croire que la ligne existe encore quelque
   part, et le prochain a le lire chercherait ou. */
/* Le passage du travail du jour a ce qui se regle une fois. */
.side .sep-menu{height:1px;background:rgba(255,255,255,.13);margin:14px 18px 4px}

/* ---------- Pictogrammes du menu ----------
   Le trait suit `currentColor` : l'icone s'eclaircit avec le texte au survol et
   sur l'entree active, sans une regle de plus. `fill`, `stroke` et
   `stroke-width` sont HERITES — poses ici, ils descendent dans le contenu clone
   par `<use>`, ce que des attributs sur les formes empecheraient.
   `flex:0 0 auto` : l'icone ne se comprime pas quand le libelle est long. */
.ic{width:17px;height:17px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;opacity:.78}
.side a:hover .ic,.side a.on .ic{opacity:1}
.main{flex:1;min-width:0;background:var(--gris)}
.topbar{background:#fff;border-bottom:1px solid var(--bord);padding:14px 26px;display:flex;align-items:center;gap:14px;position:sticky;top:0;z-index:5}
.topbar h1{margin:0}
.topbar .note{margin-left:auto;font-size:12px;color:var(--texte2);max-width:46%;text-align:right}
.screen{padding:22px 26px 60px}

/* ---------- Composants ---------- */
.card{background:#fff;border:1px solid var(--bord);border-radius:var(--radius);margin-bottom:16px}
.card>header{padding:11px 15px;border-bottom:1px solid var(--bord);font-weight:600;display:flex;align-items:center;gap:10px;font-size:13px}
.card>.body{padding:15px}
.card>.body.plat{padding:0}
.grid{display:grid;gap:14px}
.g2{grid-template-columns:repeat(2,1fr)} .g3{grid-template-columns:repeat(3,1fr)} .g4{grid-template-columns:repeat(4,1fr)}
@media(max-width:1100px){.g3,.g4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:780px){.grid{grid-template-columns:1fr}}
.kpi{background:#fff;border:1px solid var(--bord);border-radius:var(--radius);padding:14px}
.kpi .lbl{font-size:11.5px;color:var(--texte2);text-transform:uppercase;letter-spacing:.05em}
.kpi .val{font-size:25px;font-weight:700;margin-top:3px}
.kpi .sub{font-size:11.5px;color:var(--texte2)}

table{width:100%;border-collapse:collapse;font-size:13px}
th{text-align:left;background:var(--bleu-clair);padding:8px 10px;font-weight:600;font-size:12px;border-bottom:1px solid var(--bord);white-space:nowrap}
td{padding:7px 10px;border-bottom:1px solid #eef1f3;vertical-align:middle}
tbody tr:hover{background:#fafcfd}
.num-col{text-align:right;font-variant-numeric:tabular-nums}
.tableau-scroll{overflow-x:auto}

.tag{display:inline-block;padding:2px 8px;border-radius:20px;font-size:11px;font-weight:600;white-space:nowrap}
.t-devis{background:var(--bleu-clair);color:var(--bleu-fonce)}
.t-cmd{background:var(--vert-clair);color:var(--vert)}
.t-prod{background:var(--orange-clair);color:var(--orange)}
.t-alerte{background:var(--rouge-clair);color:var(--rouge)}
/* Ce qui RÉCLAME un geste — une demande de commande en attente. Cerné, parce
   qu'un aplat de plus se serait fondu dans la file des étapes. */
.t-warn{background:var(--orange-clair);color:var(--orange);box-shadow:inset 0 0 0 1px var(--orange)}
/* Ce qui vient du portail client : une mention discrète, pas un état de plus. */
.t-client{background:var(--gris);color:var(--texte2)}
.t-neutre{background:var(--gris);color:var(--texte2)}

.btn{display:inline-block;background:var(--bleu);color:#fff;border:0;border-radius:var(--radius);padding:8px 14px;font:inherit;font-weight:600;cursor:pointer;text-decoration:none}
.btn:hover{background:var(--bleu-fonce);text-decoration:none;color:#fff}
.btn.sec{background:#fff;color:var(--texte);border:1px solid var(--bord);font-weight:500}
.btn.sec:hover{background:var(--gris);color:var(--texte)}
.btn.dgr{background:var(--rouge);color:#fff} .btn.dgr:hover{background:#96291d;color:#fff}
/* Destructif mais SECONDAIRE : supprimer n'est pas l'action principale d'une
   ligne, « ouvrir » l'est. Rouge sur blanc le dit sans crier — et le texte
   restait sombre sur fond rouge en combinant .sec et .dgr, donc illisible. */
.btn.sec.dgr{background:#fff;color:var(--rouge);border-color:var(--rouge)}
.btn.sec.dgr:hover{background:var(--rouge-clair);color:var(--rouge)}
.btn.sm{padding:5px 10px;font-size:12px}
/* « Ouvrir » et « Supprimer » cote a cote, sans se coller. */
.actions-lot{white-space:nowrap} .actions-lot > *{margin-right:5px}
.actions-lot > *:last-child{margin-right:0}

.field{margin-bottom:11px}
.field label{display:block;font-size:11.5px;color:var(--texte2);margin-bottom:3px;font-weight:600}
.field input,.field select,.field textarea{width:100%;padding:7px 9px;border:1px solid var(--bord);border-radius:var(--radius);font:inherit;background:#fff}
.field input:focus,.field select:focus,.field textarea:focus{outline:2px solid #7fc4dd;outline-offset:-1px;border-color:var(--bleu)}
.field .hint{font-size:11px;color:var(--texte2);margin-top:3px}
.field.err input,.field.err select{border-color:var(--rouge);background:var(--rouge-clair)}
.field.err .hint{color:var(--rouge);font-weight:600}
/* Ce qui sort du delai annonce, ou ce que l'atelier ne peut pas tenir : la
   couleur porte l'alerte, le mot la nomme — une couleur seule ne survit pas a
   une photocopie ni a un ecran mal regle. */
.retard{color:var(--rouge);font-weight:600}
.field input[readonly]{background:var(--gris);color:var(--texte2)}
/* Une valeur qui se LIT et ne se saisit pas — la date de creation d'un lot.
   Pas un input desactive : un champ grise invite quand meme a cliquer dedans,
   et on cherche pourquoi il ne repond pas. */
.field .fige{padding:7px 9px;border:1px solid var(--bord);border-radius:var(--radius);
  background:var(--gris);color:var(--texte2)}
/* Échelon retenu à la main alors qu'un plus petit conviendrait : ce n'est pas
   une erreur — le volet se fabrique — mais ça se voit. */
.field .hint.attention{color:var(--orange);font-weight:600}
.field select option:disabled{color:var(--texte2)}

/* Zone du schéma qui se règle : le survol l'annonce sans rien surcharger. */
.zone-clic{cursor:pointer}
.zone-clic:hover rect,.zone-clic:hover circle{stroke:var(--bleu);stroke-width:1.6}

/* Poignée d'un organe : le tube d'un moteur fait quelques pixels d'épaisseur sur
   un volet de deux mètres, et se manque au clic. Le rectangle transparent qui
   l'entoure prend le clic à sa place ; le survol le montre, en voile, pour qu'on
   voie toujours l'organe dessous — c'est LUI qui dit l'emprise réelle. */
.zone-clic rect.prise{fill:transparent;stroke:none;transition:fill .12s}
.zone-clic:hover rect.prise{fill:rgba(31,111,139,.16);stroke:none}

/* Teintes retenues, sous le schéma : une pastille par sous-ensemble. */
.teintes{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.teintes .teinte{display:inline-flex;align-items:center;gap:5px;font:inherit;font-size:11px;color:var(--texte2);
  background:#fff;border:1px solid var(--bord);border-radius:20px;padding:3px 9px 3px 4px;cursor:pointer}
.teintes .teinte:hover{border-color:var(--bleu);color:var(--bleu-fonce)}
.teintes .teinte i{width:14px;height:14px;border-radius:50%;border:1px solid var(--bord);display:block}

/* Pastille de coloris : un carré de couleur, pas un champ de formulaire. */
input.coloris{width:44px;height:28px;padding:2px;border:1px solid var(--bord);border-radius:4px;
  background:#fff;cursor:pointer}

/* Cote MODIFIABLE sur le schéma : on désigne le chiffre sur le plan, comme sur
   un relevé. Le survol montre la zone de préhension, plus large que le texte. */
.cote-clic{cursor:pointer}
.cote-clic rect{fill:transparent;transition:fill .12s}
.cote-clic:hover rect{fill:var(--bleu-clair)}
.cote-clic:hover text{fill:var(--bleu-fonce)}

/* Cote DÉDUITE de l'autre : saisissable — y taper la reprend comme donnée —
   mais grisée, pour qu'on voie laquelle des deux commande. */
.field input.deduit{background:var(--gris);color:var(--texte2);font-style:italic}
.field input.deduit:focus{background:#fff;color:var(--texte);font-style:normal}
.row{display:flex;gap:10px;flex-wrap:wrap} .row>*{flex:1;min-width:130px}
/* `display:flex` bat la regle navigateur `[hidden]{display:none}`, qui n'a que
   la specificite d'un type. Une .row marquee `hidden` restait donc VISIBLE : le
   JS demandait de la cacher, la CSS decidait le contraire, et en silence. */
.row[hidden]{display:none}
label.case{font-size:12.5px;display:inline-flex;align-items:center;gap:6px;margin-right:14px}
label.case input{width:auto}

.alert{padding:9px 12px;border-radius:var(--radius);font-size:12.5px;margin-bottom:9px;border-left:3px solid}
.a-info{background:var(--bleu-clair);border-color:var(--bleu)}
.a-warn{background:var(--orange-clair);border-color:var(--orange)}
.a-err{background:var(--rouge-clair);border-color:var(--rouge)}
.a-ok{background:var(--vert-clair);border-color:var(--vert)}

.kbd{display:inline-block;border:1px solid var(--bord);border-bottom-width:2px;border-radius:4px;padding:0 5px;font:11px ui-monospace,monospace;background:#fff}
.jauge{height:8px;background:#e6ebee;border-radius:5px;overflow:hidden;margin:5px 0 3px}
.jauge i{display:block;height:100%;background:var(--vert)}
.jauge i.warn{background:var(--orange)} .jauge i.err{background:var(--rouge)}
.pastille{display:inline-block;width:13px;height:13px;border-radius:3px;border:1px solid var(--bord);vertical-align:-2px;margin-right:5px}
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--bord);margin-bottom:14px;flex-wrap:wrap}
.tabs a{padding:8px 14px;font-size:13px;cursor:pointer;border:1px solid transparent;border-bottom:0;color:var(--texte2);text-decoration:none}
.tabs a.on{background:#fff;border-color:var(--bord);border-radius:var(--radius) var(--radius) 0 0;margin-bottom:-1px;color:var(--texte);font-weight:600}
.tabs a:hover{text-decoration:none}
/* ---------- Barre de filtre ----------
   UNE SEULE HAUTEUR, UNE SEULE POLICE, UN SEUL CADRE.

   Les regles ne visaient que trois selecteurs : `input[type=search]`,
   `input[type=text]` et `select`. Tout le reste retombait sur le style natif du
   navigateur, avec sa police et sa hauteur a lui :

     - `input[type=date]`  — aucune regle, d'ou les « jj/mm/aaaa » plus petits ;
     - un input SANS attribut `type` — `[type=text]` ne le matche PAS, meme si le
       navigateur le traite comme du texte. C'est le cas du champ client, qui
       paraissait donc plus court que la recherche a cote ;
     - les libelles `.mini` a 11,5 px et `.case` a 12,5 px, contre 14 px pour les
       champs : trois tailles de police sur une seule ligne.

   D'ou une regle par EXCLUSION plutot que par liste de types : tout ce qui se
   saisit est cadre pareil, et un champ d'un type qu'on n'a pas prevu le sera
   aussi. */
.searchbar{display:flex;gap:9px;align-items:center;margin-bottom:14px;flex-wrap:wrap}
.searchbar input:not([type=checkbox]):not([type=radio]),
.searchbar select{height:36px;padding:0 10px;border:1px solid var(--bord);border-radius:var(--radius);
  font:inherit;background:#fff;color:var(--texte)}
/* La recherche prend la place qui reste ; les autres champs gardent la leur. */
.searchbar input[type=search]{flex:1;min-width:220px}
/* Le bouton s'aligne sur la meme hauteur : `inline-flex` centre son texte sans
   dependre du calcul de line-height. `font-size:inherit` couvre aussi `.btn.sm` :
   une variante plus petite a sa place dans un tableau, pas dans une barre ou
   tout doit s'aligner. */
.searchbar .btn{height:36px;padding:0 14px;display:inline-flex;align-items:center;font-size:inherit}
/* Les LIBELLES DE CHAMP — « Du », « au », une case a cocher — prennent la taille
   et la hauteur des champs : c'est le gris qui fait la hierarchie, pas une
   seconde taille de police. La hauteur commune donne au passage a la case a
   cocher la meme zone de clic qu'aux autres controles.

   Les `.mini` qui ne sont pas des libelles — la note a cote d'un bouton Retour,
   « Limite a 200 resultats » — ne sont PAS visees : ce sont des phrases, pas des
   controles, et elles ont le droit de rester discretes. */
.searchbar label,.searchbar label.case{height:36px;font-size:inherit;color:var(--texte2);
  display:inline-flex;align-items:center;gap:6px;margin-right:0}
.callout{background:#fff;border:1px solid var(--bord);border-left:4px solid var(--bleu);border-radius:var(--radius);padding:13px 15px;margin-bottom:16px;font-size:13px}
.callout b{color:var(--bleu-fonce)}

.mono-sim{background:#0f1c22;color:#c8e6f0;padding:12px;border-radius:var(--radius);font:12.5px/1.75 ui-monospace,Menlo,Consolas,monospace;white-space:pre-wrap;overflow-x:auto}
.mono-sim .ok{color:#7ee0a3} .mono-sim .ko{color:#ff9d94} .mono-sim .dim{color:#6f8b96} .mono-sim b{color:#fff}

/* ------------------------------------------- CONFIGURATEUR : TROIS COLONNES
 *
 * Le schéma à gauche, la saisie au centre, le résultat à droite — et tout est
 * visible en même temps. C'est l'écran le plus important de l'application :
 * savoir ce qu'on vend ne doit pas demander d'ouvrir une seconde fenêtre.
 *
 * Sous 1400 px, le résultat passe sous les deux autres plutôt que de se
 * comprimer : un prix illisible ne sert à rien.
 */
/*
 * Le schéma rétrécit de 20 %, et l'espace rendu va à la saisie et au résultat :
 * un dessin se lit d'un coup d'œil, une nomenclature et une décomposition de
 * prix ont besoin de largeur pour rester lisibles sans troncature.
 */
.conf{display:grid;grid-template-columns:1fr 460px 400px;gap:14px;align-items:start}
.conf .col{background:#fff;border:1px solid var(--bord);border-radius:var(--radius)}
.conf .col>header{padding:10px 14px;border-bottom:1px solid var(--bord);font-weight:600;font-size:13px;
  display:flex;align-items:center;gap:8px}
.conf .col>.body{padding:14px}
@media(max-width:1400px){.conf{grid-template-columns:1fr 1fr}.conf .col:last-child{grid-column:1/-1}}

.prix-box{background:var(--bleu-fonce);color:#fff;padding:14px;border-radius:var(--radius);margin-bottom:12px}
.prix-box .t{font-size:11.5px;opacity:.8;text-transform:uppercase;letter-spacing:.05em}
.prix-box .v{font-size:29px;font-weight:700;line-height:1.1}
.prix-box .d{font-size:12px;opacity:.85;margin-top:6px;border-top:1px solid rgba(255,255,255,.2);padding-top:6px}
.prix-box .d div{display:flex;justify-content:space-between}

/* La TEINTE dit le mode de tarification. Les deux montants se ressemblent à
   l'écran alors qu'ils ne se défendent pas pareil : l'un est un tarif négocié,
   l'autre la somme des composants. */
.prix-box.p-tarif{background:var(--bleu-fonce)}
.prix-box.p-matiere{background:#4a3b6b}
.prix-box .t .mode{float:right;opacity:.85;text-transform:none;letter-spacing:0;font-weight:600}
.prix-box .autre{font-size:11.5px;opacity:.8;margin-top:7px;border-top:1px dashed rgba(255,255,255,.25);padding-top:6px}
.prix-box .autre b{font-weight:600}
.prix-box .autre span{opacity:.75}

/* Le supplément est au-dessus du prix : c'est en le regardant qu'on le décide. */
.field.supplement{max-width:190px;margin-bottom:14px}

/* Nomenclature : l'aperçu de la colonne, puis le tableau complet en modale. */
.bom-tete{display:flex;align-items:center;gap:10px;font-size:12.5px;font-weight:600;margin:14px 0 0}
.bom-tete .mini{font-weight:400}
.bom-tete .btn{margin-left:auto}
table.bom-table td{font-size:12.5px}
table.bom-table tr.n2 td:first-child,table.bom-table tr.n2 td:nth-child(2){color:var(--texte2)}
table.bom-table .tiret{color:var(--bord)}
table.bom-table .chute{font-size:10px;color:var(--orange);font-weight:600}
/* Sous-total et prix final : ce sont les deux lignes qu'on cherche du regard. */
table.bom-table tr.total td{background:var(--bleu-clair);border-top:1px solid var(--bord);font-weight:600}
table.bom-table tr.total td.mini{font-weight:400}
/* Onglets dans une modale : la modale porte déjà son fond. */
dialog.modale .tabs{border-bottom:1px solid var(--bord);background:var(--gris)}
dialog.modale.large{max-width:1000px}

/* -------------------------------------------------------------------- MODALE
 *
 * `<dialog>` natif : le navigateur gère le fond, la pile et la touche Échap.
 * Une modale maison réinventerait tout cela, moins bien.
 */
dialog.modale{border:1px solid var(--bord);border-radius:10px;padding:0;max-width:720px;width:calc(100% - 32px);
  box-shadow:0 18px 48px rgba(15,28,34,.24)}
dialog.modale::backdrop{background:rgba(15,28,34,.45)}
dialog.modale header{padding:12px 16px;border-bottom:1px solid var(--bord);font-weight:600;display:flex;
  align-items:center;gap:8px}
dialog.modale .body{padding:16px}
dialog.modale footer{padding:12px 16px;border-top:1px solid var(--bord);display:flex;gap:8px;justify-content:flex-end;
  background:var(--gris)}

/* PLANNING DE CHARGE : une colonne par jour ouvrable.
   Le week-end n'a pas sa colonne — l'atelier ne tourne pas, et deux colonnes
   vides par semaine ne feraient que retrecir les cinq autres. */
.charge-semaine{display:grid;grid-template-columns:repeat(5,minmax(150px,1fr));gap:1px;
  background:var(--bord);border-top:1px solid var(--bord)}
.charge-jour{background:#fff;padding:9px 10px;display:flex;flex-direction:column;gap:6px;min-width:0}
.charge-jour > header{display:flex;align-items:baseline;gap:6px}
.charge-jour .j-nom{font-weight:600;font-size:12.5px}
.charge-jour .j-date{font-size:11.5px;color:var(--texte2)}
/* Un jour SATURE se voit sans etre lu : c'est le seul moment ou l'on peut
   encore ajouter des heures plutot qu'allonger le delai promis. */
.charge-jour.sature{background:var(--rouge-clair)}
.charge-jour.ferme{background:var(--gris);color:var(--texte2)}
.charge-jour .j-etat{font-weight:600;font-size:12.5px;color:var(--texte2)}
.charge-jour .j-motif{font-size:11px;color:var(--texte2);font-style:italic}
.charge-jour .j-jauge{height:6px;background:var(--gris);border-radius:3px;overflow:hidden}
.charge-jour .j-jauge span{display:block;height:100%;background:var(--bleu)}
.charge-jour.sature .j-jauge span{background:var(--rouge)}
.charge-jour .j-chiffres{font-size:12.5px;font-variant-numeric:tabular-nums}
.charge-jour .j-reste{color:var(--texte2);font-size:11px;margin-left:4px}
/* Les heures que ces volets demandent : un repere de staffing, pas une donnee
   du calcul. D'ou le gris et la petite taille. */
.charge-jour .j-heures{font-size:11px;color:var(--texte2)}
.charge-jour .j-lot{display:flex;gap:6px;font-size:11.5px;padding:2px 5px;border-radius:3px;
  background:var(--bleu-clair);color:var(--bleu-fonce);text-decoration:none}
.charge-jour .j-lot b{margin-left:auto;font-variant-numeric:tabular-nums}
.charge-jour .j-lot:hover{background:var(--bleu);color:#fff}
/* Le depart au laqueur : de la marchandise qui S'EN VA, pas du montage. Une
   autre teinte donc, pour qu'on ne compte pas deux fois la meme journee. */
.charge-jour .j-laquage{display:flex;gap:6px;font-size:11.5px;padding:2px 5px;border-radius:3px;
  background:#fdf1e0;color:#8a4b08;text-decoration:none}
.charge-jour .j-laquage b{margin-left:auto;font-variant-numeric:tabular-nums}
.charge-jour .j-laquage:hover{background:#f0a94c;color:#fff}
/* Un depart deja passe : la date de montage ne tiendra pas. */
.charge-jour .j-laquage.impossible{background:#fde8e8;color:#a11;text-decoration:line-through}
.charge-jour .j-laquage.impossible:hover{background:#c00;color:#fff}
.charge-jour .j-saisie{display:flex;flex-wrap:wrap;gap:4px;align-items:center;margin-top:auto;
  padding-top:6px;border-top:1px dotted var(--bord)}
.charge-jour .j-saisie label{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--texte2)}
.charge-jour .j-saisie input[type=number]{width:64px;padding:3px 5px;border:1px solid var(--bord);
  border-radius:var(--radius);font:inherit;font-size:12px}
.charge-jour .j-saisie input[name=motif]{width:100%;padding:3px 5px;border:1px solid var(--bord);
  border-radius:var(--radius);font:inherit;font-size:11.5px}
.charge-jour .j-fermer{white-space:nowrap}

/* ---------- Planning de production ----------
   Il remplace deux classeurs Excel. On en garde la LECTURE : une colonne par
   journee, les chariots dedans dans l'ordre ou on les pousse, et une ligne par
   dossier. On en jette l'historique : ce qui est emballe sort du planning. */

/* Les tampons, en tete et en grand : l'objectif n'est pas un quota journalier
   mais un STOCK DEVANT CHAQUE POSTE. Un tampon vide est une alerte qui PRECEDE
   le probleme, la ou un quota manque se constate a 17 h. */
.tampons{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px}
.tampon{border:1px solid var(--bord);border-radius:var(--radius);padding:9px 11px;
  display:flex;flex-direction:column;gap:1px;background:var(--vert-clair)}
.tampon .etiq{font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--texte2)}
.tampon .compte{display:flex;align-items:baseline;gap:4px}
.tampon b{font-size:22px;line-height:1.1;font-variant-numeric:tabular-nums}
.tampon .sur{font-size:12.5px;color:var(--texte2);font-variant-numeric:tabular-nums}
/* Le poste va s'arreter faute de matiere : c'est la seule alerte de cet ecran,
   elle a donc droit au rouge en pleine surface. */
.tampon.vide{background:var(--rouge-clair);border-color:#eec8c4}
.tampon.vide b{color:var(--rouge)}

/* Le tableau : une colonne par journee, qui defile lateralement. Les jours ne
   se replient pas en dessous les uns des autres — on lit une semaine d'un
   regard, comme sur le classeur. */
.planning{display:flex;gap:1px;overflow-x:auto;background:var(--bord);
  border:1px solid var(--bord);border-radius:var(--radius);margin-top:14px}
/* `min-width:0` sinon un numero de chariot un peu long elargit SA colonne et
   les journees ne s'alignent plus : on lit alors des largeurs, pas des charges. */
.planning-jour{flex:0 0 260px;min-width:0;background:var(--gris);padding:9px;
  display:flex;flex-direction:column;gap:8px}
.planning-jour > header{display:flex;align-items:baseline;gap:6px}
.planning-jour > header b{font-size:12.5px}
/* La journee survolee pendant qu'on traine un chariot : poser dans le blanc
   veut dire « en fin de journee ». */
.planning-jour.survol{background:var(--bleu-clair);outline:2px dashed var(--bleu);outline-offset:-3px}

.chariot{background:#fff;border:1px solid var(--bord);border-radius:var(--radius);
  padding:7px 8px;display:flex;flex-direction:column;gap:4px;cursor:grab}
.chariot:active{cursor:grabbing}
.chariot > header{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.chariot > header a{font-weight:600;font-size:12.5px}
.chariot .typologie{font-size:11px;color:var(--texte2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chariot .charge{margin-left:auto;font-variant-numeric:tabular-nums}
/* Un chariot plein n'accepte plus rien : le dire ici evite un glisser qui sera
   refuse a l'arrivee. */
.chariot .charge.plein{color:var(--orange);font-weight:600}
.chariot.survol{outline:2px dashed var(--bleu);outline-offset:-2px;background:var(--bleu-clair)}

/* Une ligne par DOSSIER — « le suivi se fait sur la ligne ». Deux pastilles :
   l'avancement, et le tablier qui court en parallele et occupait sa propre
   colonne dans le fichier. */
.ligne-dossier{display:flex;align-items:center;gap:4px;font-size:11.5px;
  padding-top:3px;border-top:1px dotted var(--bord)}
.ligne-dossier b{font-weight:600;white-space:nowrap}
/* Le nom du client cede la place le premier : c'est le numero de dossier qu'on
   cherche des yeux, pas lui. */
.ligne-dossier .mini{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ligne-dossier .nb{margin-left:auto;font-variant-numeric:tabular-nums}
.ligne-dossier .liv{font-variant-numeric:tabular-nums;color:var(--texte2)}
/* Livre plus tard que ce qu'on avait promis : c'est la mesure que l'atelier
   suit, et elle se lit dossier par dossier. */
.ligne-dossier .liv.retard{color:var(--rouge);font-weight:600}
.pastille.t-tablier{background:var(--vert-clair);border-color:var(--vert)}
.tag.t-tablier{background:var(--vert-clair);color:var(--vert)}

/* Ce qui attend un chariot : des cartes qu'on prend a la souris. */
.attente{display:flex;flex-wrap:wrap;gap:8px;padding:12px}
.carte-dossier{flex:0 0 190px;background:#fff;border:1px solid var(--bord);border-radius:var(--radius);
  padding:7px 9px;display:flex;flex-direction:column;gap:1px;cursor:grab}
.carte-dossier:active{cursor:grabbing}
.carte-dossier b{font-size:12.5px}

/* Choix de la ligne de fabrication, a la creation d'un lot.
   Deux cibles larges : c'est un choix qu'on fait une fois et qu'on ne revient
   pas defaire, il vaut mieux le voir que le viser. */
.choix-ligne{display:flex;gap:12px;flex-wrap:wrap}
.choix-ligne .btn-ligne{flex:1 1 220px;display:flex;flex-direction:column;align-items:flex-start;gap:6px;
  padding:14px 16px;border:1px solid var(--bord);border-radius:var(--radius);background:#fff;
  cursor:pointer;font:inherit;text-align:left}
.choix-ligne .btn-ligne:hover{border-color:var(--bleu);background:var(--bleu-clair)}
.choix-ligne .btn-ligne.on{border-color:var(--bleu);border-width:2px;background:var(--bleu-clair);
  padding:13px 15px}
.choix-ligne .btn-ligne .tag{font-size:13px}

/* Choix du type de produit : une vignette par construction, dessinée. */
.produits{display:flex;gap:10px;flex-wrap:wrap;margin:4px 0 14px}
.produits button{width:96px;padding:8px 6px;border:1px solid var(--bord);background:#fff;border-radius:var(--radius);
  cursor:pointer;font:inherit;font-size:11.5px;text-align:center;color:var(--texte2)}
.produits button.on{border-color:var(--bleu);border-width:2px;background:var(--bleu-clair);color:var(--bleu-fonce);
  font-weight:600;padding:7px 5px}
.produits svg{width:100%;height:38px;display:block;margin-bottom:4px}
/* Le négoce n'est pas un type de volet : il ne mène pas au configurateur et ne
   se « sélectionne » pas — il ouvre sa propre saisie. Un léger décrochement le
   dit, sans l'exiler dans un coin de l'écran. */
.produits .produit-negoce{margin-left:auto;border-style:dashed}

.matrice{font-size:12px}
.matrice th{position:sticky;top:0}
.matrice td{padding:2px}
.matrice input{width:74px;padding:4px 6px;border:1px solid var(--bord);border-radius:4px;font:inherit;text-align:right;font-variant-numeric:tabular-nums}
.matrice input:focus{outline:2px solid #7fc4dd;outline-offset:-1px}
.matrice th.axe{background:var(--gris);color:var(--texte2);font-variant-numeric:tabular-nums;text-align:right}

.flash{padding:11px 15px;border-radius:var(--radius);margin-bottom:16px;font-size:13px;border-left:4px solid}
.flash.ok{background:var(--vert-clair);border-color:var(--vert)}
.flash.err{background:var(--rouge-clair);border-color:var(--rouge)}
.vide{padding:30px;text-align:center;color:var(--texte2);font-size:13px}
.actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:14px}
.actions.fin{justify-content:flex-end}
.mini{font-size:11.5px;color:var(--texte2)}

/* ---------- Sélecteur WinOrders ---------- */
/* En position fixe, rattachee a la modale ouverte ou au <body> : dans la cellule
   du tableau, le conteneur overflow-x:auto la rognerait et obligerait a faire
   defiler. Le z-index ne suffit pas face a une <dialog> modale, qui vit dans la
   couche superieure du navigateur — d ou le rattachement. */
.wo-suggestions{position:fixed;z-index:60;overflow:auto;background:#fff;
  border:1px solid var(--bord);border-radius:var(--radius);box-shadow:0 8px 24px rgba(0,0,0,.18)}
.wo-suggestions ul{margin:0;padding:0;list-style:none}
.wo-suggestions li{padding:6px 9px;cursor:pointer;font-size:12.5px;border-bottom:1px solid #eef1f3}
.wo-suggestions li:last-child{border-bottom:0}
.wo-suggestions li:hover,.wo-suggestions li.on{background:var(--bleu-clair)}
.wo-suggestions .r{font-weight:600} .wo-suggestions .d{color:var(--texte2)}
/* Ce qui n'est pas montre : sans ce compte, trente lignes se lisent comme la
   liste complete. */
.wo-suggestions .wo-reste{padding:6px 9px;font-size:11.5px;color:var(--texte2);background:var(--gris);
  border-top:1px solid var(--bord);position:sticky;bottom:0}
.wo-suggestions .p{float:right;font-variant-numeric:tabular-nums}
/* Ce que la liste propose AVANT toute frappe — « Vos derniers clients » —, dit
   pour qu'on ne prenne pas une suggestion pour un résultat de recherche. */
.wo-suggestions .wo-entete{padding:5px 9px;font-size:11px;font-weight:600;color:var(--texte2);
  background:var(--gris);border-bottom:1px solid var(--bord);position:sticky;top:0}
/* Ne rien trouver n'est pas une impasse : on crée depuis la liste. */
.wo-suggestions .wo-creer{display:block;margin-top:4px;color:var(--bleu);font-weight:600}
kbd{display:inline-block;padding:1px 5px;border:1px solid var(--bord);border-bottom-width:2px;
  border-radius:4px;background:var(--gris);font:inherit;font-size:11px;line-height:1.5}

/* La colonne « Partie » ne s'affiche que lorsqu'elle a quelque chose à dire :
   plusieurs profilés, ou un tablier qui se commande plein ou ajouré. Sur un
   sous-ensemble à un seul profilé, un champ libre juste avant la référence
   invitait à saisir la référence au mauvais endroit. */
.sans-partie .col-partie{display:none}

/* Plan des sorties de manœuvre.
   Les cases sont posées aux coordonnées du dessin, en pourcentage du même repère
   que le SVG : une case ne peut donc pas s'éloigner de sa flèche quand la carte
   change de largeur. */
/* Les proportions viennent du modèle, posées en style inline sur l'élément. */
.plan-sorties{position:relative;width:100%;max-width:420px;margin:0 auto 6px}
.plan-sorties svg{position:absolute;inset:0;width:100%;height:100%}
.sortie{position:absolute;transform:translate(-50%,-50%);display:inline-flex;align-items:center;gap:3px;
  background:#fff;padding:1px 3px;border-radius:4px;font-size:11.5px;color:var(--texte2);cursor:pointer;
  white-space:nowrap}
.sortie input{width:auto;margin:0}
.sortie span{min-width:12px;text-align:center;font-weight:600}
.sortie:has(input:checked){color:var(--bleu)}
.sortie:has(input:checked) span{background:var(--bleu-clair);border-radius:3px}
.sortie:has(input:disabled){opacity:.5}

/* Au devis on ne coche pas, on DÉSIGNE : une seule sortie, et la pastille se
   voit d'un coup d'œil sur la coupe. Le bouton radio lui-même n'apporte rien
   de plus que la surbrillance, il encombrerait un dessin déjà dense. */
.plan-sorties:has(input[type=radio]) .sortie input{position:absolute;opacity:0;pointer-events:none}
.plan-sorties:has(input[type=radio]) .sortie span{min-width:17px;padding:1px 4px;border:1px solid var(--bord);
  border-radius:9px;background:#fff}
.plan-sorties:has(input[type=radio]) .sortie:hover span{border-color:var(--bleu)}
.plan-sorties:has(input[type=radio]) .sortie:has(input:checked) span{background:var(--bleu);border-color:var(--bleu);
  color:#fff}
.plan-sorties:has(input[type=radio]) .sortie:has(input:focus-visible) span{outline:2px solid var(--bleu);
  outline-offset:2px}

/* La coupe de coffre en VIGNETTE, posée sur le schéma technique.
   Sa place est là où l'on regarde le volet : la sortie est une position, pas une
   valeur à saisir. En pleine largeur dans le formulaire elle repoussait tout le
   reste ; ici elle occupe un coin que le dessin laisse presque toujours libre. */
.schema-cadre{position:relative}
.vignette-sortie{position:absolute;top:0;right:0;width:36%;min-width:132px;max-width:180px;
  background:#fff;border:1px solid var(--bord);border-radius:var(--radius);padding:5px 6px 4px;
  box-shadow:0 1px 4px rgba(31,45,55,.09)}
.vignette-sortie .v-titre{font-size:10.5px;font-weight:600;color:var(--texte2);margin-bottom:2px}
.vignette-sortie .v-aide{font-size:10.5px;color:var(--texte2);line-height:1.25;margin-top:2px}
.vignette-sortie .v-aide.attention{color:var(--orange)}
/* En vignette le plan prend toute la largeur offerte : le plafond de 420 px
   vaut pour la fiche article, où le dessin est la pièce maîtresse. */
.vignette-sortie .plan-sorties{max-width:none;margin:0}
.vignette-sortie .sortie{font-size:9.5px;padding:0 1px}

/* Remarques du volet : deux onglets sous le schéma, un seul pavé visible.
   L'onglet se TEINTE quand sa remarque n'est pas vide — c'est tout l'intérêt :
   savoir qu'il y a quelque chose à lire sans avoir à ouvrir les deux. */
.remarques{margin-top:14px}
.remarques .tabs{margin-bottom:8px}
.remarques .tabs a{padding:6px 11px;font-size:12px;user-select:none}
.remarques textarea{width:100%;padding:8px 10px;border:1px solid var(--bord);border-radius:var(--radius);
  font:inherit;font-size:12.5px;resize:vertical}
/* La pastille suffit à distinguer le plein du vide : colorer le libellé entier
   ferait deux onglets criards dès qu'on écrit dans les deux. */
.remarques .tabs a.pleine{color:var(--bleu-fonce)}
.remarques .tabs a.pleine::before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--orange);margin-right:6px;vertical-align:1px}
.remarques .tabs a.pleine.on{background:var(--orange-clair);border-color:#e8cf9e}
.vignette-sortie .sortie span{min-width:13px;padding:0 3px}

/* Un type en sommeil se lit encore, mais s'efface : il n'est plus au catalogue. */
tr.en-sommeil td{opacity:.62}
tr.en-sommeil td:first-child{opacity:1}

/* Une lame intermédiaire posée : son nom, sa cote, et de quoi la retirer.
   La liste ne montre QUE ce qui est monté — un champ vide par candidate laissait
   croire que la lame était là et qu'on avait oublié sa hauteur. */
.lame-posee{display:flex;align-items:center;gap:8px;padding:5px 0;border-bottom:1px solid var(--bord)}
.lame-posee:last-child{border-bottom:0}
/* Le sous-ensemble à gauche, sa cote à droite : c'est l'ordre de la question. */
.lame-posee select{flex:1;min-width:0}
.lame-posee input[type=number]{width:92px;flex:none}

/* Le logo tel qu'il sortira sur le devis : sur damier, pour qu'un fond
   transparent se voie avant d'etre imprime sur du blanc. */
.apercu-logo{max-width:100%;max-height:90px;object-fit:contain;padding:6px;border:1px solid var(--bord);
  border-radius:var(--radius);background:#fff}

/* Le prix de VENTE, annonce avant d'ajouter la ligne. C'est le seul chiffre qui
   parle au client — le deboursé au-dessus ne le regarde pas. */
.apercu-negoce{display:flex;align-items:baseline;gap:10px;margin-top:14px;padding:10px 12px;
  background:var(--bleu-clair);border-radius:var(--radius);color:var(--bleu-fonce)}
.apercu-negoce .a-lignes{display:flex;flex-direction:column;gap:2px}
.apercu-negoce .a-unitaire{font-size:12.5px}
/* La piece finie, sous le prix au metre : c'est elle qu'on commande, et c'est
   d'elle que le total se refait de tete. */
.apercu-negoce .a-piece{font-size:12.5px;font-weight:600}
.apercu-negoce .a-total{margin-left:auto;font-size:15px}

/* Deux choix qui s'excluent : on clique celui qu'on veut, il reste allumé.
   Une liste déroulante à deux entrées demande deux gestes pour la même chose. */
.segments{display:inline-flex;border:1px solid var(--bord);border-radius:var(--radius);overflow:hidden}
.segment{padding:7px 16px;border:0;background:#fff;color:var(--texte2);font:inherit;cursor:pointer;
  border-right:1px solid var(--bord)}
.segment:last-child{border-right:0}
.segment:hover{background:var(--bleu-clair)}
.segment.on{background:var(--bleu);color:#fff}

/* Bloc repliable : replié il ne coûte qu'une ligne, déplié il tient lieu de doc. */
.memo>summary{display:flex;gap:12px;align-items:center;justify-content:space-between;
  padding:10px 14px;cursor:pointer;font-weight:600;background:var(--gris);
  border-radius:var(--radius);list-style:none}
.memo>summary::-webkit-details-marker{display:none}
.memo>summary::before{content:'▸';margin-right:6px;color:var(--texte2);font-weight:400}
.memo[open]>summary::before{content:'▾'}
.memo[open]>summary{border-bottom:1px solid var(--bord);border-radius:var(--radius) var(--radius) 0 0}
.memo>summary:hover{background:var(--bleu-clair)}
.memo>summary .mini{font-weight:400}

/* Une proposition « muette » nomme une variable indisponible ici : on la voit,
   on comprend pourquoi elle manque, on ne peut pas l'insérer par erreur. */
.wo-suggestions li.muet{cursor:default;opacity:.55;background:var(--gris)}
.wo-suggestions li.muet:hover{background:var(--gris)}

/* État d'une formule en cours de saisie, sous le champ. */
.formule-etat{margin-top:2px;line-height:1.35}
.formule-etat .ok{color:var(--vert)}
.formule-etat .ko{color:var(--rouge)}
.formule-etat .dim{color:var(--texte2)}
.formule-etat .attention{color:var(--orange);font-weight:600}

.cell{width:100%;padding:5px 7px;border:1px solid var(--bord);border-radius:4px;font:inherit}
.cell:focus{outline:2px solid #7fc4dd;outline-offset:-1px}

/* ------------------------------------------------------ RÉORDONNANCEMENT
 *
 * L'ordre des règles est celui de la nomenclature, donc celui que lira
 * l'atelier : il se règle en déplaçant la ligne.
 *
 * La prise est une poignée dédiée, jamais la ligne entière — une ligne pleine
 * de champs de saisie doit rester sélectionnable au clic.
 */
.rang-col{white-space:nowrap;color:var(--texte2);font-size:12px;text-align:center}
.poignee{display:inline-block;cursor:grab;padding:2px 4px;border-radius:4px;color:var(--texte2);
  line-height:1;user-select:none;touch-action:none}
.poignee:hover{background:var(--gris);color:var(--texte)}
.poignee:focus-visible{outline:2px solid #7fc4dd;outline-offset:1px}
.poignee:active{cursor:grabbing}
.rang{display:inline-block;min-width:14px}
tr.tiree{background:#eef6fb}
tr.tiree .poignee{cursor:grabbing}

/* ---------------------------------------------- COMPOSITION D'UN TYPE DE VOLET
 *
 * Une partie = un bloc, une option = une carte. Le tableau qui servait avant
 * lisait mal : quatre colonnes dont deux vides pour la plupart des parties, et
 * rien pour distinguer d'un coup d'œil l'option par défaut des alternatives.
 */
.bloc-partie{border:1px solid var(--bord);border-radius:10px;padding:12px 14px 14px;margin-bottom:14px;
  background:var(--fond-doux,#fbfcfd)}
.entete-partie{display:flex;align-items:center;gap:9px;margin-bottom:9px}
.entete-partie h4{margin:0;font-size:14px}
.compteur-se{color:var(--texte2);margin-right:auto}
.t-req{background:var(--orange-clair);color:var(--orange)}
.indice-echelle{margin:0 0 10px;color:var(--texte2);line-height:1.55}

.liste-se{display:flex;flex-direction:column;gap:8px}

/* L'option par défaut porte un liseré : c'est elle qui part si le devis ne dit
 * rien, l'information la plus utile du bloc. */
.option-se{display:flex;align-items:flex-start;gap:11px;background:#fff;
  border:1px solid var(--bord);border-left:3px solid transparent;border-radius:8px;padding:9px 10px}
.option-se.est-defaut{border-left-color:var(--bleu);background:var(--bleu-clair,#f4f9fc)}

.marque-defaut{display:inline-flex;flex-direction:column;align-items:center;gap:2px;
  font-size:10px;color:var(--texte2);cursor:pointer;padding-top:3px;user-select:none}
.option-se.est-defaut .marque-defaut{color:var(--bleu);font-weight:600}

.corps-se{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}
.corps-se select{width:100%}
.bornes-se{display:flex;flex-wrap:wrap;gap:14px}
.bornes-se label{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--texte2);white-space:nowrap}
.bornes-se input{width:104px;text-align:right}

.retirer-se{flex:none;align-self:center}
.ajout-se{margin-top:9px}

@media (max-width:640px){
  .option-se{flex-wrap:wrap}
  .bornes-se{gap:9px}
  .bornes-se label{white-space:normal}
}

/* Pastille de comptage dans un onglet : l'état du paramétrage se lit sans
   ouvrir les six. */
.pastille-compte{display:inline-block;min-width:18px;padding:0 5px;margin-left:5px;
  border-radius:9px;background:var(--gris);color:var(--texte2);
  font-size:11px;font-weight:600;text-align:center;font-variant-numeric:tabular-nums}
.tabs a.on .pastille-compte{background:var(--bleu-clair);color:var(--bleu-fonce)}
.panneau[hidden]{display:none}

/* Identification d'un type, en bandeau au-dessus des onglets : ces champs ne
   relèvent d'aucun onglet, ils qualifient le type entier. */
.bandeau-identite{padding:13px 15px 4px;background:var(--gris);border-bottom:1px solid var(--bord)}
.bandeau-identite .field{margin-bottom:8px}
.bandeau-identite .hint{margin-top:2px}

/* Deux niveaux d'onglets : les blocs de la page, puis les parties techniques.
   Le second niveau s'efface visuellement pour qu'on sache toujours où on est. */
.sous-tabs{background:var(--gris);border-bottom:1px solid var(--bord)}
.sous-tabs a{font-size:12.5px;padding:7px 12px}
.sous-tabs a.on{background:#fff}
.panneau[hidden],.sous-panneau[hidden]{display:none}

/* Mode de tarification : deux cartes à choisir, comme une option de composition. */
.option-mode{flex:1;min-width:270px;display:flex;align-items:flex-start;gap:9px;background:#fff;
  border:1px solid var(--bord);border-left:3px solid transparent;border-radius:8px;padding:10px 12px;cursor:pointer}
.option-mode.est-defaut{border-left-color:var(--bleu);background:var(--bleu-clair)}
.option-mode input{width:auto;margin-top:3px;flex:none}
.option-mode span{display:block}
.option-mode .mini{display:block;margin-top:3px;line-height:1.5}

/* Grille de tarif : 600 cases, la tête de ligne et l'en-tête doivent rester
   visibles quand on fait défiler, sinon on ne sait plus quelle case on lit. */
.grille-tarif{max-height:420px;overflow:auto}
.grille-tarif table{font-size:11.5px}
.grille-tarif th,.grille-tarif td{padding:3px 7px;white-space:nowrap}
.grille-tarif thead th{position:sticky;top:0;z-index:2}
.grille-tarif th.axe{position:sticky;left:0;z-index:1;background:var(--bleu-clair);text-align:right;font-weight:600}
.grille-tarif thead th:first-child{left:0;z-index:3}
.grille-tarif td.case-vide{background:var(--orange-clair);color:var(--orange);font-weight:600}

/* ------------------------------------------------------------------ CONNEXION
   Écran d'entrée : rien de l'application n'y transparaît, pas même le menu. */
body.nu{background:var(--gris);margin:0}
.connexion{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}
.carte-connexion{background:#fff;border:1px solid var(--bord);border-radius:12px;padding:28px;width:100%;
  max-width:360px;box-shadow:0 12px 32px rgba(15,28,34,.10)}
.carte-connexion .marque{font-size:26px;font-weight:700;color:var(--bleu-fonce);letter-spacing:-.4px}
.carte-connexion .field{margin-bottom:12px}
.carte-connexion .alert{margin:0 0 14px}


/* ------------------------------------------------- NAVIGATION EN SECTIONS
   Le paramétrage comptait dix entrées : la liste dépassait l'écran et ce qu'on
   cherchait était toujours en bas. Les sections se replient, seule celle où
   l'on travaille reste ouverte. */
.side .grp-pliable{border:0}
.side .grp-pliable>summary{padding:11px 18px 6px;font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;
  opacity:.62;cursor:pointer;list-style:none;display:flex;align-items:center;gap:6px;user-select:none}
.side .grp-pliable>summary::-webkit-details-marker{display:none}
.side .grp-pliable>summary::before{content:'▸';font-size:10px;opacity:.8;transition:transform .12s}
.side .grp-pliable[open]>summary::before{transform:rotate(90deg)}
.side .grp-pliable>summary:hover{opacity:1;color:#fff}
.side .grp-pliable[open]>summary{opacity:.9;color:#fff}


/* ---------------------------------------------------------- PIED DE MENU
   Identité sur une ligne, actions sur la suivante. Tout tenait sur une seule
   dans 250 px : le nom se tronquait en « Em… » et « Mot de passe » se cassait
   sur trois lignes. */
.compte{margin-top:auto;padding:12px 16px 14px;border-top:1px solid rgba(255,255,255,.14);font-size:12.5px}
.compte .identite{display:flex;align-items:center;gap:9px;min-width:0}
.compte i{width:30px;height:30px;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;flex:0 0 30px;
  display:flex;align-items:center;justify-content:center;font-style:normal;font-weight:600;font-size:11.5px}
.compte .nom{min-width:0;display:flex;flex-direction:column;line-height:1.3}
.compte .nom b{color:#eaf3f7;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.compte .nom .role{font-weight:400;font-size:10.5px;opacity:.66;text-transform:uppercase;letter-spacing:.04em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Alignées sous le nom, pas sous la pastille : 30 px + 9 px d écart. */
.compte .actions-compte{display:flex;align-items:center;gap:14px;margin-top:9px;padding-left:39px}
.compte .actions-compte a,.compte .actions-compte button{display:inline;width:auto;padding:0;border:0;border-left:0;
  background:none;color:#9fc2d0;font:inherit;font-size:11.5px;text-decoration:underline;cursor:pointer;white-space:nowrap}
.compte .actions-compte a:hover,.compte .actions-compte button:hover{color:#fff;background:none}
.compte form{margin:0}

/* Intertitre à l intérieur d une section dépliée. */
.side .sous-grp{padding:12px 18px 4px;font-size:10px;letter-spacing:.08em;text-transform:uppercase;opacity:.42}
/* Valeur HÉRITÉE de la fiche client : lisible, mais visiblement non saisie ici. */
.herite{color:var(--texte2);font-style:italic}
/* Le négoce est une ligne du même tableau que les produits : il se négocie de
   la même façon. Ses TROIS leviers tiennent dans la colonne des coefficients —
   un article ne se vend pas pareil selon qu'il se compte, se débite, ou demande
   une coupe. */
tr.ligne-negoce td{border-top:1px solid var(--bord)}
/* UNE SEULE LIGNE, quoi qu'il arrive : `nowrap`. L'intitulé passe au-dessus du
   champ — à côté, les trois libellés mangeaient la moitié de la colonne et le
   dernier levier repassait dessous. */
.negoce-leviers{display:flex;gap:8px;justify-content:flex-end;align-items:flex-end;flex-wrap:nowrap}
.negoce-leviers label{display:flex;flex-direction:column;gap:1px;font-size:10px;line-height:1.3;
  color:var(--texte2);text-align:right;white-space:nowrap}
.negoce-leviers input{width:66px}
/* Les flèches d'incrément coûtent 17 px par champ, qu'on n'a pas ici. */
.negoce-leviers input::-webkit-outer-spin-button,
.negoce-leviers input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.negoce-leviers input[type=number]{-moz-appearance:textfield;appearance:textfield}

/* Conditions par type de produit : la couleur dit l'origine de la valeur. */
table.conditions-par-produit{font-size:13px;margin-top:4px}
table.conditions-par-produit th{background:none;border-bottom:1px solid var(--bord);font-size:11.5px;
  color:var(--texte2);padding:4px 8px}
table.conditions-par-produit td{padding:5px 8px;border-bottom:1px solid #eef1f3}
table.conditions-par-produit input{width:100%;padding:5px 7px;border:1px solid var(--bord);border-radius:4px;
  font:inherit;text-align:right;color:var(--texte);font-weight:600}
/* Grisée : reprise de la fiche client, et elle continuera de la suivre. */
table.conditions-par-produit input.herite{color:#a6b0b8;font-weight:400;background:#fbfcfd}
table.conditions-par-produit .origine{font-size:11px;color:var(--texte2)}
table.conditions-par-produit .lien-rendre{background:none;border:0;color:var(--bleu);cursor:pointer;font:inherit;
  font-size:11px;text-decoration:underline;padding:0 0 0 6px}

/* ---------- Devis à imprimer ----------
 *
 * Une PIÈCE, pas un écran : format A4, en-tête repris sur chaque feuille, et
 * rien de ce qui ne regarde que la maison. La barre d'action ne s'imprime pas.
 *
 * Les dimensions sont en millimètres, comme le papier : c'est la seule unité qui
 * donne le même résultat à l'écran et à la sortie.
 */
body.nu{background:var(--gris)}
.dv-barre{max-width:210mm;margin:12px auto;padding:10px 14px;background:#fff;border:1px solid var(--bord);
  border-radius:var(--radius);display:flex;align-items:center;gap:14px}
.dv-barre .mini{margin-right:auto;color:var(--texte2)}
.dv-alerte{background:var(--orange-clair);border-color:#e8cf9e;color:#7a5200;display:block}
.dv-alerte a{margin-left:8px}

.dv-feuille{width:210mm;min-height:297mm;margin:0 auto 12px;padding:14mm 14mm 12mm;background:#fff;
  border:1px solid var(--bord);display:flex;flex-direction:column}

.dv-tete{display:flex;justify-content:space-between;gap:16mm;padding-bottom:6mm;border-bottom:2px solid var(--bleu)}
.dv-emetteur{display:flex;gap:10px;align-items:flex-start;font-size:11px;line-height:1.45;color:var(--texte2)}
.dv-emetteur img{max-width:38mm;max-height:22mm;object-fit:contain}
.dv-emetteur b{color:var(--texte);font-size:13px;display:block;margin-bottom:2px}
.dv-objet{text-align:right;font-size:11px;color:var(--texte2);min-width:60mm}
.dv-numero{font-size:16px;font-weight:700;color:var(--bleu);letter-spacing:.02em}
/* Encadré : c'est le bloc que l'œil cherche en premier sur un devis reçu. */
.dv-client{margin-top:4mm;padding:3mm 4mm;background:var(--gris);border-radius:var(--radius);text-align:left}
.dv-client b{color:var(--texte);font-size:12.5px}
/* L'eco-contribution d'une ligne : elle S'AJOUTE au prix affiche au-dessus, et
   c'est ce prix-la qui porte la remise. D'ou le « + », discret mais present. */
.dv-eco-ligne{margin-top:1mm;font-size:10.5px;color:var(--texte2);text-align:right}
/* « dont » se met en retrait sous le total : ce n'est pas une operation, c'est
   une precision sur la ligne du dessus. */
.dv-totaux tr.dv-dont th{padding-left:5mm;font-weight:400;font-style:italic}
.dv-totaux tr.dv-dont td{font-weight:400}
/* LA COLONNE DE GAUCHE porte l'emetteur PUIS la livraison. L'emetteur tient en
   quatre lignes ; tout le reste s'empilait a droite, et la feuille perdait en
   hauteur ce que la gauche laissait en blanc. */
.dv-gauche{display:flex;flex-direction:column;gap:4mm;align-items:flex-start}

/* LA LIVRAISON, encadree et nommee. Elle etait sous l'adresse de facturation,
   ou les deux se ressemblaient assez pour qu'on les confonde : une colonne
   d'ecart les separe mieux qu'un cadre. Le cadre reste parce que c'est le bloc
   que le client doit verifier en premier. */
.dv-livraison{padding:3mm 4mm;border:1.5px solid var(--bleu);border-radius:var(--radius);
  text-align:left;font-size:11.5px;line-height:1.45;max-width:78mm}
.dv-livraison .dv-etiq{display:block;font-size:9px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--bleu);font-weight:700;margin-bottom:1mm}
.dv-livraison .dv-date{display:block;font-size:15px;color:var(--texte);margin-bottom:1mm}
/* Une commande ne se signe plus : a la place du cadre, ce qui rassure. */
.dv-accuse{margin-top:5mm;padding:3mm 4mm;background:var(--gris);border-radius:var(--radius);font-size:11.5px}
.dv-accuse b{display:block;margin-bottom:1mm}

/* Un volet occupe un tiers de la hauteur utile : trois tiennent sur la feuille. */
.dv-volet{display:flex;gap:7mm;align-items:stretch;padding:4mm 0;border-bottom:1px solid var(--bord)}
.dv-plan{flex:0 0 58mm;display:flex;flex-direction:column;gap:2mm}
.dv-schema{width:100%;height:auto;display:block}
.dv-sans-plan{height:38mm;display:flex;align-items:center;justify-content:center;background:var(--gris);
  border:1px dashed var(--bord);border-radius:var(--radius);color:var(--texte2);font-size:11px}
/* La coupe du coffre : petite, sous la vue de face, avec sa légende. */
.dv-sortie{margin:0;display:flex;align-items:center;gap:3mm;color:var(--texte)}
.dv-sortie svg{flex:0 0 16mm;height:auto;fill:none;stroke:var(--texte2);stroke-width:1.2}
.dv-sortie figcaption{font-size:10px;color:var(--texte2);line-height:1.35}
/* Le côté en gras et sur sa ligne : c'est ce qui ne se rattrape pas une fois le
   coffre percé, et la coupe symétrique ne peut pas le montrer. */
.dv-sortie figcaption b{display:block;color:var(--texte);font-size:10.5px}
.dv-cote-seul{margin:0;font-size:10.5px;color:var(--texte)}

/* `flex` en colonne : le montant se pose en bas à droite par `margin-top:auto`. */
.dv-detail{flex:1;min-width:0;display:flex;flex-direction:column}
.dv-titre{display:flex;align-items:baseline;gap:8px;font-size:14px}
.dv-rang{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 5px;
  background:var(--bleu);color:#fff;border-radius:10px;font-size:11px;font-weight:700}
/* Le repere du volet — « Salon » — juste apres le produit. Une pastille et non
   du texte gris : c'est le mot que le client cherche des yeux pour retrouver SON
   volet dans la liste, pas une precision de second rang. */
.dv-repere{font-size:11.5px;padding:1px 7px;border-radius:20px;background:var(--gris);
  color:var(--texte2);white-space:nowrap}
.dv-dim{margin-left:auto;font-size:12px;color:var(--texte2);white-space:nowrap}
.dv-presentation{margin:1.5mm 0 0;font-size:11px;line-height:1.45;color:var(--texte2)}

/* La composition : trois colonnes, la teinte au bout, alignée d'une ligne à l'autre. */
.dv-composition{width:100%;border-collapse:collapse;margin-top:2mm;font-size:11px}
.dv-composition th{width:26mm;text-align:left;font-weight:400;color:var(--texte2);padding:1px 6px 1px 0;
  vertical-align:top}
.dv-composition td{padding:1px 0;vertical-align:top}
.dv-teinte{width:32mm;text-align:right;color:var(--texte2);white-space:nowrap}
/* Les choix du client, sous la composition. Meme grille pour que les deux
   colonnes s'alignent, un filet pour dire que ce n'est pas la meme nature :
   au-dessus ce qui est monte, ici ce qui a ete demande. */
.dv-choix{margin-top:1.5mm;padding-top:1.5mm;border-top:1px dotted var(--bord)}

.dv-options{list-style:none;margin:2mm 0 0;padding:2mm 0 0;border-top:1px dotted var(--bord);font-size:11px}
.dv-options li{display:flex;gap:8px;padding:1px 0}
.dv-options li span{color:var(--texte2)}
.dv-options li b{margin-left:auto;white-space:nowrap}

/* La remarque du client, telle qu'elle a été écrite pour lui. */
.dv-remarque{margin:2mm 0 0;padding-left:3mm;border-left:2px solid var(--bord);font-size:11px;
  line-height:1.45;color:var(--texte2);white-space:pre-line}
.dv-montant{margin-top:auto;padding-top:2mm;text-align:right;white-space:nowrap}
.dv-montant .dv-qte{font-size:12px;color:var(--texte2);margin-right:6px}
.dv-montant b{font-size:15px;color:var(--bleu)}

.dv-table{width:100%;border-collapse:collapse;margin-top:6mm;font-size:12px}
.dv-table th{text-align:left;padding:4px 8px;border-bottom:1px solid var(--bord);color:var(--texte2);font-size:11px}
.dv-table td{padding:5px 8px;border-bottom:1px solid #eef1f3}
.dv-nombre{text-align:right;white-space:nowrap}

.dv-totaux{margin:8mm 0 0 auto;border-collapse:collapse;font-size:13px;min-width:70mm}
.dv-totaux th{text-align:left;padding:4px 12px 4px 0;font-weight:400;color:var(--texte2)}
.dv-totaux td{text-align:right;padding:4px 0;font-weight:600;white-space:nowrap}
.dv-ttc th,.dv-ttc td{border-top:1px solid var(--bord);padding-top:6px;font-size:15px;color:var(--bleu);font-weight:700}

.dv-signature{display:flex;justify-content:space-between;align-items:flex-start;gap:10mm;margin-top:10mm}
.dv-case{flex:0 0 70mm;height:28mm;border:1px solid var(--bord);border-radius:var(--radius)}
.dv-mentions{margin-top:8mm;font-size:10px;line-height:1.6;color:var(--texte2)}
.dv-mentions p{margin:0 0 3px}
/* `margin-top:auto` cloue le pied en bas de la feuille, même à moitié remplie. */
.dv-pied{margin-top:auto;padding-top:5mm;border-top:1px solid var(--bord);display:flex;justify-content:space-between;
  gap:10px;font-size:9.5px;color:var(--texte2)}

@media print{
  /* La marge est celle de la feuille : celle du navigateur ferait doublon. */
  @page{size:A4;margin:0}
  body.nu{background:#fff}
  .dv-barre{display:none}
  .dv-feuille{margin:0;border:0;box-shadow:none;break-after:page;page-break-after:always}
  .dv-feuille:last-child{break-after:auto;page-break-after:auto}
  /* Un volet coupé en deux par un saut de page ne se lit plus. */
  .dv-volet{break-inside:avoid;page-break-inside:avoid}
}

/* ---------------------------------------------- DOSSIER D'ATELIER

   Des feuilles, pas des écrans : elles se posent sur un établi, se lisent de
   loin et se cochent au crayon. D'où des caractères plus gros que partout
   ailleurs dans l'application, et beaucoup de blanc entre les lignes. */
.barre{max-width:210mm;margin:12px auto;padding:10px 14px;background:#fff;border:1px solid var(--bord);
  border-radius:var(--radius);display:flex;gap:10px;align-items:center}
.barre .mini{margin-right:auto;color:var(--texte2)}

.page{width:210mm;min-height:297mm;margin:12px auto;padding:12mm 12mm 14mm;background:#fff;
  border:1px solid var(--bord);box-sizing:border-box;font-size:11.5px}
.page .tete{display:flex;gap:14px;align-items:flex-start;border-bottom:2px solid var(--texte);
  padding-bottom:4mm;margin-bottom:5mm}
.page .surtitre{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--texte2)}
.page h1{margin:2px 0 3px;font-size:22px}
/* Le client et la référence : ce sont eux qu'on cherche quand on retrouve une
   feuille posée sur un volet, plus gros donc que le reste du détail. */
.page .qui{font-size:14px;margin-top:1mm}
.page .qui .cde{color:var(--texte2);font-size:12px;margin-left:6px}
.page .ref{font-size:12.5px;color:var(--texte2);margin-top:.5mm}

/* Casier et code-barres vont ensemble, calés à droite de l'en-tête. */
.page .droite{margin-left:auto;display:flex;gap:6mm;align-items:center}
/* LE CASIER SE LIT À BOUT DE BRAS : c'est le nombre qu'on cherche en chargeant
   le chariot, il n'a pas à se disputer la place avec le reste. */
.page .casier{text-align:center;border:2px solid var(--texte);border-radius:var(--radius);
  padding:1mm 4mm;min-width:20mm}
.page .casier .etiq{display:block;font-size:8.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--texte2)}
.page .casier b{font-size:30px;line-height:1.05;display:block}
.page .code{text-align:right}
.page .note{font-size:10.5px;color:var(--texte2);margin:0 0 4mm}
.page .vide{padding:14mm;text-align:center;color:var(--texte2)}
.page table{width:100%;border-collapse:collapse}
.page th{text-align:left;font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--texte2);
  border-bottom:1px solid var(--bord);padding:2mm 1.5mm}
.page td{padding:1.6mm 1.5mm;border-bottom:1px solid #edf1f3;vertical-align:top}
.page td.num,.page th.num{text-align:right}
/* La case se coche au crayon : elle doit être grande et bien détachée. */
.page td.coche{font-size:15px;line-height:1;color:var(--texte2)}
.page td.lg{font-size:13px}
/* Le casier sur la ligne de débit : la pièce se range dans le chariot en
   sortant de scie, ce nombre doit sauter aux yeux comme le repère. */
.page td.casier-col{text-align:center;font-weight:700;font-size:13px}
.page .mini{font-size:9.5px;color:var(--texte2)}

.page .corps{display:flex;gap:6mm;margin-bottom:5mm}
.page .dessin{flex:1;min-width:0}
.page .dessin svg{width:100%;height:auto}
.page .fiche{width:62mm;flex:0 0 62mm}
.page .bloc{border:1px solid var(--bord);border-radius:var(--radius);padding:2.5mm 3mm;margin-bottom:3mm}
.page .bloc .etiq{font-size:9px;text-transform:uppercase;letter-spacing:.05em;color:var(--texte2);display:block}
.page .grille{display:grid;grid-template-columns:1fr 1fr;gap:2.5mm}
.page .grille b{font-size:14px}

.page .profil{margin-bottom:5mm;break-inside:avoid;page-break-inside:avoid}
.page .profil-tete{display:flex;gap:8px;align-items:baseline;background:var(--gris);padding:2mm 2.5mm;
  border-radius:var(--radius) var(--radius) 0 0}
.page .profil-tete .teinte{font-size:10px;color:var(--texte2)}
.page .profil-tete .cumul{margin-left:auto;font-size:10px;color:var(--texte2)}
.page tr.se > td{background:#f7f9fa;padding-top:2.5mm}
/* Le « × 2 » des sous-ensembles réunis : il doit se voir, sinon on croit
   n'en monter qu'un seul. */
.page .fois{margin-left:4px;padding:0 5px;border-radius:9px;background:var(--texte);color:#fff;font-size:10px}
/* Une piece qui revient du laqueur ne se coupe pas : elle se ramasse. Le
   bandeau la distingue au premier coup d'oeil dans la nomenclature, ou tout le
   reste est a prendre au stock. */
.page tr.laque > td{background:#fdf6ec}
.page .revient{margin-left:5px;padding:0 5px;border-radius:9px;background:#8a5a00;color:#fff;font-size:9px;
  text-transform:uppercase;letter-spacing:.04em}

/* ---- ÉTIQUETTES : 16 sur A4, 105 × 37 mm, deux colonnes de huit.
   210 × 296 mm au total : la planche tombe pile, sans marge. Un décalage d'un
   millimètre ferait dériver la huitième rangée hors du support. */
.planche{width:210mm;height:296mm;margin:12px auto;background:#fff;border:1px solid var(--bord);
  display:grid;grid-template-columns:105mm 105mm;grid-template-rows:repeat(8, 37mm);box-sizing:border-box}
.etiquette{width:105mm;height:37mm;padding:3mm 4mm;box-sizing:border-box;overflow:hidden;
  display:flex;flex-direction:column;gap:.6mm}
.etiquette .rep{font-size:17px;font-weight:700;line-height:1.05}
.etiquette .qui{font-size:10px;color:var(--texte2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Ou la piece se pose — « Salon ». Lisible sans etre le titre : le poseur la
   cherche APRES avoir trouve l'etiquette par son repere. Une seule ligne, coupee
   au besoin : 105 x 37 mm ne pardonnent pas un retour a la ligne. */
.etiquette .ou{font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.etiquette .dim{font-size:11px;font-weight:600}
.etiquette .cb{margin-top:auto}
.etiquette .cb svg{display:block}
/* Les emplacements sautés d'une planche entamée : rien dessus, mais la place. */
.etiquette.vide{visibility:hidden}

@media print{
  .page{margin:0;border:0;break-after:page;page-break-after:always}
  .page:last-of-type{break-after:auto;page-break-after:auto}
  .planche{margin:0;border:0}
  /* Le trait de découpe n'existe pas sur la planche : c'est du prédécoupé. */
  .etiquette{border:0}
  /* Le filigrane se rejoue sur CHAQUE feuille : les pages se separent au poste,
     et c'est la liste de debit seule qui finit entre les mains de l'operateur. */
  .filigrane{position:fixed}
}

/* ---- DOSSIER NON COMMANDE ----
   La feuille est juste, mais ce qu'elle decrit n'est pas engage. Elle doit se
   reconnaitre A UN METRE : une liste de debit qui traine au poste se debite,
   qu'elle vienne d'une commande ou non. D'ou le travers, la taille, et le rouge.
   `pointer-events:none` : le filigrane ne doit rien intercepter a l'ecran. */
.filigrane{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;
  pointer-events:none;z-index:5}
.filigrane span{font-size:64px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:rgba(170,17,17,.13);border:6px solid rgba(170,17,17,.13);padding:10px 34px;border-radius:10px;
  transform:rotate(-24deg);white-space:nowrap}

/* Un repère bloqué se repère de loin : c'est lui qui retient tout le dossier. */
tr.repere-bloque > td{background:var(--rouge-clair)}
tr.repere-bloque > td:first-child{box-shadow:inset 3px 0 0 var(--rouge)}
/* Le casier se retape sur place : un champ étroit, dans la colonne du tableau. */
input.casier{width:52px;padding:3px 5px;border:1px solid var(--bord);border-radius:4px;font:inherit;
  font-size:12px;text-align:center;font-weight:600}

/* Le détail par construction, sous le total : des pastilles fines qui n'écrasent
   pas le chiffre qu'elles annotent. */
.detail-volets{display:inline-flex;gap:3px;flex-wrap:wrap;margin-left:4px}
.detail-volets .tag{padding:1px 6px;font-size:10px;font-weight:600}

/* ---- LE BON DU LAQUEUR : c'est SON document, pas le notre. ----
   Il reprend son en-tete, ses cadres et son pied a deux signatures : c'est la
   feuille qu'il recoit tous les jours et qu'il lit d'un coup d'oeil. */
.bon-laqueur .bon-tete{display:flex;align-items:flex-start;gap:20px;margin-bottom:14px}
.bon-laqueur .bon-de,.bon-laqueur .bon-contact{font-size:11px;line-height:1.45;flex:0 0 auto}
.bon-laqueur .bon-contact{margin-left:auto;text-align:right}
.bon-laqueur .bon-objet{flex:1;text-align:center}
.bon-laqueur .bon-objet h1{margin:0;font-size:19px}
.bon-laqueur .bon-objet div{font-weight:700;font-size:15px}
.bon-laqueur .bon-identite{width:100%;border-collapse:collapse;margin-bottom:12px;font-size:12px}
.bon-laqueur .bon-identite td{padding:3px 6px;vertical-align:bottom}
.bon-laqueur .bon-identite .souligne{border-bottom:1px solid #000}
.bon-laqueur .bon-identite .cadre{border:2px solid #000;text-align:center;padding:4px 6px}
.bon-laqueur .rouge{color:#c00;font-size:9px}
.bon-laqueur .bon-teinte{border-collapse:collapse;margin:0 auto 10px;font-size:12px}
.bon-laqueur .bon-teinte th,.bon-laqueur .bon-teinte td{border:1px solid #000;padding:3px 16px;text-align:center}
.bon-laqueur .bon-teinte thead th{font-weight:700}
.bon-laqueur .bon-teinte tbody th{text-align:left;font-weight:700}
.bon-laqueur .bon-cote{display:flex;align-items:center;justify-content:center;gap:10px;
  margin:0 auto 14px;padding:4px 10px;border:2px solid #000;width:max-content;font-size:12px}
/* Le cote NON retenu se raye, comme sur le bon papier : ce qui reste lisible
   prouve qu'on a choisi, la ou une case vide laisse penser qu'on a oublie. */
.bon-laqueur .bon-cote .raye{text-decoration:line-through;color:#666;font-weight:400}
.bon-laqueur .bon-cote .retenu{font-size:15px}
.bon-laqueur .bon-lignes{width:100%;border-collapse:collapse;font-size:12px}
.bon-laqueur .bon-lignes th,.bon-laqueur .bon-lignes td{border:1px solid #000;padding:3px 6px}
.bon-laqueur .bon-lignes .num{text-align:right}
.bon-laqueur .bon-bas{display:flex;gap:14px;margin-top:14px}
.bon-laqueur .bon-remarques{flex:1;border:1px solid #000;padding:6px 8px;min-height:70px;font-size:12px}
.bon-laqueur .bon-signatures{display:flex;flex:1;gap:0;border:2px solid #000;font-size:12px}
.bon-laqueur .bon-signatures div{flex:1;padding:6px 8px;min-height:70px}
.bon-laqueur .bon-signatures div+div{border-left:2px solid #000}

/* ---------------------------------------------------------------------------
   LA BARRE D'ENREGISTREMENT DE LA FICHE SOUS-ENSEMBLE.

   La page est longue — identification, technique, correspondances, regles — et
   un bouton pose en bas n'est jamais sous la main au moment ou l'on vient de
   modifier quelque chose en haut. La barre suit donc le defilement, et c'est
   elle qui dit s'il reste des modifications non enregistrees.
--------------------------------------------------------------------------- */
.barre-enregistrer{position:sticky;bottom:0;z-index:4;display:flex;gap:10px;align-items:center;
  flex-wrap:wrap;padding:12px 14px;margin:14px 0 0;background:#fff;
  border:1px solid var(--bord);border-radius:var(--radius);
  box-shadow:0 -2px 10px rgba(0,0,0,.06)}
/* Modifie et pas encore enregistre : la barre change de ton, sans crier. */
.barre-enregistrer.modifiee{border-color:var(--orange);background:var(--orange-clair)}
.barre-enregistrer.modifiee #etatFiche{color:var(--orange);font-weight:600}
