/* assets/ui.css — système de design « façon ELD Énergie Dash » (ge-278).
   Spec : docs/superpowers/specs/2026-10-13-ge-278-systeme-de-design-design.md. Chargé APRÈS le <style> d'index.html :
   à spécificité égale, ses règles gagnent. Pendant les lots 0–4 il SURCHARGE les règles existantes sous leurs noms actuels ;
   leur retrait d'index.html est le lot 5. Aucune couleur en dur hors :root (garde tests/ui_tokens_test.js). */

/* ── 1. jetons ── */
:root{
  --background:#fbfcfd;--foreground:#1a1f2e;   /* fond de page éclairci le 19/10 en deux temps (Valentin : #f4f6f9 « trop grisé et sombre », puis #f8fafc « encore plus ») ; les cartes blanches gardent leur bordure */
  --card:#fff;--card-foreground:#1a1f2e;
  --popover:#fff;--popover-foreground:#1a1f2e;
  --primary:#1e3a7b;--primary-foreground:#fff;
  --secondary:#f0f3f7;--secondary-foreground:#1a1f2e;
  --muted:#f0f3f7;--muted-foreground:#6b7280;
  --accent:#e6ebf5;--accent-foreground:#1e3a7b;
  --destructive:#c8281a;--destructive-foreground:#fff;
  --success:#1a7d4f;--success-foreground:#fff;
  --warning:#a55505;--warning-foreground:#fff;
  --info:#1e3a7b;--info-foreground:#fff;
  --input:#dde2ec;--ring:#1e3a7b;
  --sidebar:var(--sidebar-bg);--sidebar-foreground:rgba(255,255,255,.65);
  --sidebar-primary:#7fa3ff;--sidebar-primary-foreground:#fff;
  --sidebar-accent:rgba(255,255,255,.08);--sidebar-accent-foreground:#fff;
  --sidebar-border:rgba(255,255,255,.1);--sidebar-ring:#7fa3ff;
  --chart-1:#1e3a7b;--chart-2:#d4200a;--chart-3:#1a7d4f;--chart-4:#9aa5b8;--chart-5:#7c3aed;
  --or-externe:#be185d;--cat-mecanique:#2c53b0;--cat-manutention:#0e7490;--cat-pneu:#1e293b;--cat-autre:#4b5563; /* palette des catégories d'OR (ge-192) et du véhicule externe (ge-280), sortie du <style> d'index.html au lot 5 */
  --claude:#d97757; /* orange de la marque Claude : raccourci « Claude × ELD » du cockpit */
  --cyan:#0891b2;
  --marque-degrade:linear-gradient(135deg,#1e3a7b 0%,#163068 40%,#0e1f45 100%); /* fond des écrans hors session : accueil, connexion, mot de passe imposé */
  --visionneuse-fond:#1a1a1a; /* fond de la visionneuse PDF */
  --tf-offduty:#dcdfe4; /* frise tachy : « hors service », assez clair pour s'effacer derrière conduite et travail, assez dense pour la légende */ /* accent exploitation / GPS déjà en dur dans index.html (.avatar-exploitation, .status-attente-expl, .ctl-tab.on) */
  --radius:12px;--radius-sm:8px;--radius-md:10px;--radius-lg:12px;--radius-xl:16px;
  --shadow-xs:0 1px 2px 0 rgb(0 0 0 / .05);
  --shadow-sm:0 1px 3px 0 rgb(0 0 0 / .1),0 1px 2px -1px rgb(0 0 0 / .1);
  --shadow-md:0 4px 6px -1px rgb(0 0 0 / .1),0 2px 4px -2px rgb(0 0 0 / .1);
  --shadow-lg:0 10px 15px -3px rgb(0 0 0 / .1),0 4px 6px -4px rgb(0 0 0 / .1);
  --shadow-xl:0 20px 25px -5px rgb(0 0 0 / .1),0 8px 10px -6px rgb(0 0 0 / .1);
  --shadow:var(--shadow-sm);
  --dur:150ms;--ease:cubic-bezier(.4,0,.2,1);
  --focus-ring:0 0 0 3px color-mix(in oklab,var(--ring) 50%,transparent);
}

/* ── 2. base ── */
*,::before,::after{border-color:var(--border)}
::placeholder{color:color-mix(in oklab,currentColor 50%,transparent)}
.num,.tabular{font-variant-numeric:tabular-nums}
/* lot 5 : ce qui se clique montre la main, sans style en ligne (156 cursor:pointer en ligne le 17/10) */
:where([data-fn]:not(:disabled):not([aria-disabled="true"]),label:has(>input[type="checkbox"]),label:has(>input[type="radio"]),summary){cursor:pointer}

/* ── 3. enveloppe (lot 1) ── */
.sidebar-nav{padding:16px 8px 8px}
.sidebar-nav a.nav-item{text-decoration:none}
.sidebar-nav .nav-item{display:flex;align-items:center;gap:8px;height:32px;min-height:0;padding:8px;margin:0 0 4px;border:0;border-radius:var(--radius-md);color:var(--sidebar-foreground);font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;box-shadow:none;transition:background-color var(--dur) var(--ease),color var(--dur) var(--ease)}
.sidebar-nav .nav-item::before{content:none}
.sidebar-nav .nav-item svg{width:16px;height:16px;flex-shrink:0;opacity:1;transform:none}
.sidebar-nav .nav-item:hover{background:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}
.sidebar-nav .nav-item.active{background:color-mix(in oklab,var(--sidebar-primary) 15%,transparent);color:var(--sidebar-primary);font-weight:600;box-shadow:none}
.sidebar-nav .nav-item.active:hover{background:color-mix(in oklab,var(--sidebar-primary) 20%,transparent);color:var(--sidebar-primary)}
.sidebar-nav .nav-item.active svg{transform:none}
.sidebar-nav .nav-group-h{height:32px;padding:0 8px;margin:12px 0 4px;border-radius:var(--radius-md);font-size:12px;line-height:16px;font-weight:500;letter-spacing:0;text-transform:none;color:rgba(255,255,255,.5)}
.sidebar-nav .nav-group-h::after{content:none}
.sidebar-nav .nav-group-h .nav-chev svg{width:16px;height:16px}
.sidebar-nav .nav-divider{height:1px;margin:8px;background:var(--sidebar-border)}
.nav-item:focus-visible,.nav-group-h:focus-visible,.nav-user:focus-visible{outline:none;box-shadow:0 0 0 2px var(--sidebar-ring)}

.sidebar-user{position:relative;padding:8px;border-top:0}
.nav-user{display:flex;align-items:center;gap:8px;width:100%;height:48px;padding:8px;border:0;border-radius:var(--radius-md);background:transparent;color:var(--sidebar-foreground);font:inherit;text-align:left;cursor:pointer;transition:background-color var(--dur) var(--ease)}
.nav-user:hover,.nav-user[aria-expanded="true"]{background:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}
.nav-user-txt{display:grid;flex:1;min-width:0;line-height:1.25}
.nav-user-name{font-size:14px;font-weight:500;color:var(--sidebar-primary-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nav-user-role{font-size:12px;color:var(--sidebar-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nav-user-chev{width:16px;height:16px;flex-shrink:0;opacity:.7}
/* .menu.menu-* : la section 5 (.menu) est plus bas dans ce fichier — à une seule classe, elle gagnerait (min-width, padding, rayon). */
.menu.menu-user{left:calc(100% + 4px);bottom:8px;min-width:224px;border-radius:var(--radius-lg)}
.menu-user .nav-user-name{color:var(--popover-foreground)}
.menu-user .nav-user-role{color:var(--muted-foreground)}
.nav-user-head{display:flex;align-items:center;gap:8px;padding:6px 8px}
@media (max-width:1280px){.menu.menu-user{left:8px;right:8px;bottom:calc(100% - 4px);min-width:0}}
.avatar{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:32px;height:32px;border-radius:var(--radius-lg);background:var(--primary);color:var(--primary-foreground);font-size:12px;font-weight:700;overflow:hidden}
/* fonds par rôle conservés (palette) ; le chef d'atelier prend le bleu : son ancien blanc à 25 % serait invisible dans le menu */
.avatar.avatar-admin{background:var(--eld-red)}.avatar.avatar-approbateur{background:var(--chart-5)}.avatar.avatar-mecanicien{background:var(--success)}.avatar.avatar-exploitation{background:var(--cyan)}.avatar.avatar-chef_atelier{background:var(--primary)}

.top-bar{position:relative;top:auto;height:48px;min-height:48px;padding:0 16px;gap:8px;background:var(--background);backdrop-filter:none;-webkit-backdrop-filter:none;border-bottom:1px solid var(--border);box-shadow:none}
@media (min-width:1024px){.top-bar{padding:0 24px}}
/* Logo ELD bleu dans la barre du haut quand la barre latérale (et son logo blanc) n'est pas à l'écran : sous 1 280 px, repliée, ou
   appli installée (polish du 18/10, capture iPhone de Valentin). En ligne après le bouton du menu, comme le portail atelier ; le mode
   exploitation seule garde son logo centré (index.html). */
@media (max-width:1280px){#app:not(.expl-solo) .top-bar .topbar-logo{display:block;position:static;transform:none;height:24px;width:auto}}
#app.sidebar-repliee:not(.expl-solo) .top-bar .topbar-logo,body.is-standalone #app:not(.expl-solo) .top-bar .topbar-logo{display:block;position:static;transform:none;height:24px;width:auto}
.menu.menu-notif{right:0;left:auto;top:calc(100% + 4px);width:360px;max-width:calc(100vw - 32px);max-height:420px;max-height:min(560px,calc(100dvh - 72px));padding:0;overflow:hidden}
.menu-notif-liste{max-height:360px;max-height:min(520px,calc(100dvh - 112px));overflow-y:auto}
.notif-cloche{position:relative}
.notif-cloche .badge-count{position:absolute;top:2px;right:2px}
.notif-row{position:relative;border-bottom:1px solid var(--border)}
.notif-item{position:relative;display:flex;align-items:flex-start;gap:10px;width:100%;min-height:0;height:auto;padding:10px 40px 10px 16px;border:0;border-radius:0;background:transparent;color:var(--foreground);font:inherit;text-align:left;cursor:pointer}
.notif-row.non-lue .notif-item{background:var(--accent)}
.notif-item:hover,.notif-item:focus-visible{outline:none;background:var(--muted)}
/* Polish du 18/10 : point des non-lues dans la marge (les icônes restent alignées), icône dessinée teintée par ton-*, titre et heure
   sur la première ligne, de quoi il s'agit sur la seconde. */
.notif-point{position:absolute;left:5px;top:17px;width:6px;height:6px;border-radius:9999px;background:var(--primary)}
.notif-ico{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-md);background:color-mix(in oklab,var(--tone) 12%,transparent);color:var(--tone)}
.notif-ico svg{width:16px;height:16px}
.notif-txt{flex:1;min-width:0}
.notif-ligne{display:flex;align-items:baseline;gap:8px}
.notif-titre,.notif-msg{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.notif-titre{flex:1;min-width:0;font-size:14px;line-height:20px;font-weight:500}
.notif-row.non-lue .notif-titre{font-weight:700}
.notif-msg{margin-top:2px;font-size:12px;line-height:16px;color:var(--muted-foreground)}
.notif-date{flex-shrink:0;font-size:12px;color:var(--muted-foreground);font-variant-numeric:tabular-nums}
.notif-del{position:absolute;top:8px;right:8px;display:none;align-items:center;justify-content:center;width:22px;height:22px;min-height:0;padding:0;border:0;border-radius:var(--radius-sm);background:color-mix(in oklab,var(--destructive) 12%,transparent);color:var(--destructive);font-size:12px;font-weight:700;cursor:pointer}
.notif-row:hover .notif-del,.notif-del:focus-visible{display:flex}
.notif-del:hover{background:var(--destructive);color:var(--destructive-foreground)}
@media (max-width:768px){.notif-del{display:flex}}
.menu-notif-h{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid var(--border);font-size:14px;font-weight:500}

.content{max-width:none;padding:16px}
@media (min-width:1024px){.content{padding:24px}}
.section-header{display:flex;align-items:flex-start;justify-content:space-between;flex-wrap:wrap;gap:16px;margin-bottom:24px}
.section-title{font-size:30px;line-height:36px;font-weight:700;letter-spacing:-.025em;color:var(--foreground)}
.section-header>div:last-child:not(.section-title){display:flex;align-items:center;gap:8px;flex-shrink:0}
.page-sub{margin:0;font-size:16px;line-height:24px;color:var(--muted-foreground)}
.tdb-hello{margin-bottom:24px}
.tdb-hello h2{font-size:36px;line-height:40px;font-weight:700;letter-spacing:-.025em;color:var(--foreground)}
.tdb-hello p{margin:0;font-size:16px;line-height:24px;color:var(--muted-foreground)}
/* « Bonjour X, » plus imposant (Valentin, 18/10) : 36 px sur ordinateur, 26 px au téléphone — il ne suit plus les titres de section. */
@media (max-width:768px){.section-title{font-size:18px;line-height:28px}.tdb-hello h2{font-size:26px;line-height:32px}.page-sub,.tdb-hello p{font-size:12px;line-height:16px}}

.login-card{width:384px;max-width:calc(100vw - 32px);padding:24px;border:1px solid var(--border);border-radius:var(--radius-xl);background:var(--card);box-shadow:var(--shadow-sm)}
.login-logo{margin-bottom:16px;text-align:left}
.login-logo img{height:50px}
.login-divider{display:none}
.login-title{margin:0 0 6px;font-size:16px;line-height:1.2;font-weight:600;color:var(--foreground);text-align:left}
.login-sub{margin:0 0 24px;font-size:14px;line-height:20px;color:var(--muted-foreground);text-align:left}
.login-card .form-group{display:grid;gap:8px;margin-bottom:16px}
.login-remember{display:flex;align-items:center;gap:8px;margin-bottom:16px;font-size:14px}

@media (max-width:1280px){
  .sidebar{width:288px;transition:transform 300ms var(--ease)}
  .sidebar.open{transition-duration:500ms}
  .sidebar-overlay{background:rgb(0 0 0 / .5)}
}

/* ── 4. composants de base (lot 2) ── */
:is(.btn-primary,.btn-secondary,.btn-danger,.btn-success,.btn-soft-success,.btn-soft-danger,.btn-soft-primary,.btn-ghost,.btn-link,.btn-login){display:inline-flex;align-items:center;justify-content:center;gap:8px;height:36px;min-height:0;padding:0 16px;border:1px solid transparent;border-radius:var(--radius-md);font-family:inherit;font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;text-decoration:none;cursor:pointer;box-shadow:none;transform:none;transition:background-color var(--dur) var(--ease),color var(--dur) var(--ease),border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),opacity var(--dur) var(--ease)}
:is(.btn-primary,.btn-secondary,.btn-danger,.btn-success,.btn-soft-success,.btn-soft-danger,.btn-soft-primary,.btn-ghost,.btn-link,.btn-login) svg{width:16px;height:16px;flex-shrink:0;pointer-events:none}
:is(.btn-primary,.btn-secondary,.btn-danger,.btn-success,.btn-soft-success,.btn-soft-danger,.btn-soft-primary,.btn-ghost,.btn-login):is(:hover,:active):not(:disabled){transform:none}
.btn-primary,.btn-login{background:var(--primary);color:var(--primary-foreground)}
.btn-primary:hover:not(:disabled),.btn-primary:active:not(:disabled),.btn-login:hover:not(:disabled){background:color-mix(in oklab,var(--primary) 90%,transparent);color:var(--primary-foreground);box-shadow:none}
.btn-secondary{background:var(--background);color:var(--foreground);border-color:var(--border);box-shadow:var(--shadow-xs)}
.btn-secondary:hover:not(:disabled),.btn-secondary:active:not(:disabled){background:var(--accent);color:var(--accent-foreground);border-color:var(--border)}
.btn-danger{background:var(--destructive);color:var(--destructive-foreground)}
.btn-danger:hover:not(:disabled),.btn-danger:active:not(:disabled){background:color-mix(in oklab,var(--destructive) 90%,transparent);color:var(--destructive-foreground);box-shadow:none}
.btn-success{background:var(--success);color:var(--success-foreground)}
.btn-success:hover:not(:disabled),.btn-success:active:not(:disabled){background:color-mix(in oklab,var(--success) 90%,transparent);color:var(--success-foreground)}
.btn-ghost{background:transparent;color:var(--foreground)}
.btn-ghost:hover:not(:disabled),.btn-ghost:active:not(:disabled){background:var(--accent);color:var(--accent-foreground)}
.btn-link{height:auto;padding:0;background:none;color:var(--primary)}
.btn-link:hover{text-decoration:underline;text-underline-offset:4px}
:is(.btn-primary,.btn-secondary,.btn-success,.btn-soft-success,.btn-soft-danger,.btn-soft-primary,.btn-ghost,.btn-link,.btn-login):focus-visible{outline:none;border-color:var(--ring);box-shadow:var(--focus-ring)}
.btn-danger:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in oklab,var(--destructive) 20%,transparent)}
:is(.btn-primary,.btn-secondary,.btn-danger,.btn-success,.btn-soft-success,.btn-soft-danger,.btn-soft-primary,.btn-ghost,.btn-link,.btn-login):is(:disabled,[aria-disabled="true"]){opacity:.5;pointer-events:none}
.btn-sm{height:32px;min-height:0;padding:0 12px;gap:6px;font-size:14px;border-radius:var(--radius-md)}
.btn-lg,.btn-login{height:40px;padding:0 24px}
.btn-login{width:100%}
.btn-icon{width:36px;padding:0}
.btn-block{width:100%}
.btn-icon.btn-sm{width:32px}
@media (pointer:coarse){.btn-sm{min-height:40px}}
/* Boutons de ligne (polish du 18/10, Valentin : « trop gros face aux étiquettes ») : 28 px et 12 px, à l'échelle des étiquettes
   de statut (24 px, 12 px) ; coins de 8 px et non une pilule — ce qui se clique ne ressemble pas à ce qui se lit. Icône seule
   (act-icone) et corbeille : carrés de 28 px. La croix des lignes de formulaire (.btn-rm) garde 32 px, à côté des champs.
   Au doigt : 40 px au moins (plus bas, et sous 768 px). */
.act{height:28px;min-height:0;padding:0 10px;gap:4px;font-size:12px;line-height:16px;border-radius:var(--radius-sm)}
.act svg{width:14px;height:14px}
.act.act-icone{width:28px;padding:0;font-size:14px}   /* un signe seul (Stock : + / −) se lit à 14 px */
.act-del,.btn-rm{display:inline-flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:var(--radius-md);background:transparent;color:var(--destructive);opacity:1;cursor:pointer;transition:background-color var(--dur) var(--ease)}
.act-del{width:28px;height:28px;border-radius:var(--radius-sm)}
.act-del svg{width:14px;height:14px}
.btn-rm{width:32px;height:32px}
.act,.act-del{vertical-align:middle}   /* en ligne dans une cellule : un bouton texte et une icône seule à la même hauteur (Stock, DDV — 3 px d'écart vus le 18/10) */
@media (pointer:coarse){.act,.act-del{min-height:40px}.act.act-icone,.act-del{min-width:40px}}
.act-del:hover,.btn-rm:hover{background:color-mix(in oklab,var(--destructive) 10%,transparent);color:var(--destructive);transform:none}
.tdb-gh{height:36px;min-height:0;padding:0 12px;border-radius:var(--radius-md);color:var(--foreground);font-size:14px;font-weight:500}
.tdb-gh:hover,.tdb-gh[aria-expanded="true"]{background:var(--accent);color:var(--accent-foreground)}
.btn-spin{width:16px;height:16px;border-width:2px}
.txt-destructive,.txt-destructive:hover:not(:disabled){color:var(--destructive)}
.txt-warning,.txt-warning:hover:not(:disabled){color:var(--warning)}
.txt-success,.txt-success:hover:not(:disabled){color:var(--success)}
.txt-primary,.txt-primary:hover:not(:disabled){color:var(--primary)}
.txt-cyan{color:var(--cyan)}     /* accent des prises de service (Suivi GPS) */
.txt-purple{color:var(--purple)}   /* teinte de palette des statuts « facturé » / « à valider » (pastilles du module BC) */
/* lot 5 (décision du 17/10) : action de ligne en variante légère — fond teinté pâle, texte de la teinte (BC « Facture », Stock « + / − ») */
/* Teinte de sens d'un bloc de page : pose --tone, que la classe de page lit (fond pâle, bordure, texte) */
.ton-success{--tone:var(--success)}.ton-warning{--tone:var(--warning)}.ton-destructive{--tone:var(--destructive)}.ton-primary{--tone:var(--primary)}.ton-muted{--tone:var(--muted-foreground)}
.btn-soft-success{--tone:var(--success)}
.btn-soft-danger{--tone:var(--destructive)}
.btn-soft-primary{--tone:var(--primary)}
.btn-soft-success,.btn-soft-danger,.btn-soft-primary{background:color-mix(in oklab,var(--tone) 12%,transparent);color:var(--tone)}
:is(.btn-soft-success,.btn-soft-danger,.btn-soft-primary):is(:hover,:active):not(:disabled){background:color-mix(in oklab,var(--tone) 20%,transparent);color:var(--tone)}
.nav-back{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border:0;border-radius:var(--radius-md);background:transparent;color:var(--foreground);cursor:pointer}
.nav-back:hover{background:var(--accent);color:var(--accent-foreground)}
.nav-back svg{width:16px;height:16px}
/* Cibles tactiles : index.html (l. ~1223-1227, sans !important) portait les boutons à 44 px et .btn-sm/.act à 40 px sous 768 px ;
   les hauteurs fixes ci-dessus l'écraseraient (relecture du 13/10). */
@media (max-width:768px){
:is(.btn-primary,.btn-secondary,.btn-danger,.btn-success,.btn-soft-success,.btn-soft-danger,.btn-soft-primary,.btn-ghost,.btn-login){height:auto;min-height:44px;padding-top:10px;padding-bottom:10px}
.btn-sm,.act,.act-del,.btn-rm,.btn-icon,.nav-back{height:auto;min-height:40px}
.btn-icon,.act-del,.act.act-icone,.btn-rm,.nav-back{min-width:40px}
/* Dans une cellule, l'ancienne règle mobile d'index.html (td .btn-danger, td .btn-secondary… : 30 px, texte de 11 px) est plus
   précise que .act : même précision ici, chargée après — 40 px au doigt, 12 px comme les étiquettes (polish du 18/10). */
td .act,td .act-del{min-height:40px;font-size:12px;border-radius:var(--radius-sm)}
td .act{padding:0 10px}
td .act.act-icone,td .act-del{padding:0}
}

/* champs (spec §5.2) — %236b7280 dans les URL de données = couleur des chevrons et de la loupe (# encodé), seule exception à la garde des couleurs */
.field{display:grid;gap:8px}
.field label,.form-group label{display:flex;align-items:center;gap:8px;margin:0;font-size:14px;line-height:1;font-weight:500;text-transform:none;letter-spacing:0;color:var(--foreground)}
/* :where() sur la chaîne de :not — sans lui, :is() prend la spécificité de son argument le plus fort (0,5,1) et écrase les
   règles select (chevron, padding-right) et textarea (hauteur) ci-dessous ; à (0,1,1) elle bat encore .field input d'index.html (chargé avant). */
:is(.field,.form-group) :is(input:where(:not([type=checkbox],[type=radio],[type=file],[type=range])),select,textarea),.search-input,.filter-select,.bc-ligne input,.input,#page-tarif :is(input:where(:not([type=checkbox],[type=radio],[type=file],[type=range])),select){width:100%;height:36px;min-height:0;padding:4px 12px;border:1px solid var(--input);border-radius:var(--radius-md);background:transparent;color:var(--foreground);font-family:inherit;font-size:14px;line-height:20px;box-shadow:var(--shadow-xs);outline:none;transition:color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease)}
:is(.field,.form-group) textarea{height:auto;min-height:64px;padding:8px 12px;field-sizing:content}
:is(.field,.form-group) select,.filter-select,#page-tarif select{appearance:none;-webkit-appearance:none;padding-right:36px;background:transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center/16px;cursor:pointer}
:is(.field,.form-group) :is(input,select,textarea):focus,.search-input:focus,.filter-select:focus,.bc-ligne input:focus,.input:focus,#page-tarif :is(input,select):focus{border-color:var(--ring);box-shadow:var(--focus-ring);background-color:transparent}
:is(.field,.form-group) :is(input,select,textarea)[aria-invalid="true"],.login-input-error{border-color:var(--destructive);box-shadow:0 0 0 3px color-mix(in oklab,var(--destructive) 20%,transparent);animation:none}
:is(.field,.form-group) :is(input,select,textarea):disabled{cursor:not-allowed;opacity:.5}
.field-error{margin:0;font-size:14px;line-height:20px;color:var(--destructive)}
.field>.btn-link{justify-self:start}
/* lot 5 : une rangée de champs qui se partagent la largeur et passent à la ligne (formulaires de l'OR, de la DDV…) */
.champs-ligne{display:flex;flex-wrap:wrap;gap:12px}
.champs-ligne>:is(.field,input,select){flex:1;min-width:140px}     /* lot 5 : un lien-bouton sous un champ garde sa largeur (la grille l'étirerait) */
/* Connexion (spec §4.6 : champs §5.2) : #login-screen .form-group input (index.html, l. ~287, spécificité d'id) garde sinon 13 × 16 px de marge et 1,5 px de bordure */
/* Écran d'accueil (avant la session) et changement de mot de passe imposé : même fond que la connexion (lot 5, ex-styles en ligne) */
#splash-screen{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:var(--marque-degrade);transition:opacity .3s,visibility .3s}
#splash-screen img{height:48px;animation:splashLogo .8s cubic-bezier(.34,1.56,.64,1) both}
@keyframes splashLogo{from{opacity:0;transform:scale(.8) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}
#change-pass-screen{position:fixed;inset:0;z-index:999;display:none;align-items:center;justify-content:center;background:var(--marque-degrade)}
#l-error a{text-decoration:underline}
.topbar-recherche{position:relative;margin-left:auto;flex:0 1 320px;min-width:0}   /* ge-290 : la barre de recherche pousse à droite, la cloche la suit */
/* Polish du 19/10 : au repos, un champ plein sans bordure (il se distingue des filtres de page, bordés) ; au focus, la carte et l'anneau
   habituels. La touche du raccourci vit dans le champ et s'efface dès qu'on tape. */
.topbar-recherche .search-input{width:100%;height:36px;padding-right:10px;border-color:transparent;background-color:var(--muted);transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.topbar-recherche .search-input:placeholder-shown{padding-right:60px}   /* la place de la touche, seulement tant qu'elle est là */
/* La croix d'effacement du navigateur devient l'icône « x » de lucide, à la couleur des textes secondaires (masque : la couleur vient
   d'un jeton, pas du dessin). Un clic vide le champ et l'événement input ferme la liste. */
.topbar-recherche .search-input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;width:16px;height:16px;margin:0 0 0 6px;background-color:var(--muted-foreground);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E") center/16px 16px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E") center/16px 16px no-repeat;cursor:pointer}
.topbar-recherche .search-input::-webkit-search-cancel-button:hover{background-color:var(--foreground)}
.topbar-recherche .search-input:hover{border-color:var(--border)}
.topbar-recherche .search-input:focus{background-color:var(--card)}
.rech-kbd{position:absolute;top:8px;right:12px;height:20px;padding:0;border:0;background:none;color:var(--muted-foreground);font:inherit;font-size:12px;line-height:20px;font-weight:500;pointer-events:none}   /* le raccourci écrit, sans forme de touche (Valentin, 19/10) */
.search-input:not(:placeholder-shown)~.rech-kbd{display:none}
.topbar-notif{position:relative}
#login-screen .form-group input{height:36px;padding:4px 12px;border-width:1px;font-size:14px;background:transparent}
#login-screen .form-group input:focus{border-color:var(--ring);box-shadow:var(--focus-ring);background:transparent}
.search-input{padding-left:36px;background:transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E") no-repeat 12px center/16px}
/* lot 5 (décision du 17/10) : largeur de l'option la plus longue — la barre ne bouge pas quand on change de filtre —, bornée. 240 px :
   au-dessus du plus long libellé fixe des barres, mesuré à 189 px le 17/10 ; un nom de fournisseur plus long se coupe (la borne l'emporte). */
.filter-select{width:auto;min-width:120px;max-width:240px;flex:none}
@media (max-width:768px){.filter-select{max-width:none}} /* sous 768 px, les barres d'index.html étirent les selects (flex:1) */
/* bouton qui imite un select (#veh-type-dropdown-btn, Parc) : il porte son propre chevron SVG — pas de second chevron en fond (revue ge-278).
   Sans options, il n'a pas de « plus longue » : largeur fixe dans les mêmes bornes. */
button.filter-select{display:inline-flex;align-items:center;gap:8px;width:192px;background-image:none;padding-right:12px;justify-content:space-between;text-align:left}
button.filter-select>svg{flex:none;color:var(--muted-foreground)}
/* filtre en cours (bouton d'un menu de cases, Parc) : il se voit sans ouvrir le menu */
.filter-select.filtre-actif{border-color:var(--primary);background-color:var(--accent);color:var(--accent-foreground)}
/* carte de choix : un radio (ou une case) et son libellé dans un cadre ; le choix fait se voit au cadre, sans script (lot 5) */
.choix{display:flex;align-items:center;gap:12px;padding:12px;border:1px solid var(--border);border-radius:var(--radius-md);cursor:pointer;transition:border-color .15s,background-color .15s}
.choix:hover{border-color:var(--primary)}
.choix:has(input:checked){border-color:var(--primary);background:var(--accent)}
.form-row{gap:16px;margin-bottom:16px}
@media (max-width:768px){.form-row{grid-template-columns:1fr}}
@media (max-width:767px){:is(.field,.form-group) :is(input,select,textarea),.search-input,.filter-select{font-size:16px}}

/* !important sur border : index.html l. ~183 pose `border:none !important` sur les cases (relecture du 13/10) */
input[type="checkbox"],input[type="radio"]{-webkit-appearance:none!important;appearance:none!important;width:16px!important;height:16px!important;min-width:16px!important;min-height:16px!important;margin:0;padding:0!important;flex-shrink:0;border:1px solid var(--input)!important;border-radius:4px;background:var(--background) no-repeat center/14px;box-shadow:var(--shadow-xs);vertical-align:middle;cursor:pointer;transition:box-shadow var(--dur) var(--ease)}
input[type="radio"]{border-radius:9999px}
input[type="checkbox"]:checked{border-color:var(--primary)!important;background-color:var(--primary);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")}
input[type="checkbox"]:indeterminate{border-color:var(--primary);background-color:var(--primary);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E")}
input[type="radio"]:checked{border-color:var(--primary)!important;background-image:radial-gradient(circle,var(--primary) 0 4px,transparent 4.5px);background-size:auto}
input[type="checkbox"]:focus-visible,input[type="radio"]:focus-visible{outline:none;border-color:var(--ring)!important;box-shadow:var(--focus-ring)}
input[type="checkbox"]:disabled,input[type="radio"]:disabled{cursor:not-allowed;opacity:.5}
label:has(>input[type="checkbox"]),label:has(>input[type="radio"]){min-height:36px;display:inline-flex;align-items:center;gap:8px}

.dz,.devis-slot{border:1px dashed var(--border);border-radius:var(--radius-lg);background:color-mix(in oklab,var(--muted) 30%,transparent);color:var(--muted-foreground)}
.dz:hover,.devis-slot:hover,.devis-slot.over,.drop-hover{border-color:var(--primary);background:var(--accent)}
.devis-slot.filled{border-style:solid;background:var(--card)}
.devis-slot.retenu{border-width:2px;border-color:var(--success);background:color-mix(in oklab,var(--success) 12%,transparent)}

/* pastilles : une recette, la teinte vient de la color du modificateur existant (currentColor) */
/* .or-age retiré : c'est une cellule de tableau (td) — la recette « pastille » la passait en inline-flex et la rendait énorme et désalignée (retour du 14/10) */
:is(.status,.prio,.type-badge,.role-badge,.cat-badge,.urg-badge,.tdb-st,.inactive-tag,.chimp-pill,.file-badge){display:inline-flex;align-items:center;justify-content:center;gap:4px;min-width:0;min-height:0;height:auto;padding:4px 8px;border:0;border-radius:9999px;font-size:12px;line-height:16px;font-weight:500;letter-spacing:0;text-transform:none;white-space:nowrap;background:color-mix(in oklab,currentColor 15%,transparent);box-shadow:inset 0 0 0 1px color-mix(in oklab,currentColor 30%,transparent);animation:none}
.status-en_cours::after{content:none}
.status svg.status-icon{width:12px;height:12px}
.status-xs{padding:0 6px;font-size:10px}
/* .badge sans bordure (relecture du 13/10) ; le Tarif n'emploie plus .badge (lot 5 : .status et .alert) */
.badge{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border:0;border-radius:var(--radius-md);font-size:12px;line-height:16px;font-weight:500;white-space:nowrap;background:var(--primary);color:var(--primary-foreground)}
.badge-secondary{background:var(--secondary);color:var(--secondary-foreground)}
.badge-outline{background:transparent;color:var(--foreground);border:1px solid var(--border)}
.badge-destructive{background:var(--destructive);color:var(--destructive-foreground)}
.badge-count{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;padding:0 4px;border-radius:9999px;background:var(--eld-red);color:var(--primary-foreground);font-size:10px;font-weight:700;line-height:16px}

.alert{display:grid;grid-template-columns:16px 1fr;column-gap:12px;row-gap:2px;align-items:start;padding:12px 16px;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--card);color:var(--card-foreground);font-size:14px;line-height:20px}
.alert>svg{width:16px;height:16px;transform:translateY(2px)}
.alert-title{grid-column:2;font-weight:500;letter-spacing:-.025em}
.alert-desc{grid-column:2;color:var(--muted-foreground)}
.alert-desc p{line-height:1.625}
.alert-info{--tone:var(--info)}.alert-warning{--tone:var(--warning)}.alert-destructive{--tone:var(--destructive)}.alert-success{--tone:var(--success)}
:is(.alert-info,.alert-warning,.alert-destructive,.alert-success){border-color:color-mix(in oklab,var(--tone) 30%,transparent);background:color-mix(in oklab,var(--tone) 10%,transparent)}
:is(.alert-info,.alert-warning,.alert-destructive,.alert-success) :is(.alert-title,svg){color:var(--tone)}
/* lot 5 : encart neutre (panneaux gris d'avant), et encart sans icône — une seule colonne, sinon le texte tiendrait dans 16 px */
.alert-muted{border-color:transparent;background:var(--muted)}
.alert:not(:has(>svg)){grid-template-columns:minmax(0,1fr)}
.alert:not(:has(>svg)) :is(.alert-title,.alert-desc){grid-column:1}
.tdb-menu-note,.chimp-warn{border:1px solid color-mix(in oklab,var(--warning) 30%,transparent);border-radius:var(--radius-lg);background:color-mix(in oklab,var(--warning) 10%,transparent);color:var(--foreground)}

.empty-state{padding:48px 32px;text-align:center}
.empty-state .esi{width:48px;height:48px;margin:0 auto 16px;border-radius:0;background:none;opacity:.5;display:flex;align-items:center;justify-content:center;font-size:40px}
.empty-state .esi svg{width:48px;height:48px;opacity:1}
.empty-state .est{font-size:16px;line-height:24px;font-weight:600;color:var(--foreground)}
.empty-state .ess{max-width:340px;margin:4px auto 0;font-size:14px;line-height:20px;color:var(--muted-foreground)}
.empty-state .esa{margin-top:16px}
/* .esa n'a pas de classe de bouton dans son balisage (3 usages) : rendu d'un .btn-secondary.btn-sm */
.empty-state .esa{display:inline-flex;align-items:center;height:32px;padding:0 12px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--background);color:var(--foreground);font-size:14px;font-weight:500;box-shadow:var(--shadow-xs)}

.skeleton,.skeleton-row{background:var(--accent);background-image:none;border-radius:var(--radius-md);animation:ui-pulse 2s cubic-bezier(.4,0,.6,1) infinite}
.skeleton-row{height:48px}
@keyframes ui-pulse{50%{opacity:.5}}
.spinner{display:inline-block;width:24px;height:24px;border:2px solid currentColor;border-right-color:transparent;border-radius:9999px;animation:spin 1s linear infinite;vertical-align:middle}
.spinner-sm{width:16px;height:16px}.spinner-lg{width:32px;height:32px}
.separator{flex-shrink:0;width:100%;height:1px;background:var(--border)}
.separator.vertical{width:1px;height:16px}
.topbar-sep{background:var(--border)}

/* ── 5. surfaces flottantes (lot 3) — menus et onglets ── */
.menu{position:absolute;z-index:60;min-width:128px;padding:4px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--popover);color:var(--popover-foreground);box-shadow:var(--shadow-md);transform-origin:top;animation:ui-menu-in var(--dur) ease}
.menu[hidden]{display:none}
.menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 8px;border:0;border-radius:var(--radius-sm);background:transparent;color:inherit;font:inherit;font-size:14px;line-height:20px;text-align:left;cursor:pointer;outline:none}
.menu-item svg{width:16px;height:16px;flex-shrink:0;color:var(--muted-foreground)}
.menu-item:hover,.menu-item:focus-visible{background:var(--accent);color:var(--accent-foreground)}
.menu-item-destructive,.menu-item-destructive svg{color:var(--destructive)}
.menu-item-destructive:hover,.menu-item-destructive:focus-visible{background:color-mix(in oklab,var(--destructive) 10%,transparent);color:var(--destructive)}
.menu-item[aria-disabled="true"]{opacity:.5;pointer-events:none}
.menu-sep{height:1px;margin:4px -4px;background:var(--border)}
.menu-label{padding:6px 8px;font-size:14px;font-weight:500}
@keyframes ui-menu-in{from{opacity:0;transform:scale(.95) translateY(-8px)}to{opacity:1;transform:none}}

.tabs{display:inline-flex;align-items:center;gap:0;padding:3px;margin:0 0 16px;border:0;border-radius:var(--radius-lg);background:var(--muted);color:var(--muted-foreground)}
.tabs-full{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;width:100%}
.tabs-scroll{display:flex;width:100%;overflow-x:auto;scrollbar-width:none}
.tabs-scroll::-webkit-scrollbar{display:none}
.tabs-scroll .tab{flex:1 0 auto}
.tab{display:inline-flex;flex:1;align-items:center;justify-content:center;gap:6px;min-height:0;height:auto;margin:0;padding:4px 8px;border:1px solid transparent;border-radius:var(--radius-md);background:transparent;color:var(--foreground);font:inherit;font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;cursor:pointer;box-shadow:none;transition:color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),background-color var(--dur) var(--ease)}
.tab svg{width:16px;height:16px}
.tab.active,.tab[aria-selected="true"]{background:var(--background);color:var(--foreground);border-color:transparent;box-shadow:var(--shadow-sm)}
/* lot 5 : contrôle segmenté (spec lot 5 §6.2) — recette des onglets pour une bascule de VUE ; état en aria-checked (uiSegmentSelect) */
.segmented{display:inline-flex;align-items:center;gap:0;padding:3px;border-radius:var(--radius-lg);background:var(--muted);color:var(--muted-foreground)}
.segmented>[role="radio"]{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:auto;min-height:0;margin:0;padding:4px 12px;border:1px solid transparent;border-radius:var(--radius-md);background:transparent;color:var(--foreground);font:inherit;font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;cursor:pointer;box-shadow:none;transition:color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),background-color var(--dur) var(--ease)}
.segmented>[role="radio"] svg{width:16px;height:16px}
.segmented>[role="radio"][aria-checked="true"]{background:var(--background);color:var(--foreground);box-shadow:var(--shadow-sm)}
.segmented>[role="radio"]:focus-visible{outline:none;border-color:var(--ring);box-shadow:var(--focus-ring)}
@media (pointer:coarse){.segmented>[role="radio"]{min-height:36px}}
.menu-check{width:16px;height:16px;margin-left:auto;flex-shrink:0}
[aria-checked="false"] .menu-check{visibility:hidden}
.tab:focus-visible{outline:1px solid var(--ring);box-shadow:var(--focus-ring)}
.tab:disabled{opacity:.5;pointer-events:none}
.tabs-sm .tab{padding:2px 6px;font-size:12px;line-height:16px}
/* Sous 640 px, une barre pleine largeur défile (comme .tabs-scroll) : en grille 1fr avec des libellés insécables, ses derniers
   onglets (« Pneumatiques », « Intégrations », « Tous (n) ») passaient sous .content{overflow-x:clip} (revue finale du 13/10). */
