.scheduling-map-sheet{position:fixed;z-index:90;inset:75px 18px 18px;background:var(--ds-surface);border:1px solid var(--ds-line);border-radius:var(--ds-r-lg);box-shadow:var(--ds-e-pop);display:flex;flex-direction:column;overflow:hidden;color:var(--ds-ink);font:var(--ds-text-base)/1.4 var(--ds-font)}
.scheduling-map-sheet .scheduling-map-pin{white-space:normal;overflow-wrap:anywhere}
.scheduling-map-sheet>header{position:relative}
@media(max-width:700px){.scheduling-map-sheet .scheduling-map-options{position:static}.scheduling-map-sheet .scheduling-map-options-fields{left:12px;right:12px;top:calc(100% + 4px);width:auto;max-width:none;box-sizing:border-box;max-height:calc(100dvh - 220px)}}
.scheduling-map-travel{padding:0 10px 12px;margin-bottom:5px;border-bottom:1px solid var(--ds-line);display:flex;flex-direction:column;gap:7px}.scheduling-map-travel select{width:100%;min-width:0;font:inherit;font-size:var(--ds-text-caps);border:1px solid var(--ds-field);border-radius:var(--ds-r-md);padding:6px;background:var(--ds-surface)}.scheduling-map-travel button{border:0;border-radius:var(--ds-r-md);background:var(--ds-canvas);color:var(--ds-ink);padding:6px;text-align:left}.scheduling-map-travel small{font-size:var(--ds-text-caps);line-height:1.5;color:var(--ds-ink-3);overflow-wrap:anywhere}.scheduling-map-destination{background:#2866d8;color:white;border:2px solid white;border-radius:6px;padding:5px;font-size:11px}
.scheduling-map-options{position:relative}.scheduling-map-options>summary{cursor:pointer;list-style:none;border:1px solid var(--ds-field);border-radius:var(--ds-r-md);padding:6px 10px;background:var(--ds-surface);white-space:nowrap}.scheduling-map-options>summary:after{content:' ▾'}.scheduling-map-options-fields{position:absolute;right:0;top:calc(100% + 8px);z-index:5;width:280px;max-width:calc(100vw - 36px);max-height:calc(100dvh - 200px);overflow:auto;padding:14px;background:var(--ds-surface);border:1px solid var(--ds-line);box-shadow:var(--ds-e-pop);border-radius:var(--ds-r-lg);display:flex;flex-direction:column;gap:10px}.scheduling-map-options-fields label{display:flex;align-items:center;justify-content:space-between;gap:10px}.scheduling-map-options-fields select{max-width:150px;font:inherit;padding:5px;border:1px solid var(--ds-field);border-radius:var(--ds-r-md)}.scheduling-map-options-fields input{accent-color:var(--ds-action)}.scheduling-map-options-fields small{color:var(--ds-ink-3);line-height:1.5}.scheduling-map-options-fields :disabled{opacity:.45}.scheduling-map-options-fields :focus-visible,.scheduling-map-options>summary:focus-visible{outline:3px solid var(--ds-focus);outline-offset:2px}.scheduling-map-sheet:fullscreen{inset:0;border-radius:0}
.scheduling-map-sheet[hidden]{display:none}.scheduling-map-sheet>header{display:flex;align-items:center;gap:16px;padding:12px 16px;border-bottom:1px solid var(--ds-line);flex-wrap:wrap}.scheduling-map-sheet>header>div{display:flex;gap:7px;margin-left:auto}.scheduling-map-sheet button{cursor:pointer;font:inherit}.scheduling-map-sheet>header button{border:1px solid var(--ds-field);border-radius:var(--ds-r-md);padding:6px 10px;background:var(--ds-surface);color:var(--ds-ink-2)}.scheduling-map-sheet button:focus-visible{outline:3px solid var(--ds-focus);outline-offset:2px}.scheduling-map-notice{font-size:var(--ds-text-caps);color:var(--ds-ink-3)}.scheduling-map-body{display:flex;flex:1;min-height:0}.scheduling-map-body>aside{width:240px;flex-shrink:0;overflow:auto;background:var(--ds-surface);border-right:1px solid var(--ds-line);padding:8px}.scheduling-map-canvas{flex:1;min-width:0;position:relative;background:var(--ds-canvas)}.scheduling-map-person{display:flex;flex-direction:column;width:100%;gap:2px;text-align:left;border:1px solid transparent;border-radius:var(--ds-r-lg);background:transparent;padding:10px;color:var(--ds-ink)}.scheduling-map-person:hover,.scheduling-map-person[aria-pressed=true]{background:var(--ds-sel-bg);border-color:var(--ds-line)}.scheduling-map-person span,.scheduling-map-person small{font-size:var(--ds-text-caps);color:var(--ds-ink-3)}.scheduling-map-person small.stale{color:var(--ds-st-route-ink)}.scheduling-map-pin{border:2px solid white;border-radius:7px;background:#184e77;color:white;box-shadow:0 2px 7px #17324545;padding:5px 8px;font-size:11px!important;max-width:170px;white-space:nowrap}.scheduling-map-pin.stale{background:#96651c}.scheduling-map-warning{padding:10px;color:var(--ds-st-route-ink);font-size:var(--ds-text-sm)}@media(max-width:700px){.scheduling-map-sheet{inset:55px 6px 6px}.scheduling-map-body>aside{width:160px}.scheduling-map-sheet>header{gap:7px}.scheduling-map-notice{width:100%}}

/* Day trail, appointment and home pins; layer toggles in the header. */
.scheduling-map-layers{display:flex;align-items:center;gap:10px;font-size:var(--ds-text-caps);color:var(--ds-ink-2);margin-right:4px}
.scheduling-map-layers label{display:flex;align-items:center;gap:4px;cursor:pointer;white-space:nowrap}
.scheduling-map-stop{width:20px;height:20px;border-radius:50%;border:2px solid #fff;background:#6d28d9;color:#fff;font:700 10px/16px system-ui,sans-serif;text-align:center;padding:0;box-shadow:0 1px 5px #17324555;cursor:default}
.scheduling-map-stop.last{background:#3b1a8c}
.scheduling-map-appt{border:0;border-left:4px solid var(--appt-color,#2866d8);border-radius:4px;background:#fff;color:#1c3a5e;font:600 10px/1.2 system-ui,sans-serif;padding:3px 6px;box-shadow:0 1px 5px #17324540;white-space:nowrap;cursor:pointer}
.scheduling-map-appt:hover{background:#eaf1fb}
.scheduling-map-home{display:inline-block;border-radius:4px;background:#f4efe6;border:1px solid #c9b58f;color:#5a4a2c;font:600 10px/1.2 system-ui,sans-serif;padding:2px 6px;white-space:nowrap;box-shadow:0 1px 4px #17324530}
.scheduling-map-pin.selected{background:#d9480f}
.scheduling-map-motion{color:#2a7a3b}
.scheduling-map-trail-line{color:#3b1a8c}

/* Live status, nearest technician, planned day route. */
.scheduling-map-side{display:flex;flex-direction:column;width:300px;flex-shrink:0;min-height:0;border-right:1px solid var(--ds-line);background:var(--ds-surface)}
.scheduling-map-side>aside{width:auto!important;border-right:0;flex:1;min-height:0}
.scheduling-map-state{display:inline-block;align-self:flex-start;font-size:var(--ds-text-caps);font-weight:var(--ds-w-semi);padding:2px 7px;border-radius:var(--ds-r-full);background:var(--ds-canvas);color:var(--ds-ink-2);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scheduling-map-state-detail{color:var(--ds-ink-3)}
.scheduling-map-state.st-onsite{background:var(--ds-st-done-bg);color:var(--ds-st-done-ink)}.scheduling-map-state.st-enroute{background:var(--ds-canvas);color:var(--ds-ink)}.scheduling-map-state.st-late{background:var(--ds-st-late-bg);color:var(--ds-st-late-ink)}.scheduling-map-state.st-early{background:var(--ds-st-done-bg);color:var(--ds-st-done-ink)}.scheduling-map-state.st-overrun,.scheduling-map-state.st-idle{background:var(--ds-tint);color:var(--ds-st-route-ink)}.scheduling-map-state.st-done{background:var(--ds-canvas);color:var(--ds-ink-2)}.scheduling-map-state.st-stale{background:var(--ds-tint);color:var(--ds-st-route-ink)}
.scheduling-map-pin.st-onsite{border-color:#2fa85a}.scheduling-map-pin.st-enroute{border-color:#3b7be0}.scheduling-map-pin.st-late{border-color:#e0453a;box-shadow:0 0 0 3px #e0453a55}.scheduling-map-pin.st-early{border-color:#2aa3a8}.scheduling-map-pin.st-overrun,.scheduling-map-pin.st-idle{border-color:#e8a23a}
.scheduling-map-nearest-form{display:flex;gap:6px;align-items:center;flex:1 1 420px;min-width:0}
.scheduling-map-nearest-form input,.scheduling-map-nearest-form select{font:inherit;font-size:var(--ds-text-sm);border:1px solid var(--ds-field);border-radius:var(--ds-r-md);padding:6px 8px;background:var(--ds-surface);min-width:0}
.scheduling-map-nearest-form input{flex:2 1 160px}.scheduling-map-nearest-form select{flex:2 1 160px;max-width:260px}
.scheduling-map-nearest-form button{border:1px solid var(--ds-st-late-bd);background:var(--ds-st-late);color:var(--ds-action-fg);border-radius:var(--ds-r-md);padding:6px 10px;white-space:nowrap}
.scheduling-map-nearest{border-bottom:1px solid var(--ds-line);background:var(--ds-surface);padding:8px 10px;max-height:46%;overflow:auto;flex:0 0 auto}
.scheduling-map-nearest-head{display:flex;align-items:center;gap:8px}.scheduling-map-nearest-head strong{flex:1;font-size:var(--ds-text-sm)}.scheduling-map-nearest-head button{border:0;background:transparent;font-size:var(--ds-text-md)}
.scheduling-map-nearest-list{list-style:none;margin:6px 0 0;padding:0;counter-reset:n}
.scheduling-map-nearest-list li{display:flex;flex-direction:column;gap:2px;padding:7px 6px 7px 26px;border-radius:var(--ds-r-md);position:relative;font-size:var(--ds-text-caps);color:var(--ds-ink-2)}
.scheduling-map-nearest-list li::before{counter-increment:n;content:counter(n);position:absolute;left:6px;top:8px;width:16px;height:16px;border-radius:50%;background:#b3261e;color:#fff;font:700 10px/16px system-ui,sans-serif;text-align:center}
.scheduling-map-nearest-list li:first-child{background:var(--ds-sel-bg)}.scheduling-map-nearest-list strong{font-size:var(--ds-text-sm);color:var(--ds-ink)}.scheduling-map-nearest-list small.conflict{color:var(--ds-st-late-ink)}
.scheduling-map-nearest-actions{display:flex;gap:6px;flex-wrap:wrap;margin-top:3px}.scheduling-map-nearest-actions button{border:0;border-radius:var(--ds-r-md);background:var(--ds-canvas);color:var(--ds-ink);padding:4px 8px;font-size:var(--ds-text-caps)}
.scheduling-map-target{display:inline-block;border-radius:6px;background:#b3261e;color:#fff;font:700 11px/1.2 system-ui,sans-serif;padding:4px 8px;border:2px solid #fff;box-shadow:0 2px 7px #17324555;white-space:nowrap}
.scheduling-map-plan{display:flex;flex-direction:column;gap:5px;margin-top:2px;padding-top:6px;border-top:1px dashed var(--ds-line)}
.scheduling-map-plan-actions{display:flex;gap:6px}.scheduling-map-plan-actions button,.scheduling-map-plan>button{border:0;border-radius:var(--ds-r-md);background:var(--ds-st-done-bg);color:var(--ds-st-done-ink);padding:5px 8px;font-size:var(--ds-text-caps);text-align:left}
.scheduling-map-plan-opt{color:var(--ds-st-done-ink)}
/* The technician list scrolls inside the side column (it moved under .scheduling-map-side). */
.scheduling-map-side>aside{overflow:auto!important;padding:8px;background:var(--ds-surface);min-height:0;flex:1 1 auto}
.scheduling-map-side{overflow:hidden}

/* Named stops on the route history. Visits keep the trail violet; home is grey; an unscheduled long stop is amber with a dark ring so it stands out without using traffic red. */
.scheduling-map-stop.kind-home{background:#6b7785}
.scheduling-map-stop.kind-brief{background:#a79bd6}
.scheduling-map-stop.kind-unscheduled{background:#b45309;box-shadow:0 0 0 2px #fff,0 0 0 4px #b45309}
.scheduling-map-stops-note{display:block;color:#3b1a8c;font-size:var(--ds-text-sm);margin-top:2px}
.scheduling-map-stops-note.has-unscheduled{color:#92400e;font-weight:600}

/* ── Navy system, Phase 3 (2026-09-24): map panel chrome ──
   Only the panel chrome moves to tokens. Map markers (pins, trail, stops, homes, appointments,
   destination, nearest target) keep their colours: they are the map's legend. */
.scheduling-map-sheet{border:0;box-shadow:var(--ds-e-pop);font:var(--ds-text-base)/var(--ds-lh-base) var(--ds-font);color:var(--ds-ink)}
.scheduling-map-sheet>header{border-bottom:0;box-shadow:inset 0 -1px 0 var(--ds-line)}
.scheduling-map-sheet>header strong,.scheduling-map-sheet>header h2{font-size:var(--ds-text-md);font-weight:var(--ds-w-semi);color:var(--ds-ink)}
.scheduling-map-sheet>header button,.scheduling-map-options>summary,.scheduling-map-nearest-actions button,.scheduling-map-travel button,.scheduling-map-plan-actions button,.scheduling-map-plan>button{height:var(--ds-control-h);padding:0 var(--ds-s-3);border:0;box-shadow:var(--ds-e-secondary);border-radius:var(--ds-r-md);background:var(--ds-surface);color:var(--ds-ink);font-size:var(--ds-text-base);font-weight:var(--ds-w-medium);display:inline-flex;align-items:center}
.scheduling-map-nearest-actions button,.scheduling-map-plan-actions button,.scheduling-map-plan>button{height:28px;font-size:var(--ds-text-sm);padding:0 var(--ds-s-2)}
.scheduling-map-sheet>header button:hover,.scheduling-map-options>summary:hover,.scheduling-map-nearest-actions button:hover,.scheduling-map-travel button:hover,.scheduling-map-plan-actions button:hover{background:var(--ds-paper-hover);box-shadow:inset 0 0 0 1px var(--ds-ink-3)}
.scheduling-map-sheet .scheduling-map-nearest-form button{height:var(--ds-control-h);border:0;background:var(--ds-action);color:var(--ds-action-fg);box-shadow:var(--ds-e-primary);font-weight:var(--ds-w-semi)}
.scheduling-map-sheet .scheduling-map-nearest-form button:hover{background:var(--ds-action-hover)}
.scheduling-map-nearest-form input,.scheduling-map-nearest-form select,.scheduling-map-travel select,.scheduling-map-options-fields select{height:var(--ds-control-h);border:0;box-shadow:inset 0 0 0 1px var(--ds-field);border-radius:var(--ds-r-md);background:var(--ds-surface);color:var(--ds-ink);font-size:var(--ds-text-base)}
.scheduling-map-sheet button:focus-visible,.scheduling-map-sheet input:focus-visible,.scheduling-map-sheet select:focus-visible,.scheduling-map-options>summary:focus-visible,.scheduling-map-options-fields :focus-visible{outline:var(--ds-focus-w) solid var(--ds-focus);outline-offset:var(--ds-focus-off)}
.scheduling-map-options-fields{border:0;border-radius:var(--ds-r-lg);box-shadow:var(--ds-e-pop)}
.scheduling-map-notice,.scheduling-map-layers{font-size:var(--ds-text-sm);color:var(--ds-ink-2)}
.scheduling-map-side,.scheduling-map-side>aside,.scheduling-map-body>aside{background:var(--ds-canvas);border-right:0;box-shadow:inset -1px 0 0 var(--ds-line)}
.scheduling-map-side>aside{box-shadow:none}
.scheduling-map-person{border:0;border-radius:var(--ds-r-md);font-size:var(--ds-text-base)}
.scheduling-map-person:hover{background:var(--ds-paper-hover)}
.scheduling-map-person[aria-pressed=true]{background:var(--ds-sel-bg);box-shadow:inset 3px 0 0 var(--ds-selection)}
.scheduling-map-person span,.scheduling-map-person small{font-size:var(--ds-text-sm)}
/* Live status as navy pills: tint + ink-2 word (§6.12). */
.scheduling-map-state{height:22px;line-height:22px;padding:0 var(--ds-s-2);border-radius:var(--ds-r-sm);font-size:var(--ds-text-sm);font-weight:var(--ds-w-medium);background:var(--ds-tint);color:var(--ds-ink-2)}
.scheduling-map-state.st-onsite{background:var(--ds-st-site-bg);color:var(--ds-ink-2)}
.scheduling-map-state.st-enroute{background:var(--ds-st-route-bg);color:var(--ds-ink-2)}
.scheduling-map-state.st-late{background:var(--ds-st-late-bg);color:var(--ds-ink-2)}
.scheduling-map-state.st-early,.scheduling-map-state.st-done{background:var(--ds-st-done-bg);color:var(--ds-ink-2)}
.scheduling-map-state.st-overrun,.scheduling-map-state.st-idle,.scheduling-map-state.st-stale{background:var(--ds-st-route-bg);color:var(--ds-ink-2)}
.scheduling-map-nearest{background:var(--ds-surface);border-bottom:0;box-shadow:inset 0 -1px 0 var(--ds-line)}
.scheduling-map-nearest-head strong{font-size:var(--ds-text-md);font-weight:var(--ds-w-semi)}
.scheduling-map-nearest-list li{font-size:var(--ds-text-sm);color:var(--ds-ink-2);border-radius:var(--ds-r-md)}
.scheduling-map-nearest-list strong{font-size:var(--ds-text-base);color:var(--ds-ink)}
.scheduling-map-nearest-list small.conflict{color:var(--ds-st-late-ink)}
.scheduling-map-stops-note{font-size:var(--ds-text-sm)}
.scheduling-map-warning{background:var(--ds-tint);color:var(--ds-ink-2);border-radius:var(--ds-r-md)}

/* Pin grouping (live audit r2, 2026-09-29): vans that would touch on screen share one "Ismael +3" pin, and a
   van pin always draws over visit and home pins (they stay under the map controls, which sit at z-index 2). */
.scheduling-map-canvas .scheduling-map-pin{z-index:1}
.scheduling-map-pin-group{font-weight:var(--ds-w-semi);box-shadow:3px -3px 0 -1px var(--ds-surface),3px -3px 0 0 var(--ds-line),var(--ds-e-pop)}
.scheduling-map-appt-group{font-weight:var(--ds-w-semi);box-shadow:3px -3px 0 -1px var(--ds-surface),3px -3px 0 0 var(--ds-line)}

/* Option "initials-hover": icon only on the map; name, activity and on-site time in a hover/focus card.
   Token-first; the literal values with no token are listed at the bottom. */

/* ---- the marker: a button whose layout box is the puck plus its ring, so the puck centre is the GPS point ---- */
.vm{
  --vm-p: calc(var(--ds-s-6) + var(--ds-s-1));            /* puck 28px */
  --vm-ring-w: 5px;                                        /* 2px white gap + 3px status ring */
  position: relative; display: block; box-sizing: border-box;
  width: calc(var(--vm-p) + 2 * var(--vm-ring-w)); height: calc(var(--vm-p) + 2 * var(--vm-ring-w));
  margin: 0; padding: 0; border: 0; background: transparent; color: var(--ds-ink);
  font: var(--ds-w-semi) var(--ds-text-sm)/var(--ds-lh-sm) var(--ds-font); font-variant-numeric: var(--ds-nums);
  cursor: pointer; z-index: 1; -webkit-tap-highlight-color: transparent;
}
.vm.is-selected{ --vm-p: calc(var(--ds-s-8) + var(--ds-s-1)); z-index: 2; }  /* puck 36px */
.vm.is-hover, .vm:hover, .vm:focus-visible{ z-index: 3; }

/* ---- puck ---- */
.vm-puck{
  --vm-st: var(--ds-rule);
  --vm-gap: 2px;                                                        /* white gap between disc and status ring */
  --vm-ro: calc(var(--vm-gap) + 3px);                                   /* outer edge of the ring, for selection/focus */
  --vm-ring: 0 0 0 var(--vm-gap) var(--ds-surface), 0 0 0 var(--vm-ro) var(--vm-st);
  --vm-extra: 0 0 0 0 transparent;
  --vm-lift: var(--ds-e-float);
  position: absolute; left: var(--vm-ring-w); top: var(--vm-ring-w); z-index: 2;
  width: var(--vm-p); height: var(--vm-p); border-radius: var(--ds-r-full);
  display: grid; place-items: center; box-sizing: border-box;
  background: var(--vm-id, var(--ds-ink-3));                            /* identity colour = the chip bar colour */
  box-shadow: var(--vm-ring), var(--vm-extra), var(--vm-lift);
}
/* identity hue within 40 deg of its status ring (e.g. violet on the blue on-site ring): a wider white gap */
.vm-puck.is-near-ring{ --vm-gap: 2.5px; }
/* light identity fills (aqua, pear, rose) carry ink initials (>= 7:1) and a 1px inner edge in their darker shade, so the
   disc keeps its edge against the white gap and a pale basemap */
.vm-puck.is-light-id{ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--vm-id-ink) 65%, transparent), var(--vm-ring), var(--vm-extra), var(--vm-lift); }
.vm-ini{
  color: var(--vm-on, var(--ds-surface)); font-size: var(--ds-text-caps); line-height: var(--ds-lh-caps);
  font-weight: var(--ds-w-semi); letter-spacing: var(--ds-track-tag); text-indent: var(--ds-track-tag);
  font-variant-numeric: var(--ds-nums); user-select: none;
}
.vm.is-selected .vm-puck.is-lead .vm-ini{ font-size: var(--ds-text-sm); line-height: var(--ds-lh-sm); }
/* Two trucks whose drivers share initials (Piel's F350 and F150, both "PS"): a small white vehicle-number badge at the
   bottom right, ink digits, so the disc still reads as the person and the badge says which truck. */
.vm-num{
  position: absolute; right: -6px; bottom: -6px; z-index: 3;
  min-width: 14px; height: 14px; padding: 0 3px; box-sizing: border-box; border-radius: var(--ds-r-full);
  display: grid; place-items: center; background: var(--ds-surface); color: var(--ds-ink);
  font-size: var(--vm-text-mini); line-height: 1; font-weight: var(--ds-w-semi); letter-spacing: 0; font-variant-numeric: var(--ds-nums);
  box-shadow: 0 0 0 1px var(--ds-rule), var(--ds-e-float);
}
.vm.is-selected .vm-puck.is-lead .vm-num{ right: -5px; bottom: -5px; }
/* Nobody drives it: a light vehicle puck with an ink truck. */
.vm-puck.is-vehicle{ background: var(--ds-av-3); }
.vm-icon{ display: block; fill: none; stroke: var(--ds-ink); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

/* ---- live status ring (statusFor codes): 3px, outside the white gap ---- */
.vm-puck.st-onsite{ --vm-st: var(--ds-st-site); }
.vm-puck.st-enroute{ --vm-st: var(--ds-st-route); }
.vm-puck.st-late{ --vm-st: var(--ds-st-late); --vm-ro: calc(var(--vm-gap) + 6px);
  --vm-ring: 0 0 0 var(--vm-gap) var(--ds-surface), 0 0 0 calc(var(--vm-gap) + 3px) var(--vm-st), 0 0 0 calc(var(--vm-gap) + 6px) color-mix(in srgb, var(--ds-st-late) 26%, transparent); }
.vm-puck.st-done{ --vm-st: var(--ds-st-done); }
.vm-puck.st-overrun, .vm-puck.st-idle{ --vm-st: var(--ds-st-route); }
/* Early: the done-green ring with a gap at 12 o'clock ("not started yet"), so it never reads as day complete. */
.vm-puck.st-early{ --vm-st: var(--ds-st-done); --vm-ring: 0 0 0 var(--vm-gap) var(--ds-surface); }
.vm-arc{
  position: absolute; inset: calc(-1 * var(--vm-ro)); border-radius: var(--ds-r-full); pointer-events: none; z-index: -1;
  background: conic-gradient(transparent 0 28deg, var(--vm-st) 28deg 332deg, transparent 332deg);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.75px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.75px));
}
/* Stopped (next visit later) and off (no visits today): no status colour, only the white edge and a hairline. */
.vm-puck.st-stopped, .vm-puck.st-off, .vm-puck.st-stale{ --vm-ro: calc(var(--vm-gap) + 0.5px); --vm-ring: 0 0 0 var(--vm-gap) var(--ds-surface), 0 0 0 var(--vm-ro) var(--ds-rule); }

/* Corner badge, top-right: a 12px status disc with a white glyph, each state its own SHAPE (never colour alone):
   over time = clock, idle = pause bars, done = check; on a group face it carries the worst hidden exception
   (late = red "!", the only "!"). */
.vm-dot{
  position: absolute; top: -4px; right: -4px; width: 12px; height: 12px; border-radius: var(--ds-r-full);
  display: grid; place-items: center;
  background: var(--ds-st-route); box-shadow: 0 0 0 1.5px var(--ds-surface); z-index: 3;
}
.vm-dot.is-late{ background: var(--ds-st-late); }
.vm-dot.is-done{ background: var(--ds-st-done); }
.vm-glyph{ display: block; fill: none; stroke: var(--ds-surface); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* Heading notch: a triangle in the ring colour growing out of the ring, turned to the compass heading (moving only). */
.vm-hd{
  position: absolute; inset: 0; pointer-events: none; z-index: -1;
  transform: rotate(var(--vm-hd, 0deg));
  filter: drop-shadow(0 0 0.75px var(--ds-surface)) drop-shadow(0 0 0.75px var(--ds-surface));
}
.vm-hd::before{
  content: ''; position: absolute; left: 50%; top: -11px; width: 10px; height: var(--ds-s-2); margin-left: -5px;
  background: var(--vm-st); clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.vm-puck.st-stopped .vm-hd::before, .vm-puck.st-off .vm-hd::before, .vm-puck.st-stale .vm-hd::before{ background: var(--ds-ink-2); }

/* ---- not driven today (GPS from an earlier day): the disc goes hollow in the SAME identity colour (outline + initials),
   so it reads "not out today" without losing whose truck it is. ---- */
.vm-puck.is-dayold{ background: var(--ds-surface); box-shadow: inset 0 0 0 2px var(--vm-id-ink, var(--ds-ink-3)), var(--vm-ring), var(--vm-extra), var(--vm-lift); }
.vm-puck.is-dayold .vm-ini{ color: var(--vm-id-ink, var(--ds-ink-3)); }   /* the darker shade for a light identity: >= 4.6:1 on white */
.vm-puck.is-dayold.is-vehicle{ background: var(--ds-surface); box-shadow: inset 0 0 0 1.5px var(--ds-rule), var(--vm-ring), var(--vm-extra), var(--vm-lift); }

/* ---- group: the face puck (worst status, or the selected member) with a white "+N" count on its right edge ---- */
.vm-count{
  position: absolute; z-index: 3; top: 50%; transform: translateY(-50%);
  left: calc(var(--vm-ring-w) + var(--vm-p) + 1px);
  min-width: 20px; height: 18px; padding: 0 5px; box-sizing: border-box; border-radius: var(--ds-r-full);
  display: grid; place-items: center; background: var(--ds-surface); color: var(--ds-ink);
  font-size: var(--ds-text-caps); line-height: 1; font-weight: var(--ds-w-semi); letter-spacing: var(--ds-track-sm);
  box-shadow: 0 0 0 0.5px var(--ds-pop-edge), var(--ds-e-float);
}

/* ---- hover / focus / selected ---- */
.vm.is-hover .vm-puck.is-lead, .vm:hover .vm-puck.is-lead{ --vm-lift: var(--ds-e-pop); }
/* Selected: 2px white, a 2.5px navy ring, and a soft navy ground shadow so it reads on dark discs too. */
.vm.is-selected .vm-puck.is-lead{
  --vm-extra: 0 0 0 calc(var(--vm-ro) + 2px) var(--ds-surface), 0 0 0 calc(var(--vm-ro) + 4.5px) var(--ds-chrome);
  --vm-lift: 0 2px 6px calc(var(--vm-ro) + 2px) color-mix(in srgb, var(--ds-chrome) 45%, transparent);
}
/* A neutral identity (charcoal) is as dark as the navy ring, so only the white band tells them apart: widen it to 3px
   and move the navy out with it, so "selected" never reads as just a thicker dark puck. */
.vm.is-selected .vm-puck.is-lead.is-neutral-id{
  --vm-extra: 0 0 0 calc(var(--vm-ro) + 3px) var(--ds-surface), 0 0 0 calc(var(--vm-ro) + 5.5px) var(--ds-chrome);
}
/* A selected late truck: the navy selection ring already marks it and the red ring keeps "late", so the soft late halo
   is dropped (4 rings, not 5). */
.vm.is-selected .vm-puck.st-late.is-lead{ --vm-ro: calc(var(--vm-gap) + 3px);
  --vm-ring: 0 0 0 var(--vm-gap) var(--ds-surface), 0 0 0 var(--vm-ro) var(--vm-st); }
/* Keyboard focus: a DASHED NAVY ring (--ds-chrome, --ds-focus-w) on a white band 3px outside the status ring. Navy, not
   the focus blue, so it never reads as the blue on-site ring; dashed, so it never reads as the solid navy selection ring
   (no status or selection ring is ever dashed). */
.scheduling-map-canvas .vm:focus-visible, .vm:focus-visible{ outline: none; }
.vm:focus-visible .vm-puck.is-lead{
  --vm-extra: 0 0 0 calc(var(--vm-ro) + 3px + var(--ds-focus-w)) var(--ds-surface);
  outline: var(--ds-focus-w) dashed var(--ds-chrome); outline-offset: calc(var(--vm-ro) + 3px);
}

/* ---- expanded (fanned) group: each puck tethered to its real GPS point in ITS OWN identity colour (1.5px leader at 60%,
   an 8px surface dot ringed 1.5px in the colour, inside a 1.5px white halo), so two tethers never read as one chain ---- */
.vm-leader{
  position: absolute; left: 50%; top: 50%; height: 1.5px; margin-top: -0.75px; transform-origin: 0 50%;
  background: color-mix(in srgb, var(--vm-id-ink, var(--ds-ink-3)) 60%, transparent); z-index: 0; pointer-events: none;
  box-shadow: 0 0 0 0.5px color-mix(in srgb, var(--ds-surface) 70%, transparent);
}
.vm-real{
  position: absolute; width: 8px; height: 8px; border-radius: var(--ds-r-full); transform: translate(-50%, -50%); box-sizing: border-box;
  background: var(--ds-surface); box-shadow: inset 0 0 0 1.5px var(--vm-id-ink, var(--ds-ink-3)), 0 0 0 1.5px var(--ds-surface);
  z-index: 0; pointer-events: none;
}

/* ---- appointment chips: unchanged look; keyboard focus = the same dashed navy ring as the pucks ---- */
.scheduling-map-appt:focus-visible, .scheduling-map-sheet .scheduling-map-canvas .scheduling-map-appt:focus-visible{ outline: var(--ds-focus-w) dashed var(--ds-chrome); outline-offset: var(--ds-focus-off);
  box-shadow: 0 0 0 calc(var(--ds-focus-off) + var(--ds-focus-w)) var(--ds-surface); }
/* Past 11 people only: a visit-only technician with no colour left gets an OUTLINED bar (no fill), so it can never pass
   for a slate or charcoal truck's filled bar. */
.scheduling-map-appt.is-no-colour{ border-left: 4px double var(--ds-st-sched); }
/* A light identity's chip bar (aqua, pear, rose): a 1px edge in its darker shade round the 4px bar, so it still reads on
   the white chip and a pale basemap. Drawn on a pseudo-element so the chip's own (group) shadows are untouched. */
.scheduling-map-appt.is-light-id{ position: relative; }
.scheduling-map-appt.is-light-id::before{
  content: ''; position: absolute; left: -4px; top: 0; bottom: 0; width: 4px; box-sizing: border-box; pointer-events: none;
  border-radius: 4px 0 0 4px; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--vm-id-ink) 70%, transparent);
}

/* ---- the hover card: house hover card (6.4): white, --ds-r-lg, --ds-e-pop, caret with the pop-edge hairline.
   One component for vehicle, vehicle group, visit and grouped visits: rows led by a 20px mini identity disc. ---- */
.vm-card{
  position: absolute; left: 0; top: 0; z-index: 5; pointer-events: none; display: none;
  box-sizing: border-box; min-width: 176px; max-width: 320px; width: max-content;
  padding: var(--ds-s-2) var(--ds-s-3);
  background: var(--ds-surface); color: var(--ds-ink); border-radius: var(--ds-r-lg);
  box-shadow: var(--ds-e-pop);
  font: var(--ds-w-regular) var(--ds-text-sm)/var(--ds-lh-sm) var(--ds-font); letter-spacing: var(--ds-track-sm);
  font-variant-numeric: var(--ds-nums); text-align: left; white-space: normal;
}
.vm-card.is-open, .vm-card.vm-measure{ display: block; }   /* vm-measure: the hidden line the JS measures job text on */
.vm-card.is-appt{ width: 264px; }
/* a single vehicle card may run a little wider, so a late line ("9 min late · not at 3530 Elm Avenue (9:00 AM)") stays
   on one line under the activity */
.vm-card.is-vehicle, .vm-card.is-group{ max-width: 360px; }
.vm-card-caret{
  position: absolute; left: var(--vm-caret-x, 50%); bottom: -5px; width: 10px; height: 10px; margin-left: -5px;
  background: var(--ds-surface); transform: rotate(45deg); box-shadow: 0.5px 0.5px 0 0 var(--ds-pop-edge);
}
.vm-card.is-below .vm-card-caret{ bottom: auto; top: -5px; box-shadow: -0.5px -0.5px 0 0 var(--ds-pop-edge); }
/* beside the marker (when above and below would cover a truck or a visit chip) */
.vm-card.is-right .vm-card-caret, .vm-card.is-left .vm-card-caret{ bottom: auto; top: var(--vm-caret-y, 50%); margin: -5px 0 0; }
.vm-card.is-right .vm-card-caret{ left: -5px; box-shadow: -0.5px 0.5px 0 0 var(--ds-pop-edge); }
.vm-card.is-left .vm-card-caret{ left: auto; right: -5px; box-shadow: 0.5px -0.5px 0 0 var(--ds-pop-edge); }
.vm-card-body{ position: relative; z-index: 1; }

.vm-card-name, .vm-card-site{ font-size: var(--ds-text-md); line-height: var(--ds-lh-md); font-weight: var(--ds-w-semi); letter-spacing: var(--ds-track-tight); color: var(--ds-ink); }
.vm-card-meta{ color: var(--ds-ink-3); font-weight: var(--ds-w-medium); margin-bottom: 6px; }
.vm-card-line{ color: var(--ds-ink-2); text-wrap: pretty; overflow-wrap: anywhere; }   /* last-resort: an unbreakable run never leaves the card */   /* no one-word last line ("Colony") */
.vm-card-now{ color: var(--ds-ink); font-weight: var(--ds-w-medium); display: flex; align-items: baseline; gap: 6px; }
.vm-card-plan{ padding-left: 14px; }                                   /* lines up under the activity text, past the dot */
.vm-card-plan.is-quiet{ color: var(--ds-ink-3); }
.vm-card-lead{ font-weight: var(--ds-w-semi); }
.vm-card-plan.is-late{ color: var(--ds-ink); text-wrap: balance; }   /* a long property wraps evenly, never one word alone */
.vm-card-plan.is-late .vm-card-lead{ color: var(--ds-st-late-ink); }
.vm-card-plan.is-route .vm-card-lead{ color: var(--ds-st-route-ink); }
/* the status dot = the ring colour, so the card explains the ring */
.vm-card-dot{ flex: none; width: var(--ds-s-2); height: var(--ds-s-2); border-radius: var(--ds-r-full); box-sizing: border-box;
  background: var(--ds-surface); box-shadow: inset 0 0 0 1.5px var(--ds-st-sched); transform: translateY(-0.5px); }
.vm-card-dot.st-onsite{ background: var(--ds-st-site); box-shadow: none; }
.vm-card-dot.st-enroute, .vm-card-dot.st-overrun, .vm-card-dot.st-idle{ background: var(--ds-st-route); box-shadow: none; }
.vm-card-dot.st-late{ background: var(--ds-st-late); box-shadow: none; }
.vm-card-dot.st-done{ background: var(--ds-st-done); box-shadow: none; }
.vm-card-dot.st-early{ background: var(--ds-surface); box-shadow: inset 0 0 0 2px var(--ds-st-done); }

/* the row: mini disc + name + lines (vehicle card = one row; group card = one row per member) */
.vm-card-row{ display: grid; grid-template-columns: 20px 1fr; column-gap: var(--ds-s-2); align-items: start; }
.vm-card-row + .vm-card-row{ border-top: var(--ds-rule-hair) solid var(--ds-rule); margin-top: 6px; padding-top: 6px; }
.vm-card-row > .vm-puck.is-mini{ margin-top: 2px; }
.is-group .vm-card-row .vm-card-name{ font-size: var(--ds-text-base); line-height: var(--ds-lh-sm); }
.is-group .vm-card-row .vm-card-now{ font-weight: var(--ds-w-regular); color: var(--ds-ink-2); }
.vm-puck.is-mini{ position: relative; left: auto; top: auto; width: 20px; height: 20px; --vm-ring: 0 0 0 0 transparent; --vm-lift: 0 0 0 0 transparent; }
.vm-puck.is-mini .vm-ini{ font-size: var(--vm-text-mini); line-height: 1; letter-spacing: 0; text-indent: 0; }
.vm-puck.is-mini.is-dayold{ box-shadow: inset 0 0 0 1.5px var(--vm-id-ink, var(--ds-ink-3)); }
.vm-puck.is-mini .vm-icon{ width: 12px; height: 12px; }

/* visit card: property, job lines, then one row per visit (mini disc, time window, technician) */
.vm-card-job{ margin-top: 2px; text-wrap: wrap; }   /* clamped in JS by the same greedy wrap the browser uses */
.vm-card-job + .vm-card-visits + .vm-card-job{ margin-top: 6px; }       /* a second job at the same property */
.vm-card-more{ margin-top: var(--ds-s-2); padding-top: 6px; border-top: var(--ds-rule-hair) solid var(--ds-rule); color: var(--ds-ink-3); font-weight: var(--ds-w-medium); }
.vm-card-visits{ margin-top: 6px; display: grid; row-gap: var(--ds-s-1); }
.vm-card-visit{ display: grid; grid-template-columns: 20px 1fr; column-gap: var(--ds-s-2); align-items: center; color: var(--ds-ink); font-weight: var(--ds-w-medium); }
/* "9 min late · heading there": the visit's technician is late for THIS visit (same statusFor result as the truck ring).
   It is the visit row's second grid row, under the time (column 2), so it needs no indent or pull-up of its own and the
   mini disc stays centred on the time line. */
.vm-card-visit > .vm-puck.is-mini{ grid-row: 1; }
.vm-card-late{ grid-column: 2; color: var(--ds-st-late-ink); font-weight: var(--ds-w-medium); }
.vm-card-more-late{ color: var(--ds-st-late-ink); }   /* "+2 more visits · 1 late": a hidden late visit is still said */
/* drive lines (owner 2026-10-01): one grid under the activity, past its dot, so the start times and the drive figures line
   up down the card (right-aligned, tabular). Next in ink; Then lines and "+N more visits" quiet. The site wraps (house
   rule: full site name, never an ellipsis); its time and drive stay on its first line. */
.vm-drive{
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; column-gap: var(--ds-s-2); row-gap: 2px;
  align-items: baseline; justify-content: start; padding-left: 14px; margin-top: 2px; color: var(--ds-ink-2);   /* spare width never widens a column */
}
.vm-drive.is-nodrive{ grid-template-columns: auto minmax(0, 1fr) auto; }
.vm-drive-k{ color: var(--ds-ink-3); }
.vm-drive-site{ color: var(--ds-ink); font-weight: var(--ds-w-medium); overflow-wrap: anywhere; text-wrap: balance; }   /* even lines, so the pinned column is narrow */
.vm-drive-t, .vm-drive-d{ text-align: right; white-space: nowrap; font-variant-numeric: var(--ds-nums); }
.vm-drive-d{ color: var(--ds-ink); font-weight: var(--ds-w-medium); }
.vm-drive .is-then{ color: var(--ds-ink-3); font-weight: var(--ds-w-regular); }
/* a card with the drive grid may run to 400px, so a long property ("Hampton Inn & Suites Anaheim Resort") takes 2 lines,
   not 3, beside its time and drive figure */
.vm-card.is-vehicle.has-drive{ max-width: 400px; }
/* a group card with drive lines gets the same 400px (round 9): a member's late line ("48 min late · not at Bernardo Pines
   (8:30 AM)") stays on one line as in the single card, instead of "18 min late" alone on a line */
.vm-card.is-group.has-drive{ max-width: 400px; }
.vm-drive-line .vm-drive-k{ color: var(--ds-ink-3); }
.vm-drive-line .vm-drive-site{ color: var(--ds-ink); }
.vm-drive-line .vm-drive-d{ color: var(--ds-ink); font-weight: var(--ds-w-medium); }
/* a one-row drive line in a Then position (a late card with one following visit) is quiet like the grid's Then rows */
.vm-drive-line.is-then, .vm-drive-line.is-then .vm-drive-site, .vm-drive-line.is-then .vm-drive-d{ color: var(--ds-ink-3); font-weight: var(--ds-w-regular); }
/* "no map location": a data gap, said quietly in the drive column so it never reads as "not loaded yet" */
.vm-drive-d.is-nomap, .vm-drive-line .vm-drive-d.is-nomap{ color: var(--ds-ink-3); font-weight: var(--ds-w-regular); }
.vm-drive-more{ padding-left: 14px; margin-top: 2px; color: var(--ds-ink-3); }
.is-group .vm-drive-site{ font-weight: var(--ds-w-regular); }
.vm-card-sec.has-rule{ margin-top: var(--ds-s-2); padding-top: var(--ds-s-2); border-top: var(--ds-rule-hair) solid var(--ds-rule); }

@media (prefers-reduced-motion: no-preference){
  .vm-puck{ transition: box-shadow var(--ds-fast) var(--ds-ease); }
}

/* Literal values with no token:
   --vm-text-mini: 9px for the 20px mini-disc initials and vehicle-number badge (no design-system token fits);
   2px white gap round the puck (2.5px when the identity hue is within 40 deg of the ring hue); 3px status ring;
   0.5px hairline for stopped/off; 3px late halo; early ring gap 28deg either side of 12 o'clock
   selection: 2px white + 2.5px navy outside the ring, 0 2px 6px ground shadow at 45% navy
   focus: dashed navy ring 3px outside the status ring, on a white band (no status or selection ring is ever dashed)
   vehicle-number badge (shared initials): 14px white pill, 9px bold ink digits, -6px corner inset, 1px rule edge
   4px double chip bar for a visit-only technician past 11 people
   1.5px badge / real-point / card-dot strokes; icon stroke (the console icon family's 1.5px); 1.6px badge glyph stroke
   12px corner badge, -4px inset; 10px x 8px heading notch, tip 11px outside the puck; 0.75px white outline on it
   2px hollow (not driven today) outline; group count 18px high, min 20px wide, 5px sides, 1px outside the disc
   26% late halo strength (--ds-st-late-bg is too pale to see on a light basemap)
   1.5px leader at 60% of the identity shade, 8px real-point dot with a 1.5px identity ring and 1.5px white halo
   light identities: 1px inner edge at 65% (disc) / 70% (chip bar) of the darker shade; neutral selected: 3px white band
   Card: 264px (house hover card width) for visits, 176px min / 320px max otherwise; 10px caret; 6px dot/text, row and
   visit-list gaps; 14px plan indent (8px dot + 6px gap); 20px mini disc, 9px initials in it; 2px job line gap */

.scheduling-map-sheet .scheduling-map-pin.vm{border:0;border-radius:0;background:transparent;color:var(--ds-ink);box-shadow:none;padding:0;max-width:none;white-space:nowrap}
.vm-group{width:calc(var(--vm-p) + 2 * var(--vm-ring-w) + 24px)}

.vm, .vm-card{--vm-text-mini:9px}

/* The Map section shares the sheet, filling the page below the shell topbar. */
.scheduling-map-page{flex:1;min-height:0}
.scheduling-map-sheet.is-page{inset:var(--scheduling-map-page-top,60px) 0 0;border-radius:0;border:0;box-shadow:none}
