  :root{
    --bg:#0f172a; --panel:#111c33; --panel2:#16233f; --line:#22314f; --ink:#e6edf7;
    --mut:#93a3bd; --accent:#3b82f6; --accent2:#22d3ee; --good:#22c55e; --warn:#f59e0b;
    --bad:#ef4444; --pink:#ec4899; --purple:#a78bfa; --chip:#1e2b48;
  }
  *{box-sizing:border-box}
  html,body{margin:0;height:100%;font-family:'Segoe UI',system-ui,Arial,sans-serif;background:var(--bg);color:var(--ink)}
  a{color:var(--accent2)}
  .app{display:grid;grid-template-columns:230px 1fr;height:100vh}
  /* Embedded in AMS: AMS owns the left rail, so WOM hides its own and goes full width. */
  body.in-frame .app{grid-template-columns:1fr}
  body.in-frame .side{display:none}
  /* Ordonnanceur détaché dans son propre onglet (« ⤢ Pop out ») : pleine largeur, pas de rail,
     et pas la boîte de commandes (Re-run, filtres, bandeaux) — Bernard, 2026-10-08. */
  body.popout .app{grid-template-columns:1fr}
  body.popout .side, body.popout #schedTopBox{display:none}
  /* Menu « ⋯ » / clic droit de l'ordonnanceur (2026-10-14). */
  .ordoMenu{position:fixed;z-index:1000;min-width:240px;padding:4px;background:var(--panel2);border:1px solid var(--line);border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.45)}
  .ordoMenu button{display:flex;align-items:center;width:100%;padding:7px 10px;background:none;border:0;border-radius:6px;color:var(--ink);font-size:13px;text-align:left;cursor:pointer;white-space:nowrap}
  .ordoMenu button:hover:not(:disabled){background:var(--chip)}
  /* Vignettes des photos du bon (0202). */
  .wo-photos{display:inline-flex;flex-wrap:wrap;gap:6px;vertical-align:middle}
  .wo-photos:not(:empty){margin-left:6px}
  .wo-photo img{width:56px;height:56px;object-fit:cover;border-radius:6px;border:1px solid var(--line);display:block}
  .ordoMenu button:disabled{color:var(--mut);cursor:default}
  .ordoMenu .coche{display:inline-block;width:18px;color:var(--accent2)}
  .ordoMenu hr{border:0;border-top:1px solid var(--line);margin:4px 2px}
  /* Dans l'onglet détaché, « Back to Scheduling » remplace Run Fleet Routing et From top of day. */
  body.popout #btnRouting, body.popout #btnDebutJournee, body:not(.popout) #btnRetourOrdo{display:none}
  /* Sidebar */
  .side{background:#0b1428;border-right:1px solid var(--line);display:flex;flex-direction:column;overflow:auto}
  .brand{padding:16px 16px 12px;border-bottom:1px solid var(--line)}
  .brand h1{font-size:15px;margin:0;letter-spacing:.3px}
  .brand small{color:var(--mut);font-size:11px}
  .nav{padding:8px}
  .nav button{display:flex;gap:9px;align-items:center;width:100%;text-align:left;background:none;border:0;color:var(--mut);
    padding:9px 11px;border-radius:8px;cursor:pointer;font-size:13px}
  .nav button .ic{width:18px;text-align:center}
  .nav button:hover{background:var(--panel);color:var(--ink)}
  .nav button.active{background:var(--accent);color:#fff}
  .nav .badge{margin-left:auto;background:var(--bad);color:#fff;border-radius:10px;padding:1px 7px;font-size:11px}
  /* La cloche des notifications (0210). */
  .notif-wrap{position:relative}
  .notif-count:not(:empty){margin-left:4px;background:var(--bad);color:#fff;border-radius:10px;padding:0 6px;font-size:11px}
  .notif-panel{position:absolute;right:0;top:calc(100% + 6px);width:min(380px,90vw);max-height:60vh;overflow:auto;
    background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:8px;z-index:700;box-shadow:0 6px 24px rgba(0,0,0,.4)}
  .notif-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px}
  .notif-item{display:block;width:100%;text-align:left;background:none;border:0;border-top:1px solid var(--line);color:var(--txt);padding:8px 4px;cursor:pointer;font:inherit}
  .notif-item.non-lue{font-weight:600}
  .notif-item.non-lue::before{content:'● ';color:var(--accent)}
  .notif-item .muted{display:block;font-weight:400;font-size:11px}
  .side .foot{margin-top:auto;padding:10px;border-top:1px solid var(--line);font-size:11px;color:var(--mut)}
  /* Main */
  .main{overflow:auto;display:flex;flex-direction:column}
  .topbar{position:sticky;top:0;z-index:600;background:rgba(15,23,42,.92);backdrop-filter:blur(6px);
    border-bottom:1px solid var(--line);padding:10px 18px;display:flex;gap:10px;align-items:center;flex-wrap:wrap}
  .topbar h2{margin:0;font-size:16px;flex:0 0 auto}
  .topbar .spacer{flex:1}
  /* Étroit, le bandeau passe sur quatre lignes (260 px sur 667 à 404 px de large,
     mesuré 2026-09-28) : épinglé, il cachait les lignes défilées sous lui. */
  @media(max-width:760px){ .topbar{position:static} }
  .content{padding:18px}
  /* Buttons */
  .btn{background:var(--panel);border:1px solid var(--accent);color:var(--ink);padding:8px 12px;border-radius:8px;cursor:pointer;font-size:13px}
  .btn:hover{border-color:var(--accent)}
  .btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
  .btn.good{background:var(--good);border-color:var(--good);color:#04240f}
  .btn.warn{background:var(--warn);border-color:var(--warn);color:#3a2600}
  .btn.bad{background:var(--bad);border-color:var(--bad);color:#fff}
  .btn.sm{padding:5px 9px;font-size:12px}
  .btn:disabled{opacity:.5;cursor:not-allowed}
  /* A disabled field must LOOK disabled: the alarm return date (Postponed only) looked typeable (2026-10-22). */
  input.inp:disabled,select.inp:disabled{opacity:.45;cursor:not-allowed}
  /* Cards / grid */
  .cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}
  .card{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px}
  .card .k{color:var(--mut);font-size:12px}
  .card .v{font-size:26px;font-weight:700;margin-top:4px}
  .card .s{font-size:11px;color:var(--mut);margin-top:2px}
  .panel{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px;margin-top:14px}
  .panel h3{margin:0 0 10px;font-size:14px}
  .chartbox{position:relative;height:240px;width:100%}
  .chartbox canvas{display:block;width:100%!important;height:100%!important}
  /* Graphiques repris de la Console : créés contre réparés, ouverts par priorité */
  .histo-flux{display:flex;align-items:flex-end;gap:4px;height:140px}
  .histo-jour{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:0}
  .histo-paire{flex:1;width:100%;display:flex;align-items:flex-end;justify-content:center;gap:2px}
  .histo-paire > div{width:42%;max-width:14px;min-height:1px;border-radius:2px 2px 0 0}
  .histo-cree{background:var(--accent)}
  .histo-repare{background:var(--good)}
  .histo-date{font-size:11px;color:var(--mut);margin-top:4px}
  .histo-barre{display:flex;height:22px;border-radius:3px;overflow:hidden}
  .histo-Critical{background:var(--bad)}
  .histo-High{background:var(--warn)}
  .histo-Normal{background:var(--accent)}
  .histo-Low{background:var(--mut);opacity:.6}
  .histo-legende{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:10px;font-size:13px}
  .histo-puce{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:6px}
  .panel h3.histo-sous-titre{margin-top:20px}
  .panel > h3.histo-sous-titre:first-child{margin-top:0}
  /* Calendrier du retard : couleurs vives choisies par Bernard (2026-10-07). */
  .cal-retard-defile{overflow-x:auto}
  .cal-retard{display:grid;grid-auto-flow:column;grid-template-rows:20px repeat(7,30px);grid-template-columns:40px;grid-auto-columns:30px;gap:6px;width:max-content;font-size:13px;color:var(--mut)}
  .cal-retard-mois{white-space:nowrap;line-height:20px}
  .cal-retard-jsem{line-height:30px}
  .cal-retard-case{width:30px;height:30px;border-radius:5px;background:var(--chip)}
  .cal-retard-auj{outline:2px solid var(--accent);outline-offset:1px}
  .cal-retard-sous-titre{margin-left:8px;font-size:12px;font-weight:400;color:var(--mut)}
  .goulot{display:grid;gap:4px;align-items:center;font-size:12px;min-width:max-content}
  .goulot-jour{color:var(--mut);font-size:11px;text-align:center;white-space:nowrap}
  .goulot-auj{color:var(--accent);font-weight:600}
  .goulot-genre{white-space:nowrap;padding-right:8px}
  .goulot-case{height:22px;border-radius:3px;background:var(--chip);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;color:#000}
  .goulot-case.cal-r4,.goulot-case.cal-r5{color:#fff}
  .goulot-tendance{white-space:nowrap;padding-left:8px;color:var(--mut)}
  .goulot-alerte{color:var(--bad);font-weight:600}
  .cal-r0{background:#1fc957}.cal-r1{background:#ffd60a}.cal-r2{background:#ff9f0a}
  .cal-r3{background:#ff5a24}.cal-r4{background:#ff2442}.cal-r5{background:#d4146a}
  /* Écart sur la veille, rouge/blanc/bleu (Bernard, 2026-10-20) ; ±1-2 renforcés le même jour. */
  .cal-h0{background:#ffffff}
  .cal-hp1{background:#f9805f}.cal-hp2{background:#f2543d}.cal-hp3{background:#d82a26}.cal-hp4{background:#b3141c}.cal-hp5{background:#7f0010}
  .cal-hm1{background:#7fb5e6}.cal-hm2{background:#4f93d6}.cal-hm3{background:#2c6fbb}.cal-hm4{background:#1a539e}.cal-hm5{background:#0b3478}
  /* Jour sans bon : gris finement hachuré (Bernard, 2026-10-20). */
  .cal-vide{background-color:var(--chip);background-image:repeating-linear-gradient(45deg,rgba(255,255,255,.16) 0 1px,transparent 1px 5px)}
  .goulot-case.cal-hp3,.goulot-case.cal-hp4,.goulot-case.cal-hp5,.goulot-case.cal-hm3,.goulot-case.cal-hm4,.goulot-case.cal-hm5{color:#fff}
  .row{display:flex;gap:12px;flex-wrap:wrap}
  .row > *{flex:1;min-width:280px}
  /* Table */
  table{width:100%;border-collapse:collapse;font-size:13px}
  th,td{padding:8px 9px;border-bottom:1px solid var(--line);text-align:left;vertical-align:middle}
  th{color:var(--mut);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.4px;position:sticky;top:0;background:var(--panel)}
  tr:hover td{background:var(--panel2)}
  .tbl-wrap{max-height:62vh;overflow:auto;border:1px solid var(--line);border-radius:10px}
  /* Date-filter calendar popup */
  .wocal{position:absolute;top:calc(100% + 4px);left:0;z-index:2000;background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:10px;box-shadow:0 10px 28px rgba(0,0,0,.55);width:252px}
  .wocal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
  .wocal-head b{font-size:13px}
  .wocal-nav{background:var(--panel);border:1px solid var(--line);color:var(--ink);cursor:pointer;font-size:13px;line-height:1;padding:4px 9px;border-radius:6px}
  .wocal-nav:hover{border-color:var(--accent)}
  .wocal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
  .wocal-dow{font-size:10px;color:var(--mut);text-align:center;padding:2px 0}
  .wocal-day{position:relative;text-align:center;font-size:12px;padding:6px 0;border-radius:6px;cursor:pointer;border:1px solid transparent;color:var(--ink)}
  .wocal-day:hover{background:var(--panel)}
  .wocal-day.other{opacity:.3}
  .wocal-day.today{border-color:var(--accent2)}
  .wocal-day.sel{background:var(--accent);color:#fff;font-weight:700}
  .wocal-day .dot{position:absolute;bottom:3px;left:50%;transform:translateX(-50%);width:4px;height:4px;border-radius:50%;background:var(--good)}
  .wocal-day.sel .dot{background:#fff}
  .wocal-foot{display:flex;justify-content:space-between;align-items:center;margin-top:8px;font-size:11px;color:var(--mut)}
  /* Chips / badges */
  .chip{display:inline-block;padding:2px 9px;border-radius:20px;font-size:11px;font-weight:600;background:var(--chip);color:var(--ink)}
  .st{padding:2px 9px;border-radius:20px;font-size:11px;font-weight:700}
  .st-New{background:#334155;color:#cbd5e1}
  .st-Scheduled{background:#1e3a8a;color:#bfdbfe}
  .st-Onsite{background:#78350f;color:#fde68a}
  .st-Problem{background:#7c2d12;color:#fed7aa}
  .st-Fixed{background:#14532d;color:#bbf7d0}
  .st-NotFixed{background:#7f1d1d;color:#fecaca}
  .st-Cancelled{background:#3f3f46;color:#a1a1aa}
  .pri-Critical{color:var(--bad);font-weight:700}
  .pri-High{color:var(--warn);font-weight:700}
  .pri-Normal{color:var(--mut)}
  .pri-Low{color:var(--mut);opacity:.8}
  .muted{color:var(--mut)}
  .right{text-align:right}
  .warnrow td{background:rgba(239,68,68,.08)}
  /* Inputs */
  input,select,textarea{background:var(--bg);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:8px;font-size:13px;width:100%;font-family:inherit}
  /* Dark theme: recolour the native date-picker calendar icon from black to white */
  input[type="date"]::-webkit-calendar-picker-indicator{filter:invert(1);cursor:pointer}
  label{font-size:12px;color:var(--mut);display:block;margin:8px 0 3px}
  .grid2{display:grid;grid-template-columns:1fr 1fr;gap:10px}
  /* La bande de faits d'une fiche de bon de travail. Elle remplace une grille a
     deux colonnes qui tenait six cellules pour cinq faits courts — une ligne
     chacune, plus une case vide sur tout bon ouvert. `flex-wrap` la replie
     selon la largeur au lieu de reserver une demi-largeur par fait, et
     l'etiquette passe AU-DESSUS de la valeur : deux fois plus de faits par
     ligne, sans rien rapetisser. */
  .wo-faits{display:flex;flex-wrap:wrap;gap:.45rem 1.6rem;margin:.6rem 0 .55rem}
  .wo-fait{display:flex;flex-direction:column;gap:2px;min-width:0}
  .wo-fait-k{font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--mut);white-space:nowrap}
  .wo-fait-v{font-weight:600}
  /* Un champ éditable doit se VOIR éditable (Bernard, 2026-10-06 : « very
     hard to find ») : fond de panneau et bordure d'accent, comme les boutons,
     au lieu du fond de page et d'une bordure presque invisible.
     `width:auto` : la règle `input, select` met 100 %, et sur une carte du
     Kanban la liste passait sur sa propre ligne, pleine largeur. */
  .wo-fait-v .inp,.inp.edit{background:var(--panel2);border-color:var(--accent);cursor:pointer;padding:4px 8px;width:auto}
  /* « Due by » et « Scheduled for » groupés quand l'alerte d'échéance se centre dessous. */
  .wo-faits-dates{display:flex;flex-direction:column;gap:3px}
  .wo-faits-paire{display:flex;gap:.45rem 1.6rem}
  .wo-faits-alerte{text-align:center;color:var(--bad);font-weight:700}
  /* La fenêtre horaire du bon : préréglages d'un clic, puis deux champs d'heure. */
  .wo-fen{display:inline-flex;align-items:center;gap:.35rem;flex-wrap:wrap}
  .wo-fen-perso{display:inline-flex;align-items:center;gap:.25rem;white-space:nowrap}
  .wo-fen-perso[hidden]{display:none}
  /* La fenetre horaire sur les cartes des deux tableaux (Bernard, 2026-10-07) : gras, orange vif. */
  .wo-fen-carte{color:#ff8c1a;font-weight:700}
  /* La bande de la journée : 28 demi-heures, 06:00–20:00 (FEN_BANDE). */
  .wo-fen-bloc{display:inline-flex;flex-direction:column;gap:2px}
  .wo-fen-bande{display:grid;grid-template-columns:repeat(28,1fr);gap:2px;width:308px;user-select:none;touch-action:none}
  .wo-fen-case{height:22px;background:var(--panel2);border:1px solid var(--line);border-radius:3px;cursor:pointer}
  .wo-fen-case:hover{border-color:var(--accent)}
  .wo-fen-case.on{background:var(--accent);border-color:var(--accent)}
  .wo-fen-reperes{display:grid;grid-template-columns:repeat(7,1fr);width:308px;font-size:10px;font-weight:400;color:var(--mut)}
  .wo-fen-lu{font-variant-numeric:tabular-nums;min-width:9.5em;margin-left:.3rem}
  /* Un fait LONG (adresse, description) : l'etiquette reste a gauche, sinon
     chaque ligne d'une adresse sur deux lignes decalerait la suivante. */
  .wo-ligne{display:flex;gap:.7rem;align-items:baseline;margin:.2rem 0}
  .wo-ligne>.wo-fait-k{flex:0 0 auto}
  .grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}
  /* L'ÉCRAN DU BON (Bernard, 2026-09-22) : un bon ouvert masque le reste de
     l'onglet — en-tête, filtres, liste ou tableau. `#liveBody` est recréé à
     chaque rendu de l'onglet, donc la classe ne survit pas à un changement
     d'onglet. `#liveOutbox` reste : il dit ce qui attend d'être envoyé. */
  :has(> #liveBody.wo-ecran) > :not(#liveBody):not(#liveOutbox){display:none}
  #liveBody.wo-ecran{padding:0 !important}
  #liveBody.wo-ecran > :not(#liveDetail){display:none}
  #liveBody.wo-ecran > #liveDetail{margin-top:0 !important}
  /* Les techniciens d'un bon sur UNE ligne : ils sont deux ou trois. */
  .wo-techs{display:flex;flex-wrap:wrap;gap:.25rem 1.6rem;margin:.2rem 0 .5rem;padding:0;list-style:none}
  /* Camions et pièces : la table épouse son contenu au lieu de s'étirer sur
     toute la largeur — des colonnes à 600 px l'une de l'autre ne se lisent
     plus comme une ligne. */
  .tbl-wrap.wo-serre{display:inline-block;max-width:100%;vertical-align:top}
  .tbl-wrap.wo-serre > table{width:auto}
  .tbl-wrap.wo-serre th,.tbl-wrap.wo-serre td{padding:5px 12px}
  /* Modal */
  .modal-bg{position:fixed;inset:0;background:rgba(2,6,23,.68);display:none;align-items:flex-start;justify-content:center;z-index:1000;overflow:auto;padding:30px 12px}
  .modal-bg.on{display:flex}
  /* Embedded Route Optimizer overlay */
  /* z-index 100002 et non 1500 : `pkce.js` pose la pastille d'identite en
     position:fixed, top:8px right:8px, z-index:99999, et le selecteur
     d'applications monte a 100001. A 1500 la superposition passait DESSOUS,
     et la pastille recouvrait exactement le coin ou vivent « ← Back to
     Scheduling » et « ✕ Close ». Mesure du 2026-09-11 : le repartiteur
     voyait « Optimization finished » sans pouvoir sortir — les boutons
     etaient servis, rendus, et inatteignables. Une superposition plein ecran
     doit passer devant le chrome flottant de l'application : tant qu'elle est
     ouverte, c'est elle l'ecran. */
  #optzOverlay{position:fixed;inset:0;z-index:100002;background:var(--bg);display:none;flex-direction:column}
  #optzOverlay.on{display:flex}
  .optz-bar{display:flex;gap:12px;align-items:center;padding:8px 14px;background:#0b1428;border-bottom:1px solid var(--line);font-size:14px}
  .optz-bar .muted{color:var(--mut);font-size:13px}
  /* Un texte de statut long poussait les boutons hors de la barre : par
     defaut un element flex ne retrecit pas sous la largeur de son contenu.
     `min-width:0` le lui permet, l'ellipse dit qu'il en manque, et les
     boutons gardent leur taille. Ce qu'on peut perdre, c'est de la prose ;
     ce qu'on ne peut pas perdre, c'est la sortie. */
  #optzStatus{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .optz-bar > button{flex:0 0 auto}
  #optzFrame{flex:1;border:0;width:100%;background:#fff}
  .modal{background:var(--panel2);border:1px solid var(--line);border-radius:14px;width:min(760px,100%);padding:18px;box-shadow:0 20px 60px rgba(0,0,0,.5)}
  .modal h3{margin:0 0 12px}
  .modal .actions{display:flex;gap:10px;justify-content:flex-end;margin-top:16px}
  #map{height:70vh;border-radius:12px;border:1px solid var(--line)}
  .route-num{background:transparent!important;border:0!important;box-shadow:none!important;color:#fff;font-weight:700;font-size:10px;padding:0}
  .route-num::before{display:none!important}
  .legend{display:flex;gap:14px;flex-wrap:wrap;font-size:12px;color:var(--mut);margin-top:8px}
  .dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:5px;vertical-align:middle}
  .toast{position:fixed;left:50%;top:83.333vh;transform:translate(-50%,-50%);z-index:2000;display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none}
  .toast div{background:var(--panel2);border:1px solid var(--line);border-left:4px solid var(--accent);padding:10px 14px;border-radius:8px;font-size:13px;max-width:360px;box-shadow:0 8px 24px rgba(0,0,0,.4)}
  .toast div.ok{border-left-color:var(--good)} .toast div.err{border-left-color:var(--bad)}
  .toast div.err{pointer-events:auto;cursor:pointer} .toast div.err::after{content:' ✕';opacity:.6}
  /* « warn » = l action a ABOUTI mais elle a quelque chose a dire (un import
     applique qui a saute des rangees). Sans cette regle, toast(...,'warn')
     retombe sur le lisere d accent et se lit comme un succes ordinaire. */
  .toast div.warn{border-left-color:var(--warn)}
  .readme{max-width:900px;line-height:1.6;font-size:14px}
  .readme h3{font-size:20px;margin-top:0} .readme h4{margin-top:18px;color:var(--accent2)}
  .readme code{background:var(--bg);padding:2px 6px;border-radius:5px;border:1px solid var(--line);font-size:13px}
  .readme li{margin:4px 0}
  .readme table{margin:8px 0}
  /* Documentation library layout */
  .docs{display:grid;grid-template-columns:230px 1fr;gap:18px;align-items:start}
  .doc-nav{position:sticky;top:64px;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:8px;max-height:calc(100vh - 100px);overflow:auto}
  .doc-nav .doc-cat{font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:var(--mut);padding:10px 10px 4px}
  .doc-nav button{display:flex;gap:9px;align-items:center;width:100%;text-align:left;background:none;border:0;color:var(--mut);padding:8px 10px;border-radius:8px;cursor:pointer;font-size:13px}
  .doc-nav button:hover{background:var(--panel2);color:var(--ink)}
  .doc-nav button.active{background:var(--accent);color:#fff}
  /* Un chapitre du manuel est un <a>, pour la meme raison que le lien
     ci-dessous : c est une PAGE. Il se PORTE comme les boutons voisins. */
  .doc-nav .doc-chap{display:flex;gap:9px;align-items:center;width:100%;text-align:left;color:var(--mut);text-decoration:none;padding:8px 10px;border-radius:8px;font-size:13px}
  .doc-nav .doc-chap:hover{background:var(--panel2);color:var(--ink)}

  /* ── LE LIEN VERS LE MANUEL DE L'UTILISATEUR ──────────────────────────
     Un <a>, pas un bouton : le manuel est une PAGE, pas un onglet. Le clic
     du milieu, « ouvrir dans un nouvel onglet » et la copie du lien doivent
     marcher comme partout ailleurs — un bouton les perdrait tous les trois.

     Le href est RELATIF (`manual-*.html`). Servi, il resout sous `/apps/`,
     a cote de l'application ; en local, a cote de la page mandataire. Une
     URL absolue serait juste sur un seul des deux. */
  .doc-nav .doc-manuel{display:block;margin:2px 0 10px;padding:10px;border:1px solid var(--accent);border-radius:8px;color:var(--ink);text-decoration:none;font-size:13px;line-height:1.35}
  .doc-nav .doc-manuel:hover{background:var(--accent);color:#fff}
  .doc-nav .doc-manuel small{display:block;color:var(--mut);font-size:11px;margin-top:3px}
  .doc-nav .doc-manuel:hover small{color:#fff}
  .doc-body{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:20px 24px;min-width:0}
  .doc-body h4:first-child{margin-top:0}
  @media(max-width:760px){ .docs{grid-template-columns:1fr} .doc-nav{position:static;max-height:none} }
  .flt{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:10px}
  .flt input,.flt select{width:auto;min-width:130px}
  /* Barre de l'ordonnanceur : recherche et filtres bordés en bleu, comme les boutons */
  #schedSearch,#schedCrew,#schedEquip{border-color:var(--accent)}
  /* Liste des bons : champ de recherche et bouton Search dans une même boîte bordée en bleu */
  .searchGrp{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--accent);border-radius:8px;padding:2px 3px 2px 0}
  .searchGrp input{border:0;background:transparent}
  /* Search box with a clear (✕) button that shows only when there's text */
  .search{position:relative;display:inline-flex;align-items:center}
  .search input{padding-right:24px}
  .search .clr{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:none;border:0;background:none;color:var(--mut);cursor:pointer;font-size:14px;line-height:1;padding:2px}
  .search .clr:hover{color:var(--ink)}
  .search input:not(:placeholder-shown)+.clr{display:block}
  .tag{display:inline-block;background:var(--chip);border-radius:6px;padding:1px 7px;font-size:11px;margin:1px 2px}
  .kv{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px dashed var(--line);font-size:13px}
  /* Work-order card data elements: label left with a trailing colon, value left-justified beside it. */
  .wokv .kv{justify-content:flex-start;gap:6px}
  .wokv .kv>span{color:var(--mut);flex:none}
  .wokv .kv>span::after{content:":"}
  .wokv .kv>b{text-align:left}
  .bar{height:8px;border-radius:4px;background:var(--line);overflow:hidden}
  .bar > i{display:block;height:100%;background:var(--accent)}
  /* Clickable cross-links to related records — light yellow signals "click to travel". */
  .lnk{color:#fde68a;cursor:pointer;border-bottom:1px dotted rgba(253,230,138,.45)}
  .lnk:hover{color:#fffbe6;border-bottom-color:#fde68a}
  b .lnk,.lnk b{color:inherit}
  /* Même jaune, en pastille : les bulles Leaflet sont BLANCHES, où le texte #fde68a ne se lit pas. */
  .lnk-bon{display:inline-block;margin:2px 0;padding:1px 6px;border-radius:4px;background:#fde68a;color:#3a2600;font-weight:600;cursor:pointer}
  .lnk-bon:hover{background:#fcd34d}
  @keyframes rowflash{0%{background:rgba(253,230,138,.42)}100%{background:transparent}}
  tr.flash > td{animation:rowflash .8s ease-out}
  tr.rowhi > td{background:rgba(253,230,138,.24)}
  /* Une table « sélectionnable » (`class="tbl sel"`, ou `class="sel"` là où la
     table n'a pas la classe `tbl`) : cliquer n'importe où sur une ligne la garde
     en jaune pâle jusqu'à ce qu'une autre soit choisie. Le survol l'annonce ;
     c'est la seule différence visible avec une table muette.
     ⚠️ `tr[id]`, et non `tr` : la flotte écrit ses tables SANS `<thead>`, en-tête
     compris comme une `<tr>` ordinaire. L'analyseur la range donc dans le `tbody`
     qu'il insère, et un survol sur `tr` nu donnerait un curseur « cliquable » à
     une ligne d'en-tête qui ne l'est pas. Seules les lignes ancrées le sont. */
  /* ⚠️ UNE LIGNE PEUT DÉJÀ PORTER UNE COULEUR QUI VEUT DIRE QUELQUE CHOSE.
     `.warnrow td` (stock bas, Materials) a une spécificité PLUS FAIBLE que
     `tr.rowhi > td` : choisir une ligne sous le seuil lui faisait donc perdre
     son rouge, et elle cessait de se lire comme une alerte. On SUPERPOSE le
     jaune au lieu de le substituer — les deux restent lisibles. */
  tr.rowhi.warnrow > td{background:linear-gradient(rgba(253,230,138,.24),rgba(253,230,138,.24)),rgba(239,68,68,.08)}
  table.sel tbody tr[id]{cursor:pointer}
  table.sel tbody tr[id]:hover > td{background:rgba(253,230,138,.10)}
  table.sel tbody tr[id].rowhi:hover > td{background:rgba(253,230,138,.30)}
  table.sel tbody tr[id].rowhi.warnrow:hover > td{background:linear-gradient(rgba(253,230,138,.30),rgba(253,230,138,.30)),rgba(239,68,68,.08)}
  @keyframes cardflash{0%{box-shadow:0 0 0 3px #fde68a}100%{box-shadow:0 0 0 0 rgba(253,230,138,0)}}
  .card.flash{animation:cardflash .8s ease-out}
  .card.rowhi{box-shadow:0 0 0 2px rgba(253,230,138,.55)}
  /* ⚠️ `rowhi` ÉTAIT POSÉE SUR DU VIDE AU TABLEAU KANBAN. Ses cartes sont des
     `.woCard`, qui ne correspondent ni à `tr.rowhi > td` ni à `.card.rowhi` : le
     bon ouvert avait exactement l'air de tous les autres. Même convention que la
     carte ci-dessus — un anneau jaune — plus une teinte, parce qu'une carte se
     cherche dans une colonne alors qu'une ligne se cherche dans une table. */
  /* L'ANNEAU porte le sens, la teinte ne fait que l'appuyer : `.woCard.frozen`
     est déclarée PLUS BAS à spécificité égale, donc une carte gelée et choisie
     garde son fond cyan et perd le jaune. Mesuré, et laissé tel quel — empiler
     du jaune sur du cyan brouillerait les deux, alors que l'anneau distingue
     déjà la carte choisie parmi ses voisines gelées. */
  .woCard.rowhi{box-shadow:0 0 0 2px rgba(253,230,138,.55);background:rgba(253,230,138,.10)}
  /* La carte d'où l'on a ouvert le bon — Kanban des bons ET ordonnanceur : au
     retour ◀, un anneau jaune PLEIN — Bernard, 2026-10-07 : « surround it in
     yellow ». L'anneau pâle ci-dessus ne se repérait pas dans une colonne. */
  .woCard.rowhi{box-shadow:0 0 0 2px #facc15}
  /* Un ARRÊT de l'onglet Routes. Il n'est ni une ligne de table ni une carte —
     c'est un `div` serré sous l'en-tête d'un camion — mais il porte EXACTEMENT
     les mêmes trois nombres qu'une ligne de table (.10 au survol, .24 choisi,
     .30 les deux). Mesuré côte à côte sur le fond sombre : la bande d'un arrêt
     et celle d'une ligne se lisent à l'identique, et c'est ce qu'on veut — un
     douzième onglet ne doit pas inventer sa propre intensité.
     ⚠️ AUCUNE PROPRIÉTÉ QUE `data-css` ÉCRIT DÉJÀ. Chaque arrêt en porte un, et
     l'applicateur pose ces propriétés-là sur le `style` de l'élément — une par
     une depuis #181, mais en ligne quand même, donc `padding` et
     `border-bottom` restent hors d'atteinte d'une feuille. Seul le fond, qu'il
     n'écrit pas, peut porter la marque. */
  .rtstop[id]{cursor:pointer}
  .rtstop[id]:hover{background:rgba(253,230,138,.10)}
  .rtstop.rowhi{background:rgba(253,230,138,.24)}
  .rtstop.rowhi:hover{background:rgba(253,230,138,.30)}
  /* ⚠️ `flashPersist` POSE `flash` SUR N IMPORTE QUEL PORTEUR, et le jaune
     persistant seul ne dit pas OÙ regarder dans une tournée de vingt arrêts.
     Même animation que la ligne de table (`rowflash`), pas celle des cartes :
     un arrêt se cherche dans une colonne serrée, comme une ligne, pas comme une
     carte détachée. L animation ne pose pas `forwards`, donc le .24 de
     `rowhi` reprend la main dès qu elle finit. */
  .rtstop.flash{animation:rowflash .8s ease-out}
  /* Scheduling board card flash (jump-to on a "not routed" badge click) — pulses a few times */
  .woCard.flash{animation:cardflash .8s ease-out 0s 3}
  /* Le bloc du Gantt d'ou l'on est parti vers la fiche : ◀ le rallume. */
  .ganttBloc.rowhi{box-shadow:0 0 0 2px #fde68a;z-index:1}
  .ganttBloc.flash{animation:cardflash .8s ease-out 0s 3}
  /* Scheduling drag-and-drop */
  .woCard{position:relative;cursor:grab;border:1px solid var(--line);background:var(--panel2);border-radius:8px;padding:6px 8px 6px 22px;margin-bottom:6px}
  .woCard:hover{border-color:var(--accent)}
  .woCard:active{cursor:grabbing}
  .woCard.dragging{opacity:.35}
  .woCard .grip{position:absolute;left:5px;top:6px;color:var(--mut);font-size:13px;line-height:1;cursor:grab;user-select:none}
  .woCard:hover .grip{color:var(--accent)}
  .woCard.frozen{cursor:pointer;border-style:dashed;border-color:var(--accent2);background:rgba(34,211,238,.06)}
  .woCard.frozen .grip{cursor:default}
  .drag-ghost{position:fixed;z-index:3000;pointer-events:none;background:var(--panel2);border:1px solid var(--accent);border-radius:8px;padding:5px 6px;box-shadow:0 10px 30px rgba(0,0,0,.5);opacity:.95;max-width:230px}
  .drop-line{height:0;border-top:2px solid var(--accent);border-radius:2px;margin:3px 1px;box-shadow:0 0 5px var(--accent);pointer-events:none}
  .dayBody{min-height:34px;border-radius:8px;transition:background .12s,outline .12s}
  .dayBody.dropok{outline:2px dashed var(--accent);outline-offset:2px;background:rgba(59,130,246,.12)}
  .card.dropok{outline:2px dashed var(--accent);outline-offset:2px;background:rgba(59,130,246,.10)}   /* collapsed day: drop onto its header */
  /* Live work-order Kanban board */
  .kbwrap{display:flex;gap:10px;overflow-x:auto;padding-bottom:8px;align-items:flex-start}
  .kbcol{flex:0 0 220px;min-width:220px;background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:8px;transition:background .12s,outline .12s}
  .kbcol.dropok{outline:2px dashed var(--accent);outline-offset:2px;background:rgba(59,130,246,.10)}
  .kbcol.nodrop{outline:2px dashed #ef4444;outline-offset:2px}
  .kbcol>h4{margin:0 0 8px;font-size:12px;display:flex;align-items:center;gap:6px;text-transform:uppercase;letter-spacing:.4px;color:var(--mut)}
  .kbcol>h4 .dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto}
  .kbcol .kbcount{margin-left:auto;font-weight:normal}
  .kbcol .kbempty{color:var(--mut);font-size:12px;padding:6px 2px}
  .woCard.kb .kbcode{font-weight:700}
  /* Creneau : jour planifie (et rang quand le tableau est charge). Etat SERVEUR,
     jamais un calcul local — voir slotOf(). */
  .woCard.kb .kbslot{margin-top:3px;font-size:11px;font-weight:600;color:var(--accent)}
  .woCard.kb .kbmeta{color:var(--mut);font-size:11px;margin-top:3px;display:flex;flex-wrap:wrap;gap:2px 8px}
  .woMoveBtns{float:right;display:inline-flex;gap:3px}
  .woMoveBtns button{background:var(--chip);border:1px solid var(--line);color:var(--mut);border-radius:5px;font-size:10px;line-height:1;padding:2px 5px;cursor:pointer}
  .woMoveBtns button:hover:not(:disabled){color:var(--ink);border-color:var(--accent)}
  .woMoveBtns button:disabled{opacity:.35;cursor:default}
  .pin{cursor:pointer}
  .pin.grey{filter:grayscale(1);opacity:.4}
  .pin.grey:hover{opacity:.85}
  .lockbtn{cursor:pointer;font-size:15px;line-height:1}
  .lockbtn.grey{filter:grayscale(1);opacity:.45}
  .lockbtn.grey:hover{opacity:.8}
  /* La carte en trois lignes de l ordonnanceur (Bernard, 2026-10-16) : quoi, qui, alerte.
     Les commandes ne paraissent qu au survol ; un 📌 posé ou un 🔒 fermé reste visible. */
  .woCard.wc3 .wc-bande{position:absolute;left:0;top:0;bottom:0;width:5px;border-radius:8px 0 0 8px}
  .woCard.wc3 .wc-bande.pri-Critical{background:var(--danger,#ef4444)}
  .woCard.wc3 .wc-bande.pri-High{background:var(--warn,#f59e0b)}
  .woCard.wc3 .wc-l1{display:flex;align-items:baseline;gap:6px;font-size:13px;font-weight:600;line-height:1.3}
  .woCard.wc3 .wc-l1 .dot{flex:0 0 auto;align-self:center}
  .woCard.wc3 .wc-titre{flex:1;min-width:0}
  .woCard.wc3 .wc-duree{flex:0 0 auto;font-weight:400;color:var(--mut);font-size:12px}
  .woCard.wc3 .wc-l2{display:flex;align-items:center;gap:6px;margin-top:2px;color:var(--mut);font-size:12px;min-height:20px}
  .woCard.wc3 .wc-info{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .woCard.wc3 .wc-acts{flex:0 0 auto;display:inline-flex;align-items:center;gap:4px}
  .woCard.wc3 .wc-acts>:not(.on){display:none}
  .woCard.wc3:hover .wc-acts>*,.woCard.wc3:focus-within .wc-acts>*{display:revert}
  @media (hover:none){.woCard.wc3 .wc-acts>*{display:revert}}
  .woCard.wc3 .wc-acts .woMoveBtns{float:none}
  .woCard.wc3 .wc-acts .lockbtn{font-size:14px}
  .woCard.wc3 .wc-acts select{font-size:11px;padding:1px 4px}
  .woCard.wc3 .wc-l3{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:4px}
  .woCard.wc3 .wc-l3 .nonRepare{flex-basis:100%}
  /* La charge du jour par genre : une barre par genre chargé (Bernard, 2026-10-16). */
  .chargeBarre{display:grid;grid-template-columns:minmax(0,78px) 1fr auto;align-items:center;gap:6px;font-size:11px;color:var(--mut)}
  .chargeBarre:first-child{margin-top:6px}
  .chargeBarre .cb-nom{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .chargeBarre .cb-piste{height:6px;border-radius:3px;background:var(--chip);overflow:hidden}
  .chargeBarre .cb-plein{display:block;height:100%;background:var(--mut)}
  .chargeBarre.near .cb-plein{background:var(--warn,#f59e0b)}
  .chargeBarre.near .cb-chiffre{color:var(--warn,#f59e0b)}
  .chargeBarre.over .cb-plein{background:var(--danger,#ef4444)}
  .chargeBarre.over .cb-chiffre,.chargeBarre.over .cb-nom{color:var(--danger,#ef4444);font-weight:600}
  .woCard .lockbtn{position:absolute;right:8px;bottom:4px;font-size:19px}
  .woCard.wc3 .lockbtn{position:static}
  .daylock{margin-left:2px}
  /* Data Exchange tab */
  .dx-tools{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
  .dx-tools .spacer{flex:1}
  .dx-sel{color:var(--mut);font-size:13px}
  .dx-sel b{color:var(--accent2)}
  .dx-ghead{display:flex;align-items:center;gap:10px;padding:8px 2px;color:var(--mut);font-size:11px;text-transform:uppercase;letter-spacing:.5px}
  .dx-ghead .store{font-family:ui-monospace,Consolas,monospace;background:var(--chip);border-radius:6px;padding:2px 7px;color:var(--mut);text-transform:none;letter-spacing:0}
  .dx-row{border-top:1px solid var(--line)}
  .dx-main{display:grid;grid-template-columns:22px 1fr auto auto 30px;align-items:center;gap:12px;padding:9px 4px}
  .dx-main:hover{background:var(--panel2)}
  /* Imports et exports des autres apps : ni case a cocher ni ⓘ, et le lieu en derniere colonne. */
  .dx-main.ailleurs{grid-template-columns:1fr auto auto minmax(150px,auto)}
  .dx-nm{font-weight:600;font-size:13px}
  .dx-sub{color:var(--mut);font-size:11.5px}
  .dx-dir{display:flex;gap:5px}
  .dx-chip{font-size:10px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;padding:2px 7px;border-radius:5px}
  .dx-chip.i{background:rgba(34,197,94,.16);color:#4ade80}
  .dx-chip.e{background:rgba(167,139,250,.18);color:#c4b5fd}
  .dx-chip.x{background:rgba(239,68,68,.16);color:#f87171}
  .dx-stat{display:flex;align-items:center;gap:6px;color:var(--mut);font-size:11px;white-space:nowrap}
  .dx-dot{width:8px;height:8px;border-radius:50%;flex:none}
  .dx-dot.have{background:var(--good)} .dx-dot.partial{background:var(--warn)} .dx-dot.new{background:transparent;border:1.5px solid var(--line)}
  .dx-info{width:26px;height:26px;border-radius:7px;border:1px solid var(--line);background:var(--panel);color:var(--accent2);cursor:pointer;font-weight:700}
  .dx-info:hover{border-color:var(--accent)} .dx-info.on{background:var(--accent);color:#fff;border-color:var(--accent)}
  .dx-draw{display:none;padding:4px 10px 14px 34px;background:var(--panel2)} .dx-draw.on{display:block}
  .dx-draw dl{display:grid;grid-template-columns:96px 1fr;gap:5px 14px;margin:0;border-left:2px solid var(--accent);padding:10px 0 2px 14px}
  .dx-draw dt{color:var(--mut);font-size:10px;text-transform:uppercase;letter-spacing:.5px;font-weight:700;padding-top:2px}
  .dx-draw dd{margin:0;color:var(--ink);font-size:12.5px}
  .dx-cols{display:flex;flex-wrap:wrap;gap:4px}
  .dx-col{font-family:ui-monospace,Consolas,monospace;font-size:11px;background:var(--panel);border:1px solid var(--line);border-radius:5px;padding:1px 6px}
  .dx-col.k{border-color:var(--accent);color:var(--accent2)}
  .dx-samp{font-family:ui-monospace,Consolas,monospace;font-size:11px;color:var(--mut);background:var(--panel);border:1px solid var(--line);border-radius:6px;padding:7px 9px;overflow-x:auto;white-space:pre}
  .dx-legend{display:flex;flex-wrap:wrap;gap:14px;color:var(--mut);font-size:12px;margin-top:12px;padding-top:10px;border-top:1px solid var(--line)}
  .dx-legend span{display:flex;align-items:center;gap:6px}

  /* ── LE CONSTRUCTEUR DE RAPPORTS, EN VUE SERREE ────────────────────────
     Quatre sections, chacune avec ses menus : aux espacements de l app le
     tout depassait l ecran et il fallait derouler pour voir le resultat.
     Le resserrage vit ICI et non en `data-css` : un attribut ne peut pas
     atteindre les cellules d un tableau ni les etats de survol, et la CSP
     du deploiement refuse une balise <style> posee par le script. */
  #rptBody .panel{padding:6px 8px;margin:6px 0}
  #rptBody .panel:first-child{margin-top:0}
  #rptBody h3{margin:0 0 5px;font-size:13px}
  /* ⚠️ LA CAUSE MESUREE DE « JE NE PEUX PAS RETIRER UN FILTRE ».

     `.row > *{flex:1;min-width:280px}` (ligne 53) est fait pour des colonnes
     de formulaire, pas pour une phrase. Applique a une condition — menu,
     operateur, valeur, croix — il exige 280px POUR CHACUN : six enfants
     reclamaient 1680px, donc la ligne se repliait meme sur un grand ecran,
     et la croix, etiree a plus de mille pixels, se retrouvait SEULE sur sa
     propre rangee avec son signe au milieu. Rien ne la rattachait plus a sa
     condition. Mesure : bouton de 1037px de large, y=32 alors que sa
     condition commence a y=0.

     Ici une condition redevient une LIGNE : chaque controle prend la largeur
     de son contenu, et la croix ferme la ligne a droite. */
  #rptBody .row > *{flex:0 0 auto;min-width:0}
  #rptBody select,#rptBody input{width:auto;padding:2px 6px;font-size:12px}
  #rptBody .rpt-cond select{max-width:13rem}
  #rptBody .rpt-cond input{width:9rem}
  #rptBody .rpt-cond .rpt-x{margin-left:auto}
  /* Les deux blocs « ajouter » gardent leur mise en colonne : ce sont, eux,
     de vrais champs de formulaire avec leur etiquette au-dessus. */
  #rptBody .row > div{min-width:auto}
  #rptBody label.muted{font-size:11px}
  #rptBody table th,#rptBody table td{padding:2px 6px;font-size:12px}
  #rptBody .btn.sm{padding:1px 7px;font-size:11px}
  #rptBody .pill{font-size:10px;padding:0 5px}
  #rptBody details summary{font-size:12px}
  #rptBody pre{font-size:11px;margin:4px 0}
  #rptBody .row{gap:5px}

  /* Un groupe de filtre, et une condition : l imbrication doit rester
     LISIBLE en se resserrant — le retrait a gauche est ce qui dit « dedans »,
     donc il se reduit sans disparaitre. */
  #rptBody .rpt-grp{padding:5px 6px;margin:4px 0}
  #rptBody .rpt-grp-tete{gap:6px}
  #rptBody .rpt-cond{gap:4px;margin:2px 0 2px 12px}
  #rptBody .rpt-vide{margin-top:4px;font-size:12px}

  /* ⚠️ LA CROIX SE VOIT, ET C EST LE POINT DE LA CORRECTION.
     Elle etait un bouton gris parmi les autres, en bout de ligne : rien ne
     disait qu elle RETIRE. Au survol elle prend la couleur du danger. */
  #rptBody .rpt-x{color:var(--mut);font-weight:700;line-height:1}
  #rptBody .rpt-x:hover{background:#7f1d1d;border-color:#b91c1c;color:#fff}
  /* Le panneau de partage (P2) est un panneau DANS un panneau : sans ce
     retrait il se lit comme une section de plus du constructeur, alors qu il
     appartient a la ligne « My reports » juste au-dessus. */
  #rptBody .rpt-partage{border-left:2px solid var(--mut);padding-left:8px}
  #rptBody .rpt-partage select{max-width:16rem}
  /* ⚠️ LA CROIX TIENT AU NOM QU ELLE RETIRE. Une ligne pleine largeur mettait
     le nom a gauche et sa croix au bord oppose du panneau — le defaut meme
     signale sur les filtres. Une pastille les garde ensemble, et la taille est
     posee ICI : un texte nu n est ni un `select` ni un `input`, donc aucune
     regle de la vue compacte ne l atteignait, et un seul nom s affichait deux
     fois plus gros que tout le reste de l ecran. */
  #rptBody .rpt-part{display:inline-flex;align-items:center;gap:5px;font-size:12px;
    background:var(--chip);border:1px solid var(--line);border-radius:11px;padding:1px 3px 1px 9px}
  #rptBody .rpt-part .muted{font-size:12px}
  /* Placeholder des champs de recherche : lisible sans crier (le gris par defaut se perdait sur le fond sombre). */
  input[type=search]::placeholder,
  input[placeholder*="search" i]::placeholder, input[placeholder*="chercher" i]::placeholder,
  input[placeholder*="buscar" i]::placeholder, input[placeholder*="filt" i]::placeholder,
  input[placeholder*="find" i]::placeholder, input[placeholder^="🔍"]::placeholder{color:#93c5fd;opacity:1}

  /* Le groupe « Closed today » de la colonne Aujourd hui, et le simulateur de
     terrain (bandeau du tableau + fenetre `wom-simulateur`, locataire demo). */
  .closToday{margin-top:8px;border-top:1px dashed var(--line);padding-top:6px}
  .closTodayTete{font-size:11px;font-weight:700;color:var(--good);margin-bottom:4px}
  .woCard.clos{cursor:default;opacity:.55;padding-left:8px;font-size:12px;border-color:rgba(34,197,94,.35)}
  .woCard.clos:hover{border-color:rgba(34,197,94,.35)}
  .simMotif{background:rgba(239,68,68,.16);color:#fecaca}
  .nonRepare{margin-top:4px}
  .aujJour{margin-top:6px;font-size:11px;color:var(--mut)}.aujJour.trop{color:var(--danger,#ef4444)}
  .schedVue{display:inline-flex;gap:4px;align-items:center;margin-left:8px;font-weight:400}
  .histoJour{opacity:.92;border-style:dashed}
  .histoFait{background:rgba(34,197,94,.16)}.histoNonRepare{background:rgba(239,68,68,.16)}.histoOuvert{background:rgba(234,179,8,.16)}.histoAnnule{opacity:.7}
  .simBanniere{margin-top:8px;padding:6px 10px;border:1px solid var(--purple);border-radius:8px;background:rgba(167,139,250,.12);font-size:13px}
  body.wsim{overflow:auto;padding:14px}
  .wsimTete{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
  .wsimTete h2{margin:0;font-size:18px}
  .wsimAvis{margin:6px 0 10px;font-size:12px}
  .wsimCorps{display:grid;grid-template-columns:1fr 340px;gap:12px}
  .wsimEquipes{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px;align-content:start}
  .wsimEquipe{border:1px solid var(--line);background:var(--panel);border-radius:8px;padding:8px}
  .wsimEquipeTete{font-weight:700;margin-bottom:2px}
  .wsimArret{border:1px solid var(--line);background:var(--panel2);border-radius:6px;padding:4px 6px;margin-top:5px;font-size:12px}
  .wsimArret.courant{border-color:var(--warn);box-shadow:0 0 0 1px var(--warn)}
  .wsimArret.clos{opacity:.55}
  .wsimJournal{border:1px solid var(--line);background:var(--panel);border-radius:8px;padding:8px;font-size:12px;max-height:80vh;overflow:auto}
  .wsimJournal h3{margin:0 0 6px;font-size:14px}
  .wsimJournal > div{margin-bottom:4px}