@media (max-width:640px){.tabs-full{display:flex;overflow-x:auto;scrollbar-width:none}.tabs-full::-webkit-scrollbar{display:none}.tabs-full .tab{flex:1 0 auto}}
.tabs-collante{position:sticky;top:0;z-index:10}
.tdb-tabsrow{border-bottom:0} /* le trait sous la barre du tableau de bord (l. ~1419) doublerait celui de la pilule */
/* ge-287 (polish du 19/10) : sur le fond de page (--background), la piste --muted et l'onglet actif --background se confondaient ;
   la barre du tableau de bord prend un onglet actif blanc. Sa piste, passée au gris bordure par ge-287, revient au gris clair --muted
   le même jour (ge-290, Valentin : « moins gris ») : le fond de page, éclairci le même jour (--background), la détache désormais. */
.tdb-tabs.tabs{background:var(--muted)}
.tdb-tabs .tab.active,.tdb-tabs .tab[aria-selected="true"]{background:var(--card)}

/* dialogues (spec §6.1) */
.modal-overlay{background:rgb(0 0 0 / .5);backdrop-filter:none;-webkit-backdrop-filter:none}
.modal-overlay.open{animation:ui-fade-in var(--dur) ease}
.modal-overlay[data-state="closed"]{animation:ui-fade-out var(--dur) ease forwards;pointer-events:none}  /* en sortie : plus aucun clic capté (revue du 13/10) */
.modal{animation:ui-dialog-in 200ms ease}
.modal-overlay[data-state="closed"] .modal{animation:ui-dialog-out 200ms ease forwards}
.modal-title{font-size:18px;line-height:1.2;font-weight:600;color:var(--foreground)}
.modal-desc{font-size:14px;line-height:20px;color:var(--muted-foreground);margin:0}
/* Boîte, en-tête, corps, pied : ordinateur et tablette seulement. Sous 768 px, index.html (l. ~1276-1283, sans !important) fait de la
   modale une feuille basse à en-tête collant ; ces règles, de même spécificité et chargées après, l'écraseraient (relecture du 13/10). */
@media (min-width:769px){
.modal-overlay{padding:16px} /* sous 768 px, la feuille basse d'index.html (padding:0) colle la modale aux bords */
.modal{position:relative;width:100%;max-width:576px;max-height:90vh;overflow-y:auto;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--background);color:var(--foreground);box-shadow:var(--shadow-lg)}
.modal-sm{max-width:448px}.modal-lg{max-width:768px}.modal-xl{max-width:1152px}
.modal-header{position:static;display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:8px;padding:24px 48px 0 24px;border-bottom:0;background:transparent;border-radius:0}
.modal-body{padding:16px 24px}
.modal-footer{position:static;display:flex;justify-content:flex-end;gap:8px;padding:0 24px 24px;border-top:0;background:transparent;border-radius:0}
.modal-xl .modal-header{position:sticky;top:0;z-index:1;padding-bottom:16px;border-bottom:1px solid var(--border);background:var(--background)}
.modal-xl .modal-footer{position:sticky;bottom:0;z-index:1;padding-top:16px;border-top:1px solid var(--border);background:var(--background)}
}
.modal-close{position:absolute;top:16px;right:16px;width:16px;height:16px;padding:0;border:0;border-radius:2px;background:transparent;color:var(--foreground);font-size:18px;line-height:1;display:flex;align-items:center;justify-content:center;opacity:.7;cursor:pointer;transform:none;transition:opacity var(--dur) var(--ease)}
.modal-close::before{content:"";position:absolute;inset:-14px}
.modal-close:hover{opacity:1;background:transparent;color:var(--foreground);transform:none}
.modal-close:focus-visible{opacity:1;outline:none;box-shadow:0 0 0 2px var(--background),0 0 0 4px var(--ring)}
@media (max-width:640px){.modal-footer{flex-direction:column-reverse}.modal-footer>*{width:100%}}
@keyframes ui-fade-in{from{opacity:0}to{opacity:1}}
@keyframes ui-fade-out{from{opacity:1}to{opacity:0}}
@keyframes ui-dialog-in{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:none}}
@keyframes ui-dialog-out{from{opacity:1;transform:none}to{opacity:0;transform:scale(.95)}}

/* toasts façon Sonner (D13 : durées par type gardées dans toast()) */
/* La zone ne capte aucun clic (seuls les toasts) ; en appli installée, index.html (l. ~143) la cale en haut par top:58px !important :
   bottom repasse à auto, sinon top + bottom l'étirent sur toute la hauteur, au-dessus des modales (revue finale du 13/10).
   Tous les toasts restent visibles : en masquer au-delà de 3 laissait expirer un toast d'erreur sans qu'il soit vu. */
.toast-container{top:auto;bottom:24px;right:24px;left:auto;width:356px;max-width:calc(100vw - 32px);gap:14px;pointer-events:none}
@media (max-width:640px){.toast-container{bottom:16px;right:16px;left:16px;width:auto}}
body.is-standalone .toast-container{bottom:auto}
.toast,.toast.toast-success,.toast.toast-error,.toast.toast-warning,.toast.toast-info{pointer-events:auto;position:relative;display:flex;align-items:flex-start;gap:12px;min-width:0;max-width:none;padding:16px;border:1px solid var(--border);border-radius:8px;background:var(--popover);color:var(--popover-foreground);box-shadow:0 4px 12px rgb(0 0 0 / .1);font-size:13px;line-height:1.4;animation:ui-toast-in 400ms var(--ease)}
.toast .toast-icon svg{width:16px;height:16px}
.toast.toast-success .toast-icon{color:var(--success)}
.toast.toast-error .toast-icon{color:var(--destructive)}
.toast.toast-warning .toast-icon{color:var(--warning)}
.toast.toast-info .toast-icon{color:var(--info)}
.toast .toast-msg{flex:1;min-width:0;font-weight:500;color:var(--popover-foreground)}
.toast .toast-close{position:absolute;top:-8px;left:-8px;width:20px;height:20px;padding:0;border:1px solid var(--border);border-radius:9999px;background:var(--popover);color:var(--muted-foreground);font-size:12px;line-height:1;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity var(--dur) var(--ease)}
.toast:hover .toast-close,.toast .toast-close:focus-visible{opacity:1}
@media (hover:none){.toast .toast-close{opacity:1}}
@keyframes ui-toast-in{from{opacity:0;transform:translateY(100%)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(8px)}}

/* visionneuses photo et PDF : les boutons passés en fantôme par la tâche 5 restent clairs sur leur fond sombre (`.pdfv-head` n'existe pas : l'en-tête PDF est un div à fond bleu inline, l. ~9145) */
/* Visionneuses photo et PDF : au-dessus des modales (échelle des couches, CLAUDE.md §5.2 : 10001 et 10002) */
#modal-photo-viewer{z-index:10001;background:rgba(0,0,0,.92);cursor:default}
#modal-pdf-viewer{z-index:10002}
.pv-outils{position:absolute;top:calc(env(safe-area-inset-top,12px) + 12px);right:12px;z-index:3;display:flex;gap:6px}
.pv-zoom{display:flex;align-items:center;justify-content:center;min-width:36px;color:rgba(255,255,255,.5)}
.pv-fermer{margin-left:8px}
.pv-nav{position:absolute;top:50%;z-index:3;width:40px;transform:translateY(-50%)}
.pv-prec{left:10px}
.pv-suiv{right:10px}
#photo-counter{position:absolute;bottom:12px;left:50%;z-index:3;transform:translateX(-50%);color:rgba(255,255,255,.5)}
#photo-viewer-wrap{position:absolute;inset:0;overflow:hidden}
#photo-viewer-img{position:absolute;user-select:none}
.pdfv-cadre{display:flex;flex-direction:column;width:100%;height:100%;background:var(--visionneuse-fond)}
.pdfv-barre{flex-shrink:0;padding:10px 16px;padding-top:calc(env(safe-area-inset-top,10px) + 10px);background:var(--primary)}
#pdf-viewer-title{max-width:70%;color:var(--primary-foreground)}
.pdfv-corps{position:relative;display:flex;min-height:0}
#pdf-viewer-frame{width:100%;border:0;background:#fff}
#modal-photo-viewer .btn-ghost,#modal-pdf-viewer .btn-ghost{color:var(--primary-foreground)}
#modal-photo-viewer .btn-ghost:hover,#modal-pdf-viewer .btn-ghost:hover{background:rgba(255,255,255,.15);color:var(--primary-foreground)}

/* menus et popovers existants (spec §6.3) : menu de période du tableau de bord (la bulle, les suggestions et le tiroir de la Tarification vivent en section 8, page-tarif, depuis le lot 5) */
.tdb-menu{padding:4px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--popover);box-shadow:var(--shadow-md);animation:ui-menu-in var(--dur) ease}
.tdb-menu .tdb-opt{min-height:0;padding:6px 8px;border-radius:var(--radius-sm);font-size:14px}
.tdb-menu .tdb-opt:hover,.tdb-menu .tdb-opt:focus-visible{background:var(--accent);color:var(--accent-foreground)}

/* recherche globale (ge-290) : la liste vit dans le contexte de .top-bar (50) et se place à 60 comme .menu — au-dessus du contenu, sous .modal-overlay (10000) */
.recherche-liste{position:absolute;z-index:60;top:calc(100% + 4px);right:0;width:520px;max-width:calc(100vw - 32px);max-height:560px;max-height:min(560px,calc(100dvh - 72px));overflow-y:auto;padding:4px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--popover);color:var(--popover-foreground);box-shadow:var(--shadow-md);animation:ui-menu-in var(--dur) ease}
.recherche-liste[hidden]{display:none}
/* téléphone (spec §4.6) : la barre se réduit à une loupe ; un appui pose .plein, qui fait de #rech un panneau plein écran (champ, Fermer, liste défilante).
   Le panneau reste dans le contexte de .top-bar : celui-ci passe à 9990 le temps de l'ouverture — au-dessus de .sidebar-overlay (99) et du contenu, sous .sidebar (9999) et .modal-overlay (10000). */
.rech-loupe,.rech-fermer{display:none}
.top-bar:has(.topbar-recherche.plein){z-index:9990}
@media (max-width:767px){
  .topbar-recherche{flex:none}
  .rech-loupe{display:inline-flex;align-items:center;justify-content:center;min-width:40px;min-height:40px}
  .topbar-recherche:not(.plein)>.search-input,.topbar-recherche:not(.plein)>.recherche-liste{display:none}
  .topbar-recherche.plein{position:fixed;inset:0;z-index:60;display:flex;flex-wrap:wrap;align-content:flex-start;gap:8px;padding:8px 12px;background:var(--background)}
  .topbar-recherche.plein .rech-loupe{display:none}
  .topbar-recherche.plein>.search-input{flex:1 1 0;min-width:0;height:44px}
  .topbar-recherche.plein .rech-fermer{display:inline-flex;align-items:center;justify-content:center;min-height:44px}
  .topbar-recherche.plein>.recherche-liste{position:static;flex:1 1 100%;width:auto;max-width:none;max-height:calc(100dvh - 68px);padding:0;border:0;border-radius:0;background:transparent;box-shadow:none;animation:none;-webkit-overflow-scrolling:touch}
  .topbar-recherche.plein .rech-opt{min-height:44px}
  .topbar-recherche.plein .rech-cpt{min-height:32px}
  .rech-kbd{display:none}
  .topbar-recherche.plein .rech-pied{position:static;margin:4px 0 0;background:transparent}
}
/* Polish du 19/10 (Valentin : « trop grossier, manque de couleurs, boutons trop gros ») : la liste parle la langue du menu de la
   cloche (tuile d'icône de 28 px teintée, titre 14 px, détail 12 px gris) et des couleurs de DOMAINE du tableau de bord ; l'urgence
   reste portée par les étiquettes .tdb-st ; les boutons de la vedette sont des boutons de ligne (.act, 28 px). */
.rech-dom-flotte{--dom:var(--tdb-flotte)}.rech-dom-atelier{--dom:var(--tdb-atelier)}.rech-dom-achats{--dom:var(--tdb-achats)}
.rech-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.rech-ico{flex:none;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-sm);background:color-mix(in oklab,var(--dom) 12%,transparent);color:var(--dom)}
.rech-ico svg{width:16px;height:16px}
.rech-ico-lg{width:36px;height:36px;border-radius:var(--radius-md)}
.rech-ico-lg svg{width:20px;height:20px}
.rech-attente{position:sticky;top:0;z-index:1;height:2px;margin:-4px -4px 2px;background:linear-gradient(90deg,transparent,var(--primary),transparent);background-size:200% 100%;animation:rech-attente 1s linear infinite}
@keyframes rech-attente{from{background-position:200% 0}to{background-position:-200% 0}}
.rech-msg{padding:16px 12px;font-size:13px;line-height:18px;color:var(--muted-foreground);text-align:center}
.rech-msg-t{font-size:14px;line-height:20px;font-weight:500;color:var(--foreground)}
.rech-msg-aide{margin-top:4px;font-size:12px;line-height:16px}
/* vedette : fond et bordure à peine teintés de la couleur du domaine (pas de liseré latéral, Valentin le 19/10), la plaque en tête,
   les faits en grille libellé / valeur */
