/* ==========================================================================
   SignFlow — style.css
   Design : clair (glass), rupture volontaire avec le sombre actuel — voir
   NOTES-handoff.md pour basculer les tokens en sombre si vous préférez garder
   l'existant. Aucune police externe : stacks système uniquement (hors-ligne).
   Toutes les variables demandées sont conservées à l'identique ; les classes
   listées sont toutes couvertes, y compris celles sans usage direct dans ce
   design (stylées de façon neutre plutôt que supprimées).
   ========================================================================== */

:root{
  /* --- variables imposées : NE PAS renommer --- */
  --bg:#EDF1F7;
  --panel:rgba(255,255,255,.86);
  --panel-2:rgba(120,140,170,.10);
  --border:rgba(15,23,42,.10);
  --text:#0B1220;
  --muted:#6B7280;
  --accent:#0A84FF;
  --danger:#C0392B;
  --ok:#0E9F6E;
  --warn:#B4740E;
  --wl:#E3001B;
  --mp:#7C3AED;

  /* --- tokens additionnels (dérivés des couleurs ci-dessus) --- */
  --accent-soft:rgba(10,132,255,.13);
  --ok-soft:rgba(14,159,110,.13);
  --danger-soft:rgba(192,57,43,.12);
  --warn-soft:#FBEDC6;
  --wl-soft:rgba(227,0,27,.10);
  --mp-soft:rgba(124,58,237,.12);
  --border-strong:rgba(15,23,42,.22);

  --radius-lg:20px;
  --radius-md:14px;
  --radius-sm:10px;
  --radius-pill:999px;

  --shadow-sm:0 1px 3px rgba(15,23,42,.10);
  --shadow-md:0 14px 40px -24px rgba(15,23,42,.45);

  --font-sans:-apple-system,"Segoe UI",Roboto,system-ui,sans-serif;
  --font-mono:ui-monospace,"SF Mono",Consolas,monospace;

  --tap-min:48px; /* cible tactile minimale, tablette terrain */
}

*{box-sizing:border-box}
html,body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-sans);font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased}
button,input,select,textarea{font:inherit;color:inherit}
a{color:var(--accent)}
a:hover{color:#0070E0}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}

/* ==========================================================================
   1. Structure et mise en page
   ========================================================================== */

.wizard-header{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:14px 20px;background:var(--panel);border-bottom:1px solid var(--border);
  position:sticky;top:0;z-index:30;backdrop-filter:blur(20px) saturate(160%);-webkit-backdrop-filter:blur(20px) saturate(160%);
}

.wizard-content{
  max-width:900px;margin:0 auto;padding:20px 20px 140px;
  display:flex;flex-direction:column;gap:16px;width:100%;
}

.stepbar{
  display:flex;align-items:center;gap:6px;overflow-x:auto;-ms-overflow-style:none;scrollbar-width:none;
  padding:10px 20px;background:var(--panel-2);border-bottom:1px solid var(--border);
}
.stepbar::-webkit-scrollbar{display:none}

.step{
  display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:var(--radius-pill);
  font-size:13.5px;font-weight:500;color:var(--muted);white-space:nowrap;flex:none;
}
.step::before{
  content:attr(data-step-index);display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;border-radius:50%;background:var(--panel-2);color:var(--muted);
  font-size:12px;font-weight:700;flex:none;
}
.step[aria-current="step"]{color:var(--text);font-weight:700;background:var(--accent-soft)}
.step[aria-current="step"]::before{background:var(--accent);color:#fff}
.step.done{color:var(--ok)}
.step.done::before{content:"✓";background:var(--ok);color:#fff}

.bottombar{
  position:sticky;bottom:0;left:0;right:0;z-index:30;
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:14px 20px;background:var(--panel);border-top:1px solid var(--border);
  backdrop-filter:blur(20px) saturate(160%);-webkit-backdrop-filter:blur(20px) saturate(160%);
}

.card{
  background:var(--panel);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:20px 22px;box-shadow:var(--shadow-md);
}
.card + .card{margin-top:0}

.bloc-fiche{
  border:1px solid var(--border);border-radius:var(--radius-md);background:rgba(255,255,255,.55);
  padding:16px 18px;display:flex;flex-direction:column;gap:12px;
}

.section-title{font-size:16px;font-weight:700;margin:0 0 4px;letter-spacing:-.01em}
.section-sub{margin:0 0 12px;color:var(--muted);font-size:13px;line-height:1.5;max-width:62ch}

.form-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;
}
.field{display:flex;flex-direction:column;gap:6px}
.field label{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);font-weight:600}
.field input,.field select,.field textarea{
  width:100%;min-height:var(--tap-min);padding:11px 13px;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:#fff;font-size:15px;transition:.14s;
}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent)}
.field input::placeholder,.field textarea::placeholder{color:var(--muted)}
.field textarea{resize:vertical;min-height:90px;line-height:1.5}

/* ==========================================================================
   2. Choix et saisie
   ========================================================================== */

.chip-row{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  display:inline-flex;align-items:center;justify-content:center;padding:9px 16px;min-height:var(--tap-min);
  border-radius:var(--radius-pill);border:1px solid var(--border);background:#fff;
  font-size:14px;font-weight:500;color:var(--text);cursor:pointer;transition:.14s;
}
.chip:hover{border-color:var(--border-strong)}
.chip.on{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}

.choice-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px}
.choice-card{
  position:relative;text-align:left;padding:16px 18px;min-height:var(--tap-min);
  border-radius:var(--radius-md);border:1px solid var(--border);background:#fff;
  cursor:pointer;transition:.14s;
}
.choice-card:hover{border-color:var(--border-strong)}
.choice-card.on{border-color:var(--accent);border-width:2px;background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent)}

.qty-control{display:inline-flex;align-items:center;gap:12px}
.qty-control button{
  width:var(--tap-min);height:var(--tap-min);border-radius:50%;border:1px solid var(--border);
  background:#fff;font-size:18px;line-height:1;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
}
.qty-control button:hover{background:var(--panel-2)}
.qty-control span,.qty-control output{min-width:24px;text-align:center;font-family:var(--font-mono);font-size:16px;font-weight:600}

.time-select-pair{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end}
.time-select-pair > *{flex:1;min-width:160px}

.addr-wrap{position:relative}
.addr-suggestions{
  position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:20;
  background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);
  box-shadow:var(--shadow-md);overflow:hidden;max-height:260px;overflow-y:auto;
}
.addr-suggestion{
  padding:12px 14px;font-size:14px;cursor:pointer;border-bottom:1px solid var(--border);min-height:var(--tap-min);
  display:flex;align-items:center;
}
.addr-suggestion:last-child{border-bottom:none}
.addr-suggestion:hover,.addr-suggestion:focus{background:var(--panel-2)}

.champ-en-erreur{border-color:var(--danger) !important;background:var(--danger-soft)}
.champ-en-erreur:focus{border-color:var(--danger) !important}

/* ==========================================================================
   3. Boutons
   ========================================================================== */