.rech-vedette{margin:4px 4px 8px;padding:12px;border:1px solid color-mix(in oklab,var(--dom) 22%,var(--border));border-radius:var(--radius-md);background:color-mix(in oklab,var(--dom) 4%,var(--card));color:var(--card-foreground)}
.rech-v-tete{display:flex;align-items:center;gap:10px;min-width:0}
.rech-v-id{min-width:0}
.rech-v-l1{display:flex;align-items:center;gap:8px;min-width:0}
.rech-v-plaque{font-size:16px;line-height:20px;font-weight:700;letter-spacing:.02em;font-variant-numeric:tabular-nums;color:var(--foreground);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rech-v-l1 .tdb-st{flex:none;align-self:center}
.rech-v-lib{margin-top:2px;font-size:12px;line-height:16px;color:var(--muted-foreground);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rech-v-infos{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 16px;margin:12px 0 0;padding-top:10px;border-top:1px solid color-mix(in oklab,var(--dom) 14%,var(--border))}
.rech-v-infos>div{min-width:0}
.rech-v-infos>.rech-v-large{grid-column:1/-1}
.rech-v-infos dt{font-size:11px;line-height:16px;color:var(--muted-foreground)}
.rech-v-infos dd{margin:0;font-size:13px;line-height:18px;font-weight:500;color:var(--foreground);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rech-v-infos dd.rech-v-retard{color:var(--destructive)}
.rech-v-infos dd.rech-v-bientot{color:var(--warning)}
.rech-v-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
/* compteurs : une puce par type, le point à la couleur du domaine ; un clic déplie la rubrique */
.rech-compteurs{display:flex;flex-wrap:wrap;gap:4px;padding:4px 4px 8px}
.rech-cpt{display:inline-flex;align-items:center;gap:6px;height:24px;min-height:0;padding:0 8px;border:0;border-radius:9999px;background:var(--muted);color:var(--foreground);font:inherit;font-size:12px;line-height:16px;font-weight:500;cursor:pointer;transition:background-color var(--dur) var(--ease)}
.rech-cpt::before{content:"";flex:none;width:6px;height:6px;border-radius:9999px;background:var(--dom)}
.rech-cpt:hover,.rech-cpt:focus-visible{outline:none;background:color-mix(in oklab,var(--dom) 14%,transparent)}
.rech-cpt:focus-visible{box-shadow:var(--focus-ring)}
.rech-cpt-n{font-variant-numeric:tabular-nums}
/* rubriques : titre discret, son total à droite ; un filet entre deux rubriques */
.rech-compteurs+.rech-groupe,.rech-groupe+.rech-groupe{margin-top:4px;padding-top:4px;border-top:1px solid var(--border)}
.rech-titre{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px 4px;font-size:12px;line-height:16px;font-weight:500;color:var(--muted-foreground)}
.rech-titre-n{font-variant-numeric:tabular-nums}
.rech-titre-urgent{color:var(--warning)}
.rech-titre-urgent>span:first-child::before{content:"";display:inline-block;width:6px;height:6px;margin-right:6px;border-radius:9999px;background:currentColor;vertical-align:1px}
.rech-opt{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:var(--radius-sm);font-size:14px;line-height:20px;cursor:pointer;transition:background-color var(--dur) var(--ease)}
.rech-opt:hover{background:var(--muted)}
.rech-opt.sel{background:var(--accent)}
.rech-opt-corps{display:flex;flex:1;flex-direction:column;min-width:0}
.rech-opt-t{font-weight:500;color:var(--foreground);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rech-opt-s{font-size:12px;line-height:16px;color:var(--muted-foreground);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rech-opt .tdb-st{flex:none;align-self:center;font-weight:500}
.rech-plus{display:block;height:auto;min-height:0;margin:0 0 2px 46px;padding:2px 0;font-size:12px;line-height:16px;font-weight:500}
.rech-note{padding:2px 8px 4px 46px;font-size:12px;line-height:16px;color:var(--muted-foreground)}
/* pied : « Tout voir », collé au bas de la liste qui défile, seulement s'il reste des lignes cachées */
.rech-pied{position:sticky;bottom:-4px;display:flex;align-items:center;justify-content:center;min-height:36px;margin:4px -4px -4px;padding:6px 12px;border-top:1px solid var(--border);background:var(--muted)}
.rech-pied .btn-link{font-size:12px;line-height:16px;font-weight:500}

/* ── 6. données (lot 4) — tri et pagination ── */
.th-sort{display:inline-flex;align-items:center;gap:8px;height:auto;padding:0;border:0;background:none;color:inherit;font:inherit;font-weight:500;cursor:pointer}
.th-sort::after{content:"";width:16px;height:16px;opacity:.5;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m21 16-4 4-4-4M17 20V4M3 8l4-4 4 4M7 4v16'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m21 16-4 4-4-4M17 20V4M3 8l4-4 4 4M7 4v16'/%3E%3C/svg%3E") center/contain no-repeat}
th[aria-sort="ascending"] .th-sort::after,th[aria-sort="descending"] .th-sort::after{opacity:1}
.pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 8px;font-size:14px;color:var(--muted-foreground)}
.pagination-nav{display:flex;align-items:center;gap:4px}
@media (max-width:640px){.pagination{flex-direction:column}}
/* lot 5 : une ligne paginée reste masquée même si une règle de page pose un display sur les <tr> (spec lot 5 §6.3) */
tr[hidden]{display:none!important}
.pagination[hidden]{display:none}
/* lot 5 : message d'état d'une section ou d'une liste (spec du système §7.7 : 14 px muted centré, padding 32 px) — chargement, vide */
.ligne-inactive{opacity:.55} /* fiche désactivée gardée à l'écran (fournisseurs, référentiel) */
.etat-vide{padding:32px 16px;text-align:center;font-size:14px;line-height:20px;color:var(--muted-foreground)}
/* lot 5 : briques de liste partagées par les pages — ligne séparée, liste sans puces, petite carte bordée */
.ligne-sep{padding:8px 0;border-bottom:1px solid var(--border)}
.liste-nue{margin:0;padding:0;list-style:none}
.carte-mini{padding:8px 12px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card)}
.pagination-taille{display:inline-flex;align-items:center;gap:8px}
.pagination .filter-select{width:96px;min-width:0}
.pagination-texte{margin-right:8px;font-variant-numeric:tabular-nums}
.table-wrap>.pagination{border-top:1px solid var(--border)}

/* cartes (spec §7.1) */
.card,.table-wrap,.user-card,.tdb-carte,.tdb-tuile{border:1px solid var(--border);border-radius:var(--radius-xl);background:var(--card);color:var(--card-foreground);box-shadow:var(--shadow-sm)}
/* Pas de display/gap/padding sur .card nue : #page-sms (l. ~2879-2932, `class="card" style="padding:16px"`) et les gabarits de la
   Tarification l'utilisent déjà (relecture du 13/10). La mise en page de la carte standard n'est posée que sur ses enfants et sur .card-kpi. */
.card-header{display:grid;grid-template-rows:auto auto;gap:6px;padding:0 24px}
.card-header:has(.card-action){grid-template-columns:1fr auto}
.card-action{grid-column:2;grid-row:1/span 2;align-self:start;justify-self:end}
.card-title{font-size:16px;line-height:1;font-weight:600}
.card-desc{font-size:14px;line-height:20px;color:var(--muted-foreground)}
.card-content,.card-footer{padding:0 24px}
.card-footer{display:flex;align-items:center}
/* carte standard (lot 5, Réglages) : une carte qui porte un .card-header prend la mise en page de la spec §7.1 (pas de padding sur .card nue) */
.card:has(>.card-header){display:flex;flex-direction:column;gap:24px;padding:24px 0}
/* interrupteur (lot 5) : bouton role="switch", état en aria-checked — même recette que .bc-cw-switch */
.switch{position:relative;display:inline-block;flex-shrink:0;width:36px;height:20px;min-height:0;padding:0;border:0;border-radius:9999px;background:var(--input);cursor:pointer;transition:background-color var(--dur) var(--ease)}
.switch::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:9999px;background:var(--background);box-shadow:var(--shadow-sm);transition:transform var(--dur) var(--ease)}
.switch[aria-checked="true"]{background:var(--primary)}
.switch[aria-checked="true"]::after{transform:translateX(16px)}
.switch:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.switch:disabled{cursor:not-allowed;opacity:.5}
.user-card{transform:none}
.user-card:hover{box-shadow:var(--shadow-sm)}
.uc-av{width:32px;height:32px;border-radius:var(--radius-lg);font-size:12px}

/* KPI (spec §7.4) */
.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}
.card-kpi.simple{display:flex;flex-direction:column;gap:0;padding:24px}
.kpi-head{display:flex;align-items:center;justify-content:space-between;padding-bottom:8px}
.kpi-title{font-size:14px;line-height:20px;font-weight:500}
.kpi-ico{display:flex;color:var(--muted-foreground)}
.kpi-ico svg{width:16px;height:16px}
.kpi-value{font-size:24px;line-height:32px;font-weight:700;font-variant-numeric:tabular-nums}
.kpi-sub{font-size:12px;line-height:16px;color:var(--muted-foreground)}
.kpi-cliquable{cursor:pointer;transition:border-color var(--dur) var(--ease)}
.kpi-cliquable:hover{border-color:color-mix(in oklab,var(--primary) 40%,transparent)}
.tdb-tuile{padding:16px;gap:6px;transform:none}
/* Première ligne (retour 14/10) : le chiffre au premier plan, l'étiquette et le statut au second. */
.tdb-tuile .tdb-tuile-l{font-size:10px;line-height:14px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--muted-foreground)}
.tdb-tuile .tdb-tuile-v{font-size:26px;line-height:32px;font-weight:700;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.tdb-tuile .tdb-tuile-s{font-size:11px;line-height:15px;color:var(--muted-foreground)}
.tdb-tuile .tdb-st,.tdb-bandeau-cote .tdb-st{font-size:10px;line-height:14px;font-weight:500;padding:0 6px;opacity:.85}
/* ge-288 (polish du 19/10) : « N hors carte » du bandeau est une étiquette comme celles des tuiles, cliquable (carte agrandie) ;
   au doigt, la zone touchée s'élargit à 40 px de haut, pas le dessin. */
.tdb-muets{appearance:none;position:relative;align-self:center;cursor:pointer} /* .tdb-st est en flex-start (tuiles, en colonne) */
.tdb-muets:hover{opacity:1}
.tdb-muets:focus-visible{outline:none;box-shadow:var(--focus-ring)}
@media (pointer:coarse){.tdb-muets::after{content:"";position:absolute;inset:-13px -4px}}
.tdb-tuile.tdb-cliquable:hover{border-color:color-mix(in oklab,var(--primary) 40%,transparent);box-shadow:var(--shadow-sm)}
/* Polish du 18/10 (Valentin) : 7 tuiles au plus par écran (TDB_TUILES_MAX), sur une seule ligne dès qu'elles y tiennent —
   à 1 400 px, sept tuiles font ~150 px, la place d'un « 10 747 km » ; en dessous, la grille auto-fit les replie. */
@media (min-width:1400px){.tdb-tuiles{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr)}}
/* Fenêtre « Données » et liste entière au téléphone : la feuille basse touche les bords comme les autres fenêtres — sa largeur propre
   (index.html, min(640px, 100% − 32px)) la laissait flotter 16 px à gauche et à droite (Valentin, 18/10 : « mal centrée »). */
@media (max-width:768px){#modal-tdb-liste .modal{width:100%}}
/* Fenêtre de détail d'une tuile (spec du 18/10) : sections titrées, sections et suites repliées (<details>), bouton vers la page au pied */
#modal-tdb-liste .tdb-detail-section+.tdb-detail-section{margin-top:16px}
#modal-tdb-liste .tdb-detail-section>h6{margin:0 0 4px;font-size:12px;line-height:16px;font-weight:600;color:var(--muted-foreground)}
#modal-tdb-liste details>summary{padding:8px 0;font-size:13px;line-height:20px;font-weight:500;color:var(--muted-foreground);cursor:pointer}
#modal-tdb-liste details>summary:hover{color:var(--foreground)}
#tdb-liste-pied[hidden]{display:none}
.delta{display:inline-flex;align-items:center;gap:2px;padding:2px 6px;border-radius:var(--radius-md);font-size:11px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}
.delta-up{--tone:var(--success)}.delta-down{--tone:var(--destructive)}
.delta-up.invert{--tone:var(--destructive)}.delta-down.invert{--tone:var(--success)}
:is(.delta-up,.delta-down){color:var(--tone);background:color-mix(in oklab,var(--tone) 10%,transparent);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--tone) 25%,transparent)}

/* graphiques (spec §7.5) */
.tdb-carte{padding:24px;gap:16px}
.tdb-carte .tdb-carte-h h5{font-size:16px;line-height:1;font-weight:600}
.tdb-carte .tdb-sub{font-size:14px;line-height:20px;color:var(--muted-foreground)}
.tdb-chart{height:300px}
@media (max-width:600px){.tdb-chart{height:220px}}
.tdb-btn-donnees{height:24px;padding:0 8px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--background);color:var(--foreground);font-size:12px;font-weight:500;box-shadow:var(--shadow-xs)}
.tdb-btn-donnees:hover{background:var(--accent);color:var(--accent-foreground)}
/* ge-170 lot 4 : badge de variation dans le titre d'une carte de graphique (classes .delta de §3), deux panneaux alignés */
.tdb-carte-h h5 .delta{margin-left:8px;vertical-align:2px}
.tdb-carte-h>div:first-child{flex:1 1 160px;min-width:0}   /* le titre se replie avant de renvoyer « Données » à la ligne */
.tdb-chart-double{display:flex;flex-direction:column;gap:4px}
.tdb-panneau{position:relative;flex:1 1 0;min-height:0}
.tdb-panneau-bas{flex:0 0 58px}
/* tableau de chaleur (spec §3.3) : 5 paliers sur --primary, colonne d'alerte sur --destructive */
.tdb-chart-chaleur{display:flex;align-items:center;overflow-x:auto}
.tdb-chaleur{display:grid;gap:3px;width:100%;font-size:12px}
.tdb-chaleur.cols-1{grid-template-columns:minmax(90px,auto) repeat(1,minmax(44px,1fr))}.tdb-chaleur.cols-2{grid-template-columns:minmax(90px,auto) repeat(2,minmax(44px,1fr))}
.tdb-chaleur.cols-3{grid-template-columns:minmax(90px,auto) repeat(3,minmax(44px,1fr))}.tdb-chaleur.cols-4{grid-template-columns:minmax(90px,auto) repeat(4,minmax(44px,1fr))}
.tdb-chaleur.cols-5{grid-template-columns:minmax(90px,auto) repeat(5,minmax(44px,1fr))}.tdb-chaleur.cols-6{grid-template-columns:minmax(90px,auto) repeat(6,minmax(44px,1fr))}
.tdb-chaleur.cols-7{grid-template-columns:minmax(90px,auto) repeat(7,minmax(44px,1fr))}.tdb-chaleur.cols-8{grid-template-columns:minmax(90px,auto) repeat(8,minmax(44px,1fr))}
.tdb-chaleur .ch-r{display:contents}
/* Polish du 18/10 : la teinte du domaine du bloc (--ch-dom, posée par .dom-*), bleu de la flotte sinon ; alerte au corail des graphiques.
   Chiffre foncé jusqu'au palier 4 (70 %, ≥ 5:1), blanc sur le palier 5 foncé de 25 % (≥ 4,5:1 dans chaque teinte). */
.tdb-chaleur.dom-flotte{--ch-dom:var(--tdb-flotte)}.tdb-chaleur.dom-atelier{--ch-dom:var(--tdb-atelier)}.tdb-chaleur.dom-achats{--ch-dom:var(--tdb-achats)}.tdb-chaleur.dom-energie{--ch-dom:var(--tdb-energie)}
.tdb-chaleur .ch{--ch:var(--ch-dom,var(--tdb-flotte));display:grid;place-items:center;min-height:32px;border-radius:6px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--foreground)}
.tdb-chaleur .ch-alerte{--ch:var(--tdb-alerte)}
.tdb-chaleur .ch-tete{min-height:auto;padding-bottom:2px;color:var(--muted-foreground);font-weight:500}
.tdb-chaleur .ch-ligne{justify-items:start;padding-right:8px;font-weight:500}
.tdb-chaleur .ch-0{color:var(--muted-foreground)}
.tdb-chaleur .ch-1{background:color-mix(in oklab,var(--ch) 15%,transparent)}
.tdb-chaleur .ch-2{background:color-mix(in oklab,var(--ch) 32%,transparent)}
.tdb-chaleur .ch-3{background:color-mix(in oklab,var(--ch) 50%,transparent)}
.tdb-chaleur .ch-4{background:color-mix(in oklab,var(--ch) 70%,transparent)}
.tdb-chaleur .ch-5{background:color-mix(in oklab,var(--ch) 75%,black);color:var(--primary-foreground)}
.tdb-chaleur .ch-alerte:not(.ch-0){box-shadow:inset 0 0 0 2px var(--tdb-alerte)}

/* tableaux (spec §7.2) */
.table-wrap{overflow-x:auto}
/* Un tableau large défile dans sa carte ; sa barre d'outils et sa pagination restent sous les yeux (revue finale du lot 5, 390 px) */
.table-wrap>.table-toolbar,.table-wrap>.pagination{position:sticky;left:0}
.table-frame{border:1px solid var(--border);border-radius:var(--radius-md);overflow-x:auto}
.table-summary{display:flex;flex-wrap:wrap;justify-content:space-between;gap:4px 16px;margin-bottom:12px;font-size:14px;color:var(--muted-foreground)}
tr.inactive td{opacity:.5}
.num{text-align:right}
.text-destructive{color:var(--destructive)}
.table-toolbar{gap:12px;padding:16px;border-bottom:1px solid var(--border)}
.dash-table-title{padding:16px;font-size:16px;font-weight:600}
table th{height:40px;padding:0 8px;background:transparent;color:var(--foreground);font-size:14px;line-height:20px;font-weight:500;text-transform:none;letter-spacing:0;border-bottom:1px solid var(--border);vertical-align:middle}
table td{padding:8px;font-size:14px;line-height:20px;border-bottom:1px solid var(--border);vertical-align:middle}
:is(.table-wrap,.modal) table :is(th,td):first-child{padding-left:16px}
:is(.table-wrap,.modal) table :is(th,td):last-child{padding-right:16px}
table tbody tr:last-child td{border-bottom:0}
table tbody tr:nth-child(even) td{background:transparent}
table tbody tr:hover td{background:color-mix(in oklab,var(--muted) 50%,transparent)!important}
table tr.no-hover:hover td{background:inherit!important}
table tfoot td{background:color-mix(in oklab,var(--muted) 50%,transparent);border-top:1px solid var(--border);font-weight:500}
.row-alert td{background:color-mix(in oklab,var(--destructive) 6%,transparent)!important} /* index.html l. ~92/1629 : !important */
.row-alert td:first-child{box-shadow:inset 3px 0 0 var(--destructive)}
.totaux-bar{border:1px solid var(--border);border-radius:var(--radius-lg);background:color-mix(in oklab,var(--muted) 50%,transparent);color:var(--foreground);box-shadow:none}
.totaux-bar .tot-label{color:var(--muted-foreground);opacity:1}
.totaux-bar .tot-val{color:var(--foreground)}
.totaux-bar .tot-val.tot-total{font-size:20px;line-height:28px}

/* cartes Leaflet : contrôles (spec §7.6) */
.leaflet-bar,.leaflet-control-layers,.map-base-switch,.map-traffic-btn,.map-view-btn{border:1px solid var(--border)!important;border-radius:var(--radius-md)!important;background:var(--card);box-shadow:var(--shadow-sm)!important}
.leaflet-bar a{width:36px!important;height:36px!important;line-height:36px!important} /* index.html l. ~492 : 30 px !important */
.map-base-switch,.map-traffic-btn,.map-view-btn{height:36px}
.map-base-switch button[aria-pressed="true"],.map-base-switch button.on,.map-base-switch button.active{background:var(--primary);color:var(--primary-foreground)}
.tdb-bandeau-titre,.tdb-bandeau-leg,.tdb-province{border:1px solid var(--border);border-radius:var(--radius-md);font-size:12px}
/* Bouton Plan / Satellite du bandeau (ge-286) : discret, 28 px à l'œil ; au doigt, la zone touchée s'élargit à 40 px, pas le dessin.
   Au-dessus de la carte (sa .leaflet-container est à z-index 0, l. ~904 d'index.html), sous le menu de période (isolation du bandeau). */
.tdb-fond-btn{position:absolute;top:8px;right:8px;z-index:1;display:flex;align-items:center;justify-content:center;width:28px;height:28px;min-width:0;min-height:0;padding:0;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card);color:var(--muted-foreground);box-shadow:var(--shadow-sm);cursor:pointer}
.tdb-fond-btn[hidden]{display:none}
.tdb-fond-btn svg{width:16px;height:16px}
.tdb-fond-btn:hover{color:var(--primary)}
.tdb-fond-btn[aria-pressed="true"]{color:var(--primary);border-color:color-mix(in oklab,var(--primary) 40%,transparent)}
.tdb-fond-btn:focus-visible{outline:none;border-color:var(--ring);box-shadow:var(--focus-ring)}
@media (pointer:coarse){.tdb-fond-btn::after{content:"";position:absolute;inset:-6px}}

/* ── 7. utilitaires (lot 5) ── */
/* Liste FERMÉE (spec lot 5 §6.1) : au plus 26 classes (25 prévues, u-md ajoutée à la page BC), chacune remplace une vingtaine de déclarations en ligne au moins (compte du
   17/10 sur index.html, hors HORS SPA, entre parenthèses). Ce qu'aucune ne couvre devient un composant ou une classe de page (§8).
   Elles viennent après les composants : à spécificité égale, l'utilitaire l'emporte. */
.u-row{display:flex;align-items:center;gap:8px}       /* display:flex 397 · align-items:center 303 · gap 8-10 px 229 */
.u-stack{display:flex;flex-direction:column;gap:8px}  /* flex-direction:column 30 */
.u-gap-4{gap:4px}                                      /* gap 4-6 px 130 */
.u-gap-12{gap:12px}                                    /* gap 12-16 px 38 */
.u-wrap{flex-wrap:wrap}                                /* 122 */
.u-between{justify-content:space-between}              /* 61 */
.u-grow{flex:1;min-width:0}                            /* flex:1 91 */
.u-xs{font-size:12px;line-height:16px}                 /* .6x-.74rem 378 */
.u-sm{font-size:14px;line-height:20px}                 /* .75-.88rem 552 */
.u-md{font-size:16px;line-height:24px}                 /* .9-1.05rem 55 — montants et valeurs mis en avant (ajouté à la page BC, 26e) */
.u-muted{color:var(--muted-foreground)}                /* --text3 395, libellés en --text2 */
.field label .u-muted{font-weight:400}                 /* l'aide d'un libellé (« — admin ») est une description (§3.4 : 400) */
.u-fg{color:var(--foreground)}                         /* --text 46, valeurs en --text2 */
.u-600{font-weight:600}                                /* 282 */
.u-700{font-weight:700}                                /* 328 */
.u-upper{text-transform:uppercase;letter-spacing:.025em} /* 98 */
.u-nowrap{white-space:nowrap}                          /* 78 */
.u-center{text-align:center}                           /* 109 — text-align:right (88) : .num */
.u-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap} /* text-overflow:ellipsis 24 */
.u-mb-4{margin-bottom:4px}                             /* margin-bottom 4-8 px 157 */
.u-mb-8{margin-bottom:8px}
.u-mb-12{margin-bottom:12px}                           /* 10-12 px 99 */
.u-mb-16{margin-bottom:16px}                           /* 14-16 px 118 */
.u-mt-4{margin-top:4px}                                /* margin-top 4-8 px 117 */
.u-mt-8{margin-top:8px}
.u-mt-12{margin-top:12px}                              /* 10-12 px 53 */
.u-mt-16{margin-top:16px}                              /* 14-16 px 21 */

/* ── 8. pages (lot 5) ── */
/* Ce qu'aucun composant ni utilitaire ne couvre, page par page, en couleurs de rôle : une sous-section « page-<id> » chacune, dans
   l'ordre de migration. Après les composants : une règle qui en surcharge un y est plus spécifique (#page-<id> …). */

/* page-bc — bons de commande, saisie (#modal-bc), fiche (#modal-detail) */
#bc-devis-section{position:relative}
.bc-cw{display:flex;align-items:center;gap:12px;width:100%;padding:12px 16px;border:0;border-radius:var(--radius-lg);background:var(--muted);color:var(--foreground);font:inherit;text-align:left;cursor:pointer}
.bc-cw:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.bc-cw-switch{position:relative;flex-shrink:0;width:36px;height:20px;border-radius:9999px;background:var(--input);transition:background-color var(--dur) var(--ease)}
.bc-cw-thumb{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:9999px;background:var(--background);box-shadow:var(--shadow-sm);transition:transform var(--dur) var(--ease)}
.bc-cw[aria-checked="true"] .bc-cw-switch{background:var(--primary)}
.bc-cw[aria-checked="true"] .bc-cw-thumb{transform:translateX(16px)}
.bc-grille-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.bc-grille-com{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:16px}
#bc-frais-port{width:100px}
.bc-antidate-champ{max-width:280px}
.bc-veh-chips{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-height:36px;padding:4px 8px;border:1px solid var(--input);border-radius:var(--radius-md);box-shadow:var(--shadow-xs)}
/* une ligne de commande : la grille de l'en-tête, à toutes les largeurs au-dessus de 768 px (la règle .form-row d'index.html
   la ramenait à une colonne dès 1 280 px) */
.bc-ligne{display:grid;grid-template-columns:2.5fr 1.5fr .8fr 1fr 1fr 32px;gap:8px;align-items:center;margin-bottom:8px}
.bc-ligne-tete{padding:0 2px}
.bc-ligne .bcl-veh,.bc-ligne .bcl-livre{grid-column:1/-1}
.totaux-bar .tot-ttc{padding-left:16px;border-left:1px solid var(--border)}
.bc-grille-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
#bc-veh-add{min-width:130px;flex:1;min-height:28px;padding:4px 2px;border:0;outline:none;background:none;font-family:inherit}
.bc-ligne input.bcl-veh-add{height:auto;min-height:28px;padding:2px 4px;border:0;outline:none;background:none;box-shadow:none;font-family:inherit;font-size:12px;line-height:16px}
.bc-chip-x{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;padding:0;border:0;border-radius:9999px;background:none;color:inherit;font-size:16px;line-height:1;cursor:pointer}
.bc-chip-x:hover{background:color-mix(in oklab,currentColor 12%,transparent)}
.bc-recv-apercu{display:block;max-width:100%;max-height:300px;margin:0 auto 16px;border:1px solid var(--border);border-radius:var(--radius-lg)}
.bc-recv-qte{width:64px}
.bc-pastille-ronde{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:9999px;background:color-mix(in oklab,var(--tone,var(--muted-foreground)) 12%,transparent);color:var(--tone,var(--muted-foreground))}
.bc-ecart-type{text-transform:capitalize}
.bc-italique{font-style:italic}
.bc-score{border:2px solid var(--tone);border-radius:var(--radius-xl);overflow:hidden}
.bc-score-tete{background:color-mix(in oklab,var(--tone) 8%,transparent)}
.bc-score-titre,.bc-verdict{color:var(--tone)}
.status.bc-verdict{color:var(--tone)}
.bc-score-anneau circle.fond{stroke:var(--border)}
.bc-score-anneau circle.val{stroke:var(--tone)}
.bc-score-anneau text.val{fill:var(--tone)}
.bc-score-anneau text.sur{fill:var(--muted-foreground)}
.bc-score-tete{padding:16px}
.bc-score-col{flex:1;min-width:200px}
.bc-score-ligne{padding:12px 16px;border-bottom:1px solid var(--border)}
.bc-score-pied{padding:12px 16px;background:var(--muted)}
.bc-haut{display:flex;align-items:flex-start;gap:8px}
.bc-liste-ligne{padding:8px 0;border-bottom:1px solid var(--border)}
.bc-carte-ligne{padding:8px 12px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card)}
.bc-encart{padding:12px 16px;border-radius:var(--radius-md)}
.bc-valeur{font-size:20px;line-height:28px;font-weight:700;font-variant-numeric:tabular-nums}
.bc-droite{justify-content:flex-end}
.bc-histo{padding:8px 12px;border-left:3px solid;border-radius:var(--radius-sm)}
.bc-histo .status{flex-shrink:0}
.dz-resultat{padding:12px 16px;border:1px solid color-mix(in oklab,var(--tone) 40%,transparent);border-radius:var(--radius-md);background:color-mix(in oklab,var(--tone) 12%,transparent)}
.dz-tuiles{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.dz-attente-bloc{display:flex;align-items:center;justify-content:center;min-height:280px}
.dz-echec{width:100%;box-sizing:border-box}
.dz-echec>svg{flex:none;color:var(--destructive)}
.devis-slot.inactif{opacity:.3;cursor:not-allowed}
.ds-retenu{padding:2px 8px;border:1px solid var(--success);border-radius:9999px;background:var(--card)}
.comparatif-table{width:100%}
.comparatif-table .cmp-desig{font-weight:500}
.comparatif-table td.cmp-best{background:color-mix(in oklab,var(--success) 12%,transparent)}
.comparatif-table tr.cmp-sous-total{background:var(--muted)}
.comparatif-table tr.cmp-total{background:var(--primary)}
.comparatif-table tr.cmp-total td{color:var(--primary-foreground)}

/* page-or — ordres de réparation. Liste par groupes (ge-190, ge-192, ge-195, ge-280) et vue tableau « feuille de calcul »
   (2026-07-28), sorties du <style> d'index.html au lot 5 : la densité propre à la liste (td 9px 16px) laisse place au tableau du
   système (§7.2) ; le zébrage part (§7.2 « fin des lignes zébrées »), la vue tableau garde son en-tête collant et ses colonnes
   courtes sans retour à la ligne. */
#or-search{flex:1 1 240px;min-width:200px;max-width:400px}
#or-vue{margin-left:auto}
#or-statut-tabs{max-width:100%;margin:0;overflow-x:auto;scrollbar-width:none}
#or-statut-tabs::-webkit-scrollbar{display:none}
#or-list-body td:nth-child(1),#or-list-body td:nth-child(2),#or-list-body td:nth-child(3),#or-list-body td:nth-child(5),#or-list-body td:nth-child(6){width:1%;white-space:nowrap}
#or-list-body thead.or-th-sr tr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.or-groupe>summary{list-style:none}
.or-groupe>summary::-webkit-details-marker{display:none}
.or-groupe-head{display:flex;align-items:center;gap:8px;padding:8px 4px;cursor:pointer}
.or-groupe-n{font-size:16px;line-height:24px;font-weight:700;color:var(--foreground)}
.or-age{font-size:12px;line-height:16px;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--muted-foreground)}
.or-age.warn{color:var(--warning);font-weight:700}
.or-age.alert{color:var(--destructive);font-weight:700}
.or-bloque{display:block;margin-top:4px;font-size:12px;line-height:16px;color:var(--muted-foreground)}
.or-avct{font-size:12px;line-height:16px;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--muted-foreground)}
.or-avct.done{color:var(--success);font-weight:700}
/* « Sur parc » au second plan (Valentin, 18/10) : hors de la recette des pastilles de statut, qui lui donnait la taille de « En cours » ;
   même teinte légère que la liste « Flotte live » du Suivi GPS (.fp-parc). */
.or-parc{--tone:var(--success);display:inline-flex;align-items:center;padding:0 6px;border-radius:9999px;background:color-mix(in oklab,var(--tone) 12%,transparent);color:var(--tone);font-size:10px;line-height:16px;font-weight:500;white-space:nowrap}
.or-parc.vieux{--tone:var(--warning)}
.or-externe{display:inline-flex;align-items:center;padding:0 8px;border:1px solid var(--or-externe);border-radius:9999px;background:transparent;color:var(--or-externe);font-size:10px;line-height:16px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap;vertical-align:middle}
.or-filtre-ext{display:inline-flex;align-items:center;gap:8px;font-size:14px;line-height:20px;font-weight:500;color:var(--foreground);white-space:nowrap;cursor:pointer}
.modal .or-filtre-ext{white-space:normal} /* case « Véhicule externe » des modales : sa description passe à la ligne à 390 px */
.or-externe-client{font-size:14px;font-weight:600;color:var(--muted-foreground)}
.or-pieces :is(th,td){padding:8px;font-size:14px;border-bottom:1px solid var(--border);text-align:left;vertical-align:middle}
.or-pieces th{font-size:12px;color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.025em}
.or-pieces :is(th,td).num{text-align:right} /* Qté : la règle de cellules ci-dessus (0,1,1) battait .num */
.or-piece-src{display:inline-flex;padding:0 8px;border-radius:9999px;background:var(--muted);color:var(--muted-foreground);font-size:12px;line-height:16px;font-weight:600;white-space:nowrap}
.cat-mecanique{color:var(--cat-mecanique)}.cat-carrosserie{color:var(--purple)}.cat-manutention{color:var(--cat-manutention)}.cat-pneu{color:var(--cat-pneu)}.cat-autre{color:var(--cat-autre)}
.file-badge{background:transparent;color:var(--muted-foreground);box-shadow:inset 0 0 0 1px var(--border)}
.or-tache-actions{display:flex;gap:4px;opacity:0;transition:opacity var(--dur) var(--ease)}
li:hover>.or-tache-actions,.or-tache-actions:focus-within{opacity:1}
@media (hover:none){.or-tache-actions{opacity:1}}
.or-step{flex:1;padding-bottom:8px;border-bottom:3px solid}
.or-xls-wrap{max-height:calc(100vh - 300px);overflow:auto}
.or-xls{font-variant-numeric:tabular-nums}
.or-xls th{position:sticky;top:0;z-index:2;background:var(--background)}
.or-xls :is(.c-num,.c-immat,.c-depuis,.c-statut){white-space:nowrap}
.or-xls .c-travaux{max-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.or-xls .veh-sub{font-size:12px;line-height:16px;color:var(--muted-foreground);white-space:nowrap}
/* fiche (#modal-or-fiche) et modales du module */
.or-grid{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);gap:20px;align-items:start}
.or-colonne{display:flex;flex-direction:column;gap:20px}
#modal-or-fiche .or-carte{overflow:visible}
.or-carte-corps{padding:0 24px 24px}
.or-carte-liste{display:flex;flex-direction:column;padding-top:4px}
.or-fiche-map{height:220px;overflow:hidden;border:1px solid var(--border);border-radius:var(--radius-md)}
.or-mecs{display:flex;flex-wrap:wrap;gap:8px 16px}
.or-stepper{display:flex;gap:8px;margin:0 0 16px;padding:0;list-style:none}
.or-inline-haut{display:inline-flex;align-items:flex-start;gap:4px;vertical-align:top}
.or-grille-infos{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px}
.or-histo-pas{position:relative;padding:0 0 16px 20px;border-left:2px solid var(--border)}
.or-histo-point{position:absolute;top:2px;left:-6px;width:10px;height:10px;border-radius:9999px;box-shadow:0 0 0 3px var(--card)}
.or-label{font-weight:500}
.or-tache-faite{text-decoration:line-through;color:var(--muted-foreground)}
.or-carte-accent{border-left:3px solid var(--primary)}
.or-texte-defile{max-height:260px;overflow-y:auto;white-space:pre-wrap}
.or-texte-court{max-height:140px;overflow-y:auto;white-space:pre-wrap}
.or-note{padding:12px 16px;font-style:italic}
.or-citation{padding:8px 12px;border-left:3px solid var(--border);border-radius:0 var(--radius-md) var(--radius-md) 0;background:var(--muted)}
.or-grille-photos{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.or-photo{position:relative;display:block}
.or-photo img{display:block;width:auto;max-width:100%;max-height:240px;border-radius:var(--radius-sm)}
.or-photo-etiquette{position:absolute;bottom:8px;left:8px;padding:0 6px;border-radius:var(--radius-sm);background:rgb(15 25 55 / .75);color:#fff;font-size:12px;line-height:16px;font-weight:700}
.or-tri-actions{display:flex;flex-direction:column;gap:12px;padding-top:16px;border-top:1px solid var(--border)}
.or-grille-cartes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px}
.or-sep-pointille{padding-top:12px;border-top:1px dashed var(--border)}
.or-zone-refus{align-items:center;gap:8px}
.or-pleine-ligne{flex:0 0 100%}
.or-piece-des{flex:1 1 220px}
.or-piece-qte{width:96px}
.or-pied-sep{padding-top:12px;border-top:1px solid var(--border)}
.or-plein{width:100%}
.or-fin{align-self:flex-end}
.or-debut{align-self:flex-start}
.or-num-decale{margin-left:8px}
.or-vignette{display:block;overflow:hidden;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--muted);cursor:zoom-in}
.or-vignette-tuile img{display:block;width:100%;height:110px;object-fit:cover}
#or-fiche-map-btn{margin-left:8px;vertical-align:top}
.creneau-pill{padding:8px 12px;border:1px solid var(--border);border-radius:var(--radius-md);cursor:pointer}
.creneau-pill:has(input:checked){border-color:var(--primary);background:var(--accent)}
/* file de tri : pièces de l'OR (choix multiple en boutons) */
#or-tri-pieces{display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px;}
#or-tri-pieces .choice{min-height: 44px; width: 100%; border: 1px solid var(--border); border-radius: 7px;
  background: #fff; color: var(--foreground); display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; padding: 9px 13px;  font-size:13px; font-weight: 600;
  cursor: pointer; transition: border-color .15s, background .15s, color .15s;}
#or-tri-pieces .choice:hover{border-color: var(--primary);}
#or-tri-pieces .choice:focus-visible{outline: 2px solid var(--primary); outline-offset: 2px;}
#or-tri-pieces .choice.selected{background: var(--primary); border-color: var(--primary); color: #fff;}
/* L'erreur ne tient pas à la seule couleur : la bordure rouge est doublée d'une phrase
   sous le champ, lue par les lecteurs d'écran via aria-live. */
#or-tri-pieces.manque .choice{border-color: var(--destructive);}
#or-tri-pieces-err{display: none; color: var(--destructive); font-size:12px; font-weight: 600; margin-top: 6px;}
#or-tri-pieces-err.on{display: block;}
@media (max-width: 420px){ #or-tri-pieces{grid-template-columns: 1fr;} }
/* Fiche OR sur une colonne sous 768 px ; minmax(0,…) : avec 1fr, le contenu imposait 380 px dans une modale de 384 (ge-202) */
@media (max-width:768px){.or-grid{grid-template-columns:minmax(0,1fr)}}
@media (max-width:768px){.bc-grille-3,.bc-grille-com,.bc-grille-2{grid-template-columns:minmax(0,1fr)}.bc-ligne{grid-template-columns:repeat(3,minmax(0,1fr))}.bc-ligne-tete{display:none}.bc-ligne .bcl-desig{grid-column:1/-1}.bc-ligne .bcl-total{grid-column:1/3;text-align:left}.bc-ligne .btn-rm{justify-self:end}}

/* page-vehicules — parc : carte de flotte (Leaflet), filtre des types en menu de cases, liste paginée */
#veh-map-wrap{overflow:hidden}
#veh-map-wrap .veh-map-tete{padding:12px 16px;border-bottom:1px solid var(--border)}
#veh-map-search{flex:1 1 200px;min-width:120px;max-width:300px}
#veh-fleet-map{position:relative;z-index:1;height:400px}
#veh-search{min-width:220px}
#veh-type-dropdown-wrap{position:relative}
#veh-type-dropdown{top:calc(100% + 4px);left:0;min-width:256px;max-height:320px;overflow-y:auto}
#veh-type-dropdown .menu-label,#exp-type-dd .menu-label{white-space:nowrap}
#exp-type-wrap{position:relative}
#exp-type-wrap>.filter-select{width:100%;max-width:none}
#exp-type-dd{top:calc(100% + 4px);left:0;right:0;max-height:240px;overflow-y:auto}
#veh-count{margin-left:auto}
#cam-finance-section,.cam-encart-info{padding:16px;border:1px solid color-mix(in oklab,var(--info) 30%,transparent);border-radius:var(--radius-md);background:color-mix(in oklab,var(--info) 6%,transparent)}
.cam-section{padding-top:16px;border-top:1px solid var(--border)}
#modal-km-correction label:has(>input:is([type="radio"],[type="checkbox"])){font-weight:400}
/* fiche véhicule (#modal-camion-detail) et ses chargeurs Trimble ; .alert y sert d'encart neutre, d'où le préfixe d'id
   pour les grilles (.alert:not(:has(>svg)) pèse plus qu'une classe seule) */
#modal-camion-detail :is(.cam-grille-2,.cam-grille-3,.cam-grille-4,.cam-grille-auto){display:grid;gap:8px}
#modal-camion-detail .cam-grille-2{grid-template-columns:repeat(2,minmax(0,1fr))}
#modal-camion-detail .cam-grille-3{grid-template-columns:repeat(3,minmax(0,1fr))}
#modal-camion-detail .cam-grille-4{grid-template-columns:repeat(4,minmax(0,1fr))}
#modal-camion-detail .cam-grille-auto{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
#modal-camion-detail .cam-grille-large{gap:16px}
#modal-camion-detail svg{flex-shrink:0}
#cam-loc-box{overflow:hidden;border-radius:var(--radius-md);background:var(--muted)}
#cam-loc-box .cam-loc-tete{padding:12px 16px}
.cam-point{display:inline-block;flex:none;width:10px;height:10px;border-radius:50%;background:var(--border)}
.cam-point-sm{width:8px;height:8px}
.cam-point-rouge{background:var(--destructive)}
.cam-assurance{padding:8px 12px;border-radius:var(--radius-md);background:color-mix(in oklab,currentColor 12%,transparent)}
.cam-assureur{font-weight:400}
.cam-doc{display:flex;align-items:flex-start;gap:8px}
.cam-echeance{display:inline-flex;align-items:center;gap:4px;margin-right:8px}
.cam-ligne-fine{padding:4px 0}
.cam-ligne-liste{padding:4px 0;border-bottom:1px solid var(--border)}
.cam-a-droite{margin-left:auto}
.cam-fin{justify-content:flex-end}
.cam-ged-depot{padding:16px;border:2px dashed var(--border);border-radius:var(--radius-md);background:var(--card)}
.cam-ged-ligne{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px}
.cam-ged-champ{flex:1;min-width:120px}
.cam-ged-ico{display:flex;align-items:center;justify-content:center;flex:none;width:32px;height:32px;border-radius:var(--radius-sm);background:color-mix(in oklab,currentColor 12%,transparent)}
.cam-ged-actions{flex:none}
.cam-seg{display:inline-flex;align-items:center;gap:6px}
.cam-seg-decale{margin-left:8px}
.cam-direct-ligne{padding:6px 0}
.cam-direct-ligne+.cam-direct-ligne{border-top:1px solid var(--border)}
.cam-direct-nom{flex:1;min-width:200px}
.cam-direct-paire{gap:24px}
.cam-panneau{padding:12px 16px;border-radius:var(--radius-md);background:var(--card)}
.cam-panneau-serre{padding:6px 16px}
.cam-jauge{height:6px;overflow:hidden;border-radius:9999px;background:var(--border)}
.cam-jauge>span{display:block;height:100%;border-radius:inherit;transition:width .3s}
.cam-kpi{font-size:24px;line-height:32px}
.cam-kpi span{font-weight:400}
.cam-valeur{font-size:18px;line-height:28px}
.cam-defile{overflow-x:auto}
.cam-table{width:100%}
.cam-live{display:inline-block;width:8px;height:8px;margin-left:4px;border-radius:50%;background:var(--success);animation:pulse-dot 2s infinite}
.cam-fichier,.cam-jour{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:center;padding:8px 12px;border-left:3px solid var(--border);border-radius:var(--radius-sm)}
.cam-fichier-4{grid-template-columns:auto minmax(0,1fr) auto auto}
.cam-jour{grid-template-columns:minmax(0,1fr) auto auto}
.cam-fichier-ok,.cam-jour-actif{border-left-color:var(--success);background:color-mix(in oklab,var(--success) 5%,transparent)}
.cam-jour-alerte{border-left-color:var(--warning);background:color-mix(in oklab,var(--warning) 5%,transparent)}
.cam-plus{display:flex;margin:8px auto 2px}
.dh-chevron{transition:transform .18s}
.cam-resume{padding:8px 4px;cursor:pointer}
#cam-docs-attente .cam-doc-cat{height:32px;min-width:125px;max-width:170px;font-size:12px}
#cam-docs-attente .cam-doc-cat-manque{border-color:var(--warning)}
/* popup des cartes de flotte (_fleetPopupHtml : Parc, Suivi GPS, tableau de bord) */
.flotte-pop-modele{margin:-2px 0 4px}
.flotte-pop-code{letter-spacing:.5px}
.flotte-pop-btn{width:100%;margin-top:8px}
.releve-champs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:0 12px}
.releve-resume{padding:8px 12px;border-radius:var(--radius-md);background:var(--muted)}
.pos-age{display:inline-block;padding:3px 8px;border-radius:var(--radius-sm);background:color-mix(in oklab,var(--warning) 8%,transparent);color:var(--warning)}
.pos-age-vieille{background:color-mix(in oklab,var(--warning) 16%,transparent)}