/* le bouton principal est le <button> nu */
button{
  padding:12px 20px;min-height:var(--tap-min);border-radius:var(--radius-md);
  border:1px solid var(--accent);background:var(--accent);color:#fff;
  font-size:15px;font-weight:600;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  cursor:pointer;transition:.14s;
}
button:hover{background:#0070E0;border-color:#0070E0}
button:active{transform:translateY(1px)}
button:disabled{opacity:.45;cursor:not-allowed}

.btn-secondary{
  background:#fff;color:var(--text);border:1px solid var(--border);
}
.btn-secondary:hover{background:var(--panel-2);border-color:var(--border-strong)}

.btn-danger{
  background:#fff;color:var(--danger);border:1px solid rgba(192,57,43,.35);
}
.btn-danger:hover{background:var(--danger-soft)}

/* ==========================================================================
   4. Fiches produit et points de vente
   ========================================================================== */

.terminal-product-card{
  border:1px solid var(--border);border-radius:var(--radius-md);background:#fff;
  padding:15px 16px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;
}

.unite-row{
  display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;
  padding:10px 0;border-top:1px solid var(--border);
}
.unite-row:first-child{border-top:none}

.lien-fiche-terminal{font-size:13px;text-decoration:underline;cursor:pointer}

.fiche-terminal-overlay{
  position:fixed;inset:0;z-index:90;background:rgba(11,18,32,.55);
  display:flex;align-items:center;justify-content:center;padding:24px;
}
.fiche-terminal-modal{
  background:#fff;border-radius:var(--radius-lg);max-width:720px;width:100%;max-height:88vh;overflow-y:auto;
  padding:24px;box-shadow:var(--shadow-md);
}
/* Photos des terminaux sans modèle 3D (les PAX) : une vignette de 180 px de
   haut perdue dans une fenêtre de 720 px ne montrait rien. La photo occupe
   maintenant le même cadre que la visionneuse 3D. */
.fiche-terminal-galerie{display:flex;gap:10px;overflow-x:auto;padding-bottom:6px}
.fiche-terminal-galerie img{
  height:auto;width:100%;max-height:46vh;object-fit:contain;
  border-radius:var(--radius-md);background:var(--panel-2);border:none;
  aspect-ratio:4/3;flex:1 1 0;min-width:0;
}
/* Plusieurs photos : elles restent côte à côte, un peu plus petites. */
.fiche-terminal-galerie:not(.solo) img{max-height:34vh}
/* Caractéristiques en pastilles plutôt qu'en liste à puces : on les parcourt
   du regard comme les pastilles de résumé des points de vente, au lieu de lire
   trois colonnes de texte (demande Olivier, 2026-08-04). */
.fiche-terminal-specs{
  display:flex;flex-wrap:wrap;gap:6px;margin:14px 0 0;padding:0;list-style:none;
}
.fiche-terminal-specs li{
  display:inline-flex;align-items:center;padding:5px 12px;
  border-radius:var(--radius-pill);background:var(--panel-2);color:var(--text);
  font-size:12.5px;font-weight:600;line-height:1.35;
}
/* La visionneuse n'a pas de taille intrinsèque : sans ces règles elle garde son
   300×150 par défaut au milieu du cadre, le terminal paraît lointain et le zoom
   se retrouve rogné par une fenêtre minuscule (constaté 2026-08-04).
   `max-height` garde le titre et les caractéristiques visibles sans défiler. */
.fiche-terminal-3d{
  position:relative;
  width:100%;aspect-ratio:4/3;max-height:46vh;
  border-radius:var(--radius-md);background:var(--panel-2);
  display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:13px;
}
.fiche-terminal-3d model-viewer{position:absolute;inset:0;width:100%;height:100%;display:block}
.fiche-terminal-aide{margin-top:12px;padding:10px 12px;border-radius:var(--radius-sm);background:var(--accent-soft);color:var(--accent);font-size:13px}
.fiche-terminal-chargement{
  display:flex;align-items:center;justify-content:center;min-height:180px;color:var(--muted);font-size:13.5px;
}

/* ==========================================================================
   5. Récapitulatif et totaux
   ========================================================================== */

.recap-ligne{display:flex;justify-content:space-between;gap:12px;font-size:14.5px;padding:6px 0}
.recap-ligne-total{
  display:flex;justify-content:space-between;gap:12px;font-size:15px;font-weight:700;
  padding:10px 0 0;border-top:1px solid var(--border);margin-top:4px;
}
.recap-badge-offert{
  display:inline-flex;align-items:center;padding:3px 10px;border-radius:var(--radius-pill);
  background:var(--ok-soft);color:var(--ok);font-size:11.5px;font-weight:700;
}
.recap-encart{
  border:1px solid var(--border);border-radius:var(--radius-md);background:#fff;padding:14px 16px;
}

.total-pill{
  display:inline-flex;flex-direction:column;gap:1px;padding:7px 13px;border-radius:var(--radius-pill);
  background:var(--panel);border:1px solid var(--border);box-shadow:var(--shadow-sm);
}
.total-pill .label,.total-pill dt{font-size:9.5px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:var(--muted)}
.total-pill .value,.total-pill dd{font-weight:700;font-size:13px;font-family:var(--font-mono);margin:0}

.badge{
  display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:var(--radius-pill);
  background:var(--panel-2);color:var(--text);font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
}
.fournisseur-badge{background:var(--accent-soft);color:var(--accent)}
.fournisseur-badge[data-fournisseur="worldline"]{background:var(--wl-soft);color:var(--wl)}
.fournisseur-badge[data-fournisseur="marketpay"]{background:var(--mp-soft);color:var(--mp)}

/* ==========================================================================
   6. Signature et documents
   ========================================================================== */

.signature-pad{
  border:1.5px dashed var(--border-strong);border-radius:var(--radius-md);background:#fff;
  aspect-ratio:16/7;width:100%;position:relative;
}
.signature-stylet-canvas{width:100%;height:100%;border-radius:var(--radius-md);touch-action:none;cursor:crosshair}

.methode-signature-grid{display:flex;flex-direction:column;gap:10px}
.methode-signature-grid .choice-card{display:flex;align-items:center;gap:14px;min-height:var(--tap-min)}

.avertissement-signature{
  margin-top:10px;padding:10px 13px;border-radius:var(--radius-sm);
  background:var(--warn-soft);color:var(--warn);font-size:13px;font-weight:600;
}

.upload-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.upload-slot{
  border:1.5px dashed var(--border-strong);border-radius:var(--radius-md);background:#fff;
  padding:16px;min-height:120px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:10px;text-align:center;font-size:13px;color:var(--muted);cursor:pointer;
}
.upload-slot:hover{border-color:var(--accent);color:var(--accent)}
.upload-slot.rempli{border-style:solid;border-color:var(--ok);color:var(--ok)}

.scanner-overlay{
  position:fixed;inset:0;z-index:95;background:#000;display:flex;flex-direction:column;
}
.scanner-modal{background:#000;color:#fff;flex:1;display:flex;flex-direction:column}
.scanner-video{width:100%;flex:1;object-fit:cover;background:#000}
.scanner-canvas-photo{width:100%;max-height:100%;object-fit:contain}
.scanner-crop-zone{position:absolute;inset:0;pointer-events:none}
.scanner-svg-crop{position:absolute;inset:0;width:100%;height:100%}
.scanner-poly{fill:rgba(10,132,255,.18);stroke:var(--accent);stroke-width:2}
.scanner-coin{
  position:absolute;width:26px;height:26px;border-radius:50%;background:var(--accent);
  border:3px solid #fff;box-shadow:var(--shadow-sm);pointer-events:auto;cursor:grab;transform:translate(-50%,-50%);
}
.scanner-hint{
  position:absolute;top:16px;left:0;right:0;text-align:center;color:#fff;font-size:13px;
  text-shadow:0 1px 3px rgba(0,0,0,.6);
}
.scanner-actions{
  position:absolute;bottom:0;left:0;right:0;display:flex;justify-content:center;gap:14px;
  padding:20px;background:linear-gradient(to top,rgba(0,0,0,.6),transparent);
}
.scanner-fichier-label{
  display:inline-flex;align-items:center;justify-content:center;min-height:var(--tap-min);
  padding:0 18px;border-radius:var(--radius-pill);background:rgba(255,255,255,.15);color:#fff;
  font-size:14px;cursor:pointer;
}
.decoupe-zone{
  position:absolute;border:2px solid var(--accent);border-radius:4px;box-shadow:0 0 0 9999px rgba(0,0,0,.45);
}

/* ==========================================================================
   7. Divers
   ========================================================================== */

.violations{
  display:flex;flex-direction:column;gap:8px;padding:14px 16px;border-radius:var(--radius-md);
  background:var(--danger-soft);border:1px solid rgba(192,57,43,.3);
}
.violation{display:flex;align-items:flex-start;gap:8px;font-size:13.5px;color:var(--danger)}
.violation::before{content:"⚠";flex:none}

.modale-overlay{
  position:fixed;inset:0;z-index:90;background:rgba(11,18,32,.55);
  display:flex;align-items:center;justify-content:center;padding:24px;
}
.modale{
  background:#fff;border-radius:var(--radius-lg);max-width:520px;width:100%;
  padding:24px;box-shadow:var(--shadow-md);
}

/* ==========================================================================
   8. Ruptures responsive
   Cible principale : tablette (768–1024px), utilisée debout par le commercial.
   ========================================================================== */

/* Mobile — < 640px : tout en une colonne, boutons pleine largeur */
@media (max-width:640px){
  .wizard-content{padding:14px 14px 150px}
  .form-grid,.choice-grid,.upload-grid{grid-template-columns:1fr}
  .bottombar{flex-direction:column;align-items:stretch}
  .bottombar button{width:100%}
  .fiche-terminal-modal,.modale{padding:18px}
}

/* Tablette — 641–1024px : cible principale, 2 colonnes, cibles tactiles larges */
@media (min-width:641px) and (max-width:1024px){
  .wizard-content{max-width:100%;padding:18px 24px 150px}
  .form-grid{grid-template-columns:repeat(2,1fr)}
  .choice-grid{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
}

/* Desktop — > 1024px : conteneur recentré, comportement identique à la tablette */
@media (min-width:1025px){
  .wizard-content{max-width:920px}
}


/* ==========================================================================
   9. Ajouts — écran Tableau de bord (nouvelles classes, non demandées au départ)
   Voir commentaire de livraison pour le détail de chaque classe.
   ========================================================================== */

.filter-seg{display:inline-flex;gap:4px;padding:4px;border-radius:var(--radius-pill);background:var(--panel-2);border:1px solid var(--border)}
.filter-opt{padding:8px 16px;min-height:40px;border-radius:var(--radius-pill);border:none;background:transparent;color:var(--muted);font-size:13.5px;font-weight:600;cursor:pointer}
.filter-opt.on{background:#fff;color:var(--text);box-shadow:var(--shadow-sm)}
.avatar{width:38px;height:38px;border-radius:50%;background:var(--accent);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:14px;flex:none}

.stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.stat-tile{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius-lg);padding:18px 20px;box-shadow:var(--shadow-md)}
.stat-label{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);font-weight:700}
.stat-value{font-size:30px;font-weight:700;letter-spacing:-.03em;margin-top:8px;font-variant-numeric:tabular-nums}
.stat-delta{font-size:12.5px;color:var(--muted);margin-top:5px}
.stat-delta.up{color:var(--ok);font-weight:600}
@media (max-width:900px){.stat-grid{grid-template-columns:1fr 1fr}}
@media (max-width:640px){.stat-grid{grid-template-columns:1fr}}

.dash-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media (max-width:900px){.dash-grid{grid-template-columns:1fr}}

.bar-row{display:grid;grid-template-columns:130px 1fr 40px;align-items:center;gap:12px;font-size:13.5px}
.bar-row + .bar-row{margin-top:11px}
.bar-label{color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bar-track{height:9px;border-radius:var(--radius-pill);background:var(--panel-2);overflow:hidden}
.bar-fill{height:100%;border-radius:var(--radius-pill);background:var(--accent)}
.bar-fill.c2{background:var(--mp)}
.bar-fill.c3{background:var(--ok)}
.bar-fill.c4{background:var(--warn)}
.bar-count{font-family:var(--font-mono);font-size:12.5px;text-align:right;color:var(--muted)}
.legend{display:flex;gap:18px;flex-wrap:wrap;margin-top:14px;font-size:12.5px;color:var(--text)}
.legend-dot{width:9px;height:9px;border-radius:3px;display:inline-block;margin-right:7px;vertical-align:middle}

.table{width:100%;border-collapse:collapse;font-size:13.5px}
.table th{text-align:left;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);font-weight:700;padding:0 14px 11px 0;white-space:nowrap}
.table td{padding:13px 14px 13px 0;border-top:1px solid var(--border);vertical-align:middle}
.table-wrap{overflow-x:auto;margin-top:12px}
.statut-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:var(--radius-pill);font-size:11.5px;font-weight:700}
.statut-pill[data-statut="signe"]{background:var(--ok-soft);color:var(--ok)}
.statut-pill[data-statut="brouillon"]{background:var(--panel-2);color:var(--muted)}
.statut-pill[data-statut="attente"]{background:var(--warn-soft);color:var(--warn)}
.table-empty{padding:40px 16px;text-align:center;color:var(--muted);font-size:14px}
.icon{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.8;vertical-align:middle}


/* ==========================================================================
   10. Ajouts — parcours Worldline (nouvelles classes)
   ========================================================================== */

.step-divider{display:flex;align-items:center;gap:12px;margin:8px 0 4px}
.step-divider .n{width:28px;height:28px;border-radius:50%;background:var(--accent);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;flex:none}
.step-divider h2{margin:0;font-size:20px}
.saved-row{display:flex;align-items:flex-start;gap:12px;padding:14px 16px;border:1px solid var(--border);border-radius:var(--radius-md);background:#fff}
.saved-row .ok-mark{color:var(--ok);font-size:16px;flex:none}
.field-group{padding-top:16px;border-top:1px solid var(--border)}
.field-group:first-child{padding-top:0;border-top:none}
.field-group-title{font-weight:700;font-size:14px;margin-bottom:10px}


/* ==========================================================================
   11. Ajouts — écran Nouveau contrat
   ========================================================================== */

.provider-card{
  display:flex;flex-direction:column;align-items:center;gap:20px;
  padding:40px 24px;min-height:220px;justify-content:center;
}
.provider-card img{width:200px;height:auto;object-fit:contain}
.provider-card .go{font-size:14px;font-weight:600;color:var(--accent)}


/* ==========================================================================
   12. Complément — classes employées par l'application et absentes de la
      livraison design. Le prompt envoyé à la session design listait les
      classes ayant déjà une règle dans l'ancien style.css : il a donc omis
      celles stylées par sélecteur descendant (`.choice-card .title`) et
      celles qui n'avaient encore aucune règle. Réglé sur les captures
      d'écran fournies par Olivier le 2026-08-03.
   ========================================================================== */

/* -- Champ pleine largeur dans une grille -- */
.form-grid .full { grid-column: 1 / -1; }
.field label .req { color: var(--danger); margin-left: 2px; }

/* -- Intérieur des cartes de choix (abonnement, financement, Bancontact) -- */
.choice-card .title { font-weight: 700; font-size: 15px; letter-spacing: -.01em; }
.choice-card .sub { font-size: 13px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
.choice-card .price { font-family: var(--font-mono); font-size: 19px; font-weight: 700; color: var(--accent); margin-top: 8px; }

/* -- Barre d'étapes : le code produit `<div class="step on"><span class="num">1</span>`,
      pas `data-step-index` ni `aria-current`. On désactive donc le pseudo-élément
      livré et on style le span réellement présent. -- */
.step::before { content: none; }
.step .num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%; background: var(--panel-2);
  color: var(--muted); font-size: 12px; font-weight: 700; flex: none;
}
.step.on { color: var(--text); font-weight: 700; background: var(--accent-soft); }
.step.on .num { background: var(--accent); color: #fff; }
.step.done { color: var(--ok); }
.step.done .num { background: var(--ok); color: #fff; }
.step.clickable { cursor: pointer; }

/* -- Badge fournisseur : le code écrit `fournisseur-badge worldline`, pas un
      attribut data-* -- */
.fournisseur-badge.worldline { background: var(--wl-soft); color: var(--wl); }
.fournisseur-badge.marketpay { background: var(--mp-soft); color: var(--mp); }

/* -- Violations : le conteneur est toujours présent dans la page, même vide.
      La couleur appartient donc au message, pas au conteneur, sous peine
      d'afficher un bandeau vide sur chaque écran. -- */
.violations { background: none; border: none; padding: 0; gap: 8px; }
.violations:empty { display: none; }
.violation {
  padding: 11px 14px; border-radius: var(--radius-sm); font-weight: 500;
  background: var(--warn-soft); color: var(--warn); border: 1px solid rgba(180,116,14,.28);
}
.violation.bloquant { background: var(--danger-soft); color: var(--danger); border-color: rgba(192,57,43,.3); }
.violation.avertissement { background: var(--warn-soft); color: var(--warn); border-color: rgba(180,116,14,.28); }
.violation::before { content: "⚠"; }

/* -- Lignes de récapitulatif -- */
.recap-ligne .libelle { font-size: 14px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.recap-ligne .prix { font-size: 14px; font-weight: 700; white-space: nowrap; font-family: var(--font-mono); }
.recap-ligne .prix .cadence { font-size: 11.5px; font-weight: 400; color: var(--muted); font-family: var(--font-sans); }
.recap-ligne-total .libelle { font-weight: 700; }
.recap-ligne-total .prix { font-size: 15px; }

/* -- Fiches repliées : point de vente et terminal -- */
.terminal-product-card .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; width: 100%; }
.terminal-product-card .head .title { font-weight: 700; font-size: 14.5px; }
.terminal-product-card .head .price { font-family: var(--font-mono); font-weight: 600; color: var(--accent); }
.terminal-replie, .site-replie { cursor: pointer; transition: .14s; }
.terminal-replie:hover, .site-replie:hover { border-color: var(--border-strong); }
.tid-list { display: flex; flex-direction: column; gap: 8px; }

/* -- Signature et documents -- */
.signature-pad {
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: 14px; aspect-ratio: auto; min-height: 64px; padding: 14px;
}
.signature-pad.signed { border-style: solid; border-color: var(--ok); color: var(--ok); font-weight: 600; }

/* -- Barre du bas : pastilles de totaux -- */
.totals { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* -- Boutons nommés du scanner et des modales. Le bouton nu est déjà le
      bouton principal ; ceux-ci n'ont besoin que de leur variante. -- */
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-supprimer, .btn-fermer, .btn-rescanner, .btn-scanner-upload,
.scanner-annuler, .scanner-recommencer { background: #fff; color: var(--text); border: 1px solid var(--border); }
.scanner-annuler, .scanner-recommencer, .btn-fermer {
  background: rgba(255,255,255,.15); color: #fff; border-color: rgba(255,255,255,.3);
}
.scanner-camera, .scanner-capturer, .scanner-valider, .scanner-crop, .btn-decouper-signature {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.scanner-camera-hint { color: var(--muted); font-size: 13px; text-align: center; }
.scanner-fichier-input { display: none; }

/* -- Divers -- */
.actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.titre { font-weight: 700; font-size: 15px; }
.statut-ok { color: var(--ok); font-weight: 600; }

/* -- Sélecteur segmenté : même `.chip` que les autres, mais présenté en
      groupe exclusif sur les captures (cartes internationales, niveau et
      détail de paiement). La rangée porte la variante. -- */
.chip-row.segmente {
  display: inline-flex; gap: 2px; padding: 3px; border-radius: var(--radius-pill);
  background: var(--panel-2); border: 1px solid var(--border);
}
.chip-row.segmente .chip {
  border: none; background: none; color: var(--muted); min-height: 38px; font-weight: 500;
}
/* L'option retenue en bleu plein, comme partout ailleurs dans le parcours
   (financement, jours de fermeture, abonnements Bancontact). En blanc sur gris,
   on ne voyait pas au premier coup d'œil laquelle était choisie — demande
   Olivier, 2026-08-04, sur le modèle de terminal et la connectivité. */
.chip-row.segmente .chip.on {
  background: var(--accent); color: #fff; font-weight: 700; box-shadow: var(--shadow-sm);
}
.chip-row.segmente .chip.on:hover { background: var(--accent); color: #fff; }

/* ==========================================================================
   13. Éléments nus — la livraison design ne stylait que des classes, alors
       que le tableau de bord, l'écran de connexion et la gestion des
       utilisateurs s'appuient sur `header`, `main`, `table` et les titres.
       Repris de l'ancienne feuille, transposé en clair.
   ========================================================================== */

header {
  padding: 14px 24px; border-bottom: 1px solid var(--border); background: var(--panel);
  display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap;
  backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%);
}

main { max-width: 1180px; margin: 24px auto 60px; padding: 0 20px; display: flex; flex-direction: column; gap: 16px; }

h1 { font-size: 26px; font-weight: 700; letter-spacing: -.02em; margin: 0 0 4px; }
h2 { font-size: 17px; font-weight: 700; letter-spacing: -.01em; margin: 0 0 10px; }
h3 { font-size: 15px; font-weight: 700; margin: 0 0 8px; }

table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border);
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
td { text-align: left; padding: 12px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }

/* Statuts de contrat, employés par le tableau de bord */
.badge.brouillon { background: var(--panel-2); color: var(--muted); }
.badge.signe { background: var(--ok-soft); color: var(--ok); }
.badge.en_attente_signature { background: var(--warn-soft); color: var(--warn); }
.badge.genere { background: var(--accent-soft); color: var(--accent); }

/* Marque de l'application, à droite du logo Inocrea dans l'en-tête. Elle
   s'efface sous 1000 px : le logo suffit à identifier l'écran, et la place
   gagnée évite que le filtre et l'avatar passent à la ligne. */
.marque-app {
  font-size: 16px;
  letter-spacing: -.01em;
  border-left: 1px solid var(--border);
  padding-left: 12px;
}
@media (max-width: 1000px) { .marque-app { display: none; } }

/* Entrées du menu de compte, sous l'avatar. */
.menu-compte-lien {
  display: block;
  padding: 10px 12px;
  border-radius: 10px;
  text-decoration: none;
  color: var(--text);
  font-size: 14px;
}
.menu-compte-lien:hover { background: var(--panel-2); }

/* Les cartes de choix sont des <button> dans le gabarit livré. Or `button` est
   le bouton principal (fond bleu) : au survol, `button:hover` a la même
   spécificité que `.choice-card` et l'emportait par sa position, repeignant la
   carte en bleu. On réaffirme donc le fond et la couleur du texte ici, en fin
   de feuille. */
.choice-card,
.choice-card:hover,
.choice-card:active { background: #fff; color: var(--text); }
/* `button` est en `inline-flex` centré : une carte de choix qui empile un titre
   et une description les mettrait côte à côte, centrés. Elle reste un bloc. */
.choice-card { display: block; }
.choice-card:hover { border-color: var(--border-strong); }
.choice-card.on,
.choice-card.on:hover { background: var(--accent-soft); border-color: var(--accent); }

/* Fond de page en dégradé, relevé sur la maquette : une nappe lavande en haut
   à droite, une nappe bleue en haut à gauche, fondues dans le gris-bleu de
   base. C'est ce que floute le `backdrop-filter` de l'en-tête et de la barre du
   bas — sans lui, l'effet de verre n'a rien à montrer. Fixé au viewport pour
   que le dégradé ne défile pas avec le contenu. */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(1100px 520px at 88% -8%, rgba(186,175,255,.50), transparent 62%),
    radial-gradient(900px 460px at 6% -6%, rgba(150,196,255,.45), transparent 62%),
    var(--bg);
  background-attachment: fixed;
}
main.wizard-content { flex: 1 0 auto; }

/* Verrouillage de la carte fournisseur pendant la création du contrat. */
.provider-card[aria-busy="true"] { opacity: .6; pointer-events: none; }

/* Gabarits de contenu : le tableau de bord a besoin de plus large que les
   920 px du parcours, et « Nouveau contrat » centre son contenu — dans les deux
   axes, le contenu tenant dans un écran. */
.contenu-large { max-width: 1200px; }
.contenu-centre { align-items: center; text-align: center; justify-content: center; }

/* Une carte fournisseur porte une ombre dès le repos, comme les cartes du
   tableau de bord : elle se détache du fond dégradé. Au survol elle se soulève,
   son ombre s'étale et son libellé d'action s'éteint. Repris de la maquette. */
.provider-card {
  /* `display` est réaffirmé ici : la règle qui remet les cartes de choix en
     bloc (plus haut, pour les cartes titre + description du financement)
     neutraliserait sinon la colonne centrée du logo et de son libellé. */
  display: flex;
  box-shadow: var(--shadow-md);
  transition: transform .16s, box-shadow .16s, border-color .14s;
}
.provider-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 22px 44px -22px rgba(15,23,42,.42);
}
/* Le libellé d'action est gris au repos et s'allume en bleu au survol : la
   carte entière est le bouton, le bleu signale celle qu'on est sur le point de
   choisir. */
.provider-card .go { color: var(--muted); transition: color .16s; }
.provider-card:hover .go { color: var(--accent); }
.provider-card:active { transform: translateY(-1px); }

/* Blocs d'une fiche point de vente — adresse de livraison, informations du
   site, terminaux, chèques-repas… La livraison design les sépare par un simple
   filet ; ils sont trop nombreux et trop longs pour que l'œil suive. On en fait
   des blocs à part entière : fond franc, ombre douce, et de l'air entre eux
   (demande Olivier, 2026-08-04). */
.bloc-fiche {
  background: #fff;
  box-shadow: var(--shadow-sm), 0 10px 28px -20px rgba(15,23,42,.35);
  padding: 18px 20px;
}
.bloc-fiche + .bloc-fiche { margin-top: 16px; }

/* Un bloc imbriqué — la fiche d'un terminal à l'intérieur du bloc Terminaux —
   se pose sur un fond légèrement teinté pour ne pas se confondre avec le bloc
   qui le porte. */
.bloc-fiche .bloc-fiche { background: rgba(255,255,255,.62); box-shadow: var(--shadow-sm); }

/* Le titre d'un bloc respire un peu plus que celui d'une carte. */
.bloc-fiche > .section-title { margin-bottom: 2px; }

/* En-tête d'un contrat : numéro et fournisseur. Le rouge de marque Worldline
   passait pour un message d'erreur dans un en-tête ; il prend ici le bleu de
   l'application, avec une pastille devant (demande Olivier, 2026-08-04). Les
   badges des tableaux gardent la couleur de marque, qui y sert à distinguer les
   lignes d'un coup d'œil. */
.numero-contrat {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--muted);
  white-space: nowrap;
}
.wizard-header .fournisseur-badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 16px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.wizard-header .fournisseur-badge::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.wizard-header .fournisseur-badge.marketpay { background: var(--mp-soft); color: var(--mp); }

/* ==========================================================================
   14. Barre de totaux et de navigation, en bas du parcours

   Elle reste un enfant du contenu, en `sticky` et non en `fixed` : un élément
   fixe s'ancre à la fenêtre réelle, pas au conteneur — il se détacherait de la
   largeur du parcours dès que celui-ci est contraint (aperçu tablette dans un
   cadre, par exemple). Coins arrondis et léger retrait du bas : la barre flotte
   au-dessus du contenu, elle n'est pas collée aux bords de l'écran.

   Un seul point de bascule, à 640 px, qui change en même temps la disposition
   des pastilles (rangée → grille 2×2) et celle des boutons (texte → icône).
   C'est ce qui garantit que la barre ne déborde jamais et garde une hauteur
   constante, quel que soit le nombre de totaux — deux chez Worldline, jusqu'à
   quatre chez MarketPay.
   ========================================================================== */

.bottombar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  width: min(920px, calc(100% - 40px));
  bottom: 12px;
  gap: 12px;
  flex-wrap: nowrap;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: rgba(255,255,255,.72);
  box-shadow: var(--shadow-md);
  backdrop-filter: blur(12px) saturate(150%);
  -webkit-backdrop-filter: blur(12px) saturate(150%);
}

/* Les pastilles prennent la place restante, ce qui fait tomber le fondu de
   droite dans le vide tant qu'elles ne débordent pas. Au-delà, elles défilent
   à l'horizontale, le fondu signalant qu'il reste quelque chose à voir. */
.bottombar .totals {
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
}
.bottombar .totals::-webkit-scrollbar { display: none; }

.bottombar .total-pill { flex: none; padding: 6px 12px; }
.bottombar .total-pill .label { font-size: 9.5px; }
.bottombar .total-pill .value { font-size: 12.5px; }

.bottombar .actions { flex: none; gap: 8px; }
.bottombar .actions button { min-height: 38px; padding: 0 16px; font-size: 14px; }
.bottombar .actions .icone { display: none; width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; }

/* Mobile : les quatre totaux doivent rester lisibles d'un coup d'œil, donc
   grille plutôt que défilement, et les boutons se réduisent à leur flèche. */
@media (max-width: 640px) {
  .bottombar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    bottom: 8px;
    padding: 10px 12px;
    width: calc(100% - 20px);
  }
  .bottombar .totals {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .bottombar .total-pill { padding: 5px 10px; }
  .bottombar .total-pill .label { font-size: 9px; }
  .bottombar .total-pill .value { font-size: 13px; }
  .bottombar .actions { justify-content: flex-end; }
  .bottombar .actions button {
    width: 38px;
    height: 38px;
    min-height: 38px;
    padding: 0;
    border-radius: 50%;
  }
  .bottombar .actions button .texte { display: none; }
  .bottombar .actions button .icone { display: block; }
}

/* Bouton d'ajout d'un point de vente : il ouvre une saisie, il ne valide rien.
   Il n'a donc pas à peser autant qu'un « Suivant » — corps de texte et hauteur
   réduits, aligné à gauche, et détaché du bloc qui le précède pour qu'on ne le
   lise pas comme faisant partie de celui-ci (demande Olivier, 2026-08-04). */
.btn-ajout {
  align-self: flex-start;
  min-height: 40px;
  padding: 0 16px;
  font-size: 13.5px;
  font-weight: 600;
}


/* Liste des points de vente. Son conteneur était un simple bloc : deux magasins
   se retrouvaient collés bord à bord, et la liste démarrait au ras du bloc
   Financement. Elle devient une colonne espacée, détachée de ce qui la précède
   (demande Olivier, 2026-08-04). Le `:not(:empty)` évite un blanc fantôme tant
   qu'aucun point de vente n'existe. */
#wl-sites-list,
#mp-sites-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}


/* Une heure se lit d'un bloc. La règle livrée étire chaque enfant du groupe à
   au moins 160 px — les deux-points et les minutes se retrouvaient repoussés
   loin de leur heure, au point que les minutes d'ouverture paraissaient
   appartenir à la fermeture (relevé par Olivier, 2026-08-04). Les sélecteurs
   gardent donc leur largeur naturelle, serrés autour du séparateur. */
.time-select-pair {
  flex-wrap: nowrap;
  align-items: center;
  gap: 6px;
}
.time-select-pair > * { flex: 0 0 auto; min-width: 0; }
.time-select-pair select { width: 92px; padding-left: 12px; padding-right: 8px; }
.time-select-pair > span {
  padding: 0 2px;
  color: var(--muted);
  font-weight: 700;
}

/* ==========================================================================
   15. Densité du parcours

   Les fiches point de vente font plusieurs écrans de haut ; le commercial passe
   son temps à faire défiler pendant que le client attend. On resserre donc la
   saisie (demande Olivier, 2026-08-04).

   Écart assumé avec le design : la cible tactile passe de 48 à 42 px. Le design
   visait une tablette utilisée debout ; 42 px reste confortable au doigt et
   rend une vingtaine de pixels par ligne de formulaire. Pour revenir en
   arrière, il suffit de remettre `--tap-min: 48px`.
   ========================================================================== */

:root { --tap-min: 42px; }

/* Trois colonnes plutôt que deux dès qu'elles tiennent : le design figeait la
   tablette à deux, ce qui étirait « Fréquence de règlement », « Clôture
   journalière » et « Activation » sur trois lignes au lieu d'une. */
.form-grid {
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 12px;
}

.field { gap: 4px; }
.field label { font-size: 10.5px; }
.field input,
.field select,
.field textarea { padding: 9px 12px; font-size: 14.5px; }
.field textarea { min-height: 76px; }

.card { padding: 16px 18px; }
.bloc-fiche { padding: 14px 16px; gap: 10px; }
.bloc-fiche + .bloc-fiche { margin-top: 12px; }

.section-title { font-size: 15px; }
.section-sub { font-size: 12.5px; margin-bottom: 10px; max-width: none; }

.chip { padding: 7px 14px; font-size: 13.5px; }
.time-select-pair select { width: 86px; }

/* Un champ qui doit rester en tête de ligne — les deux bornes d'une plage
   horaire ne se lisent que côte à côte. */
.field.debut-ligne { grid-column-start: 1; }

/* Fiche terminal ouverte. Elle empilait cinq groupes en pleine largeur — deux
   pastilles de modèle sur une ligne, deux de connectivité sur la suivante, et
   ainsi de suite sur toute la hauteur d'un écran. Elle passe en colonne de
   cartes avec ses champs en grille : modèle et connectivité voisinent, système
   de caisse et installation aussi, l'abonnement Bancontact garde la largeur
   entière pour ses deux panneaux (demande Olivier, 2026-08-04). */
.terminal-product-card {
  flex-direction: column;
  align-items: stretch;
  /* `flex-wrap: wrap` vient de la règle d'origine, pensée pour une carte en
     ligne. Conservé en direction colonne, il étirait le premier bloc de près de
     90 px pour combler une hauteur qu'il croyait devoir remplir. */
  flex-wrap: nowrap;
  gap: 12px;
}
.terminal-product-card .head { align-items: center; }
.grille-terminal { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

/* « Voir détails produit » ouvre une fiche, c'est un lien — pas une action.
   Faute de fond déclaré, il héritait du bouton principal et s'affichait en
   aplat bleu pleine largeur au milieu de la fiche terminal. */
.lien-fiche-terminal {
  align-self: flex-start;
  min-height: 0;
  padding: 0;
  border: none;
  background: none;
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 500;
}
.lien-fiche-terminal:hover { background: none; border: none; color: #0070E0; }

/* Cartes de financement : un seul mot d'ordre par carte, donc centré — les
   cartes de choix sont alignées à gauche par défaut, ce qui suppose un titre
   suivi d'une description (demande Olivier, 2026-08-04). */
#wl-mode-chips .choice-card { text-align: center; }



/* Résumé d'un point de vente replié : ce que contient le magasin se lit en
   pastilles plutôt qu'en phrases enchaînées par des points médians — modèles
   avec leur quantité, abonnements Bancontact, services (demande Olivier,
   2026-08-04). Le contexte (activité, horaires, IBAN) reste en texte gris
   dessous : c'est une description, pas une liste d'éléments. */
.pastilles-resume {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 7px 0 5px;
}
.pastille-resume {
  display: inline-flex;
  align-items: center;
  padding: 4px 11px;
  border-radius: var(--radius-pill);
  background: var(--panel-2);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.pastille-resume.vide { color: var(--muted); font-weight: 500; }

/* Case à cocher étiquetée : la case et son libellé forment une seule cible,
   dimensionnée pour le doigt. Employée pour les exclusions — « Aucun système de
   caisse » — là où une pastille laissait croire à un choix parmi d'autres.
   Le sélecteur `.field label.case-a-cocher` est nécessaire : sans lui, elle
   hérite du style des libellés de champ (petites majuscules grises). */
.field label.case-a-cocher,
.case-a-cocher {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 38px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  text-transform: none;
  letter-spacing: normal;
  cursor: pointer;
}
.case-a-cocher input[type="checkbox"] {
  width: 19px;
  height: 19px;
  accent-color: var(--accent);
  flex: none;
  cursor: pointer;
}

/* Le rail segmenté ne se casse jamais sur deux lignes — un choix exclusif se lit
   d'un coup d'œil ou pas du tout — et s'arrête à la largeur de ses options :
   dans un `.field` en colonne, il s'étirait sinon sur toute la largeur, étalant
   « Axium RX5000 » et « 4G » sur des moitiés démesurées. */
.chip-row.segmente {
  flex-wrap: nowrap;
  align-self: flex-start;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.chip-row.segmente::-webkit-scrollbar { display: none; }
.chip-row.segmente .chip { white-space: nowrap; flex: none; }

/* Les huit types de cartes tiennent sur une seule ligne : présentés en deux
   rangées, on ne voyait plus qu'il s'agit d'une même famille de choix. La
   typographie et les marges se resserrent juste assez (demande Olivier,
   2026-08-04) ; en dessous de la largeur nécessaire, la rangée défile
   horizontalement plutôt que de se casser. */
#ci-types-chips {
  flex-wrap: nowrap;
  gap: 5px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
#ci-types-chips::-webkit-scrollbar { display: none; }
#ci-types-chips .chip {
  flex: none;
  white-space: nowrap;
  padding: 6px 11px;
  font-size: 12.5px;
  min-height: 34px;
}

/* Barre d'étapes : un bloc arrondi dans la colonne de contenu, comme les cartes
   qu'elle surmonte, plutôt qu'un bandeau barré d'un filet de bord à bord
   (demande Olivier, 2026-08-04). */
.stepbar {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 8px 10px;
}

/* Le conteneur d'étape est lui-même un `.wizard-content` imbriqué dans celui du
   gabarit de base : il ajoutait 20 px de marge de chaque côté, si bien que les
   cartes étaient plus étroites que la barre d'étapes juste au-dessus. Il ne
   garde que l'espacement vertical entre ses blocs. */
#step-content {
  max-width: none;
  padding: 0;
}

/* Récapitulatif : les blocs par point de vente et le total du contrat étaient
   empilés bord à bord dans un conteneur sans espacement, alors que le bloc
   client au-dessus respirait de 16 px. Même écart partout (demande Olivier,
   2026-08-04). Le `display` reste posé par le script, qui masque le conteneur
   du fournisseur non retenu. */
#recap-lignes-worldline,
#recap-lignes-marketpay {
  flex-direction: column;
  gap: 16px;
}

/* Documents à joindre : une ligne par pièce — icône, nom, statut, action —
   plutôt que trois zones de dépôt en pointillés côte à côte, qui laissaient peu
   de place au nom complet et rien pour le statut (maquette du design, reprise
   le 2026-08-04). */
.ligne-document {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: #fff;
}
.ligne-document + .ligne-document { margin-top: 10px; }
.ligne-document-icone {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.ligne-document-titre { flex: 1; font-weight: 600; font-size: 13.5px; }
.ligne-document .actions { flex: none; }
.ligne-document .actions button { min-height: 34px; padding: 0 14px; font-size: 12.5px; }
.ligne-document.depose { border-color: rgba(14,159,110,.35); }
.ligne-document.depose .ligne-document-icone { background: var(--ok-soft); color: var(--ok); }
.ligne-document .statut-ok { font-size: 12.5px; white-space: nowrap; }

@media (max-width: 640px) {
  .ligne-document { flex-wrap: wrap; }
  .ligne-document-titre { flex: 1 1 100%; order: -1; }
}

/* Méthodes de signature : une ligne par méthode, son icône dans une pastille
   qui s'allume avec la carte sélectionnée (maquette du design, 2026-08-04).
   `.choice-card` étant remise en bloc pour les cartes titre + description, on
   rétablit ici la disposition en ligne. */
.methode-signature-grid .choice-card {
  display: flex;
  align-items: center;
  gap: 14px;
}
.methode-icone {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: var(--panel-2);
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  transition: .14s;
}
.methode-icone .icon { width: 19px; height: 19px; }
.methode-signature-grid .choice-card.on .methode-icone { background: var(--accent); color: #fff; }
.methode-texte { display: flex; flex-direction: column; }

/* Aperçu du bon de commande : c'est le geste qui précède la signature, le
   commercial doit le voir tout de suite — bouton plein, arrondi, ajusté à son
   libellé (demande Olivier, 2026-08-04). */
.lien-apercu {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  width: fit-content;
  margin-bottom: 14px;
  padding: 0 20px;
  min-height: 40px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  transition: .14s;
}
.lien-apercu:hover { background: #0070E0; border-color: #0070E0; color: #fff; }

/* Fiche client du récapitulatif : identité en tête, coordonnées dessous,
   séparées par un filet. Chaque coordonnée porte son icône, ce qui la rend
   reconnaissable sans étiquette (maquette d'Olivier, 2026-08-04). */
.client-entete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.client-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
}
.client-nom {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -.01em;
  margin-top: 4px;
}
.client-identite { color: var(--muted); font-size: 13px; margin-top: 2px; }
.client-langue {
  flex: none;
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
}
.client-coords {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 8px 20px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.client-coord {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
}
.client-coord .icon { color: var(--muted); flex: none; }
.client-coord.absent { color: var(--warn); }
.client-coord.absent .icon { color: var(--warn); }

/* En-tête d'un magasin dans le récapitulatif : pastille bleue portant l'icône
   de commerce et le numéro d'ordre, puis l'identité du point de vente
   (maquette d'Olivier, 2026-08-04). */
.site-entete {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 14px;
}
.site-pastille {
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: var(--accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.site-pastille .icon { width: 20px; height: 20px; }
.site-numero {
  position: absolute;
  right: -5px;
  bottom: -5px;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  border-radius: var(--radius-pill);
  background: #fff;
  color: var(--accent);
  border: 1px solid var(--accent);
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.site-entete { align-items: center; flex-wrap: wrap; }
.site-nom { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
/* Les coordonnées suivent l'enseigne sur la même ligne, séparées d'elle par un
   filet. Sous 640 px elles passent dessous, sans le filet. */
.site-details {
  color: var(--muted);
  font-size: 13.5px;
  padding-left: 14px;
  border-left: 1px solid var(--border);
}
@media (max-width: 640px) {
  .site-details {
    flex: 1 1 100%;
    padding-left: 0;
    border-left: none;
  }
}

/* Récapitulatif tarifaire : des sections séparées par un filet plutôt que des
   sous-cartes encadrées, qui hachaient la lecture d'un décompte qu'on parcourt
   de haut en bas. Le total du magasin ferme le bloc, en bleu (maquette
   d'Olivier, 2026-08-04). */
.recap-section + .recap-section {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.recap-section-titre {
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -.01em;
  margin-bottom: 8px;
}
.recap-section .recap-ligne { padding: 3px 0; }
/* Le sous-total d'une section : libellé en retrait, montant affirmé. */
.recap-section .recap-ligne-total { border-top: none; margin-top: 4px; padding-top: 4px; }
.recap-section .recap-ligne-total .libelle { color: var(--muted); font-weight: 500; }

.recap-total-bloc {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 15px;
  font-weight: 700;
}
.recap-total-montant {
  font-family: var(--font-mono);
  font-size: 20px;
  color: var(--accent);
  white-space: nowrap;
}
.recap-total-montant .cadence {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--muted);
  font-family: var(--font-sans);
}


/* Les blocs d'une étape respirent d'un même écart, quel que soit le
   fournisseur : le conteneur porte l'espacement plutôt que chaque élément sa
   marge, qui variait d'un bloc à l'autre (demande Olivier, 2026-08-04). Le
   `display` est posé par le script, qui masque le panneau du fournisseur non
   retenu. */
#content-worldline,
#content-marketpay {
  flex-direction: column;
  gap: 16px;
}

/* Abonnements MarketPay : `auto-fit` laissait une formule seule — INO-Max pour
   « Terminal + Mobile » — s'étirer sur toute la largeur, alors qu'à deux elles
   font chacune la moitié. `auto-fill` garde la colonne vide : une carte a la
   même taille qu'elle soit seule ou accompagnée (relevé par Olivier,
   2026-08-04). */
#mp-formules { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* Boutons « + » et « − » d'un compteur : la règle du design leur donne un fond
   blanc sans redéfinir la couleur du texte, héritée du bouton principal — les
   signes étaient blancs sur blanc, donc invisibles (relevé par Olivier,
   2026-08-04). Même famille de défaut que le survol bleu des cartes de choix. */
.qty-control button {
  color: var(--accent);
  font-weight: 700;
  border-color: var(--border-strong);
}
.qty-control button:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.qty-control button:disabled { color: var(--muted); border-color: var(--border); }

/* Le bouton d'ajout MarketPay vit dans la carte « Points de vente », qui n'a
   pas d'espacement propre : il collait au bloc du dessus — surtout quand il
   devient « Enregistrer le point de vente », qui ferme la fiche ouverte
   (relevé par Olivier, 2026-08-04). */
#mp-ajouter-site { margin-top: 16px; }

/* Bénéficiaires effectifs : même colonne espacée que les points de vente, et
   une fiche repliée qui réagit au survol comme les autres résumés. */
#beneficiaires-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
#beneficiaires-list:not(:empty) { margin-bottom: 16px; }
.ubo-replie { transition: .14s; }
.ubo-replie:hover { border-color: var(--border-strong); }

/* Tableau comparatif des tarifs de transaction MarketPay. Corps réduit et
   chiffres tabulaires : cinq à six colonnes doivent tenir sans défiler sur un
   écran d'ordinateur (maquette d'Olivier, 2026-08-04). */
.modale-tarifs { max-width: 900px; max-height: 85vh; overflow: auto; }
.tarifs-famille {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 16px 0 6px;
}
.tarifs-transaction {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.tarifs-transaction th,
.tarifs-transaction td { padding: 9px 10px; white-space: nowrap; }
/* Chaque famille a sa teinte — bleu pour le mobile, violet pour le terminal —
   portée par la variable `--teinte` que pose le script. Elle distingue les deux
   tableaux au premier coup d'œil (maquette d'Olivier, 2026-08-04). */
.tarifs-transaction thead th {
  text-align: right;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--teinte, var(--text));
  border-bottom: 2px solid var(--teinte, var(--border-strong));
  vertical-align: bottom;
}
.tarifs-transaction thead th:first-child {
  text-align: left;
  font-size: 10.5px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
}
.tarifs-transaction thead th span {
  display: block;
  font-size: 11px;
  font-weight: 400;
  color: var(--muted);
}
/* Le style global des `th` met les en-têtes en petites majuscules : ici ce
   sont des libellés de ligne, ils se lisent normalement. */
.tarifs-transaction tbody th {
  text-align: left;
  font-weight: 400;
  font-size: 12.5px;
  letter-spacing: normal;
  text-transform: none;
  color: var(--text);
  border-bottom: none;
}
.tarifs-transaction tbody td {
  text-align: right;
  font-family: var(--font-mono);
}
.tarifs-transaction tbody tr + tr th,
.tarifs-transaction tbody tr + tr td { border-top: 1px solid var(--border); }
.tarifs-legende {
  margin: 8px 0 0;
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.5;
}
.tarifs-legende strong { color: var(--teinte, var(--text)); }

/* `.scanner-actions` est écrite pour la superposition plein écran de la caméra :
   positionnée en absolu, plaquée en bas, sur un dégradé sombre. Elle sert aussi
   de simple rangée de boutons dans le bloc de signature papier et dans les
   modales, où ce positionnement la faisait flotter au milieu du récapitulatif
   (signalé par Olivier, 2026-08-04). Le comportement plein écran est donc
   réservé au scanner ; partout ailleurs, c'est une rangée ordinaire. */
.scanner-actions {
  position: static;
  padding: 0;
  background: none;
  justify-content: flex-start;
  flex-wrap: wrap;
}
.scanner-overlay .scanner-actions {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  justify-content: center;
  padding: 20px;
  background: linear-gradient(to top, rgba(0,0,0,.6), transparent);
}

/* Zone de signature au stylet. La feuille livrée met le cadre sur
   `.signature-pad`, un conteneur que le canvas de l'étape 5 n'a pas : il
   s'affichait sans bordure ni fond, donc invisible — le commercial ne voyait
   plus où signer (signalé par Olivier, 2026-08-04). Son `height: 100%` sur un
   parent de hauteur libre l'écrasait en outre à 90 px.

   Le canvas isolé porte donc son propre cadre ; dans un `.signature-pad`, il
   continue de le remplir. */
.signature-stylet-canvas {
  height: auto;
  min-height: 180px;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: #fff;
  display: block;
}
.signature-pad .signature-stylet-canvas {
  height: 100%;
  min-height: 0;
  border: none;
  border-radius: var(--radius-md);
}

/* La zone de signature suit immédiatement la dernière méthode proposée : sans
   marge, son cadre en pointillés touchait la carte « Zoho Sign » (signalé par
   Olivier, 2026-08-04). Vaut aussi pour les blocs papier et Zoho, qui prennent
   la même place. */
#bloc-stylet,
#bloc-papier,
#bloc-zoho { margin-top: 16px; }

/* Cadrage du scanner — deux défauts de la feuille livrée, relevés par Olivier
   le 2026-08-04 sur une carte d'identité photographiée.

   1. Le calque de découpe portait `width:100%; height:100%`, ce qui écrasait
      les dimensions que le script lui calcule d'après la photo affichée : le
      cadre débordait sous l'image, dans la bande noire. Il épouse maintenant le
      canvas, dont il reprend les attributs.

   2. Les poignées de coin étaient stylées comme des éléments HTML — `width`,
      `height`, `border-radius`, `background`, `border` — alors que le script
      crée des `<circle>` SVG, sur lesquels ces propriétés n'ont aucun effet.
      Elles s'affichaient donc en noir, sans contour. Elles reçoivent leurs
      propriétés SVG : `fill`, `stroke`, `stroke-width`. */
.scanner-crop-zone {
  display: flex;
  align-items: center;
  justify-content: center;
}
.scanner-svg-crop {
  inset: auto;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: auto;
  height: auto;
  overflow: visible;
}
circle.scanner-coin {
  width: auto;
  height: auto;
  border: none;
  border-radius: 0;
  background: none;
  box-shadow: none;
  transform: none;
  fill: var(--accent);
  stroke: #fff;
  stroke-width: 3;
  paint-order: stroke;
  pointer-events: auto;
  cursor: grab;
}

/* Découpe de la signature sur la pièce d'identité. `.decoupe-zone` est écrite
   dans la feuille livrée comme le **rectangle de sélection** — positionné en
   absolu, bordé, avec une ombre de 9999 px qui assombrit le reste. Or ici c'est
   le conteneur du canvas : le tracé, lui, est dessiné dans le canvas par le
   script. Le positionnement absolu sortait la carte du cadre et laissait les
   boutons flotter par-dessus (signalé par Olivier, 2026-08-04). */
.modale-decoupe { max-width: 860px; }
.modale-decoupe .decoupe-zone {
  position: static;
  border: none;
  border-radius: 0;
  box-shadow: none;
  display: flex;
  justify-content: center;
  margin-top: 12px;
}
.modale-decoupe .decoupe-zone canvas {
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  cursor: crosshair;
  touch-action: none;
}

/* Signature relevée sur la pièce d'identité, affichée au-dessus du pavé de
   signature pour comparaison. Sans contrainte de hauteur, une découpe large
   occupait plus de place que la zone où le client doit signer (signalé par
   Olivier, 2026-08-04) : elle est ramenée à une bande de référence. */
#signature-reference {
  margin-bottom: 12px;
}
#signature-reference img {
  display: block;
  max-width: 100%;
  max-height: 96px;
  width: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fff;
  margin-top: 6px;
}


/* ==========================================================================
   Sélecteur de langue de l'interface (en-tête)
   ========================================================================== */

/* Deux pastilles jointes, FR|NL : la langue active en bleu plein, l'autre en
   blanc. Assez petit pour ne pas concurrencer le logo, assez large pour rester
   touchable sur tablette. */
.selecteur-langue{
  display:inline-flex; align-items:stretch; margin-right:10px;
  border:1px solid var(--border-strong); border-radius:var(--radius-pill);
  overflow:hidden; background:#fff;
}
.selecteur-langue .opt-langue{
  appearance:none; border:none; background:#fff; color:var(--muted);
  font-size:12px; font-weight:700; letter-spacing:.03em;
  padding:6px 11px; min-height:32px; cursor:pointer; line-height:1;
}
.selecteur-langue .opt-langue + .opt-langue{ border-left:1px solid var(--border); }
.selecteur-langue .opt-langue:hover{ color:var(--accent); background:var(--accent-soft); }
.selecteur-langue .opt-langue.on{ background:var(--accent); color:#fff; }
.selecteur-langue .opt-langue.on:hover{ background:var(--accent); color:#fff; }


/* ==========================================================================
   Consigne et actions empilées (signature papier)
   ========================================================================== */

/* Une marche à suivre se lit avant d'agir : encadrée et teintée, elle ne se
   confond plus avec les légendes grises du reste de l'écran. */
.bloc-consigne{
  display:flex; align-items:flex-start; gap:10px; margin:0 0 12px;
  padding:12px 14px; border-radius:var(--radius-md);
  background:var(--accent-soft); color:var(--text); font-size:14px; line-height:1.45;
}
.bloc-consigne .icon{ flex:none; width:18px; height:18px; margin-top:1px; color:var(--accent); }

/* Deux actions de poids différent : empilées et pleine largeur, la cible est
   large au doigt et l'ordre de lecture reste celui du geste. */
.actions-empilees{ display:flex; flex-direction:column; gap:10px; }
.actions-empilees > *{
  display:inline-flex; align-items:center; justify-content:center; gap:9px;
  width:100%; min-height:var(--tap-min); font-size:14.5px; font-weight:700;
}
.actions-empilees .icon{ width:18px; height:18px; flex:none; }


/* Champ suivi de son action — IBAN à vérifier, n° d'entreprise à rechercher.
   Les deux se collent en un seul groupe arrondi : l'action appartient au
   champ, elle ne flotte pas à côté (demande Olivier, 2026-08-04). */
.champ-avec-action{ display:flex; align-items:stretch; gap:0; }
.champ-avec-action > input{
  flex:1; min-width:0;
  border-top-right-radius:0; border-bottom-right-radius:0;
}
.champ-avec-action > button{
  display:inline-flex; align-items:center; justify-content:center; gap:7px; white-space:nowrap;
  border-top-left-radius:0; border-bottom-left-radius:0;
  margin-left:-1px;                 /* les deux bordures n'en font qu'une */
  padding-left:14px; padding-right:16px;
}
.champ-avec-action > button .icon{ width:16px; height:16px; flex:none; }

/* Variante à icône seule : une loupe carrée au bout du champ. Le libellé
   n'apporte rien à côté d'un champ IBAN — l'icône suffit, et la ligne reste
   assez large pour lire le numéro en entier (demande Olivier, 2026-08-04). */
.champ-avec-action > button.action-icone{
  width:var(--tap-min); min-width:var(--tap-min); padding:0;
}

/* ==========================================================================
   Bloc bancaire — IBAN, BIC, nom sur le relevé, puis le résultat
   ========================================================================== */

/* Les trois champs s'empilent dans l'ordre où on les lit sur un extrait de
   compte, et le résultat de la vérification vient tout en bas, sous les trois. */
.bloc-bancaire{ display:flex; flex-direction:column; gap:12px; }
.bloc-bancaire .field{ margin:0; }
.bloc-bancaire .resultat-iban{ font-size:13.5px; font-weight:600; }
.bloc-bancaire .resultat-iban.valide{ color:var(--ok); }
.bloc-bancaire .resultat-iban.invalide{ color:var(--danger); }
.bloc-bancaire .resultat-iban.attente{ color:var(--warn); }
/* Vide, le message ne doit pas creuser un blanc. */
.bloc-bancaire .resultat-iban:empty{ display:none; }

/* Un IBAN, un BIC et un nom de 16 caractères sont des données courtes : un
   champ large comme la carte laisse croire qu'on en attend davantage. Les trois
   font la même largeur (demande Olivier, 2026-08-05). */
.bloc-bancaire .field{ max-width:300px; }
/* La loupe s'ajoute à droite du champ : sans cette rallonge, l'input IBAN
   serait plus court que le BIC et le nom. */
.bloc-bancaire .field.champ-iban{ max-width:calc(300px + var(--tap-min)); }

/* Le résultat de la vérification se lit à côté du nom, pas sous les champs :
   la carte garde sa hauteur et l'œil reste sur la même ligne. Le décalage
   aligne le message sur le champ, pas sur son libellé. */
.ligne-releve{ display:flex; align-items:flex-start; gap:16px; flex-wrap:wrap; }
.ligne-releve > .field{ margin:0; flex:0 0 300px; }
.ligne-releve > .resultat-iban{ flex:1; min-width:220px; padding-top:28px; }
#vf-releve-note{ margin-top:0.3rem; }