/* page-fournisseurs — carnet fournisseurs, relevés orphelins, fiche */
#fourn-search{flex:1 1 240px;min-width:180px}
#fourn-orphans{padding:16px 20px;border:1.5px dashed var(--border);border-radius:var(--radius-xl);background:var(--card)}
.fourn-nom{min-width:160px}
.fourn-email{display:inline-block;max-width:220px;vertical-align:middle;color:var(--primary)}
.fourn-sep{padding-top:12px;border-top:1px solid var(--border)}
.fourn-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.fourn-stat-val{font-size:18px;line-height:28px}
/* page-ddv — demandes de devis : sélecteur de fournisseurs (puces, suggestions, carnet), lignes, fiche */
#ddv-count{font-weight:500}
#ddv-search{flex:1 1 240px;min-width:180px}
.ddv-choix{padding:12px;border:1px solid var(--input);border-radius:var(--radius-lg)}
#ddv-chips{min-height:28px}
.ddv-puce-x{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:0;border-radius:50%;background:color-mix(in oklab,currentColor 15%,transparent);color:inherit;font-size:12px;line-height:16px}
.ddv-liste{overflow:hidden;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card)}
#ddv-browse{max-height:260px;overflow:auto}
.ddv-item{padding:8px 12px;border-bottom:1px solid var(--border)}
.ddv-item[data-fn]:hover{background:var(--accent)}
.ddv-item-ko{background:var(--muted)}
.ddv-item-creer{border-bottom:0;background:color-mix(in oklab,var(--primary) 5%,transparent)}
.ddv-famille{position:sticky;top:0;padding:4px 12px;background:var(--muted)}
.ddv-coche{display:flex;align-items:center;justify-content:center;flex:none;width:16px;height:16px;border:1px solid var(--input);border-radius:4px;color:var(--primary-foreground)}
.ddv-coche-on{border-color:var(--primary);background:var(--primary)}
.ddv-coche-vide{flex:none;width:16px}
.ddv-ligne-row{display:flex;gap:8px}
.ddv-ligne-row .ddv-ref{flex:0 0 96px;width:auto}
.ddv-ligne-row .ddv-qte{flex:0 0 64px;width:auto}
.ddv-dest{padding:4px 0}
/* page-controles — contrôles & échéances : vue Liste / Calendrier, filtres, calendrier, préventif, pneus, actions */
#ctrl-month-label{min-width:140px}
.ctrl-espace{flex:1}
#ctrl-search,#prev-search,#pneus-search{max-width:260px}
#ctrl-calendar{padding:16px}
.ctrl-cal{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:2px;width:100%;overflow:hidden}
.ctrl-cal-header{padding:8px;text-align:center;font-size:12px;line-height:16px;font-weight:700;color:var(--muted-foreground);text-transform:uppercase}
.ctrl-cal-header.weekend{opacity:.6}
.ctrl-cal-day{min-height:80px;padding:6px 8px;overflow:hidden;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--card);font-size:12px;line-height:16px;transition:border-color .2s,box-shadow .2s}
.ctrl-cal-day:hover{border-color:var(--primary);box-shadow:0 0 0 2px color-mix(in oklab,var(--primary) 8%,transparent)}
.ctrl-cal-day.today{border-color:var(--primary);background:var(--accent);box-shadow:inset 0 0 0 1px var(--primary)}
.ctrl-cal-day.weekend{background:var(--muted);opacity:.7}
.ctrl-cal-day.other-month{opacity:.3}
.ctrl-cal-day .day-num{margin-bottom:4px;font-size:13px;font-weight:700}
.ctrl-cal-evt{--tone:var(--primary);margin-bottom:2px;padding:2px 4px;overflow:hidden;border-radius:var(--radius-sm);background:color-mix(in oklab,var(--tone) 12%,transparent);color:var(--tone);font-size:11px;line-height:16px;font-weight:600;white-space:nowrap;text-overflow:ellipsis;transition:transform .15s,box-shadow .15s}
.ctrl-cal-evt:hover{transform:scale(1.02);box-shadow:var(--shadow-xs)}
.ctrl-cal-evt:is(.urgence-expire,.urgence-critique){--tone:var(--destructive)}
.ctrl-cal-evt.urgence-urgent{--tone:var(--warning)}
.ctrl-cal-evt.statut-planifie{--tone:var(--purple)}
.ctrl-cal-evt.statut-fait{--tone:var(--success)}
.ctrl-kpi-attente{min-height:80px;opacity:.4}
.ctrl-sous{font-weight:400}
.ctrl-ligne{padding:6px 0}
.ctrl-ligne-fine{padding:4px 0}
.ctrl-a-droite{margin-left:auto}
.ctrl-ligne-clic{cursor:pointer}
.ctrl-gaz{color:var(--cat-manutention)}
#prev-exp-cbs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px;max-height:220px;overflow-y:auto}
#kpi-detail-body{max-height:60vh;overflow-y:auto}
.ctrl-action{justify-content:flex-start;height:auto;padding:12px;text-align:left}
.ctrl-action-ok:hover{border-color:var(--success);background:color-mix(in oklab,var(--success) 12%,transparent)}
.ctrl-action-primaire:hover{border-color:var(--primary);background:var(--accent)}
.ctrl-action-danger:hover{border-color:var(--destructive);background:color-mix(in oklab,var(--destructive) 12%,transparent)}
/* ge-202 lot 1 : sous 768 px la rangée Liste · Calendrier · mois · statut passe à la ligne, filtres deux par deux */
@media (max-width:768px){.ctrl-toolbar{flex-wrap:wrap}.ctrl-espace{display:none}#ctrl-month-label{flex:1;min-width:0}.ctrl-toolbar>select{flex:1 1 100%}:is(#ctrl-search,#prev-search,#pneus-search){flex:1 1 100%;max-width:none}.ctrl-filters .filter-select{flex:1 1 calc(50% - 6px)}.ctrl-cal{gap:1px}.ctrl-cal-day{min-height:60px;padding:4px}}
@media (max-width:600px){.ctrl-cal-day{min-width:44px;min-height:50px}.ctrl-cal-evt{padding:1px 2px;font-size:10px}}
.hayon-note-presta{padding:10px 14px;border-left:3px solid var(--border);border-radius:0 var(--radius-md) var(--radius-md) 0;background:var(--background)}

/* page-controle — Suivi GPS (cockpit exploitation, ex-<style> local d'index.html) : scène immersive (carte plein cadre,
   tout flotte dessus — spec du système §4.5), panneaux et pilules flottants (couche 600 de l'échelle), prises de service,
   mode expl-solo. Cibles de 44 px sous 600 px gardées (spec lot 5 §12.2). */
/* Layout immersif (maquette option C) : carte plein cadre, tout le reste flotte dessus */
/* isolation (polish du 18/10) : les calques du cockpit (600) restent DANS la scène — le menu des notifications de la barre du haut
   (50) passait dessous. Même règle que le bandeau du tableau de bord. */
#page-controle .ctl-stage{position:relative;height:calc(100vh - 140px);height:calc(100dvh - 140px);min-height:480px;border-radius:14px;overflow:hidden;border:1px solid var(--border);box-shadow:0 1px 3px rgba(30,58,123,.05);isolation:isolate}
#app.expl-solo #page-controle.active{display:flex;flex-direction:column;flex:1;min-height:0}
#app.expl-solo #page-controle .ctl-stage{height:auto;flex:1;min-height:0;border-radius:0;border:0}
#page-controle #ctl-map{position:absolute;inset:0;z-index:0}
/* Compteurs en pastille flottante (maquette : floatbar) */
#page-controle .ctl-floatbar{position:absolute;top:12px;left:50%;transform:translateX(-50%);z-index:600;display:flex;flex-wrap:wrap;justify-content:center;max-width:calc(100% - 24px);background:var(--card);border:1px solid var(--border);border-radius:99px;padding:6px 8px;box-shadow:0 12px 40px -8px rgba(16,27,45,.45)}
#page-controle .fstat{display:flex;align-items:center;gap:7px;padding:3px 12px;font-size:12px;font-weight:600;color:var(--muted-foreground);white-space:nowrap}
#page-controle .fstat+.fstat{border-left:1px solid var(--border)}
#page-controle .fstat .n{font-variant-numeric:tabular-nums;font-weight:700;font-size:14px}
/* Panneau flottant groupé Flotte live / À renseigner, repliable */
/* bottom:108px : laisse la place au groupe d'actions remonté (cf .ctl-actions) */
#page-controle .ctl-floatpanel{position:absolute;top:64px;right:12px;bottom:108px;width:min(315px,calc(100% - 24px));z-index:600;background:var(--card);border:1px solid var(--border);border-radius:14px;box-shadow:0 12px 40px -8px rgba(16,27,45,.45);display:flex;flex-direction:column;overflow:hidden}
#page-controle .ctl-floatpanel.folded{bottom:auto}
#page-controle .ctl-floatpanel.folded .ctl-search-wrap,#page-controle .ctl-floatpanel.folded .ctl-body{display:none!important}
/* Onglets Flotte live / À renseigner : la pilule .tabs du lot 3, pleine largeur du panneau */
/* Tête du panneau (polish du 18/10) : onglets et bouton de repli côte à côte. La barre (.tabs-full : width:100 %) gardait sa marge
   de 8 px et dépassait le panneau (overflow:hidden) de 16 px : rognée à droite, chevron collé au bord. */
#page-controle .ctl-panel-tete{display:flex;align-items:center;gap:4px;margin:8px}
#page-controle .ctl-tabs.tabs{display:flex;flex:1;width:auto;min-width:0;margin:0}
#page-controle .ctl-tab.tab{flex:1;min-height:0;padding:2px 6px;font-size:12px;line-height:16px;font-weight:500;color:var(--foreground);background:transparent;box-shadow:none;white-space:nowrap}
#page-controle .ctl-tab.tab.on,#page-controle .ctl-tab.tab[aria-selected="true"]{background:var(--background);box-shadow:var(--shadow-sm)}
#page-controle .ctl-fold{border:0;border-radius:var(--radius-md);background:transparent;color:var(--muted-foreground);width:28px;height:28px;padding:0;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0}
#page-controle .ctl-fold:hover{color:var(--primary);background:var(--muted)}
#page-controle .ctl-fold svg{transition:transform .2s}
#page-controle .ctl-floatpanel.folded .ctl-fold svg{transform:rotate(180deg)}
#page-controle .ctl-search-wrap{padding:9px 10px;border-bottom:1px solid var(--border)}
#page-controle .ctl-body{overflow-y:auto;padding:8px;flex:1;min-height:0}
/* Barre flottante de filtres par type */
#page-controle .ctl-filterrow{position:absolute;bottom:12px;left:50%;transform:translateX(-50%);z-index:600}
#page-controle .ctl-typebar{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;min-width:0;background:var(--card);border:1px solid var(--border);border-radius:99px;padding:5px 6px;box-shadow:0 12px 40px -8px rgba(16,27,45,.45)}
#page-controle .tchip{border:0;background:transparent;color:var(--foreground);font-weight:600;font-size:12px;padding:6px 13px;border-radius:99px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}
#page-controle .tchip:hover{color:var(--primary)}
#page-controle .tchip.on{background:var(--primary);color:#fff;font-weight:700}
/* Bouton Prises de service flottant */
#page-controle .ctl-ps{position:absolute;right:12px;bottom:36px;z-index:600;display:inline-flex;align-items:center;gap:7px;background:var(--cyan);border:1px solid var(--cyan);color:#fff;font-weight:700;font-size:12px;padding:8px 14px;border-radius:99px;cursor:pointer;box-shadow:0 12px 40px -8px rgba(16,27,45,.5);transition:filter .15s}
#page-controle .ctl-ps:hover{filter:brightness(1.06)}
/* Groupe d'actions exploitation : le conteneur porte le positionnement, les
   boutons redeviennent statiques (sinon ils s'empilent au même endroit). */
/* bottom:60px (et pas 36 comme l'ancien bouton seul) : à 3 boutons le groupe
   fait ~450px et recouvrait la barre de filtres centrée sur les écrans
   ≤1200px. On passe au-dessus d'elle ; le panneau remonte d'autant. */
/* Même emprise que le panneau « Flotte live » (right/width identiques) et
   contenu centré : les boutons restent alignés sous lui quelle que soit
   leur largeur, sans décalage en dur à recalculer. */
#page-controle .ctl-actions{position:absolute;right:12px;bottom:60px;z-index:600;width:min(315px,calc(100% - 24px));display:flex;flex-wrap:wrap;justify-content:center;gap:7px}
#page-controle .ctl-actions .ctl-act{position:static;right:auto;bottom:auto}
/* Raccourci Claude Desktop (connecteur ELD de Claude Team), coin bas gauche — demande 2026-10-06. Forme de
   référence `.ctl-ps` (pilule, ombre, hauteur 34 px), en blanc : c'est un raccourci, pas une action d'exploitation.
   Position selon la place, toutes mesurées le 06/10 (Docker, libellé « Claude × ELD » = 126 px) :
   - cockpit plein écran (expl-solo) ≥ 1350 px : sur la ligne de « Coter une course » (bottom:15px = son bas). Le bloc
     « Coter une course / Activité chauffeur » commence à 158 px du bord à 1366 et recule d'1 px pour 2 px d'écran en
     moins ; le bouton finit à 138 px, plus 12 px d'écart ;
   - sinon (plus étroit, ou menu latéral admin) : un cran au-dessus, à hauteur du groupe d'actions de droite (60 px) ;
   - ≤ 1100 px : ce bloc s'empile sur deux lignes et monte à ~70 px du bas (1024 : 698–774 pour 768) → 84 px ;
   - ≤ 900 px (tablette, téléphone) : masqué. `claude://` n'est documenté que pour Claude Desktop (Windows, macOS,
     Linux), et la barre de filtres y passe elle aussi sur deux lignes (chevauchement à 800 px). */
#page-controle .ctl-claude-btn{position:absolute;left:12px;bottom:60px;z-index:600;display:inline-flex;align-items:center;gap:7px;background:var(--card);border:1px solid var(--border);color:var(--foreground);font-weight:700;font-size:12px;padding:8px 14px;border-radius:99px;text-decoration:none;white-space:nowrap;box-shadow:0 12px 40px -8px rgba(16,27,45,.5);transition:border-color .15s,color .15s}
#page-controle .ctl-claude-btn:hover{border-color:var(--claude);color:var(--claude)}
#page-controle .ctl-claude-btn svg{color:var(--claude);flex-shrink:0}
@media(min-width:1350px){ #app.expl-solo #page-controle .ctl-claude-btn{bottom:15px} }
@media(max-width:1100px){ #page-controle .ctl-claude-btn{bottom:84px} }
@media(max-width:900px){ #page-controle .ctl-claude-btn{display:none} }
/* « Tous les OR » est secondaire face à « Prises de service » (cyan plein) */
/* Style secondaire du groupe d'actions : attaché à la PLACE, pas au bouton — il
   habille celui qui occupe le premier rang, aux côtés de « Prises de service »
   qui reste l'action principale en bleu plein. */
/* Le bloc des actions de gauche prend le positionnement qui etait sur `.ctl-tachy-btn` : accroche
   a gauche du groupe de filtres, centre verticalement. Les deux boutons redeviennent de simples
   enfants en flux, cote a cote. `flex-wrap` pour qu'ils s'empilent plutot que de sortir de l'ecran
   quand la place manque. */
/* `flex-wrap:nowrap` et non wrap : ancre par sa DROITE a `calc(100% + 8px)` sans `left` ni `width`,
   le bloc calcule une largeur disponible NEGATIVE (403 px de conteneur moins 411 px de decalage),
   se rabat sur sa largeur minimale et empile les deux boutons. En nowrap il deborde vers la gauche,
   ce qui est exactement l'effet voulu. Sous 1100 px la place manque pour de bon : on les empile
   alors volontairement, plutot que de les laisser sortir de l'ecran. */
#page-controle .ctl-leftactions{position:absolute;right:calc(100% + 8px);top:50%;transform:translateY(-50%);
  display:flex;align-items:center;gap:8px;flex-wrap:nowrap;justify-content:flex-end}
@media (max-width:1100px){ #page-controle .ctl-leftactions{flex-wrap:wrap} }
#page-controle .ctl-leftactions .ctl-tachy-btn{position:static;transform:none;right:auto;top:auto}

/* Les trois commandes de carte — Plan/Satellite, Trafic, Immat — flottent sur la meme carte que les
   boutons d'action mais avaient trois formes differentes : rayons 6 et 9 px, hauteurs 22, 30 et 34,
   ombres inegales. Elles prennent la pilule, l'ombre portee ET la hauteur de `.ctl-ps`, qui est la
   forme de reference de tout ce qui flotte ici (demande Valentin, 19/09). La HAUTEUR, elle, reste
   celle d'origine (30 px) : arbitrage de Valentin, troisieme passe — la reference de ce coin est
   Plan/Satellite, pas les boutons d'action de la barre du bas. Le mobilier de vue se tient plus
   discret que les actions, c'est voulu. La couleur non plus ne bouge pas : ce sont des commandes
   de vue, et le fond clair les en distingue.
   Les trois sont nommees ensemble exprès : le 19/09 Trafic avait ete oublie de cette regle parce
   qu'il n'existe pas en local — `addTrafficOverlay()` ne cree le bouton que si `TOMTOM_KEY` est
   renseignee, et elle est vide dans `docker/test.env`. Une commande absente de l'ecran de test
   reste une commande de la prod. */
#page-controle .map-view-btn,
#page-controle .map-traffic-btn,
#page-controle .map-base-switch{border-radius:99px;box-shadow:0 12px 40px -8px rgba(16,27,45,.5)}
#page-controle .map-base-switch{padding:3px;overflow:hidden}
#page-controle .map-base-switch button{border-radius:99px}
/* Trafic et Immat sont le meme objet — une bascule d'affichage avec son temoin — et se lisent
   en colonne. Chacun etant dimensionne par son texte (85 et 88,7 px), leurs bords droits ne
   tombaient pas au meme endroit et les deux pastilles flottaient chacune a sa position. Largeur
   commune et temoin cale a droite : la colonne a un bord net (demande Valentin, 19/09). */
#page-controle .map-traffic-btn,
#page-controle .map-view-btn{min-width:92px}
#page-controle .map-traffic-btn .tdot,
#page-controle .map-view-btn .tdot{margin-left:auto}
/* La Legende est un BOUTON quand elle est repliee et un PANNEAU quand elle est ouverte : pilule
   dans le premier cas comme les autres commandes flottantes, rayon du `.ctl-floatpanel` (14 px)
   dans le second — une pilule sur une liste depliee n'aurait aucun sens. Selecteur en `.folded`
   (0-3-0) : la regle d'origine avait la meme specificite et arrivait
   PLUS LOIN dans la feuille, donc elle gagnait a l'ordre. */
#page-controle .ctl-actions #ctl-trame-btn{background:var(--card);border-color:var(--border);color:var(--primary)}
/* Coter porte desormais la classe de son voisin `.ctl-tachy-btn` : meme forme, meme taille, et
   la couleur primaire deja dedans. C'est l'ancienne classe `.ctl-ps` qui posait probleme — elle impose
   `position:absolute`, et `.ctl-act` ne la battait pas (meme specificite, ordre defavorable), si
   bien que le bouton refusait d'entrer en flux dans la barre du bas. */
#page-controle .ctl-actions #ctl-trame-btn:hover{background:var(--muted);filter:none}
#page-controle .ctl-tachy-btn{position:absolute;right:calc(100% + 8px);top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;gap:7px;background:var(--primary);border:1px solid var(--primary);color:#fff;font-weight:700;font-size:12px;padding:8px 14px;border-radius:99px;cursor:pointer;box-shadow:0 12px 40px -8px rgba(16,27,45,.5);transition:filter .15s;white-space:nowrap}
#page-controle .ctl-tachy-btn:hover{filter:brightness(1.08)}
/* Jumeau DROIT de .ctl-tachy-btn : meme habillage, ancre de l'autre cote de la barre
   de types (left au lieu de right). Meme rang de couche (600 porte par .ctl-filterrow). */
#page-controle .ctl-right-btn{position:absolute;left:calc(100% + 8px);top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;gap:7px;background:var(--primary);border:1px solid var(--primary);color:#fff;font-weight:700;font-size:12px;padding:8px 14px;border-radius:99px;cursor:pointer;box-shadow:0 12px 40px -8px rgba(16,27,45,.5);transition:filter .15s;white-space:nowrap}
#page-controle .ctl-right-btn:hover{filter:brightness(1.08)}
#page-controle .ctl-row{display:flex;align-items:center;gap:10px;padding:8px 9px;border-radius:9px;cursor:pointer}
#page-controle .ctl-row:hover{background:var(--muted)}
#page-controle .ctl-row .sd{width:11px;height:11px;border-radius:50%;flex-shrink:0;box-sizing:border-box}
#page-controle .ctl-row .fp{font-variant-numeric:tabular-nums;font-weight:700;font-size:13px;letter-spacing:-.01em}
/* Pastille « Sur parc » de la liste Flotte live. Elle vit sur la ligne de la PLAQUE, là où
   l'œil se pose en balayant : c'est la question qu'on pose à cette liste (« lequel est au
   parc ? »), pas une nuance à aller chercher en deuxième ligne. Vert plein, texte blanc —
   le libellé porte l'information, la couleur ne fait que la renforcer. */
/* « Sur parc » au second plan (Valentin, 18/10) : teinte légère comme une étiquette de statut, plus de blanc sur plein en gras, qui
   prenait le pas sur la plaque. */
#page-controle .ctl-row .fp-parc.vieux{--tone:var(--warning)} /* [ge-145] sur parc, position > 60 min */
#page-controle .ctl-row .fp-parc{--tone:var(--success);display:inline-block;margin-left:6px;padding:0 6px;border-radius:99px;background:color-mix(in oklab,var(--tone) 12%,transparent);color:var(--tone);font-size:10px;line-height:16px;font-weight:500;vertical-align:1px}
#page-controle .ctl-row .fm{font-size:12px;color:var(--muted-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#page-controle .ctl-row .fr{margin-left:auto;text-align:right;font-variant-numeric:tabular-nums;font-size:11px;color:var(--muted-foreground);white-space:nowrap;line-height:1.35;flex-shrink:0}
#page-controle .ctl-row .fr .sp{color:var(--success);font-weight:700}
/* [ge-104 b] Hors carte : sous la carte, replié par défaut, masqué si vide (attribut hidden) */
#page-controle .ctl-offmap{margin-top:10px;border:1px solid var(--border);border-radius:12px;background:var(--card);font-size:13px;flex-shrink:0}
#page-controle .ctl-offmap summary{cursor:pointer;padding:10px 14px;font-weight:700;color:var(--foreground);list-style:none;display:flex;align-items:center;gap:8px;user-select:none}
#page-controle .ctl-offmap summary::-webkit-details-marker{display:none}
#page-controle .ctl-offmap summary::before{content:'';width:0;height:0;border:5px solid transparent;border-left-color:var(--muted-foreground);border-right:0;transition:transform .15s}
#page-controle .ctl-offmap[open] summary::before{transform:rotate(90deg)}
#page-controle .ctl-offmap-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:2px 14px;padding:0 12px 10px}
#page-controle .ctl-offrow{display:flex;align-items:center;gap:8px;padding:5px 4px;min-width:0}
#page-controle .ctl-offrow .fp{font-variant-numeric:tabular-nums;font-weight:700;font-size:12px;white-space:nowrap}
#page-controle .ctl-offrow .fm{font-size:11px;color:var(--muted-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}
#page-controle .ctl-offrow .tag{font-size:10px;font-weight:800;padding:1px 7px;border-radius:99px;white-space:nowrap;flex-shrink:0}
#page-controle .ctl-offrow .tag-hs{background:color-mix(in oklab,var(--destructive) 12%,transparent);color:var(--destructive)}
#page-controle .ctl-offrow .tag-alive{background:color-mix(in oklab,var(--success) 15%,transparent);color:var(--success)}
#page-controle .ctl-offrow .tag-muet{background:color-mix(in oklab,var(--warning) 12%,transparent);color:var(--warning)}
#page-controle .ctl-dcard{border:1px solid var(--border);border-radius:11px;padding:10px 11px;margin-bottom:8px;background:var(--muted);transition:border-color .15s}
#page-controle .ctl-dcard:hover{border-color:var(--primary)}
#page-controle .ctl-dcard .dp{font-variant-numeric:tabular-nums;font-weight:700;font-size:13px}
#page-controle .ctl-dcard .dn{font-variant-numeric:tabular-nums;font-size:11px;color:var(--muted-foreground)}
/* Légende = mode d'emploi ET filtre : chaque ligne isole sa famille ou son état sur la
   carte comme dans la liste. Ancrée en bas à gauche — le haut-gauche est pris par le zoom,
   le switch Plan/Satellite et le bouton Trafic. */
/* Repliée par défaut : dépliée en permanence, la légende encombre la carte pour rien. */
/* Filtre actif + légende repliée = la carte ment sans le dire : le badge le rattrape. */
.ps-step{display:inline-flex;align-items:center;border:1px solid var(--border);border-radius:8px;overflow:hidden;background:var(--card);vertical-align:middle}
.ps-step button{border:0;background:transparent;width:28px;height:30px;font-size:16px;cursor:pointer;color:var(--muted-foreground);line-height:1}
.ps-step button:hover{background:var(--muted)}
.ps-step b{min-width:64px;text-align:center;font-size:13px;border-left:1px solid var(--border);border-right:1px solid var(--border);line-height:30px}
.ps-step input.ps-htime{min-width:74px;text-align:center;font-size:12px;border:0;border-left:1px solid var(--border);border-right:1px solid var(--border);background:transparent;color:var(--success);font-weight:700;line-height:30px;padding:0 4px;font-family:inherit}
.ps-drow{display:flex;align-items:center;gap:8px;padding:8px 10px;border:1px solid var(--border);border-radius:10px;background:var(--muted);flex-wrap:wrap}
/* Grisage par ÉLÉMENTS et non par la ligne : une opacité posée sur .ps-drow serait
   héritée par le badge .ps-sent sans échappatoire possible (l'opacité d'un parent ne
   s'annule pas depuis un enfant). Le badge « SMS envoyé » doit rester pleinement lisible. */
.ps-drow.repos > :not(div),.ps-drow.repos > div > :not(.ps-sent){opacity:.65}
.ps-drow.repos .ps-step.ps-hour{visibility:hidden}
.ps-drow.ps-off > :not(div),.ps-drow.ps-off > div > :not(.ps-sent){opacity:.45}
.ps-drow.ps-off .ps-when{visibility:hidden}
.ps-sent{display:inline-block;padding:1px 7px;border-radius:99px;font-size:11px;font-weight:700;background:color-mix(in oklab,var(--success) 14%,transparent);color:var(--success);margin-left:6px;white-space:nowrap;vertical-align:middle}
.ps-info-row{flex-basis:100%;display:flex;gap:6px;align-items:center}
.ps-info-row .ps-info{flex:1;min-width:120px;font-size:12px;padding:5px 8px;border:1px solid var(--border);border-radius:7px;background:var(--card);color:var(--foreground)}
.ps-credit{font-size:11px;color:var(--muted-foreground);white-space:nowrap}
.ps-credit.over{color:var(--destructive);font-weight:700}
.ps-hist-btn{display:inline-flex;align-items:center;gap:5px;min-height:30px;padding:0 11px;font-size:12px;font-weight:700;border:1px solid var(--cyan);color:var(--cyan);background:color-mix(in oklab,var(--cyan) 7%,transparent);border-radius:8px;cursor:pointer;transition:background .15s}
.ps-hist-btn:hover{background:color-mix(in oklab,var(--cyan) 16%,transparent)}
.psh-row{display:flex;align-items:center;gap:10px;padding:8px 11px;border:1px solid var(--border);border-radius:10px;background:var(--muted);cursor:pointer}
.psh-row:hover{background:var(--card)}
.psh-row.open{border-color:var(--cyan);border-radius:10px 10px 0 0}
.psh-det{border:1px solid var(--cyan);border-top:0;border-radius:0 0 10px 10px;padding:10px 12px 9px;font-size:12px;background:var(--card)}
.ps-seg{display:inline-flex;border:1px solid var(--border);border-radius:8px;overflow:hidden}
.ps-seg button{border:0;background:var(--card);color:var(--muted-foreground);font-weight:700;font-size:12px;padding:7px 11px;cursor:pointer}
.ps-seg button+button{border-left:1px solid var(--border)}
.ps-drow.service .ps-seg .b-svc{background:var(--success);color:#fff}
.ps-drow.repos .ps-seg .b-rep{background:var(--muted-foreground);color:#fff}
@media(max-width:900px){#page-controle .ctl-floatpanel{top:76px;bottom:96px}}
/* Téléphone (incident affichage 2026-07-23) : les pastilles flottantes centrées se
   chevauchaient (compteurs wrappés sous le panneau, bouton PS sur les filtres).
   → bandeau compteurs 4 colonnes pleine largeur en haut, panneau dessous,
   filtres en 1 ligne scrollable en bas, bouton PS au-dessus des filtres. */
@media(max-width:640px){
  #page-controle .ctl-stage{height:calc(100vh - 118px);height:calc(100dvh - 118px);min-height:420px}
  #page-controle .ctl-floatbar{top:8px;left:8px;right:8px;transform:none;max-width:none;border-radius:12px;padding:4px;display:grid;grid-template-columns:repeat(4,1fr)}
  #page-controle .fstat{flex-direction:column;justify-content:center;text-align:center;gap:1px;padding:3px 2px;font-size:10px;line-height:1.15;white-space:normal}
  #page-controle .fstat+.fstat{border-left:0}
  #page-controle .fstat .n{font-size:14px}
  #page-controle .ctl-floatpanel{top:64px;left:8px;right:8px;width:auto;bottom:118px}
  #page-controle .ctl-filterrow{bottom:8px;left:8px;right:8px;transform:none;max-width:none;display:flex;align-items:center;gap:6px}
  #page-controle .ctl-typebar{flex:1;min-width:0;flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;border-radius:12px;scrollbar-width:none}
  #page-controle .ctl-typebar::-webkit-scrollbar{display:none}
  #page-controle .tchip{padding:6px 11px;font-size:12px;flex-shrink:0}
  #page-controle .ctl-ps{right:8px;bottom:54px;padding:7px 12px;font-size:12px}
  #page-controle .ctl-actions{right:8px;bottom:54px;width:calc(100% - 16px)}
  #page-controle .ctl-actions .ctl-act{padding:7px 12px;font-size:12px}
  #page-controle .ctl-tachy-btn{position:static;transform:none;flex-shrink:0;padding:7px 12px;font-size:12px}
  #page-controle .ctl-right-btn{position:static;transform:none;flex-shrink:0;padding:7px 12px;font-size:12px}
}
/* [ge-168] Téléphone (≤ 600 px — un seul point de bascule, pour ne pas livrer la coquille téléphone à une
   tablette en paysage, leçon ge-120 ; rien ne change au-dessus). Mesuré le 26/09 à 390 px : « Coter une
   course » et « Activité chauffeur » hors écran, deux puces sous « Tous les OR », le panneau sur 75 % de la
   carte, Plan/Satellite sous le bandeau des compteurs, 16 cibles sous 44 px.
   La carte est l'écran : compteurs en haut, panneau replié dessous (Controle.load), puis la carte, et en bas
   un dock EN FLUX. Les rangées s'y empilent d'elles-mêmes quel que soit le rôle (boutons masqués), sans
   hauteur en dur à recalculer ; déplié, le panneau descend jusqu'au dock sans le couvrir. */
@media (max-width:600px){
  #page-controle .ctl-stage{display:flex;flex-direction:column;gap:6px;padding:64px 8px 8px}
  #page-controle .ctl-floatpanel{position:relative;top:auto;left:auto;right:auto;bottom:auto;width:auto;order:0;margin-bottom:auto;flex:0 0 auto;min-height:0}
  #page-controle .ctl-floatpanel:not(.folded){flex:1 1 0}
  #page-controle .ctl-tab.tab{min-height:44px}
  #page-controle .ctl-fold{width:44px;min-height:44px}
  #page-controle .ctl-search-wrap .search-input{min-height:44px}
  #page-controle .ctl-actions,#page-controle .ctl-filterrow{position:relative;top:auto;left:auto;right:auto;bottom:auto;transform:none;width:auto;max-width:none;z-index:600}
  #page-controle .ctl-actions{order:1;display:flex;flex-wrap:nowrap;gap:6px}
  #page-controle .ctl-actions .ctl-act{flex:1 1 0;justify-content:center;min-height:44px}
  #page-controle .ctl-filterrow{order:2;display:flex;flex-direction:column;align-items:stretch;gap:6px}
  #page-controle .ctl-right-btn{order:1;justify-content:center;min-height:44px}
  #page-controle .ctl-leftactions{order:2;position:static;transform:none;display:flex;flex-wrap:nowrap;gap:6px}
  #page-controle .ctl-leftactions .ctl-tachy-btn{flex:1 1 0;justify-content:center;min-height:44px}
  #page-controle .ctl-typebar{order:3;flex:0 0 auto;padding:4px}
  #page-controle .tchip{min-height:44px;min-width:44px;padding:6px 12px}
  /* Commandes de carte (Plan/Satellite, Trafic — prod seulement, TOMTOM_KEY vide en local —, Immat) : sous le
     panneau replié, plus sous le bandeau des compteurs. Mention légale OSM en haut à droite, hors du dock. 140 px : le panneau
     replié finit à 132 px depuis ses onglets de 44 px (106 px le laissait couvrir Plan / Satellite — polish du 18/10). */
  #page-controle #ctl-map .leaflet-top{top:140px}
  #page-controle #ctl-map .leaflet-bottom.leaflet-right{top:140px;bottom:auto}
  #page-controle .map-base-switch button,#page-controle .map-view-btn,#page-controle .map-traffic-btn{min-height:44px}
  /* Panneau déplié : il couvre la carte jusqu'au dock — ses commandes, dessous, ne sont plus des cibles. */
  #page-controle .ctl-stage:has(> .ctl-floatpanel:not(.folded)) #ctl-map .leaflet-top,
  #page-controle .ctl-stage:has(> .ctl-floatpanel:not(.folded)) #ctl-map .leaflet-bottom.leaflet-right{visibility:hidden}
  #page-controle .map-base-switch{height:auto} /* 30 px fixes + overflow:hidden : les boutons de 44 px en débordaient */
  #page-controle .map-base-switch button{min-width:56px}
  /* Fenêtre tachy ou historique ouverte : elle couvre le bas de l'écran, le dock dessous n'est plus touchable. */
  body:has(#tacho-window.open) #page-controle .ctl-filterrow,body:has(#tacho-window.open) #page-controle .ctl-actions,
  body:has(#vh-window.open) #page-controle .ctl-filterrow,body:has(#vh-window.open) #page-controle .ctl-actions{visibility:hidden}
}
/* Mode solo exploitation : l'app EST la tour de contrôle (pas de sidebar/onglets) */
#app.expl-solo .sidebar,#app.expl-solo .sidebar-overlay,#app.expl-solo .btn-sidebar,#app.expl-solo .topbar-sep{display:none!important}
#app.expl-solo .top-bar button[aria-label="Notifications"]{display:none!important}
#app.expl-solo #topbar-logout{display:inline-flex!important}
#app.expl-solo .main-wrap{margin-left:0}
#app.expl-solo .content{max-width:none;padding:0;display:flex;flex-direction:column}
#app.expl-solo #page-title{font-weight:700;font-size:18px;color:var(--primary);display:inline-flex;align-items:center;gap:8px;letter-spacing:0;text-transform:none}
#app.expl-solo #page-title .s{color:var(--muted-foreground);font-weight:400}
/* Le cockpit est plein cadre (padding 0 sur .content) ; les autres pages
   atteignables en solo (ex. « Tous les OR ») héritaient de ce 0 et se
   retrouvaient collées aux bords. On leur rend une gouttière. */
#app.expl-solo .content > .page:not(#page-controle){padding:10px 22px 26px}
/* Titre en double : la top-bar affiche déjà le nom de la page en solo. */
#app.expl-solo .content > .page:not(#page-controle) .section-header .section-title{display:none}
/* Le titre masqué, le bandeau se réduit à une rangée de boutons : les 28px
   de marge dimensionnés pour un titre+sous-titre creusent alors un vide
   avant les onglets. On resserre en solo uniquement (2026-07-29). */
#app.expl-solo .content > .page:not(#page-controle) .section-header{margin-bottom:12px}
/* tracé du parcours (Trace) : barre de lecture au-dessus des filtres du cockpit */
/* bottom:96px = juste au-dessus du bouton « Prises de service » (qui culmine à 85px) et de
   la barre de filtres par type — mesuré, pas estimé : à 74px la barre les recouvrait. */
#trace-bar{position:absolute;left:50%;transform:translateX(-50%);bottom:96px;z-index:640;background:var(--card);border:1px solid var(--border);border-radius:12px;box-shadow:0 10px 34px rgba(15,25,55,.26);padding:9px 12px;display:none;min-width:min(520px,94vw);max-width:94vw}
#trace-bar.open{display:block}
#trace-bar .tb-head{display:flex;align-items:center;gap:10px;margin-bottom:7px}
#trace-bar .tb-plate{font-variant-numeric:tabular-nums;font-weight:700;font-size:13px}
#trace-bar .tb-stats{font-size:12px;color:var(--muted-foreground);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#trace-bar .tb-close{background:var(--muted);border:none;width:24px;height:24px;border-radius:6px;cursor:pointer;font-size:14px;line-height:1;flex-shrink:0;color:var(--muted-foreground)}
#trace-bar .tb-close:hover{background:var(--border)}
#trace-bar .tb-releve{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--border);background:#fff;color:var(--primary);border-radius:7px;padding:4px 9px;font-size:12px;font-weight:700;cursor:pointer;flex-shrink:0}
#trace-bar .tb-releve:hover{background:var(--muted)}
#trace-bar .tb-ctl{display:flex;align-items:center;gap:8px}
#trace-bar .tb-btn{border:1px solid var(--border);background:#fff;border-radius:7px;width:30px;height:30px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--primary);flex-shrink:0;padding:0}
#trace-bar .tb-btn:hover{background:var(--muted)}
#trace-bar .tb-btn.play{background:var(--primary);color:#fff;border-color:var(--primary)}
#trace-bar #trace-range{flex:1;accent-color:var(--primary);cursor:pointer;min-width:80px}
#trace-bar .tb-time{font-variant-numeric:tabular-nums;font-size:12px;color:var(--foreground);flex-shrink:0;min-width:44px;text-align:right}
#trace-bar .tb-speed{border:1px solid var(--border);border-radius:7px;background:#fff;font-size:12px;font-weight:700;padding:4px 6px;cursor:pointer;color:var(--muted-foreground);flex-shrink:0}
#trace-bar .tb-msg{font-size:12px;color:var(--warning);margin-top:6px;display:none}
#trace-bar .tb-msg.on{display:block}
@media(max-width:640px){#trace-bar{bottom:88px;padding:8px 10px}#trace-bar .tb-stats{white-space:normal}}
/* Châssis commun aux deux fenêtres flottantes (frise tachy + historique véhicule) :
 sélecteurs groupés plutôt qu'une seconde feuille de style à maintenir en parallèle. */
/* left décalé de la sidebar : à 22px du viewport, la moitié gauche de la fenêtre passait
 SOUS la sidebar (z-index 9999 contre 650) — 228 px masqués sur 460. Même cause que le
 rognage des modales corrigé par aa3094f, que ce fix-là n'avait pas étendu aux fenêtres
 flottantes. Décalage plutôt que surenchère de z-index : une fenêtre non-modale ne doit
 ni passer sous la nav, ni la recouvrir. Le drag écrase left en inline, donc ceci ne
 gouverne que la position d'ouverture. */
#tacho-window,#vh-window{position:fixed;top:96px;left:calc(var(--sidebar-w) + 22px);width:min(460px,92vw);z-index:650;background:var(--card);border:1px solid var(--border);border-radius:12px;box-shadow:0 16px 46px rgba(15,25,55,.34);overflow:hidden;display:none}
/* Décalage : les deux fenêtres sont non-modales et peuvent coexister (comparer une frise et
 un historique a du sens), donc elles ne doivent pas s'ouvrir exactement au même endroit.
 Décalage VERTICAL et non horizontal : à droite (right:22px) la fenêtre recouvrait le
 panneau « Flotte live » du cockpit sur 305 px — mesuré en prod — c'est-à-dire l'outil de
 travail principal de l'exploitant. À gauche, on garde aussi le même comportement que la
 frise sur écran étroit (22px + min(460px,92vw) ne débordent pas). Les 54 px d'écart
 laissent l'entête de la frise visible dessous, donc attrapable à la souris. */
#vh-window{top:150px;max-height:min(70vh,620px);overflow:auto}
#tacho-window.open,#vh-window.open{display:block}
#tacho-window .tw-head,#vh-window .tw-head{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--primary);color:#fff;cursor:grab;user-select:none;touch-action:none}
#tacho-window .tw-head.grabbing,#vh-window .tw-head.grabbing{cursor:grabbing}
#tacho-window .tw-title,#vh-window .tw-title{font-weight:800;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
#tacho-window .tw-sub,#vh-window .tw-sub{font-size:11px;opacity:.85;font-weight:600}
#tacho-window .tw-close,#vh-window .tw-close{background:rgba(255,255,255,.18);border:none;color:#fff;width:26px;height:26px;border-radius:6px;cursor:pointer;font-size:16px;line-height:1;flex-shrink:0}
#tacho-window .tw-close:hover,#vh-window .tw-close:hover{background:rgba(255,255,255,.32)}
#tacho-window .tw-body,#vh-window .tw-body{padding:12px 14px 14px}
/* L'entête reste visible quand l'historique défile : c'est la poignée de déplacement. */
#vh-window .tw-head{position:sticky;top:0;z-index:2}
/* Les 3 contextes sans sidebar (mêmes que les overrides margin-left:0 de .main-wrap) :
 sans eux, le décalage ci-dessus creuserait un trou de la largeur de la sidebar à gauche. */
@media (max-width:1280px){ #tacho-window,#vh-window{left:22px} }
body.is-standalone #tacho-window,body.is-standalone #vh-window{left:22px}
#app.expl-solo #tacho-window,#app.expl-solo #vh-window{left:22px}
.tf-frise{position:relative;height:44px;border-radius:6px;overflow:hidden;background:var(--muted);border:1px solid var(--border)}
.tf-seg{position:absolute;top:0;bottom:0;min-width:1px;cursor:pointer}
.tf-seg.unk{background:repeating-linear-gradient(45deg,var(--border),var(--border) 5px,var(--muted) 5px,var(--muted) 10px)}
.tf-seg:hover{filter:brightness(1.1);outline:2px solid rgba(0,0,0,.3);outline-offset:-2px;z-index:2}
/* Segment épinglé par un clic : contour marqué pour que la couleur cliquée et le texte
 affiché dessous soient reliés sans ambiguïté. */
.tf-seg.sel{outline:2px solid var(--foreground);outline-offset:-1px;z-index:3}
/* Trait « maintenant » sur une journee en cours : la partie a droite est du futur, pas du vide. */
.tf-now{position:absolute;top:-2px;bottom:-2px;width:2px;background:var(--foreground);opacity:.55;z-index:4;pointer-events:none}
.tf-detail{min-height:19px;margin-top:10px;padding-top:9px;border-top:1px solid var(--border);font-size:12px;color:var(--muted-foreground);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
/* L'astuce vit ICI et non dans le bandeau du haut : elle y volait la largeur du badge
 « Actuellement », qui se cassait en deux lignes. Et une zone vide qui n'affichait qu'un
 filet horizontal ressemblait à un élément inachevé. */
.tf-detail:empty::after{content:'Cliquez un segment pour en voir le détail';color:var(--muted-foreground);font-size:12px}
.tf-axis{position:relative;height:15px;margin-top:4px}
.tf-tick{position:absolute;top:0;font-size:10px;color:var(--muted-foreground);transform:translateX(-50%);white-space:nowrap;font-variant-numeric:tabular-nums}
.tf-tick.first{transform:none}
.tf-tick.last{transform:translateX(-100%)}
.tf-legend{display:flex;flex-wrap:wrap;gap:11px;margin-top:12px}
.tf-lg{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--muted-foreground);font-weight:600}
.tf-dot{width:11px;height:11px;border-radius:3px;flex-shrink:0}
#tacho-window .tw-ctl{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border);background:var(--muted)}
#tacho-window .tw-grp{display:inline-flex;border:1px solid var(--border);border-radius:7px;overflow:hidden;background:#fff}
#tacho-window .tw-seg{border:none;background:none;padding:4px 9px;font-size:12px;font-weight:700;cursor:pointer;color:var(--muted-foreground)}
#tacho-window .tw-seg.on{background:var(--primary);color:#fff}
#tacho-window .tw-dwrap{position:relative;flex:1;min-width:140px}
#tacho-window #tw-driver-search{width:100%;padding:5px 9px;border:1px solid var(--border);border-radius:7px;font-size:12px;box-sizing:border-box}
#tacho-window .tw-dd{position:absolute;top:calc(100% + 3px);left:0;right:0;max-height:184px;overflow:auto;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 8px 22px rgba(0,0,0,.18);z-index:5;display:none}
#tacho-window .tw-dd.on{display:block}
#tacho-window .tw-dd div{padding:6px 10px;font-size:12px;cursor:pointer;display:flex;justify-content:space-between;gap:8px}
#tacho-window .tw-dd div:hover{background:var(--muted)}
#tacho-window .tw-datectl{display:inline-flex;align-items:center;gap:4px}
#tacho-window .tw-nav{border:1px solid var(--border);background:#fff;color:var(--primary);width:28px;height:28px;border-radius:7px;cursor:pointer;font-size:16px;line-height:1;font-weight:700;flex-shrink:0}
#tacho-window .tw-nav:hover{background:var(--muted)}
#tacho-window #tw-date{border:1px solid var(--border);border-radius:7px;padding:4px 8px;font-size:12px;color:var(--foreground)}
/* [ge-168] Téléphone (≤ 600 px, même bascule que le cockpit) : pleine largeur, ancrées en bas, sans glisser-déposer
 (au doigt, il se bat avec le défilement — _floatWinDrag s'efface) ; croix et commandes à 44 px. « !important » :
 le glisser-déposer du bureau pose left/top en style en ligne. Hauteur plafonnée : les commandes de carte
 (Plan/Satellite, Trafic, Immat) restent visibles au-dessus. */
@media (max-width:600px){
#tacho-window,#vh-window{left:8px!important;right:8px!important;top:auto!important;bottom:8px;width:auto}
#vh-window{max-height:55vh;max-height:55dvh}
#tacho-window .tw-head,#vh-window .tw-head{cursor:default;touch-action:auto}
#tacho-window .tw-close,#vh-window .tw-close{width:44px;height:44px}
#tacho-window .tw-nav{width:44px;height:44px}
#tacho-window .tw-seg{min-height:44px}
#tacho-window #tw-date,#tacho-window #tw-driver-search{min-height:44px}
/* Liste des chauffeurs DANS le flux : en absolu sous le champ, elle sortait par le bas de l'écran (fenêtre ancrée
   en bas, overflow:hidden) ; ici la fenêtre grandit vers le haut, sous les commandes de carte. */
#tacho-window .tw-dd{position:static;margin-top:4px}
#tacho-window .tw-dd div{min-height:44px;align-items:center}
#vh-window .tw-body button{min-height:44px} /* « voir plus » de l'historique (renderVehicleHistory) */
}
/* [ge-085 phase B] Temps de conduite réglementaires sous la frise (4 lignes + mention) */
.tf-dstat{margin-top:12px;padding-top:10px;border-top:1px solid var(--border)}
.tf-dstat-title{font-size:12px;font-weight:800;color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.03em;margin-bottom:6px}
.tf-dstat-row{display:flex;align-items:center;gap:7px;font-size:12px;padding:3px 0;flex-wrap:wrap}
.tf-dstat-row .lb{color:var(--muted-foreground);font-weight:600;flex:0 0 auto;min-width:150px}
.tf-dstat-row .vl{font-variant-numeric:tabular-nums;color:var(--foreground);font-weight:700;white-space:nowrap}
.tf-dstat-row .vl.warn{color:var(--warning)}
.tf-dstat-row .vl.alert{color:var(--destructive)}
/* Jauge (2026-09-13) : l'oeil lit le remplissage avant le chiffre. Piste neutre, remplissage a la
 couleur du niveau. */
.tf-dstat-row .gg{flex:1 1 40px;height:5px;min-width:34px;border-radius:3px;background:var(--muted);overflow:hidden}
.tf-dstat-row .gg>i{display:block;height:100%;border-radius:3px;background:var(--success)}
.tf-dstat-row .gg.warn>i{background:var(--warning)}
.tf-dstat-row .gg.alert>i{background:var(--destructive)}
.tf-dstat-row .vl.neg{color:var(--destructive)}
/* Ligne sans jauge (l'arret obligatoire) : sa phrase est trop longue pour tenir a cote du libelle.
 Plutot que de la laisser retomber n'importe ou, on lui donne sa propre ligne, alignee sous le
 libelle. Le depassement se lit alors comme une phrase, pas comme un debordement. */
.tf-dstat-row .vl.solo{flex:1 1 100%;padding-left:20px;margin-top:1px;line-height:1.35}
.tf-dstat-note{margin-top:7px;font-size:11px;color:var(--muted-foreground);line-height:1.4}
.tf-dstat-note.stale{color:var(--warning)}
/* cockpit : gabarits du module (lot 5, 13b) — liste flotte, cartes « à renseigner », prises de service, trame */
#ctl-c-rens{color:var(--cyan)}
#page-controle .ctl-row .sd{background:var(--sd)}
#page-controle .ctl-row .sd.sd-muet{border:2.5px solid var(--sd);background:transparent;opacity:.8}
#page-controle .ctl-plein{width:100%}
#page-controle .ctl-vide-ico{align-items:center}
#page-controle .ctl-dcard.ctl-dcard-hayon,#page-controle .ctl-dcard.ctl-dcard-hayon:hover{border-left:3px solid var(--warning)}
.ctl-note{font-style:italic}
#ps-q{flex:1;min-width:160px}
#ps-add-toggle{align-self:flex-start}
#ps-add-form{flex-direction:column;gap:8px;padding:12px;border:1px dashed var(--border);border-radius:var(--radius-md)}
.ps-champ{flex:1;min-width:120px}
.ps-fin{justify-content:flex-end}
#ps-list,#psh-list{display:flex;flex-direction:column;gap:6px;overflow-y:auto}
#ps-list{max-height:42vh}
#psh-list{max-height:52vh}
.ps-aide{padding:8px 12px;border:1px dashed var(--border);border-radius:var(--radius-md)}
.ps-aide-titre{display:inline-flex;align-items:center;gap:4px}
.ps-coche{flex:none}
.ps-nom{flex:1;min-width:110px}
.ps-groupe{padding:6px 2px 0;font-weight:800}
.ps-sep{border-bottom:2px solid var(--border)}
.ps-ligne{padding:1px 0}
.psh-heure{flex-shrink:0}
.psh-texte{white-space:pre-wrap}
.trame-table{width:100%}
.trame-table td{padding:4px 8px;vertical-align:top}
.trame-table .trame-section{background:var(--muted)}
.trame-label{width:36%}
.trame-grille{display:grid;grid-template-columns:minmax(0,1fr);gap:12px}
.trame-grille-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.trame-grille-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.trame-anom{padding:8px 0}
.trame-anom-box{margin:4px 0 12px 24px}
#tacho-window .tw-dd .tw-dd-vide{cursor:default;justify-content:center}
.tf-cur{display:inline-flex;align-items:center;gap:6px}
/* marqueur de flotte en mode « points » (grammaire des marqueurs) : pastille blanche, liseré et point à la couleur de la famille */
.flotte-pin-point{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border:2px solid var(--c);border-radius:var(--radius-sm);background:#fff;color:var(--foreground);font-weight:800;box-shadow:0 2px 7px rgb(0 0 0 / .5)}
.flotte-pin-dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--c)}
.replay-pastille{display:inline-block;width:8px;height:8px;margin-right:6px;border-radius:9999px} /* activité tachy dans la bulle du curseur de relecture */

/* page-tarif — tarification des courses (ex-<style> principal d'index.html, l. ~1710-2121) */
/* ── Tarification : reprise des maquettes HTML de Valentin (maquettes-html-tarification) ──
   Structure, densité et composants repris à l'identique ; SEULE la palette est convertie aux
   tokens du logiciel (le teal de la maquette devient --primary, etc.) — décision de Valentin du 18/09,
   qui prime sur le README des maquettes. Aucune couleur en dur ne subsiste.
   Tout est cadré sous #page-tarif : les classes de la maquette (.card, .field, .btn, .badge,
   .toolbar, .filters…) portent les mêmes noms que celles du logiciel et les écraseraient partout
   ailleurs. Le chrome de la maquette (topbar, nav, brand, user-menu) n'est PAS repris : le
   logiciel a sa sidebar, deux navigations se contrediraient. */
#page-tarif h3{margin-bottom: 0; font-size:14px; line-height: 1.25;}
#page-tarif .subtitle{margin: 0; color: var(--muted-foreground);}
#page-tarif .grid-main{display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 22px; align-items: start;}
/* `minmax(0, 1fr)` et non la piste implicite `auto` : sur un item de grille, `min-width: auto` vaut
   min-content, donc la piste se dimensionne au contenu le plus large et DÉBORDE son conteneur au lieu
   de le suivre. Déclencheur mesuré : le tableau des tronçons est en `white-space: nowrap` (l.1799) —
   dès qu'un itinéraire est calculé, la piste passait à 1024 px dans une colonne de 591, les cinq cartes
   sortaient de 433 px et passaient SOUS la carte Résultat. Visible seulement sidebar ouverte (> 1280 px,
   elle reprend 250 px) : les deux points de bascule ne coïncident pas (grille Tarification : 1050 px).
   Antérieur au polish du 19/09 — reproduit à l'identique sur d85a28f. */
#page-tarif .stack{display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px;}
#page-tarif .card__header{display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 18px 20px 0;}
#page-tarif .card__title{display: flex; align-items: center; gap: 10px;}
#page-tarif .card__body{padding: 18px 20px 20px;}
#page-tarif .card__footer{padding: 0 20px 20px;}
#page-tarif .icon{display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; color: var(--primary); flex: 0 0 auto;}
#page-tarif .icon svg{width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.8;}
#page-tarif .form-grid{display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 18px;}
#page-tarif .form-grid.two{grid-template-columns: repeat(2, minmax(0, 1fr));}
#page-tarif .form-grid.five{grid-template-columns: repeat(5, minmax(0, 1fr));}
/* Les trois mesures (km · conduite · péage) reprennent l'ordre des colonnes du tableau des tronçons
   juste au-dessus : on lit la même triplette deux fois de suite. Classe AUTONOME, sans `.form-row` :
   celle-ci passe à `1fr !important` sous 1280 px (l.1139), ce qui aurait empilé trois nombres de six
   caractères sur trois lignes pleine largeur entre 1280 et 700 px. */
#page-tarif .tc-mesures{display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px;}
/* Casse normale comme la maquette : les règles globales `.field label` imposent
   uppercase + letter-spacing, il faut les neutraliser explicitement (décision Valentin 18/09). */
#page-tarif .input-wrap{position: relative;}
#page-tarif .input-wrap .input-icon{position: absolute; right: 11px; top: 50%; transform: translateY(-50%); color: var(--muted-foreground); pointer-events: none;}
#page-tarif .input-wrap .input-icon svg{width: 17px; height: 17px;}
#page-tarif .route-list{display: grid; gap: 11px;}
/* Lot 4 : cinq colonnes — numéro, libellé de l'étape, lieu, temps de l'arrêt, retrait de la livraison.
   Les deux dernières ont une doublure vide (.route-duree-vide / .route-rm-vide) sur les étapes qui n'en
   portent pas, sinon la grille se décale d'une colonne d'une ligne à l'autre. */
#page-tarif .route-row{display: grid; grid-template-columns: 28px 140px minmax(0, 1fr) 78px 34px; gap: 11px; align-items: center;}
#page-tarif .route-duree{width: 100%; text-align: center;}
#page-tarif .route-rm{background: none; border: none; color: var(--destructive); cursor: pointer; padding: 4px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px;}
#page-tarif .route-rm:hover{background: color-mix(in oklab,var(--destructive) 12%,transparent);}
#page-tarif .route-add{margin-top: 12px;}
#page-tarif .route-number{width: 23px; height: 23px; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; background: var(--primary); color: #fff; font-size: 11px; font-weight: 700;}
/* Le lieu non positionne : pastille CREUSE. Positionne : pleine. Le remplissage est un indice de forme,
   lisible en niveaux de gris, pose sur un element qui existait deja — pas une icone de plus. */
#page-tarif .route-row:not(.est-positionne) .route-number{background: #fff; color: var(--muted-foreground); border: 1.5px solid var(--border);}
#page-tarif .route-label{display: flex; align-items: center; gap: 8px; font-size: 12px;}
#page-tarif .route-label .pin{color: var(--primary); font-size: 16px;}
#page-tarif .route-summary{display: flex; gap: 8px; align-items: center; margin: 16px 0 0; color: var(--muted-foreground); font-size: 12px;}
#page-tarif .route-summary strong{color: var(--foreground);}
#page-tarif .section-label{margin: 13px 0 9px; font-size: 12px; font-weight: 700;}
/* `grid-auto-rows: 1fr` : toutes les rangées prennent la hauteur de la plus haute, sinon une
   rangée où un libellé passe sur deux lignes fait 50 px pendant que la suivante reste à 42. */
/* [ge-177] Choix « Pièces » du tri d'un signalement. Le composant `.choice` de la
   tarification, repris tel quel plutôt que redessiné — même produit, même geste : choisir
   une option parmi peu. Trois écarts assumés, tous dus au contexte : 44 px de haut et non
   42 (la modale sert aussi sur tablette, c'est la cible tactile minimale du projet), deux
   colonnes au lieu de quatre (deux options), et un état d'erreur, que la tarification n'a
   pas besoin d'avoir puisque aucun de ses choix n'est bloquant. */

#page-tarif .choice-grid{display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 10px;}
/* 4 colonnes et non 5 comme la maquette : ses libellés sont courts (« Frigo »), les nôtres
   viennent de la base (« Semi frigo bi-température ») et passaient sur 3 lignes à 5 colonnes. */
#page-tarif .choice-grid.semi{grid-template-columns: repeat(4, minmax(0, 1fr));}
#page-tarif .choice{min-height: 42px; border: 1px solid var(--border); border-radius: 7px; background: #fff; color: var(--foreground); display: inline-flex; align-items: center; justify-content: flex-start; gap: 8px; padding: 9px 13px; font-size: 12px; font-weight: 600;}
#page-tarif .choice:hover{border-color: var(--primary);}
#page-tarif .choice.selected{background: var(--primary); border-color: var(--primary); color: #fff;}
/* Pas de coche sur un choix selectionne (decision Valentin, 19/09). L etat est porte par l inversion
   de luminance — fond bleu fonce, texte blanc — qui se lit AUSSI en niveaux de gris : ce n est donc
   pas « la couleur seule », et l accessibilite est tenue. `aria-pressed` est pose sur chaque bouton
   pour les lecteurs d ecran. C est deja ce que font les pastilles .filter-pill.active du meme ecran,
   qui n ont jamais eu de coche : la coche etait l exception, pas la regle. */
/* L'icône ne se comprime jamais ; c'est le libellé qui prend la place restante et se coupe.
   `inline-flex` et non `inline` : un SVG en flux inline traîne un décalage de ligne de base. */
#page-tarif .choice-ic{flex: 0 0 auto; display: inline-flex; align-items: center; opacity: .7;}
#page-tarif .choice.selected .choice-ic{opacity: 1;}
#page-tarif .choice-lb{min-width: 0; text-align: left; line-height: 1.25;}
#page-tarif .material-footer{display: grid; grid-template-columns: minmax(0, 1fr) 430px; gap: 18px; align-items: end; margin-top: 18px;}
#page-tarif .radio-row{display: flex; gap: 22px; flex-wrap: wrap; align-items: center; min-height: 40px;}
#page-tarif .radio-option{display: inline-flex; gap: 8px; align-items: center; font-size: 12px;}
#page-tarif .duration-grid{display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px;}
#page-tarif .info-line{display: flex; align-items: center; gap: 7px; color: var(--muted-foreground); font-size: 12px; margin-top: 14px;}
/* Mise à disposition (spec 2026-09-25 §6) : la case de l'en-tête, les valeurs en lecture seule, la pastille +1 jour. */
#page-tarif .tc-mode{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;cursor:pointer;white-space:nowrap;color:var(--foreground)}
#page-tarif .tc-mode input{margin:0}
#page-tarif .tc-mode.est-fige{cursor:default;color:var(--muted-foreground)}
#page-tarif .tc-ro{display:block;padding:9px 12px;border-radius:8px;background:var(--muted);color:var(--foreground);font-weight:600;min-height:20px;line-height:20px}
/* justify-self : le .field est une grille, sans ça la pastille s'étire sur toute la largeur du champ. */
#page-tarif .tc-plus1{display:inline-block;justify-self:start;width:max-content;margin-top:4px;font-size:11px;font-weight:600;color:var(--primary);background:var(--muted);border-radius:999px;padding:2px 8px}
#page-tarif .tc-mad-erreur{color:var(--destructive);font-size:13px;margin-top:6px;min-height:1em}
/* Bornee a la hauteur de la fenetre et defilante : sans ca, detail ouvert, son bas passait 104 px sous
   le pli sans moyen d'y acceder, et la molette faisait descendre la colonne de gauche a la place. */
#page-tarif .result-card{position: sticky; top: 84px; max-height: calc(100vh - 104px); overflow-y: auto; overscroll-behavior: contain;}
#page-tarif .result-price{margin-top: 14px; padding-bottom: 16px; border-bottom: 1px solid var(--border);}
#page-tarif .result-price__label{color: var(--foreground); font-weight: 600;}
#page-tarif .result-price__value{margin-top: 2px; color: var(--primary); font-size:40px; line-height: 1.1; font-weight: 800; letter-spacing: -.035em;}
#page-tarif .result-rows{display: grid; gap: 16px; padding: 19px 0; border-bottom: 1px solid var(--border);}
/* [ge-182] `white-space: nowrap` sur toute la valeur poussait la ligne a 499 px dans une carte de
   366 px : « Marge 89,26 € · 19,8 % du prix client · 24,7 % du cout de revient » ne pouvait pas
   revenir a la ligne, et la carte prenait une barre de defilement horizontale (capture du 21/09).
   Le nowrap descend donc au FRAGMENT : un montant ne se coupe plus entre le nombre et son unite,
   mais la valeur se repartit aux separateurs. `margin-left: auto` la garde alignee a droite une
   fois passee sous son libelle — une colonne de montants se lit par la droite. */
#page-tarif .result-row{display: flex; justify-content: space-between; gap: 6px 18px; flex-wrap: wrap;}
#page-tarif .result-row>span{min-width: 0;}
#page-tarif .result-row strong{white-space: normal; text-align: right; margin-left: auto; min-width: 0;}
#page-tarif .result-row strong .nw{white-space: nowrap;}
/* [ge-183] Une info-bulle que rien n'annonce n'est jamais trouvee : soulignement pointille
   et curseur d'aide. Le `title` natif est le pattern du projet (76 usages) et il a le merite
   d'etre lu par les lecteurs d'ecran — mais il ne s'ouvre PAS au toucher, d'ou le rappel
   ci-dessous : sur tablette, les pourcentages se retrouvent dans « Detail du calcul ». */
#page-tarif .result-row strong.a-survoler{text-decoration: underline dotted var(--muted-foreground); text-underline-offset: 3px; cursor: help;}
/* [ge-184] Bulle maison plutot que l'attribut `title` : le natif met pres d'une seconde a
   apparaitre, ce qui donne exactement l'impression que rien ne se passe quand on glisse le
   curseur sur le chiffre (signale par Valentin). Celle-ci s'affiche tout de suite.
   Elle s'ouvre aussi au FOCUS, donc au clavier et au toucher (tabindex sur la valeur) : le
   `title` natif, lui, reste hors de portee sur tablette.
   Placee SOUS la valeur et alignee a droite : la carte est en overflow:auto, une bulle qui
   deborderait serait rognee ou rendrait la barre de defilement horizontale de ge-182.
   z-index 5 : rang local a la carte, il ne rentre pas en concurrence avec l'echelle globale
   des couches flottantes (CLAUDE.md §5.2) — aucune modale ni sidebar ne vit dans ce contexte. */
#page-tarif .result-row{position: relative;}
#page-tarif .bulle{position: absolute; top: calc(100% + 6px); right: 0; z-index: 5;
  border: 1px solid var(--border); background: var(--popover); color: var(--popover-foreground); padding: 16px; border-radius: var(--radius-md);
  font-size:12px; font-weight: 500; line-height: 1.45; max-width: 250px;
  white-space: normal; text-align: left; box-shadow: var(--shadow-md);
  opacity: 0; visibility: hidden; transition: opacity .12s ease; pointer-events: none;}
#page-tarif .result-row strong.a-survoler:hover ~ .bulle,
#page-tarif .result-row strong.a-survoler:focus ~ .bulle{opacity: 1; visibility: visible;}
@media (prefers-reduced-motion: reduce){ #page-tarif .bulle{transition: none;} }
#page-tarif .label-emphasis{font-size: 14px !important;}
#page-tarif .result-badge-wrap{margin: 12px 0 24px;}
#page-tarif .general-grid{grid-template-columns: repeat(4, minmax(0, 1fr));}
/* Prix client SOUS le minimum : rouge. Au-dessus : vert (.success). Sans ce rang, le badge du refus
   sortait dans la couleur par defaut et ne se distinguait pas de celui de l'acceptation. */
#page-tarif .admin-grid{display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 22px; align-items: start;}
#page-tarif .rate-header{display: flex; justify-content: space-between; gap: 18px; align-items: center;}
#page-tarif .week-select{width: 305px; max-width: 100%;}
#page-tarif .rate-list{display: grid; margin-top: 12px;}
#page-tarif .rate-row{display: grid; grid-template-columns: 150px minmax(120px, 1fr) 190px; align-items: center; gap: 18px; padding: 12px 0; border-bottom: 1px solid var(--border);}
#page-tarif .rate-row:last-child{border-bottom: 0;}
#page-tarif .rate-name{display: flex; align-items: center; gap: 12px; font-weight: 700;}
#page-tarif .rate-name .emoji{display: inline-flex; align-items: center; color: var(--primary);}
#page-tarif .rate-input{max-width: 190px; display: flex; gap: 8px; align-items: center; font-weight: 700;}
#page-tarif .rate-input input{text-align: right; font-weight: 700;}
#page-tarif .rate-date{text-align: right; color: var(--muted-foreground); font-size: 12px;}
#page-tarif .rate-actions{display: flex; justify-content: space-between; gap: 16px; align-items: center; padding-top: 12px;}
#page-tarif .rate-actions p{margin: 0; color: var(--muted-foreground); font-size: 12px;}
#page-tarif .activity-list{display: grid;}
#page-tarif .activity{display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; gap: 11px; align-items: start; padding: 14px 0; border-bottom: 1px solid var(--border);}
#page-tarif .activity:last-child{border-bottom: 0;}
#page-tarif .activity__title{font-weight: 700;}
#page-tarif .activity__meta, #page-tarif .activity time{margin-top: 3px; color: var(--muted-foreground); font-size: 12px;}
#page-tarif .toolbar{display: flex; justify-content: space-between; gap: 18px; align-items: center; margin: 18px 0;}
#page-tarif .filters{display: flex; gap: 9px; flex-wrap: wrap;}
#page-tarif .filter-pill{min-height: 36px; border-radius: 999px; border: 1px solid var(--border); background: #fff; padding: 7px 18px; color: var(--foreground); font-weight: 600;}
#page-tarif .filter-pill.active{color: #fff; background: var(--primary); border-color: var(--primary);}
#page-tarif .search-row{display: flex; gap: 12px; min-width: min(470px, 100%);}
#page-tarif .search-row input{min-width: 240px;}
#page-tarif .table-card{overflow: hidden;}
#page-tarif .table-scroll{overflow-x: auto;}
#page-tarif table{width: 100%; border-collapse: collapse; min-width: 980px;}
#page-tarif th, #page-tarif td{text-align: left; padding: 16px 14px; border-bottom: 1px solid var(--border); white-space: nowrap;}
#page-tarif th{background: var(--muted); color: var(--foreground); font-size: 12px;}
#page-tarif td{font-size: 12px;}
#page-tarif tr.selected-row td{background: var(--accent);}
#page-tarif .table-note{padding: 14px 18px; color: var(--muted-foreground); font-size: 12px;}
#page-tarif .action-link{border: 0; background: transparent; color: var(--primary); font-weight: 700; padding: 4px;}
#page-tarif .material-layout{display: grid; grid-template-columns: minmax(0, 1fr) 355px; min-height: calc(100vh - 66px);}
#page-tarif .material-main{min-width: 0; padding: 26px 24px 50px;}
#page-tarif .drawer{background: #fff; border-left: 1px solid var(--border); box-shadow: -8px 0 24px rgba(30,58,123,.07); padding: 23px 22px; position: sticky; top: 66px; height: calc(100vh - 66px); overflow-y: auto;}
#page-tarif .drawer__header{display: flex; justify-content: space-between; align-items: center; margin-bottom: 26px;}
#page-tarif .drawer__header h2{font-size:24px;}
#page-tarif .drawer__identity{display: flex; gap: 12px; margin-bottom: 24px;}
#page-tarif .drawer__identity .emoji{font-size:26px;}
#page-tarif .drawer__actions{display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 30px;}
#page-tarif .close-btn{border: 0; background: transparent; color: var(--foreground); font-size:24px;}
@media (max-width: 1050px){
#page-tarif .grid-main, #page-tarif .admin-grid{grid-template-columns: 1fr;}
#page-tarif .result-card{position: static;}
#page-tarif .material-footer{grid-template-columns: 1fr;}
#page-tarif .choice-grid.semi{grid-template-columns: repeat(3, minmax(0, 1fr));}
#page-tarif .material-layout{grid-template-columns: 1fr;}
#page-tarif .drawer{position: static; height: auto; border: 1px solid var(--border); margin: 0 24px 30px; border-radius: var(--radius);}
}
@media (max-width: 780px){
#page-tarif .form-grid, #page-tarif .form-grid.two, #page-tarif .form-grid.five{grid-template-columns: 1fr;}
/* Lot 4 : entre 700 et 780 px, la grille à 5 colonnes du desktop tient encore ; en dessous, c'est
   le bloc @media 700 px plus bas qui reprend la main. Rien à surcharger ici. */
#page-tarif .choice-grid, #page-tarif .choice-grid.semi{grid-template-columns: repeat(2, minmax(0, 1fr));}
#page-tarif .duration-grid{grid-template-columns: 1fr;}
#page-tarif .result-price__value{font-size:36px;}
#page-tarif .rate-header, #page-tarif .rate-actions{flex-direction: column; align-items: stretch;}
#page-tarif .rate-row{grid-template-columns: 1fr; gap: 7px;}
#page-tarif .rate-input{max-width: none;}
#page-tarif .rate-date{text-align: left;}
#page-tarif .search-row{min-width: 0; flex-direction: column;}
#page-tarif .search-row input{min-width: 0;}
#page-tarif .material-main{padding: 18px 12px 30px;}
#page-tarif .drawer{margin: 0 12px 24px;}
}
/* ── Sans équivalent dans la maquette : autocomplétion d'adresse, bandeaux d'itinéraire,
   corrections motivées, tableau des tronçons, pastilles de l'historique, détail du calcul. ── */
#tarif-pane-cotation .tc-seg{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
#tarif-pane-cotation .tc-seg button{min-height:36px}
/* Le detail du calcul vit dans une carte de 340 px, pas dans un tableau de page. Il faut donc defaire
   trois choses que la regle generale `#page-tarif th, #page-tarif td` lui impose : le `nowrap`, qui
   l'etirait a 980 px soit 661 px HORS de sa carte (mesure le 19/09), et le padding de 16/14 px, qui
   n'a pas de sens sur deux colonnes etroites. `table-layout:fixed` borne ensuite les colonnes. */
/* `min-width:0` est LA ligne qui compte : `#page-tarif table` impose `min-width: 980px` a toutes les
   tables de la page — c'est voulu pour les grandes tables, qui defilent dans un `.table-scroll`.
   Le detail du calcul, lui, vit dans une carte de 340 px : le min-width l'y etirait a 980, soit
   661 px hors de la carte. `max-width:100%` seul n'y pouvait rien, min-width gagne toujours. */
#tarif-pane-cotation .tc-detail{table-layout:fixed;width:100%;max-width:100%;min-width:0;border-collapse:collapse}
#tarif-pane-cotation .tc-detail-sous{font-weight:400}
#tarif-pane-cotation .tc-detail td{padding:4px 0;border-bottom:1px solid var(--border);vertical-align:top;white-space:normal;overflow-wrap:anywhere}
#tarif-pane-cotation .tc-detail td:last-child{width:34%;text-align:right;white-space:nowrap}
/* Le mot « positionnee » est retire (19/09) : la pastille numerotee passe de creuse a pleine et le champ
   affiche l'adresse normalisee — deux indices, le mot faisait le troisieme. Le span reste, vide, comme
   ancre du `renderPosition()` et porteur de l'aria-label pour les lecteurs d'ecran. */
#tarif-pane-cotation .tc-pos{display:none}
/* boîte .menu du composant (lot 5, D18 : sans uiMenu*, le champ garde le focus) ; ici sa place et sa hauteur seulement */
#tarif-pane-cotation .tc-sugg{left:0;right:0;top:100%;z-index:20;max-height:calc(5 * 48px);overflow:auto}
#tarif-pane-cotation .tc-sugg-item{flex-direction:column;align-items:flex-start;gap:0;min-height:44px}
#tarif-pane-cotation .tc-sugg-item.sel{background:var(--accent);color:var(--accent-foreground)}
#tarif-pane-cotation .tc-sugg-type{color:var(--muted-foreground);font-size:12px}
/* ---- Colonne d'actions figee a droite (piste C, 19/09) -------------------------------------
   Le tableau Materiel fait 1337 px pour 957 visibles : pour atteindre le bouton d'une ligne il
   fallait descendre chercher la barre de defilement tout en bas, glisser, et on perdait de vue
   la ligne visee. La derniere colonne reste desormais collee au bord droit pendant que le reste
   defile. Le fond est OPAQUE et l'ombre portee a gauche : sans eux le contenu qui defile passe
   visiblement dessous. Scope `.table-scroll` : le tableau du detail de cotation n'en est pas un
   et garde son `td:last-child` a lui. */
/* Plus AUCUNE colonne figee : ni Materiel ni Historique n'ont de colonne d'actions, leurs boutons
   vivent dans le panneau lateral. Une colonne collee au bord droit n'aurait plus rien a y tenir
   — ce serait « Assurance / an » ou « Par » qui s'y retrouverait, sans raison. */
#page-tarif .table-scroll table tbody tr{cursor:pointer}
/* Le tableau Materiel doit TENIR dans la page, sans defilement horizontal (demande Valentin, 19/09).
   Retirer la colonne d'actions rendait 191 px et laissait 1146 px pour ~1107 visibles : il manquait
   encore 39 px. Le padding generique de 16/14 px — pense pour des tableaux pleine page — est ramene
   a 12/9, ce qui rend 10 px par colonne sur neuf colonnes. `min-width:0` leve le plancher de 980 px
   de `#page-tarif table`, et la colonne du nom peut passer a la ligne : ensemble, le tableau se
   comprime au lieu de deborder quand la fenetre retrecit. */
#tarif-pane-materiel table{min-width:0}
#tarif-pane-materiel th, #tarif-pane-materiel td{padding:12px 9px}
#tarif-pane-materiel td:first-child, #tarif-pane-materiel th:first-child{white-space:normal}
/* Meme traitement pour l'Historique : sans sa colonne d'actions (321 px) la table restait a 1308 px
   pour ~1109 visibles. Padding resserre, plancher de 980 px leve, et les quatre colonnes de TEXTE
   — client, trajet, materiel, auteur — peuvent passer a la ligne. Les codes, dates, montants et
   statuts gardent leur `nowrap` : un numero ou un montant coupe en deux ne se lit plus. */
#tarif-pane-historique table{min-width:0}
#tarif-pane-historique th, #tarif-pane-historique td{padding:12px 9px}
#tarif-pane-historique tbody td:nth-child(3), #tarif-pane-historique tbody td:nth-child(4),
#tarif-pane-historique tbody td:nth-child(5), #tarif-pane-historique tbody td:nth-child(10){white-space:normal}

/* Le bouton de calcul est l'action PRINCIPALE de sa carte : il en a la couleur, et il porte seul
   l'etat bloque — plus de phrase grise a cote. Bloque, son libelle nomme l'etape suivante ; le
   curseur et l'opacite disent qu'il n'est pas cliquable (regle « Disabled States » du skill UX :
   ne jamais confondre desactive et normal). Pleine largeur sous 700 px, ou la cible compte. */
/* Le bouton de retour : icone ET libelle sur une ligne, un peu d'air a droite du titre de section.
   `white-space:nowrap` pour qu'il ne se casse pas en deux a 375 px, ou il tient encore. */
#page-tarif .tarif-retour{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;margin-right:12px}
#tarif-pane-cotation .tc-calcul-btn:disabled{opacity:.55;cursor:not-allowed}
@media (max-width:700px){ #tarif-pane-cotation .tc-calcul-btn{width:100%} }


/* ---- Panneau lateral --------------------------------------------------------------------- */
.tp{position:fixed;top:0;right:0;bottom:0;width:min(384px,75vw);z-index:9998;
  background:var(--background);border-left:1px solid var(--border);box-shadow:var(--shadow-lg);
  display:flex;flex-direction:column;transform:translateX(102%);transition:transform 300ms var(--ease);
  visibility:hidden}
.tp.ouvert{transform:translateX(0);visibility:visible;transition-duration:500ms}
@media (prefers-reduced-motion: reduce){ .tp{transition:none} }
.tp__tete{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
  padding:20px 22px 14px;border-bottom:1px solid var(--border)}
.tp__titre{font-weight:700;font-size:16px;color:var(--foreground)}
.tp__sous{color:var(--muted-foreground);font-size:13px;margin-top:2px}
.tp__fermer{width:36px;height:36px;flex:0 0 36px;border:none;border-radius:10px;background:var(--muted);
  color:var(--muted-foreground);font-size:20px;line-height:1;cursor:pointer}
.tp__fermer:hover{background:var(--border)}
.tp__corps{flex:1;overflow-y:auto;padding:18px 22px}
.tp__pied{padding:14px 22px;border-top:1px solid var(--border);display:flex;gap:8px;flex-wrap:wrap}
.tp__pied:empty{display:none}
/* Une ligne du panneau : libelle a gauche, valeur a droite. `min-width:0` sur la valeur, sinon une
   valeur longue pousse le libelle hors du panneau au lieu de passer a la ligne. */
.tp__l{display:flex;justify-content:space-between;gap:14px;padding:9px 0;border-bottom:1px solid var(--border)}
.tp__l:last-child{border-bottom:0}
.tp__l span{color:var(--muted-foreground);font-size:14px;flex:0 0 auto}
.tp__l strong{text-align:right;min-width:0;overflow-wrap:anywhere;font-size:14px}
.tp__groupe{font-weight:700;font-size:12px;text-transform:uppercase;letter-spacing:.6px;
  color:var(--muted-foreground);margin:18px 0 4px}
.tp__groupe:first-child{margin-top:0}

/* L'entree epinglee du depot : un filet a gauche et un fond tres pale. Elle doit se reperer d'un coup
   d'oeil sans crier plus fort que les suggestions de l'IGN, qui sont la reponse a ce qu'on tape. */
#tarif-pane-cotation .tc-sugg-item.epingle{border-left:3px solid var(--primary);background:var(--accent)}
#tarif-pane-cotation .tc-sugg-item.epingle .tc-sugg-type{color:var(--primary);font-weight:600}
#tarif-pane-cotation .tc-note{color:var(--muted-foreground);font-size:13px}
#tarif-pane-cotation .tc-lieu .tc-pos{display:block;margin-left:0}
/* `min-width:0` : `#page-tarif table` impose un plancher de 980 px, pense pour les grands tableaux
   de la page qui defilent dans un `.table-scroll`. Ce tableau-ci vit dans une carte de ~705 px et
   s'y etirait a 980 : « Conduite » et « Peage TTC » etaient coupees, alors que le peage est
   precisement ce qu'on vient chercher. La colonne des lieux peut passer a la ligne pour absorber
   la difference ; les trois colonnes de chiffres gardent leur `nowrap`. Mesure le 19/09. */
#tarif-pane-cotation .tc-troncons{width:100%;max-width:100%;min-width:0;border-collapse:collapse;font-size:13px}
#tarif-pane-cotation .tc-troncons th,#tarif-pane-cotation .tc-troncons td{padding:4px 6px;border-bottom:1px solid var(--border);text-align:left;white-space:nowrap}
#tarif-pane-cotation .tc-troncons td:first-child,#tarif-pane-cotation .tc-troncons th:first-child{white-space:normal;overflow-wrap:anywhere}
#tarif-pane-cotation .tc-bandeau{border-radius:8px;padding:8px 10px;font-size:14px;margin-top:6px;font-weight:500}
#tarif-pane-cotation .tc-bandeau-orange{background:color-mix(in oklab,var(--warning) 12%,transparent);color:var(--warning)}
#tarif-pane-cotation .tc-bandeau-rouge{background:color-mix(in oklab,var(--destructive) 12%,transparent);color:var(--destructive)}
#tarif-pane-cotation .tc-bandeau-info{background:var(--accent);color:var(--primary)}
#tarif-pane-cotation .tc-bandeau-neutre{background:var(--background);color:var(--muted-foreground);font-weight:400}
#tarif-pane-cotation .tc-repli > summary{cursor:pointer;font-weight:500;list-style:revert}
#tarif-pane-cotation .tc-repli[open] > summary{margin-bottom:6px}
#tarif-pane-cotation .tc-repli{font-weight:400}
/* La maquette n'a pas d'autocomplétion : la liste s'ancre sur le champ de la 3e colonne. */
#page-tarif .route-row .tc-lieu-champ{position:relative;min-width:0}
/* La maquette réserve 140 px au libellé ; le nôtre porte en plus le badge « positionnée »,
   qui passe sous le texte plutôt que de le comprimer sur trois lignes. */
/* Lot 4 : deux colonnes en plus — le temps de l'arrêt et le retrait de la livraison. */
#page-tarif .route-row{grid-template-columns: 28px 158px minmax(0, 1fr) 78px 34px;}
#page-tarif .route-label .tc-pos{display:block;margin-left:0;font-size:11px;line-height:1.2}
/* La maquette a un simple <select> de semaine ; le logiciel a une navigation ‹ › avec statut de publication. */
#page-tarif .rate-nav{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:12px}
#page-tarif .rate-boutons{display:flex;gap:8px;flex-wrap:wrap}
/* L'unité tient sur une ligne, et l'en-tête de carte se replie plutôt que de casser le titre en deux. */
#page-tarif .rate-input > span{white-space:nowrap}
#page-tarif .card__header{flex-wrap:wrap}
#page-tarif .card__header h2{white-space:nowrap}
/* La navigation de semaine porte un libellé long (« Semaine du .. au .. (en cours) ») : sans min-width:0
   elle impose sa largeur à la carte, qui déborde alors de la page en étroit (mesuré 487 px à 390). */
#page-tarif .card__header,#page-tarif .card__body,#page-tarif .rate-nav,#page-tarif .rate-list{min-width:0}
#page-tarif .rate-nav > span{min-width:0;overflow-wrap:anywhere}
@media (max-width:780px){#page-tarif .card__header h2{white-space:normal}}
/* En-tête de l'écran Matériel : la maquette a un .page-header ; le nôtre vit dans un onglet,
   on en reprend la composition (titre + sous-titre à gauche, action à droite) sans son chrome. */
#page-tarif .page-header-tarif{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap;margin-bottom:16px}
#page-tarif .page-header-tarif h2{margin:0;font-size:18px}
#page-tarif .table-card .table-scroll table{width:100%}
/* Lot 4 en étroit : le libellé prend toute la ligne, puis lieu | temps | retrait sur la suivante.
   Sans une déclaration explicite pour CHAQUE enfant, les deux colonnes ajoutées partent en
   placement automatique et s'auto-dimensionnent : le lieu tombe à 45 px et le temps à 195 px. */
/* Sous 700 px, le lieu prend sa PROPRE ligne, sur toute la largeur. Mesuré à 390 px : partagée avec
   la durée (62) et le ⊖ (30) plus 33 px de gouttières, la colonne du lieu tombait à 151 px et coupait
   « Saisir la ville ou le code postal » (~210 px) à « Saisir la ville ou le co ». La grille était juste,
   c'est le nombre de colonnes qui ne tenait pas. Ligne 1 = repère · libellé · durée · ⊖, ligne 2 = le lieu.
   Chaque enfant garde sa colonne ET sa ligne déclarées : sans ça le placement automatique reprend la main. */
@media (max-width:700px){
  #page-tarif .route-row{grid-template-columns:28px minmax(0,1fr) 62px 30px;row-gap:6px}
  #page-tarif .route-number{grid-column:1;grid-row:1}
  #page-tarif .route-label{grid-column:2;grid-row:1}
  #page-tarif .route-duree,#page-tarif .route-duree-vide{grid-column:3;grid-row:1}
  #page-tarif .route-rm,#page-tarif .route-rm-vide{grid-column:4;grid-row:1}
  #page-tarif .route-row .tc-lieu-champ{grid-column:2 / -1;grid-row:2}
  #page-tarif .route-duree{padding-left:4px;padding-right:4px}
  /* Les trois mesures passent en colonne : à 390 px, trois colonnes donnaient 89 px chacune,
     de quoi couper « 527,52 » et le libellé « Temps de conduite (hh:mm) ». */
  #page-tarif .tc-mesures{grid-template-columns:1fr;gap:12px}
}
#page-tarif .route-row .tc-sugg{left:0;right:0}
#tarif-pane-cotation .tc-corr{font-size:13px;color:var(--muted-foreground);margin-top:2px;display:flex;gap:6px;flex-wrap:wrap;align-items:center}
#tarif-pane-cotation .tc-corr:empty{display:none}
#tarif-pane-cotation .tc-corr s{color:var(--destructive)}
#tarif-pane-cotation .tc-corr input{flex:1;min-width:180px;min-height:36px}
.tc-pastille{display:inline-block;font-size:11px;font-weight:600;padding:1px 6px;border-radius:10px;margin-left:4px;vertical-align:middle;background:var(--accent);color:var(--primary)}
.tc-pastille.corrige{background:color-mix(in oklab,var(--warning) 12%,transparent);color:var(--warning)}
/* lot 5 (14b) : ex-styles en ligne des gabarits du module ; .num doit battre les text-align:left de #page-tarif th/td et des tronçons (même spécificité, placée après) */
#page-tarif :is(th,td).num,#tarif-pane-cotation .tc-troncons :is(th,td).num{text-align:right}
#page-tarif .form-row.tc-haut{align-items:start}
#page-tarif .form-row.tc-bas{align-items:end}
#tarif-pane-cotation #tc-coef{margin-top:0}
#tarif-pane-cotation .tc-attente{opacity:.5}
#tarif-pane-historique .th-filtres{display:flex;flex-wrap:wrap;gap:8px;align-items:flex-end}
#tarif-pane-historique .th-filtre-client{flex:1;min-width:160px}
#th-total{margin-left:auto}
#page-tarif .tr-versions{margin:6px 0 0 18px}
#page-tarif .tr-journal{padding:18px}
#tm-cout-jour{padding:8px 0}
/* page-reglages — réglages : cartes de configuration et d'intégrations, matrice des permissions, comptes (lot 5) */
#page-reglages .reg-cartes{display:flex;flex-direction:column;gap:16px}
#page-reglages .reg-grille-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
@media (max-width:768px){#page-reglages .reg-grille-2{grid-template-columns:minmax(0,1fr)}}
#page-reglages .card-desc b{color:var(--foreground)}
#perms-container .perm-statut{position:sticky;top:0;z-index:10;min-height:24px;margin-bottom:8px;padding:8px 0;background:var(--background);text-align:right}
#perms-container .perm-grille{display:grid;grid-template-columns:repeat(var(--n),minmax(0,1fr));gap:12px}
@media (max-width:1280px){#perms-container .perm-grille{grid-template-columns:minmax(0,1fr)}}
#perms-container .perm-role-h{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid var(--border);font-size:14px;font-weight:600}
#perms-container .perm-role-h .avatar{width:24px;height:24px;font-size:12px}
#perms-container .perm-role-corps{padding:12px 16px}
#perms-container .perm-cat{margin:16px 0 8px;font-size:12px;font-weight:600;color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.025em}
#perms-container .perm-cat:first-child{margin-top:0}
#perms-container .perm-groupe{margin:8px 0 4px;font-size:10px;font-weight:600;color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.025em}
#perms-container .perm-groupe.suite{padding-top:8px;border-top:1px dashed var(--border)}
#perms-container .perm-ligne{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 0;font-size:12px}
#perms-container .perm-ligne.est-fige{color:var(--muted-foreground)}
#users-list{display:flex;flex-direction:column;gap:12px}
#users-list .reg-compte{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px}
#users-list .reg-compte-id{display:flex;align-items:center;gap:12px;min-width:0}
#users-list .reg-compte-txt{min-width:0}
#users-list .reg-compte-actions{display:flex;align-items:center;gap:8px}
#users-list .inactive-tag{margin-left:8px}
#users-list .reg-cloche[aria-pressed="true"]{border-color:var(--warning);background:color-mix(in oklab,var(--warning) 12%,transparent);color:var(--warning)}
@media (max-width:768px){#users-list .reg-compte{flex-wrap:wrap;padding:12px 16px}#users-list .reg-compte-actions{width:100%;padding-top:8px;border-top:1px solid var(--border)}#users-list .reg-compte-actions .role-badge{margin-right:auto}}

/* page-users — Personnel : barres d'outils, fiche mécanicien, performance et coaching des chauffeurs (lot 5) */
#users-tab-chauffeurs #btn-chauff-import{margin-left:auto}
#modal-mec-profile .mp-entete{padding-bottom:0;border-bottom:0}
#mec-profile-body{padding-top:0}
#modal-mec-profile .mp-chargement{display:flex;justify-content:center;padding:40px}
#modal-mec-profile .mp-tete{display:flex;align-items:flex-start;gap:20px;margin-bottom:24px;padding:20px 0 24px;border-bottom:1px solid var(--border)}
#modal-mec-profile .mp-avatar{width:72px;height:72px;border-radius:9999px;font-size:24px;box-shadow:var(--shadow-md)}
#modal-mec-profile .mp-nom{margin-bottom:4px;font-size:20px;font-weight:700;color:var(--foreground)}
#modal-mec-profile .mp-point{width:4px;height:4px;border-radius:9999px;background:var(--border)}
#modal-mec-profile .mp-taux{flex-shrink:0}
#modal-mec-profile .mp-taux-val{font-size:20px;font-weight:700;color:var(--foreground)}
#modal-mec-profile .mp-kpis{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-bottom:24px}
#modal-mec-profile .mp-kpi-val{font-size:24px;font-weight:700}
#modal-mec-profile .mp-or{display:flex;align-items:center;gap:14px;padding:12px 14px;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--card);transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
#modal-mec-profile .mp-or:hover{border-color:var(--primary);box-shadow:var(--shadow-sm)}
#modal-mec-profile .mp-or-barre{flex-shrink:0;width:4px;height:36px;border-radius:2px;background:var(--c)}
#modal-mec-profile .mp-or-fleche{flex-shrink:0;opacity:.3}
#users-tab-performance .perf-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
.perf-kpi-val{font-size:26px;font-weight:700}
.perf-kpi-unite{font-weight:400}
#modal-chauffeur-history .coach{padding:14px;border:1px solid color-mix(in oklab,var(--c) 20%,transparent);border-radius:var(--radius-lg);background:color-mix(in oklab,var(--c) 12%,transparent)}
#modal-chauffeur-history .coach-score{font-size:30px;font-weight:700;line-height:1;color:var(--c)}
#modal-chauffeur-history .coach-teinte{color:var(--c)}
#modal-chauffeur-history .coach-compteurs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;min-width:240px}
#modal-chauffeur-history .coach-compteur{padding:6px 10px;border-radius:var(--radius-sm);background:var(--card)}

/* page-sms — Envoi SMS : grille, cartes de contact, crédit, journal, historique, archives (lot 5) */
#page-sms .sms-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:16px;align-items:start}
#page-sms .sms-carte{padding:16px}
#page-sms .sms-colonne{display:flex;flex-direction:column;gap:16px}
#page-sms .sms-pousse{margin-left:auto}
#page-sms .sms-fixe{flex-shrink:0}
#page-sms .sms-leger{font-weight:400}
#page-sms .sms-moyen{font-weight:500}
#page-sms .sms-recherche{flex:1 1 180px;min-width:150px}
#sms-contacts{max-height:60vh;overflow-y:auto}
#sms-contacts .sms-contact{padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--card)}
#sms-contacts .sms-contact.est-choisi{border-color:var(--primary);background:color-mix(in oklab,var(--primary) 4%,var(--card))}
#sms-contacts .sms-contact input[type="checkbox"]{flex-shrink:0;width:18px;height:18px}
#sms-contacts .sms-champ{height:32px;padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card);color:var(--foreground);font:inherit;font-size:12px}
#sms-contacts .sms-champ:focus{outline:none;border-color:var(--ring);box-shadow:var(--focus-ring)}
#sms-contacts .sms-champ-info{flex:1;min-width:110px}
#sms-preview{min-height:44px;white-space:pre-wrap;overflow-wrap:anywhere}
#sms-credit{display:inline-block;padding:3px 10px;border-radius:9999px;background:var(--muted);color:var(--muted-foreground)}
#sms-credit.sms-credit-ko{background:color-mix(in oklab,var(--destructive) 12%,transparent);color:var(--destructive)}
#sms-log{max-height:140px;overflow-y:auto;padding-top:8px;border-top:1px solid var(--border)}
#sms-log .sms-log-ligne{padding:2px 0}
#sms-history{max-height:40vh;overflow-y:auto}
#sms-history .sms-hist-ligne{padding:9px 4px;border-bottom:1px solid var(--border)}
#page-sms .sms-kpis{display:flex;flex-wrap:wrap;gap:12px}
#page-sms .sms-kpi{flex:1 1 140px;padding:14px 16px}
#page-sms .sms-kpi-val{font-size:26px;font-weight:700}
#page-sms .sms-filtre-nom{flex:1 1 140px;min-width:120px}
#page-sms .sms-filtre-tel{flex:1 1 120px;min-width:110px}
#page-sms .sms-date{flex:0 0 auto;width:auto}
#sms-arch-pager{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px;padding:12px 4px}
#modal-sms-hist-detail .sms-detail-grille{display:grid;grid-template-columns:auto minmax(0,1fr);gap:6px 14px;align-items:baseline}
#modal-sms-hist-detail .sms-casse{word-break:break-all}
#modal-sms-hist-detail .sms-texte{white-space:pre-wrap}

/* page-referentiel — référentiel articles : groupes de familles, fiche article, questions, séparation (lot 5) */
#page-referentiel .ref-recherche{flex:1 1 240px;min-width:180px}
#page-referentiel tr.ref-groupe{background:var(--muted)}
#page-referentiel tr.ref-groupe>td{padding:10px 12px}
#page-referentiel .ref-moyen{font-weight:500}
#page-referentiel .ref-leger{font-weight:400}
#page-referentiel .ref-question{display:flex;flex-wrap:wrap;align-items:flex-start;gap:12px;padding:12px 14px;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--card)}
#page-referentiel .ref-question-corps{flex:1;min-width:240px}
#refart-lignes,#ref-fusion-cibles{max-height:240px;overflow-y:auto}
#modal-ref-article .ref-sep{padding-top:12px;border-top:1px solid var(--border)}
#modal-ref-article .ref-newref{flex:1 1 140px}
#modal-ref-article .ref-ligne{padding:4px 0}
#modal-ref-eclater .ref-eclater-ligne{padding:5px 0;border-bottom:1px solid var(--border)}
#modal-ref-eclater .ref-eclater-txt{flex:1;min-width:180px}

/* page-catalogue — catalogue prix : KPI date, cartes d'alerte (lot 5) */
#page-catalogue .cat-kpi-date{font-size:14px;line-height:20px}
#page-catalogue .cat-leger{font-weight:400}
#cat-alertes-list .cat-alerte{padding:14px 16px;border:1.5px solid var(--border);border-radius:var(--radius-lg);background:var(--muted)}
#cat-alertes-list .cat-alerte.est-non-lue{border-color:var(--c);background:var(--card)}
#cat-alertes-list .cat-alerte-tete{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:10px}
#cat-alertes-list .cat-alerte-corps{flex:1;min-width:200px}
#cat-alertes-list .cat-alerte-actions{display:flex;align-items:flex-start;gap:6px}

/* page-cuves — cuves & fluides : cartes à jauge (carburant) et à cuve (huile), résumé, synthèse (lot 5, ex-règles d'index.html l. ~178-195) */
/* teinte d'état : posée par la classe, lue par la jauge, la pastille, les barres */
#page-cuves .cuve-ton-destructive{--t:var(--destructive)}
#page-cuves .cuve-ton-warning{--t:var(--warning)}
#page-cuves .cuve-ton-primary{--t:var(--primary)}
#page-cuves .cuve-ton-success{--t:var(--success)}
@keyframes cuveApparition{from{transform:scale(.95);opacity:0}to{transform:scale(1);opacity:1}}
@keyframes cuveVague{from{transform:translateX(0)}to{transform:translateX(-50%)}}
#page-cuves .cuve-chargement{padding:60px;text-align:center;color:var(--muted-foreground)}
#page-cuves .cuve-chargement-ico{margin-bottom:8px} /* indicateur .spinner à la place de l'emoji ⛽ (polish du 18/10) */
#page-cuves .cuve-section-titre{display:flex;align-items:center;gap:8px;margin-bottom:14px;font-size:16px;font-weight:700}
#page-cuves .cuve-grille{display:grid;gap:16px;margin-bottom:28px}
#page-cuves .cuve-grille-3{grid-template-columns:repeat(3,minmax(0,1fr))}
#page-cuves .cuve-grille-4{grid-template-columns:repeat(4,minmax(0,1fr));margin-bottom:20px}
#page-cuves .cuve-pilotage{margin-top:32px;padding-top:28px;border-top:1px solid var(--border)}
#page-cuves .cuve-pilotage .cuve-section-titre{margin-bottom:16px}
#cuves-chart-section{display:grid;grid-template-columns:420px minmax(0,1fr);gap:16px}
#page-cuves .cuve-panneau{padding:14px 16px}
#page-cuves .cuve-panneau-large{padding:16px 20px}
#page-cuves .cuve-panneau-titre{font-size:12px;font-weight:700;color:var(--foreground)}
#page-cuves .cuve-synthese{margin-bottom:24px}
#page-cuves .cuve-compte{font-weight:500}
#page-cuves .cuve-carte{position:relative;overflow:hidden;padding:24px;text-align:center;animation:cuveApparition .4s ease both}
#page-cuves .cuve-carte.alert-low{border-color:var(--warning);background:linear-gradient(135deg,var(--card) 0%,color-mix(in oklab,var(--warning) 6%,var(--card)) 100%)}
#page-cuves .cuve-carte.alert-critical{border-color:var(--destructive);background:linear-gradient(135deg,var(--card) 0%,color-mix(in oklab,var(--destructive) 6%,var(--card)) 100%)}
#page-cuves .cuve-tete{display:flex;align-items:flex-start;justify-content:space-between;text-align:left}
#page-cuves .cuve-produit{font-size:10px;font-weight:700;color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.025em}
#page-cuves .cuve-coloree .cuve-produit{color:var(--c)}
#page-cuves .cuve-nom{font-size:14px;font-weight:700;color:var(--foreground)}
#page-cuves .cuve-statut{padding:3px 10px;border-radius:9999px;background:var(--t);color:var(--primary-foreground);font-size:10px;font-weight:700}
#page-cuves .cuve-gauge-wrap{position:relative;width:150px;height:95px;margin:0 auto 6px}
#page-cuves .cuve-gauge-svg{width:150px;height:95px}
#page-cuves .cuve-gauge-track{fill:none;stroke:var(--muted);stroke-width:10;stroke-linecap:round}
#page-cuves .cuve-gauge-fill{fill:none;stroke:var(--t);stroke-width:10;stroke-linecap:round;transition:stroke-dashoffset 1.5s cubic-bezier(.4,0,.2,1)}
#page-cuves .cuve-gauge-pct{font-size:14px;font-weight:700;fill:var(--foreground)}
#page-cuves .cuve-volume{font-size:18px;font-weight:700;color:var(--foreground)}
#page-cuves .cuve-unite{font-size:11px;font-weight:500;color:var(--muted-foreground)}
#page-cuves .cuve-compare-bar{display:flex;gap:2px;height:6px;margin-top:8px;overflow:hidden;border-radius:3px}
#page-cuves .cuve-compare-bar>div{height:100%;background:var(--t)}
#page-cuves .cuve-compare-bar .mesure{border-radius:3px 0 0 3px}
#page-cuves .cuve-compare-bar .theo{border-radius:0 3px 3px 0;opacity:.4}
#page-cuves .cuve-legende{display:flex;justify-content:space-between;margin-top:2px;font-size:10px;color:var(--muted-foreground)}
#page-cuves .cuve-pied{display:flex;justify-content:space-between;margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
#page-cuves .cuve-muet{margin-top:6px;padding:3px 8px;border-radius:var(--radius-sm);background:color-mix(in oklab,var(--destructive) 12%,transparent);color:var(--destructive);font-size:10px;font-weight:700}
#page-cuves .cuve-maj{margin-top:6px;font-size:10px;color:var(--muted-foreground)}
#page-cuves .cuve-maj.txt-destructive{color:var(--destructive)}
#page-cuves .cuve-tank{position:relative;width:60px;height:80px;margin:0 auto 10px;overflow:hidden;border:2.5px solid var(--border);border-radius:6px 6px 10px 10px;background:var(--muted)}
#page-cuves .cuve-coloree .cuve-tank{border-color:var(--c)}
#page-cuves .cuve-tank-fill{position:absolute;bottom:0;left:0;right:0;border-radius:0 0 8px 8px;background:var(--t);transition:height 1.5s cubic-bezier(.4,0,.2,1)}
#page-cuves .cuve-coloree .cuve-tank-fill{background:var(--c)}
#page-cuves .cuve-tank-wave{position:absolute;top:-4px;left:0;width:200%;height:8px;opacity:.3;fill:var(--t);animation:cuveVague 3s linear infinite}
#page-cuves .cuve-coloree .cuve-tank-wave{fill:var(--c)}
#page-cuves .cuve-pct{font-size:18px;font-weight:700;line-height:1;color:var(--foreground)}
#page-cuves .cuve-leger{font-weight:400}
#page-cuves .cuve-mesures{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
#page-cuves .cuve-mesure{padding:2px 7px;border-radius:var(--radius-sm);background:var(--muted);font-size:11px}
#page-cuves .cuve-mesure-alerte{background:color-mix(in oklab,var(--warning) 12%,transparent);color:var(--warning);font-weight:700}
#page-cuves .cuve-resume{display:flex;flex-direction:column;gap:10px}
#page-cuves .cuve-resume-titre{margin-bottom:4px;font-size:11px;font-weight:700;text-transform:uppercase}
#page-cuves .cuve-resume-val{font-size:18px;font-weight:700}
#page-cuves .cuve-resume-alerte{gap:6px;margin-bottom:2px}
#page-cuves .cuve-pastille{flex-shrink:0;width:8px;height:8px;border-radius:9999px;background:var(--c,var(--muted-foreground))}
#page-cuves .cuve-produit-pastille{padding:2px 8px;border-radius:var(--radius-sm);background:color-mix(in oklab,var(--c,var(--muted-foreground)) 13%,transparent);color:var(--c,var(--foreground));font-size:12px;font-weight:700}
#page-cuves .cuve-niveau{gap:6px}
#page-cuves .cuve-niveau-piste{flex:1;height:8px;overflow:hidden;border-radius:3px;background:var(--muted)}
#page-cuves .cuve-niveau-barre{height:100%;border-radius:3px;background:var(--t)}
#page-cuves .cuve-niveau-pct{min-width:36px;font-size:12px;font-weight:700;text-align:right}
#page-cuves .cuve-ton-texte{color:var(--t)}
@media (max-width:1024px){#page-cuves .cuve-grille-3,#page-cuves .cuve-grille-4{grid-template-columns:repeat(2,minmax(0,1fr))}#cuves-chart-section{grid-template-columns:minmax(0,1fr)}}
@media (max-width:768px){#page-cuves .cuve-carte{padding:16px}#page-cuves .cuve-gauge-wrap,#page-cuves .cuve-gauge-svg{width:120px;height:76px}#page-cuves .cuve-tank{width:48px;height:64px}}
@media (max-width:600px){#page-cuves .cuve-grille-3,#page-cuves .cuve-grille-4{grid-template-columns:minmax(0,1fr)}}

/* page-chauff-import — import RH : trois questions dans l'ordre (quel fichier, ce qui change, qui échappe au fichier) ; une liste, un bouton,
   le secondaire replié (audit Rams 2026-09-10). Ex-règles d'index.html, en couleurs de rôle (lot 5). */
#page-chauff-import .chimp-wrap{max-width:860px}
#page-chauff-import .dz .chimp-ico{display:inline-flex}
#page-chauff-import .chimp-warn{margin:22px 0 -8px;padding:10px 14px;font-size:14px;font-weight:600}
#page-chauff-import .chimp-warn.soft{background:var(--muted);color:var(--muted-foreground);font-weight:500}
#page-chauff-import .chimp-note{margin-top:18px;font-size:14px;color:var(--muted-foreground)}
#page-chauff-import .chimp-lead{display:flex;flex-wrap:wrap;align-items:center;gap:12px 20px;margin:28px 0 12px}
#page-chauff-import .chimp-lead h2{flex:1;min-width:240px;margin:0;font-size:20px;font-weight:700;color:var(--foreground)}
#page-chauff-import .chimp-lead h2 small{display:block;margin-top:4px;font-size:14px;font-weight:500;color:var(--muted-foreground)}
#page-chauff-import .chimp-list{overflow:hidden;border:1px solid var(--border);border-radius:var(--radius-xl);background:var(--card);box-shadow:var(--shadow-sm)}
#page-chauff-import .chimp-list table{width:100%;border-collapse:collapse;font-size:14px}
#page-chauff-import .chimp-list td{padding:12px 16px;border-bottom:1px solid var(--border);vertical-align:middle}
#page-chauff-import .chimp-list tr:last-child td{border-bottom:0}
#page-chauff-import .chimp-list td.st{width:1%;padding-right:8px;white-space:nowrap}
#page-chauff-import .chimp-list td.who{width:34%;font-weight:600;color:var(--foreground)}
#page-chauff-import .chimp-list td.who small{display:block;margin-top:1px;font-size:12px;font-weight:400;font-variant-numeric:tabular-nums;color:var(--muted-foreground)}
#page-chauff-import .chimp-list td.what{color:var(--foreground)}
#page-chauff-import .chimp-list td.what s{color:var(--muted-foreground)}
#page-chauff-import .chimp-list td.act{width:1%;white-space:nowrap;text-align:right}
#page-chauff-import .chimp-pill.new{color:var(--success)}
#page-chauff-import .chimp-pill.upd{color:var(--primary)}
#page-chauff-import .chimp-pill.gone{color:var(--warning)}
#page-chauff-import .chimp-pill.off{color:var(--muted-foreground)}
#page-chauff-import .chimp-more{margin-top:16px}
#page-chauff-import .chimp-more>summary{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:12px 14px;border-radius:var(--radius-lg);background:var(--muted);font-size:14px;font-weight:600;color:var(--foreground);list-style:none;user-select:none;transition:background-color var(--dur) var(--ease)}
#page-chauff-import .chimp-more>summary:hover{background:var(--accent)}
#page-chauff-import .chimp-more>summary:focus-visible{outline:none;box-shadow:var(--focus-ring)}
#page-chauff-import .chimp-more>summary::-webkit-details-marker{display:none}
#page-chauff-import .chimp-more>summary .chev{flex-shrink:0;color:var(--muted-foreground);transition:transform .18s ease}
#page-chauff-import .chimp-more[open]>summary .chev{transform:rotate(90deg)}
#page-chauff-import .chimp-more>summary .hint{margin-left:auto;font-size:12px;font-weight:500;color:var(--muted-foreground)}
#page-chauff-import .chimp-more .chimp-list{margin-top:8px;border-radius:var(--radius-lg)}
#page-chauff-import .chimp-done{margin-top:24px;padding:24px;border:1px solid color-mix(in oklab,var(--success) 25%,transparent);border-radius:var(--radius-xl);background:color-mix(in oklab,var(--success) 12%,transparent)}
#page-chauff-import .chimp-done h3{margin:0 0 6px;font-size:16px;color:var(--success)}
#page-chauff-import .chimp-done p{margin:0 0 14px;font-size:14px;color:var(--muted-foreground)}
@media (max-width:640px){#page-chauff-import .chimp-lead :is(.btn-primary,.btn-danger){width:100%}#page-chauff-import .chimp-list td.who{width:auto}#page-chauff-import .chimp-more>summary .hint{display:none}}

/* ot-heritee — fiche OT héritée (#modal-ot-detail) et ses modales (planifier, pause du chrono, rapport) : la page OT est retirée
   (lot 5), la fiche reste atteinte par les liens viewOT(n) d'anciennes notifications (ex-styles en ligne) */
.ot-fiche-grille{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.ot-fiche-tab{width:100%}
.ot-fiche-tab tr>td:first-child{padding:3px 8px 3px 0} /* (0,2,2), après « :is(.table-wrap,.modal) table :is(th,td):first-child » de la section 6 */
.ot-chrono{padding:12px 16px;border-radius:var(--radius-md);background:var(--eld-red-soft)}
.ot-chrono-titre,.ot-chrono-live,.ot-chrono-btn{color:var(--eld-red)}
.ot-chrono-live{font-size:24px;line-height:32px;letter-spacing:.05em}
.btn-teinte{border-color:currentColor}
.ot-log-ligne{display:flex;align-items:flex-start;gap:8px;padding:4px 0}
.ot-log-ligne:not(:last-child){border-bottom:1px solid var(--border)}
.ot-log-total{padding:1px 6px;border-radius:4px;background:var(--primary);color:var(--primary-foreground)}
.ot-vignette{flex-shrink:0;width:100px;height:80px;padding:0;overflow:hidden;border:1px solid var(--border);border-radius:var(--radius-sm);background:none;cursor:pointer}
.ot-vignette-sm{width:60px;height:60px;cursor:default}
.ot-vignette img{display:block;width:100%;height:100%;object-fit:cover}
.ot-rap-chrono{font-size:20px;line-height:28px}
#plan-mec-assistants .filter-select{max-width:none}
.mec-q-item{padding:8px 12px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card);cursor:grab;user-select:none;transition:box-shadow var(--dur) var(--ease)}
.mec-q-item:hover{box-shadow:0 2px 8px rgba(0,0,0,.08)}
.mec-q-item.nouveau{border-color:var(--purple);background:color-mix(in oklab,var(--purple) 12%,transparent)}

/* page-stock — pièces détachées : fiche pièce, scanner (caméra et viseur), comptage d'inventaire */
.stk-tete{align-items:flex-start}
.stk-titre{font-size:18px;line-height:28px}
.stk-qte{font-size:30px;line-height:36px}
.stk-qte-sm{font-size:20px;line-height:28px}
.stk-unite{font-weight:400}
.stk-code{padding:16px;border:2px solid var(--border);border-radius:var(--radius-md);background:#fff}
#modal-piece-detail .stk-grille{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.stk-qte-champ{flex:none;width:72px}
.stk-centre{justify-content:center}
.stk-confirme{padding:20px;font-size:18px;line-height:28px}
/* fond du flux caméra : le noir de la vidéo, pas une couleur de rôle (même statut que le blanc du code-barres) */
.scan-zone{position:relative;overflow:hidden;aspect-ratio:4/3;max-height:280px;border-radius:var(--radius-xl);background:black}
.scan-zone video{display:block;width:100%;height:100%;object-fit:cover}
.scan-viseur{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}
.scan-cadre{position:relative;width:70%;height:60%}
.scan-coin{position:absolute;width:28px;height:28px;border:0 solid rgb(255 255 255 / .7)}
.scan-coin-hg{top:0;left:0;border-top-width:3px;border-left-width:3px;border-radius:4px 0 0 0}
.scan-coin-hd{top:0;right:0;border-top-width:3px;border-right-width:3px;border-radius:0 4px 0 0}
.scan-coin-bg{bottom:0;left:0;border-bottom-width:3px;border-left-width:3px;border-radius:0 0 0 4px}
.scan-coin-bd{right:0;bottom:0;border-right-width:3px;border-bottom-width:3px;border-radius:0 0 4px 0}
.scan-ligne{position:absolute;left:10%;right:10%;height:2px;background:var(--primary);opacity:.8;animation:scanLine 2s ease-in-out infinite}
#modal-inv-comptage>.modal{display:flex;flex-direction:column;height:90vh}
#modal-inv-comptage .modal-body{overflow-y:auto}
#inv-comptage-stats .stat-card{padding:12px 16px}
#inv-comptage-stats .stat-value{font-size:20px;line-height:28px}
.stk-inv{width:100%}
.stk-inv tr.stk-ecart td{background:color-mix(in oklab,var(--destructive) 12%,transparent)}
/* fiche véhicule à 390 px : les grilles de 3 et 4 (KPI 7 jours, sondes) passent à 2 colonnes */
@media (max-width:480px){#modal-camion-detail :is(.cam-grille-3,.cam-grille-4){grid-template-columns:repeat(2,minmax(0,1fr))}.cam-kpi{font-size:20px;line-height:28px}}
.veh-immat{color:var(--primary);font-weight:600}
.veh-dot{display:inline-block;width:8px;height:8px;margin-right:4px;border-radius:50%;background:var(--muted-foreground)}
.veh-dot-roule{background:var(--success)}
.veh-pin{padding:2px 8px;border:2px solid #fff;border-radius:var(--radius-sm);background:var(--primary);color:#fff;font-size:12px;line-height:16px;font-weight:700;white-space:nowrap;box-shadow:0 2px 6px rgb(0 0 0 / .3)}
.veh-pin-roule{background:var(--success)}
.veh-pin-engin{background:var(--warning)}
/* ge-202 lot 3 : sous 768 px la carte (400 px) repoussait la liste sous la ligne de flottaison, et les filtres tronqués */
@media (max-width:768px){#veh-fleet-map{height:240px}#veh-search{min-width:0;flex:1 1 100%}#page-vehicules .table-toolbar>:is(.filter-select,#veh-type-dropdown-wrap){flex:1 1 calc(50% - 6px)}#veh-type-dropdown-wrap>.filter-select{width:100%}}

/* ── 9. mouvement réduit (toujours en dernier) ── */
@media (prefers-reduced-motion:reduce){
  *,::before,::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}
