:root {
    --bg-app: #0f172a;
    --bg-panel: rgba(30, 41, 59, 0.7);
    --brand: #1e293b;
    --accent: #ef4444;
    --ready: #10b981;
    --busy: #f59e0b;
    --break: #64748b;
    --w-left: 360px;
    --w-right: 380px;
    --text-main: #f8fafc;
    --text-muted: #94a3b8;
    --border: rgba(255, 255, 255, 0.1);
    --glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
}

/* Hide the Leaflet Routing Machine direction/itinerary boxes.
   We only use the drawn route lines, never the turn-by-turn panels,
   so these empty containers are suppressed (they otherwise stack down
   the right edge of the map, one per active job). */
.leaflet-routing-container {
    display: none !important;
}

/* ---- Compact, scannable job rows (Active Jobs) ---- */
.job-row { background: var(--bg-panel, rgba(30,41,59,0.7)); border: 1px solid var(--border, rgba(255,255,255,0.1)); border-radius: 8px; padding: 7px 9px; margin-bottom: 7px; cursor: pointer; transition: background .15s, transform .15s; }
.job-row:hover { background: rgba(255,255,255,0.06); transform: translateX(2px); }
.job-row.alert { box-shadow: 0 0 0 1px rgba(220,38,38,0.55); }
.job-row-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.job-ref { font-weight: 700; font-size: 0.84rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.job-meta { display: flex; gap: 6px; align-items: center; flex-shrink: 0; }
.job-pill { font-size: 0.58rem; font-weight: 800; letter-spacing: 0.03em; padding: 2px 7px; border-radius: 10px; white-space: nowrap; }
.job-time { font-size: 0.68rem; color: var(--text-muted); white-space: nowrap; }
.job-row-mid { display: flex; justify-content: space-between; gap: 10px; margin-top: 4px; font-size: 0.75rem; }
.job-row-mid > span { flex: 1; min-width: 0; }
.job-route { color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }
.job-row-act { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.job-act { border: none; border-radius: 5px; color: #fff; font-weight: 700; font-size: 0.72rem; padding: 5px 10px; cursor: pointer; }
.job-abort { border: none; background: rgba(255,255,255,0.08); border-radius: 5px; padding: 4px 7px; cursor: pointer; font-size: 0.8rem; line-height: 1; }
.job-abort:hover { background: rgba(220,38,38,0.28); }

/* ---- Collapsible sidebar section headers ---- */
.sidebar-h3 { cursor: pointer; user-select: none; display: flex; align-items: center; justify-content: space-between; }
.sec-chev { transition: transform .2s; font-size: 0.7rem; margin-right: 5px; }

/* ---- Give Active Jobs the spare vertical space in the left sidebar ---- */
/* Active Fleet keeps a modest share; Active Jobs grows to fill the gap;
   the Export and Fleet Vehicles blocks only take the height they need. */
#panel-left #list-fleet { flex: 2 1 0; min-height: 90px; }
#panel-left #list-jobs { flex: 6 1 0; min-height: 140px; }
#panel-left #list-history { flex: 0 0 auto !important; }
#panel-left #list-fleet-vehicles { flex: 0 0 auto !important; }

/* ---- Vertical resize handles between stacked panel sections ---- */
.v-resizer { height: 9px; flex: 0 0 auto; cursor: row-resize; position: relative; margin: -3px 0 5px; }
.v-resizer::before {
    content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    width: 40px; height: 3px; border-radius: 3px; background: rgba(255,255,255,0.18); transition: background .15s;
}
.v-resizer:hover::before, .v-resizer.dragging::before { background: var(--accent, #ef4444); width: 60px; }
/* Let the panels scroll once boxes are sized larger than the screen */
#panel-left, #panel-right { overflow-y: auto; }
#log-request-body { flex: 0 0 auto; }
#controller-guide { flex: 1 1 auto; overflow-y: auto; min-height: 80px; }

/* Job rider name (readable on both themes) */
.job-rider { color: #38bdf8; }

/* ---- Light-theme contrast fixes for the newer components ---- */
.light-theme .job-row { background: #ffffff; border-color: rgba(0,0,0,0.12); }
.light-theme .job-row:hover { background: #eef2f7; }
.light-theme .job-ref { color: #0f172a; }
.light-theme .job-route, .light-theme .job-time { color: #475569; }
.light-theme .job-rider { color: #0369a1; }
.light-theme .job-abort { background: rgba(0,0,0,0.06); }
.light-theme #panel-left h3, .light-theme #panel-right h3, .light-theme .sidebar-h3 { color: #334155 !important; }
.light-theme .v-resizer::before { background: rgba(0,0,0,0.2); }
.light-theme .expand-panel { background: rgba(248,250,252,0.98); border-right-color: rgba(0,0,0,0.12); }
.light-theme .expand-head { color: #0f172a; border-bottom-color: rgba(0,0,0,0.1); background: rgba(0,0,0,0.03); }

/* ---- Cascading expand panels (Active Fleet / Active Jobs over the map) ---- */
#map-container { position: relative; }
.expand-panel {
    position: absolute; top: 0; left: 0; bottom: 0;
    width: min(640px, 78%);
    background: rgba(9, 14, 25, 0.97);
    border-right: 1px solid var(--border, rgba(255,255,255,0.12));
    box-shadow: 14px 0 44px -12px rgba(0,0,0,0.65);
    z-index: 1200; display: none; flex-direction: column;
    transform: translateX(-26px); opacity: 0;
    transition: transform .25s ease, opacity .25s ease;
}
.expand-panel.open { display: flex; transform: translateX(0); opacity: 1; }
.expand-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 13px 16px; font-weight: 700; color: var(--text-main, #f8fafc);
    border-bottom: 1px solid var(--border, rgba(255,255,255,0.1));
    background: rgba(255,255,255,0.03);
}
.expand-head button {
    border: none; background: var(--accent, #ef4444); color: #fff;
    padding: 6px 13px; border-radius: 6px; cursor: pointer; font-weight: 700; font-size: 0.8rem;
}
.expand-grid {
    flex: 1; overflow-y: auto; padding: 14px;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 10px; align-content: start;
}

body {
    margin: 0;
    font-family: 'Inter', sans-serif;
    background: var(--bg-app);
    color: var(--text-main);
    display: grid;
    grid-template-columns: minmax(200px, var(--w-left)) 4px 1fr 4px var(--w-right);
    grid-template-rows: 60px 1fr;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

header {
    grid-column: 1/-1;
    background: rgba(15, 23, 42, 0.8);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border);
    color: white;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;
    z-index: 2000;
    box-shadow: var(--glass-shadow);
}

.brand {
    font-size: 1.4rem;
    font-weight: 800;
    display: flex;
    align-items: center;
    gap: 10px;
    background: linear-gradient(to right, #38bdf8, #818cf8);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

.brand i {
    -webkit-text-fill-color: #38bdf8;
}

.version-tag {
    font-size: 0.7rem;
    background: rgba(255, 255, 255, 0.1);
    padding: 3px 8px;
    border-radius: 12px;
    font-weight: 500;
    margin-left: 10px;
    border: 1px solid var(--border);
    -webkit-text-fill-color: var(--text-muted);
}

.sync-status {
    font-size: 0.75rem;
    background: rgba(0, 0, 0, 0.3);
    padding: 4px 8px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: 15px;
    border: 1px solid var(--border);
}

.dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #ccc;
    transition: all 0.3s ease;
}

.dot.live {
    background: #10b981;
    box-shadow: 0 0 8px #10b981;
}

.dot.error {
    background: #ef4444;
    box-shadow: 0 0 8px #ef4444;
}

.resizer {
    background: rgba(255, 255, 255, 0.05);
    cursor: col-resize;
    z-index: 1500;
    transition: all 0.2s ease;
}

.resizer:hover,
.resizer.dragging {
    background: rgba(56, 189, 248, 0.5);
    box-shadow: 0 0 10px rgba(56, 189, 248, 0.3);
}

.sidebar {
    background: var(--bg-panel);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    display: flex;
    flex-direction: column;
    padding: 20px;
    overflow: hidden;
    z-index: 1000;
    min-width: 200px;
}

#panel-left {
    grid-column: 1;
    border-right: 1px solid var(--border);
}

#panel-right {
    grid-column: 5;
    border-left: 1px solid var(--border);
}

#map-container {
    grid-column: 3;
    position: relative;
    height: 100%;
    width: 100%;
}

#map {
    background: #1e293b;
    width: 100%;
    height: 100%;
    z-index: 1;
}

/* Dark mode map tiles via CSS filter.
   grayscale() first: this is a dispatch map, and the greens, blues and pinks
   OpenStreetMap paints for woodland, parks and landuse are noise a controller
   never acts on — draining them leaves the roads, junctions and place names,
   which are the only things being read. It also lets the job pins and route
   lines (the only saturated colour left on screen) carry all the attention.
   Contrast is nudged up because removing colour costs road/background
   separation. hue-rotate is gone: it existed to preserve hues through the
   invert, and there are no hues left to preserve. */
.leaflet-layer,
.leaflet-control-zoom-in,
.leaflet-control-zoom-out,
.leaflet-control-attribution {
    filter: grayscale(92%) invert(100%) brightness(96%) contrast(108%);
}
/* ...but NOT the vector basemaps (v3.18). The filter above exists to turn one
   specific raster style — OpenStreetMap's — into something readable at night.
   Clean and Quiet are designed palettes, and inverting them produces muddy
   pseudo-colour rather than a dark map. They stay as drawn in both themes; a
   controller who wants a dark map uses Streets, or hides the basemap entirely. */
.leaflet-gl-layer {
    filter: none !important;
}
.leaflet-container {
    background: #0f172a !important;
}

.map-relocating {
    cursor: crosshair !important;
}

#relocate-banner {
    position: absolute;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(15, 23, 42, 0.9);
    backdrop-filter: blur(8px);
    border: 1px solid var(--border);
    color: white;
    padding: 12px 24px;
    border-radius: 30px;
    z-index: 2000;
    display: none;
    font-weight: 600;
    box-shadow: var(--glass-shadow);
    white-space: nowrap;
    animation: slideDown 0.3s ease-out;
}

@keyframes slideDown {
    from { transform: translate(-50%, -20px); opacity: 0; }
    to { transform: translate(-50%, 0); opacity: 1; }
}

.section {
    flex: 1;
    overflow-y: auto;
    margin-bottom: 15px;
    border-bottom: 1px solid var(--border);
    padding-bottom: 15px;
}

.section::-webkit-scrollbar {
    width: 6px;
}
.section::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.05);
    border-radius: 4px;
}
.section::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.2);
    border-radius: 4px;
}

.card {
    padding: 12px;
    border: 1px solid var(--border);
    border-left: 4px solid var(--border);
    margin-bottom: 8px;
    background: rgba(255, 255, 255, 0.03);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s ease;
    position: relative;
}

.card:hover {
    transform: translateX(4px);
    background: rgba(255, 255, 255, 0.08);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.card.free { border-left-color: var(--ready); }
.card.busy { border-left-color: var(--busy); }
.card.break {
    border-left-color: var(--break);
    background: rgba(0, 0, 0, 0.2);
    opacity: 0.7;
}

.card.alert {
    border: 1px solid var(--accent);
    border-left: 4px solid var(--accent);
    animation: pulse-border 2s infinite;
}

@keyframes pulse-border {
    0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
    70% { box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }
    100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}

button {
    cursor: pointer;
    font-family: 'Inter', sans-serif;
    transition: all 0.2s ease;
}

.btn-main, .btn-sec, .btn-warn, .btn-danger {
    border: none;
    padding: 12px;
    width: 100%;
    border-radius: 8px;
    font-weight: 600;
    margin-bottom: 8px;
    color: white;
    text-shadow: 0 1px 2px rgba(0,0,0,0.2);
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

.btn-main { background: linear-gradient(135deg, #10b981, #059669); }
.btn-main:hover { background: linear-gradient(135deg, #34d399, #10b981); transform: translateY(-1px); box-shadow: 0 6px 12px rgba(16, 185, 129, 0.3); }

.btn-sec { background: linear-gradient(135deg, #3b82f6, #2563eb); }
.btn-sec:hover { background: linear-gradient(135deg, #60a5fa, #3b82f6); transform: translateY(-1px); box-shadow: 0 6px 12px rgba(59, 130, 246, 0.3); }

.btn-warn { background: linear-gradient(135deg, #64748b, #475569); }
.btn-warn:hover { background: linear-gradient(135deg, #94a3b8, #64748b); transform: translateY(-1px); box-shadow: 0 6px 12px rgba(100, 116, 139, 0.3); }

.btn-danger { background: linear-gradient(135deg, #ef4444, #dc2626); }
.btn-danger:hover { background: linear-gradient(135deg, #f87171, #ef4444); transform: translateY(-1px); box-shadow: 0 6px 12px rgba(239, 68, 68, 0.3); }

.btn-cancel-job {
    float: right;
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.1);
    color: var(--text-muted);
    border-radius: 6px;
    padding: 4px 8px;
    font-size: 0.7rem;
    margin-left: 5px;
    font-weight: 500;
}

.btn-cancel-job:hover {
    background: rgba(239, 68, 68, 0.2);
    color: #f87171;
    border-color: rgba(239, 68, 68, 0.5);
}

.btn-head {
    background: rgba(255, 255, 255, 0.05);
    color: white;
    border: 1px solid rgba(255, 255, 255, 0.1);
    padding: 6px 12px;
    border-radius: 6px;
    font-size: 0.85rem;
    font-weight: 500;
    backdrop-filter: blur(4px);
}

.btn-head:hover {
    background: rgba(255, 255, 255, 0.15);
}

.btn-head.logout {
    background: rgba(239, 68, 68, 0.2);
    border-color: rgba(239, 68, 68, 0.3);
    color: #fca5a5;
}
.btn-head.logout:hover {
    background: rgba(239, 68, 68, 0.4);
}

.input-std {
    width: 100%;
    padding: 10px 12px;
    margin-bottom: 12px;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid var(--border);
    color: white;
    border-radius: 6px;
    box-sizing: border-box;
    font-family: 'Inter', sans-serif;
    transition: all 0.2s ease;
}

.input-std:focus {
    outline: none;
    border-color: #38bdf8;
    background: rgba(0, 0, 0, 0.4);
    box-shadow: 0 0 0 2px rgba(56, 189, 248, 0.2);
}

.input-std option {
    background: #1e293b;
    color: white;
}

.db-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin-top: 10px;
}

.db-table th {
    text-align: left;
    background: rgba(0, 0, 0, 0.2);
    padding: 10px;
    border-bottom: 2px solid var(--border);
    color: var(--text-muted);
    font-weight: 600;
}

.db-table td {
    padding: 10px;
    border-bottom: 1px solid rgba(255,255,255,0.05);
}

.tab-group {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
    background: rgba(0,0,0,0.2);
    padding: 4px;
    border-radius: 8px;
}

.tab-btn {
    flex: 1;
    padding: 8px;
    border: none;
    background: transparent;
    cursor: pointer;
    font-weight: 600;
    border-radius: 6px;
    color: var(--text-muted);
}

.tab-btn.active {
    background: rgba(255,255,255,0.1);
    color: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.btn-edit {
    color: #60a5fa;
    font-weight: 600;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    background: rgba(59, 130, 246, 0.1);
    transition: all 0.2s ease;
    margin-right: 5px;
    display: inline-block;
}
.btn-edit:hover {
    background: rgba(59, 130, 246, 0.2);
}

.btn-del {
    color: #f87171;
    font-weight: 600;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    background: rgba(239, 68, 68, 0.1);
    transition: all 0.2s ease;
}
.btn-del:hover {
    background: rgba(239, 68, 68, 0.2);
}

.modal-mask {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    display: none;
    justify-content: center;
    align-items: center;
    z-index: 3000;
}

.modal {
    background: var(--bg-app);
    padding: 30px;
    border-radius: 16px;
    width: 550px;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
    border: 1px solid var(--border);
    animation: modalPop 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes modalPop {
    from { transform: scale(0.95); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.modal h2 {
    margin-top: 0;
    margin-bottom: 20px;
    font-weight: 600;
}

.row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.lbl {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 6px;
    display: block;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

#preview-box {
    display: none;
    background: rgba(56, 189, 248, 0.1);
    padding: 10px;
    margin-bottom: 12px;
    border-left: 4px solid #38bdf8;
    border-radius: 0 6px 6px 0;
    font-size: 0.8rem;
    color: #bae6fd;
}

.mileage-tag {
    float: right;
    background: rgba(255,255,255,0.1);
    padding: 2px 8px;
    border-radius: 12px;
    font-size: 0.75rem;
    color: var(--text-main);
    font-weight: 600;
    margin-left: 5px;
    border: 1px solid var(--border);
}

.time-badge {
    font-size: 0.75rem;
    background: rgba(56, 189, 248, 0.2);
    color: #7dd3fc;
    padding: 2px 8px;
    border-radius: 12px;
    margin-left: 5px;
    vertical-align: middle;
    border: 1px solid rgba(56, 189, 248, 0.3);
}

.flow-line {
    stroke-dasharray: 10, 10;
    animation: dash 1s linear infinite;
    opacity: 0.9;
}

.job-route-line {
    stroke-dasharray: 8, 8;
    animation: dash-reverse 1.5s linear infinite;
    opacity: 0.5;
}

@keyframes dash {
    to { stroke-dashoffset: -200; }
}

@keyframes dash-reverse {
    to { stroke-dashoffset: 200; }
}

.rider-wrapper {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: grab;
}

.rider-wrapper:active { cursor: grabbing; }

.rider-dot {
    width: 16px;
    height: 16px;
    background: var(--brand);
    border: 3px solid white;
    border-radius: 50%;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
    transition: all 0.3s ease;
}

.rider-label {
    position: absolute;
    bottom: 24px;
    background: rgba(15, 23, 42, 0.9);
    backdrop-filter: blur(4px);
    color: white;
    border: 2px solid var(--brand);
    padding: 4px 10px;
    border-radius: 6px;
    font-weight: 700;
    font-size: 11px;
    white-space: nowrap;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    z-index: 1000;
}

.rider-wrapper.busy .rider-dot { background: var(--busy); }
.rider-wrapper.busy .rider-label { border-color: var(--busy); color: #fde68a; }

.rider-wrapper.free .rider-dot { background: var(--ready); }
.rider-wrapper.free .rider-label { border-color: var(--ready); color: #a7f3d0; }

.rider-wrapper.break .rider-dot { background: var(--break); border-color: #cbd5e1; }
.rider-wrapper.break .rider-label { border-color: var(--break); color: #cbd5e1; }

.veh-btn {
    flex: 1;
    padding: 10px;
    border: 1px solid var(--border);
    background: rgba(255,255,255,0.05);
    cursor: pointer;
    font-weight: 600;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--text-main);
}

.veh-btn.active {
    background: rgba(56, 189, 248, 0.2);
    color: #38bdf8;
    border-color: rgba(56, 189, 248, 0.5);
}

h3 {
    margin: 0 0 15px 0;
    color: var(--text-muted);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

#mobile-nav {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 70px;
    background: rgba(15, 23, 42, 0.9);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-top: 1px solid var(--border);
    z-index: 3000;
    justify-content: space-around;
    align-items: center;
    box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.3);
}

.nav-item {
    text-align: center;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.75rem;
    font-weight: 500;
    flex: 1;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    transition: all 0.2s ease;
}

.nav-item.active {
    color: #38bdf8;
    background: rgba(255, 255, 255, 0.05);
}

.nav-item i {
    font-size: 1.5rem;
    display: block;
    margin-bottom: 6px;
}

@media (max-width: 800px) {
    body {
        grid-template-columns: 100%;
        grid-template-rows: auto 1fr 70px;
    }

    header { flex-wrap: wrap; gap: 8px; padding: 8px 12px; }
    header > div { flex-wrap: wrap; justify-content: flex-start; gap: 5px; }
    header .btn-head { padding: 7px 9px; font-size: 0.78rem; }
    header .btn-head[title="Analytics"] { display: none; }

    .resizer { display: none !important; }

    .sidebar {
        display: none;
        grid-column: 1;
        grid-row: 2;
        width: 100%;
        height: 100%;
        border: none;
        z-index: 1500;
        box-sizing: border-box;
    }

    /* ID-level rules so they beat the base #panel-left/#panel-right column rules */
    #panel-left, #panel-right {
        grid-column: 1;
        grid-row: 2;
        width: 100%;
        height: 100%;
        border: none;
        overflow-y: auto;
    }

    #map-container {
        display: block;
        grid-column: 1;
        grid-row: 2;
        width: 100%;
        height: 100%;
    }

    #mobile-nav { display: flex; grid-row: 3; }

    .modal {
        width: 90%;
        max-height: 80vh;
        padding: 20px;
    }

    header { padding: 0 15px; }
    .brand { font-size: 1.2rem; }
}

/* LOGIN SCREEN */
#login-screen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--bg-app);
    background-image: radial-gradient(circle at 50% 50%, rgba(30, 41, 59, 1) 0%, rgba(15, 23, 42, 1) 100%);
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    color: white;
}

#login-box {
    background: rgba(255, 255, 255, 0.03);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    padding: 40px;
    border-radius: 16px;
    text-align: center;
    width: 320px;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
    border: 1px solid rgba(255, 255, 255, 0.1);
    animation: modalPop 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

#login-box h1 {
    margin-top: 0;
    font-size: 2rem;
    margin-bottom: 5px;
    background: linear-gradient(to right, #38bdf8, #818cf8);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

#login-box h1 i {
    -webkit-text-fill-color: #38bdf8;
    margin-right: 8px;
}

/* CUSTOM TOAST NOTIFICATIONS */
#toast-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.toast {
    background: rgba(15, 23, 42, 0.9);
    backdrop-filter: blur(8px);
    border-left: 4px solid #3b82f6;
    color: white;
    padding: 12px 20px;
    border-radius: 6px;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
    font-size: 0.9rem;
    font-weight: 500;
    transform: translateX(120%);
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s;
    opacity: 0;
    max-width: 300px;
}

.toast.show {
    transform: translateX(0);
    opacity: 1;
}

.toast.success { border-left-color: #10b981; }
.toast.error { border-left-color: #ef4444; }
.toast.warning { border-left-color: #f59e0b; }
.toast.info { border-left-color: #3b82f6; }

/* SKELETON / SHIMMER LOADING PLACEHOLDERS
   Shown while a first fetch is in flight, so a slow connection looks like
   "loading" rather than "empty" or "broken". Purely decorative — marked
   aria-hidden at the call site so screen readers skip it. */
.sk-card {
    pointer-events: none;
}

.sk-line {
    height: 12px;
    margin: 10px 0;
    border-radius: 6px;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.06) 25%, rgba(255, 255, 255, 0.16) 37%, rgba(255, 255, 255, 0.06) 63%);
    background-size: 400% 100%;
    animation: sk-shimmer 1.4s ease-in-out infinite;
}

@keyframes sk-shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* Respect a user's reduced-motion setting: keep the placeholder, drop the sweep. */
@media (prefers-reduced-motion: reduce) {
    .sk-line { animation: none; }
}

/* Light theme overrides */
.light-theme {
    --bg-app: #f1f5f9;
    --bg-panel: rgba(255, 255, 255, 0.8);
    --brand: #f8fafc;
    --text-main: #0f172a;
    --text-muted: #475569;
    --border: rgba(0, 0, 0, 0.1);
    --glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}

.light-theme header {
    background: rgba(255, 255, 255, 0.85);
    color: #0f172a;
}

/* Light-theme header controls (otherwise white-on-white and invisible) */
.light-theme .btn-head {
    background: rgba(0, 0, 0, 0.04);
    color: #0f172a;
    border: 1px solid rgba(0, 0, 0, 0.12);
}
.light-theme .btn-head:hover {
    background: rgba(0, 0, 0, 0.08);
}
.light-theme #ctrl-status {
    color: #0f172a;
}

.light-theme #map {
    background: #e2e8f0;
}

/* Light theme: no invert, but mute the same landuse colour for the same reason
   as the dark rule above — roads and labels, not woodland. */
.light-theme .leaflet-layer,
.light-theme .leaflet-control-zoom-in,
.light-theme .leaflet-control-zoom-out,
.light-theme .leaflet-control-attribution {
    filter: grayscale(88%) contrast(104%) !important;
}

.light-theme .leaflet-container {
    background: #e2e8f0 !important;
}

.light-theme .card {
    background: rgba(0, 0, 0, 0.02);
}

.light-theme .card:hover {
    background: rgba(0, 0, 0, 0.05);
}

.light-theme .card.break {
    background: rgba(0, 0, 0, 0.08);
}

.light-theme #relocate-banner {
    background: rgba(255, 255, 255, 0.95);
    color: #0f172a;
}

.light-theme .input-std {
    background: rgba(255, 255, 255, 0.9);
    color: #0f172a;
}

.light-theme .input-std option {
    background: #ffffff;
    color: #0f172a;
}

.light-theme .tab-group {
    background: rgba(0, 0, 0, 0.05);
}

.light-theme .tab-btn.active {
    background: rgba(0, 0, 0, 0.1);
    color: #0f172a;
}

.light-theme .modal {
    background: #ffffff;
}

.light-theme #login-screen {
    background: #f1f5f9;
    background-image: radial-gradient(circle at 50% 50%, rgba(241, 245, 249, 1) 0%, rgba(226, 232, 240, 1) 100%);
    color: #0f172a;
}

.light-theme #login-box {
    background: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(0, 0, 0, 0.1);
}

.light-theme #toast-container .toast {
    background: rgba(255, 255, 255, 0.95);
    color: #0f172a;
}

/* --- Controller Quick Guide --- */
#controller-guide {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
    flex: 1;
    overflow-y: auto;
}

#controller-guide h4 {
    margin: 0 0 14px 0;
    font-size: 0.85rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    display: flex;
    align-items: center;
    gap: 8px;
}

#controller-guide h4 i {
    color: #818cf8;
}

.guide-steps {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 16px;
}

.guide-step {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.step-num {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: linear-gradient(135deg, #818cf8, #38bdf8);
    color: white;
    font-size: 0.7rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 1px;
}

.step-text {
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.step-text strong {
    color: var(--text-main);
}

.step-text em {
    color: #38bdf8;
    font-style: normal;
    font-weight: 600;
}

.guide-reminder {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px;
    border-radius: 8px;
    background: rgba(245, 158, 11, 0.1);
    border: 1px solid rgba(245, 158, 11, 0.25);
    margin-top: 8px;
}

.guide-reminder > i {
    color: #f59e0b;
    font-size: 1rem;
    margin-top: 2px;
    flex-shrink: 0;
}

.guide-reminder strong {
    display: block;
    font-size: 0.8rem;
    color: #fbbf24;
    margin-bottom: 4px;
}

.guide-reminder p {
    margin: 0;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* Light theme overrides */
.light-theme .guide-reminder {
    background: rgba(245, 158, 11, 0.08);
    border-color: rgba(245, 158, 11, 0.3);
}

.light-theme .guide-reminder strong {
    color: #b45309;
}

.light-theme .step-text em {
    color: #2563eb;
}

/* Stack database form fields vertically on compact mobile screens */
@media (max-width: 500px) {
    .modal .row {
        grid-template-columns: 1fr; /* Drop to 1 single column */
        gap: 8px;
    }
    
    .modal-mask .modal {
        width: 95%;
        padding: 15px;
    }
    
    .db-table th, .db-table td {
        padding: 6px 8px; /* Slightly reduce cell padding for touch targets */
        font-size: 0.85rem;
    }
}

/* ==============================
   JOB HISTORY VIEWER
   ============================== */

.history-header {
    margin-bottom: 20px;
}

.history-header h2 {
    margin-bottom: 4px;
}

.history-header h2 i {
    color: #818cf8;
    margin-right: 8px;
}

.history-subtitle {
    font-size: 0.8rem;
    color: var(--text-muted);
}

/* Time Range Filter Buttons */
.history-time-filters {
    display: flex;
    gap: 6px;
    margin-bottom: 16px;
    background: rgba(0, 0, 0, 0.2);
    padding: 4px;
    border-radius: 10px;
}

.history-time-btn {
    flex: 1;
    padding: 8px 6px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-weight: 600;
    font-size: 0.78rem;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s ease;
    font-family: 'Inter', sans-serif;
}

.history-time-btn:hover {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-main);
}

.history-time-btn.active {
    background: linear-gradient(135deg, rgba(129, 140, 248, 0.3), rgba(56, 189, 248, 0.2));
    color: white;
    box-shadow: 0 2px 8px rgba(129, 140, 248, 0.2);
}

/* Search Row */
.history-search-row {
    margin-bottom: 16px;
}

.history-search-row .input-std {
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.08);
    font-size: 0.85rem;
    padding: 10px 14px;
}

/* Stats Bar */
.history-stats {
    display: flex;
    gap: 10px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.stat-chip {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: 20px;
    font-size: 0.78rem;
    font-weight: 600;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border);
    color: var(--text-muted);
}

.stat-chip i {
    font-size: 0.7rem;
}

.stat-chip:nth-child(1) i { color: #10b981; }
.stat-chip:nth-child(2) i { color: #38bdf8; }
.stat-chip:nth-child(3) i { color: #818cf8; }

/* Results Container */
.history-results {
    max-height: 400px;
    overflow-y: auto;
    padding-right: 4px;
}

.history-results::-webkit-scrollbar {
    width: 5px;
}
.history-results::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.03);
    border-radius: 4px;
}
.history-results::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.15);
    border-radius: 4px;
}

/* Date Group Headers */
.history-date-group {
    margin-bottom: 16px;
}

.history-date-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}

.history-date-label {
    font-weight: 700;
    font-size: 0.82rem;
    color: #818cf8;
    white-space: nowrap;
}

.history-date-count {
    font-size: 0.72rem;
    color: var(--text-muted);
    background: rgba(255, 255, 255, 0.05);
    padding: 2px 8px;
    border-radius: 10px;
}

.history-date-line {
    flex: 1;
    height: 1px;
    background: var(--border);
}

/* Individual Job Cards */
.history-job {
    display: grid;
    grid-template-columns: 100px 1fr auto;
    gap: 12px;
    align-items: start;
    padding: 12px 14px;
    margin-bottom: 6px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.04);
    transition: all 0.15s ease;
    animation: histFadeIn 0.3s ease-out;
}

@keyframes histFadeIn {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
}

.history-job:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(129, 140, 248, 0.2);
}

.history-job-meta {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.history-job-ref {
    font-weight: 700;
    font-size: 0.82rem;
    color: #38bdf8;
}

.history-job-time {
    font-size: 0.72rem;
    color: var(--text-muted);
}

.history-job-body {
    min-width: 0;
}

.history-job-route {
    font-size: 0.82rem;
    font-weight: 500;
    margin-bottom: 4px;
    word-break: break-word;
}

.history-job-route .arrow {
    color: var(--text-muted);
    margin: 0 4px;
}

.history-job-details {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.history-job-detail {
    display: flex;
    align-items: center;
    gap: 4px;
}

.history-job-detail i {
    font-size: 0.65rem;
}

.history-job-miles {
    padding: 3px 10px;
    border-radius: 12px;
    font-size: 0.72rem;
    font-weight: 600;
    background: rgba(56, 189, 248, 0.1);
    border: 1px solid rgba(56, 189, 248, 0.2);
    color: #7dd3fc;
    white-space: nowrap;
    align-self: center;
}

/* Empty State */
.history-empty {
    text-align: center;
    padding: 40px 20px;
    color: var(--text-muted);
}

.history-empty i {
    font-size: 2.5rem;
    display: block;
    margin-bottom: 14px;
    opacity: 0.4;
}

.history-empty p {
    margin: 0;
    font-size: 0.9rem;
}

/* Light theme overrides for history */
.light-theme .history-time-btn.active {
    background: linear-gradient(135deg, rgba(99, 102, 241, 0.15), rgba(59, 130, 246, 0.1));
    color: #4f46e5;
    box-shadow: 0 2px 6px rgba(79, 70, 229, 0.15);
}

.light-theme .history-date-label {
    color: #6366f1;
}

.light-theme .history-job-ref {
    color: #2563eb;
}

.light-theme .history-job-miles {
    background: rgba(37, 99, 235, 0.08);
    border-color: rgba(37, 99, 235, 0.15);
    color: #2563eb;
}

/* Responsive: compact job cards on mobile */
@media (max-width: 600px) {
    .history-job {
        grid-template-columns: 1fr;
        gap: 6px;
    }
    
    .history-job-meta {
        flex-direction: row;
        gap: 8px;
        align-items: center;
    }
    
    .history-job-miles {
        align-self: flex-start;
    }
    
    .history-time-filters {
        flex-wrap: wrap;
    }
    
    .history-time-btn {
        min-width: 0;
    }
}

/* --- 14-DAY CALENDAR ROTA --- */
.calendar-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 12px;
    margin-top: 15px;
}
.calendar-day {
    background: var(--bg-panel, rgba(22, 27, 34, 0.8));
    border: 1px solid var(--border, rgba(255,255,255,0.1));
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    min-height: 120px;
}
.calendar-day.today {
    border-color: #38bdf8;
    box-shadow: 0 0 10px rgba(56, 189, 248, 0.2);
}
.calendar-day.warning {
    border-color: #ef4444;
}
.calendar-day-header {
    background: rgba(0,0,0,0.3);
    padding: 8px 10px;
    font-size: 0.85rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid var(--border, rgba(255,255,255,0.05));
    color: var(--text-main, #f8fafc);
}
.coverage-badge {
    background: rgba(239, 68, 68, 0.15);
    color: #ef4444;
    padding: 2px 6px;
    border-radius: 12px;
    font-size: 0.7rem;
    font-weight: 600;
}
/* Light theme: #ef4444 on a faint-red tint over a white card is too weak
   (~3.5:1). Darken the text so it meets AA. Only this badge lacked a
   light-theme tuning; the other status chips already have overrides. */
.light-theme .coverage-badge {
    background: rgba(220, 38, 38, 0.10);
    color: #b91c1c;
}
.calendar-day-body {
    padding: 10px;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.no-shifts {
    color: var(--text-muted, #64748b);
    font-size: 0.8rem;
    text-align: center;
    margin-top: auto;
    margin-bottom: auto;
}
.shift-entry {
    background: rgba(0,0,0,0.2);
    border-radius: 6px;
    padding: 6px;
    font-size: 0.8rem;
    border-left: 3px solid #38bdf8;
}
.shift-time {
    color: var(--text-muted, #94a3b8);
    font-size: 0.75rem;
    margin-bottom: 3px;
}
.shift-details {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.shift-person {
    color: var(--text-main, #e2e8f0);
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 5px;
}
.btn-del-shift {
    background: none;
    border: none;
    color: #ef4444;
    cursor: pointer;
    opacity: 0.7;
}
.btn-del-shift:hover {
    opacity: 1;
}

/* --- ITEM SELECTOR --- */
.item-selector-btn {
    width: 100%;
    padding: 10px 14px;
    margin-bottom: 12px;
    background: rgba(22, 27, 34, 0.8);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition: all 0.2s;
    box-sizing: border-box;
}
.item-selector-btn:hover {
    border-color: #38bdf8;
    background: rgba(255,255,255,0.05);
}

.item-category {
    margin-bottom: 8px;
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    overflow: hidden;
}
.item-category-header {
    background: rgba(0,0,0,0.3);
    padding: 10px 15px;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: 600;
    color: #e2e8f0;
}
.item-category-header:hover {
    background: rgba(0,0,0,0.5);
}
.item-category-body {
    background: transparent;
}
.item-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 15px;
    border-top: 1px solid rgba(255,255,255,0.05);
    font-size: 0.9rem;
    color: #cbd5e1;
}
.item-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}
.btn-qty {
    background: rgba(255,255,255,0.1);
    border: 1px solid rgba(255,255,255,0.2);
    border-radius: 4px;
    width: 28px;
    height: 28px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    font-weight: bold;
    color: #e2e8f0;
}
.btn-qty:hover {
    background: #38bdf8;
    color: #1e293b;
    border-color: #38bdf8;
}
.item-qty {
    min-width: 20px;
    text-align: center;
    font-weight: 600;
}

/* ============================================================
   v2.24 VISUAL IMPROVEMENTS
   (urgent pulse · job-age colours · status chips · map declutter
    · focus/hover polish · light-theme contrast fixes)
   ============================================================ */

/* --- Urgent jobs pulse slowly so they physically draw the eye --- */
@keyframes urgent-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.55); }
    70%  { box-shadow: 0 0 0 9px rgba(220, 38, 38, 0); }
    100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0); }
}
.urgent-pulse { animation: urgent-pulse 1.8s ease-out infinite; }
/* Respect users who turn animations off at OS level */
@media (prefers-reduced-motion: reduce) {
    .urgent-pulse, .card.alert { animation: none; }
    .urgent-pulse { box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.55); }
}

/* --- Job age: neutral < 30 min, amber 30–60, red > 60 --- */
.job-age-warn {
    background: rgba(245, 158, 11, 0.22) !important;
    color: #fbbf24 !important;
    border: 1px solid rgba(245, 158, 11, 0.45) !important;
    border-radius: 10px; padding: 1px 7px;
}
.job-age-late {
    background: rgba(220, 38, 38, 0.22) !important;
    color: #fca5a5 !important;
    border: 1px solid rgba(220, 38, 38, 0.55) !important;
    border-radius: 10px; padding: 1px 7px; font-weight: 700;
}
.light-theme .job-age-warn { color: #92400e !important; background: rgba(245, 158, 11, 0.15) !important; }
.light-theme .job-age-late { color: #991b1b !important; background: rgba(220, 38, 38, 0.12) !important; }

/* --- Rider acceptance line on a job (awaiting vs accepted) --- */
/* Solid colours + dark text so it's unmistakable and reads in both themes. */
.job-accept { margin-top: 5px; border-radius: 6px; padding: 4px 9px; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.02em; }
.job-accept.accepted { background: #10b981; color: #04231a; }
.job-accept.awaiting { background: #f59e0b; color: #1f2933; }

/* --- Status chips: one consistent style, symbol + word (colour-blind safe) --- */
.status-chip {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 0.68rem; font-weight: 800; letter-spacing: 0.04em;
    padding: 2px 9px; border-radius: 10px; text-transform: uppercase;
    white-space: nowrap; vertical-align: middle; line-height: 1.5;
}
.status-chip.free    { background: rgba(16, 185, 129, 0.16);  color: #34d399; border: 1px solid rgba(16, 185, 129, 0.35); }
.status-chip.busy    { background: rgba(245, 158, 11, 0.16);  color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.35); }
.status-chip.break   { background: rgba(100, 116, 139, 0.16); color: #a8b3c2; border: 1px solid rgba(100, 116, 139, 0.4); }
.status-chip.onboard { background: rgba(142, 68, 173, 0.2);   color: #d8b4fe; border: 1px solid rgba(142, 68, 173, 0.45); }
.light-theme .status-chip.free    { color: #047857; }
.light-theme .status-chip.busy    { color: #92400e; }
.light-theme .status-chip.break   { color: #475569; }
.light-theme .status-chip.onboard { color: #6b21a8; }

/* --- Stale rider position (v3.33) -----------------------------------------
   The portal reports only while it is open, so a phone locked in a pocket goes
   quiet. A full-strength dot would keep claiming "here, now" from a fix hours
   old. Faded and dashed says: this is where we LAST heard from them. The
   tooltip carries the actual age. --- */
.rider-wrapper.pos-stale { opacity: 0.45; }
.rider-wrapper.pos-stale .rider-dot { outline: 2px dashed rgba(255, 255, 255, 0.7); outline-offset: 2px; }

/* --- Map declutter: hospital icons fade at low zoom so riders & routes
       stand out; full detail returns as you zoom in --- */
.loc-marker { transition: opacity 0.25s ease; font-size: 16px; display: flex; align-items: center; justify-content: center; line-height: 1; }
.map-zoomed-out .loc-marker { opacity: 0.35; filter: grayscale(40%); font-size: 11px; }

/* Site-kind artwork (v3.30): hospitals and GP surgeries are pictures, not
   emoji — 🏥 and 🩺 were indistinguishable at this size. Sized in `em` on
   purpose, so the declutter rule above still shrinks pictures and emoji
   together from one number and can never leave the two out of step. */
img.loc-ic { width: 1.15em; height: 1.15em; object-fit: contain; vertical-align: -0.2em; }
.loc-marker img.loc-ic { width: 1.4em; height: 1.4em; display: block; vertical-align: baseline; }

/* --- Map view (v3.16) ------------------------------------------------------
   Site names printed on the map, for when the street map is switched off. Kept
   small and low-contrast enough that 129 of them do not become the new clutter. */
.loc-label.leaflet-tooltip {
    background: rgba(15, 23, 42, 0.82);
    color: #e2e8f0;
    border: 1px solid rgba(148, 163, 184, 0.32);
    border-radius: 4px;
    box-shadow: none;
    padding: 1px 5px;
    font-size: 10px;
    font-weight: 600;
    white-space: nowrap;
}
.loc-label.leaflet-tooltip::before { display: none; }   /* no callout arrow at this size */
.light-theme .loc-label.leaflet-tooltip {
    background: rgba(255, 255, 255, 0.9);
    color: #0f172a;
    border-color: rgba(15, 23, 42, 0.18);
}
/* Zoomed out, the labels would overlap into a smear — the markers already fade
   at this zoom (rule above), so the names go entirely. */
.map-zoomed-out .loc-label.leaflet-tooltip { display: none; }
/* ...except the blood bike groups' short names: that layer is looked at
   zoomed right out, across the whole country, and there are only 48. */
.map-zoomed-out .loc-label.bbg-label.leaflet-tooltip { display: block; }

/* --- Planned relay handover points on the map (v3.50) --- */
.relay-pt { background: none; border: none; }
.relay-pt span {
    display: flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 50%;
    background: #f5f3ff; color: #6d28d9; border: 2px solid #7c3aed;
    font: 700 11px/1 system-ui, sans-serif; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
.relay-pt.next span { background: #7c3aed; color: #fff; border-color: #fff; }
.relay-pt.done span { opacity: 0.45; }

/* --- Blood bike groups layer (v3.49) ---------------------------------------
   Indigo, so a group's HQ can never be mistaken for a hospital, an SOS or a
   job pin. Solid shield = a known base; hollow = a town or registered address
   only (the popup says which). Not faded by the zoomed-out declutter. */
.bbg-marker { background: none; border: none; cursor: pointer; }
.bbg-marker svg { display: block; overflow: visible; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45)); transition: transform 0.15s ease; transform-origin: 50% 100%; }
.bbg-marker:hover svg, .bbg-marker:focus svg { transform: scale(1.18); }
.bbg-marker:focus { outline: none; }
.bbg-marker:focus-visible svg { outline: 2px solid #a5b4fc; outline-offset: 2px; }
.bbg-shield { fill: #4f46e5; stroke: #ffffff; stroke-width: 1.6; }
.bbg-drop { fill: #ffffff; }
.bbg-approx .bbg-shield { fill: rgba(238, 242, 255, 0.92); stroke: #4f46e5; stroke-width: 2; }
.bbg-approx .bbg-drop { fill: #4f46e5; }
.bbg-menu-ic { display: inline-flex; vertical-align: -0.2em; }

.bbg-popup .leaflet-popup-content-wrapper {
    background: #111827;
    color: #e5e7eb;
    border: 1px solid rgba(129, 140, 248, 0.35);
    border-radius: 10px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}
.bbg-popup .leaflet-popup-tip { background: #111827; }
.bbg-popup .leaflet-popup-content { margin: 12px 14px; font-size: 12px; line-height: 1.45; }
.bbg-popup a.leaflet-popup-close-button { color: #9ca3af; }
.bbg-pop-kicker { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #a5b4fc; }
.bbg-pop-name { font-size: 14px; font-weight: 700; margin: 2px 18px 2px 0; text-wrap: balance; }
.bbg-pop-where { color: #cbd5e1; }
.bbg-pop-prec { display: inline-block; margin-top: 6px; padding: 1px 7px; border-radius: 999px; font-size: 10px; font-weight: 600; }
.bbg-prec-base { background: rgba(16, 185, 129, 0.16); color: #6ee7b7; }
.bbg-prec-registered, .bbg-prec-town { background: rgba(245, 158, 11, 0.16); color: #fcd34d; }
.bbg-pop-note { margin-top: 6px; color: #9ca3af; font-size: 11px; }
.bbg-pop-sub { margin-top: 10px; padding-top: 8px; border-top: 1px solid rgba(148, 163, 184, 0.2); font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #a5b4fc; }
.bbg-pop-sub span { font-weight: 500; letter-spacing: 0; text-transform: none; color: #9ca3af; margin-left: 4px; }
.bbg-pop-near { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 2px; }
.bbg-near-btn {
    width: 100%; display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
    background: none; border: none; border-radius: 6px; padding: 4px 6px; margin: 0 -6px;
    color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.bbg-near-btn:hover, .bbg-near-btn:focus-visible { background: rgba(129, 140, 248, 0.16); outline: none; }
.bbg-near-btn span { text-decoration: underline; text-decoration-color: rgba(165, 180, 252, 0.5); text-underline-offset: 2px; }
.bbg-near-btn b { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; color: #c7d2fe; }

.light-theme .bbg-popup .leaflet-popup-content-wrapper,
.light-theme .bbg-popup .leaflet-popup-tip { background: #ffffff; color: #111827; border-color: rgba(79, 70, 229, 0.25); }
.light-theme .bbg-pop-kicker, .light-theme .bbg-pop-sub { color: #4338ca; }
.light-theme .bbg-pop-where { color: #334155; }
.light-theme .bbg-pop-note, .light-theme .bbg-pop-sub span { color: #64748b; }
.light-theme .bbg-prec-base { background: rgba(16, 185, 129, 0.14); color: #047857; }
.light-theme .bbg-prec-registered, .light-theme .bbg-prec-town { background: rgba(245, 158, 11, 0.16); color: #92400e; }
.light-theme .bbg-near-btn b { color: #3730a3; }
.light-theme .bbg-near-btn:hover, .light-theme .bbg-near-btn:focus-visible { background: rgba(79, 70, 229, 0.08); }

/* With the street map off there are no tiles to invert or mute, so the dark-mode
   tile filter has nothing to act on. Slightly lift the empty canvas instead, so
   it reads as a deliberate plain background rather than a failed tile load.
   (.light-theme lives on <html>, .map-plain on <body> — hence the order.) */
body.map-plain #map { background: #131c2e; }
.light-theme body.map-plain #map { background: #eef2f7; }

/* The per-kind counts in the Map view menu. .hmenu-item is already flex with its
   own gap, so margin-left:auto is all that is needed to right-align these. */
.mv-count { margin-left: auto; color: #64748b; font-size: 0.72rem; font-variant-numeric: tabular-nums; }

/* --- Keyboard-focus visibility (accessibility) --- */
button:focus-visible, a:focus-visible, select:focus-visible,
input:focus-visible, textarea:focus-visible, [onclick]:focus-visible {
    outline: 2px solid #38bdf8;
    outline-offset: 2px;
    border-radius: 4px;
}

/* --- Empty-state panels (friendlier than bare text) --- */
.empty-state {
    text-align: center; padding: 26px 14px; color: var(--text-muted);
}
.empty-state i { font-size: 1.7rem; display: block; margin-bottom: 8px; opacity: 0.45; }
.empty-state .es-title { font-weight: 600; font-size: 0.85rem; margin-bottom: 3px; color: var(--text-main); opacity: 0.75; }
.empty-state .es-hint { font-size: 0.74rem; line-height: 1.5; }

/* --- Light-theme contrast fixes (day-shift legibility) --- */
.light-theme .time-badge { background: rgba(2, 132, 199, 0.1); color: #0369a1; border-color: rgba(2, 132, 199, 0.25); }
.light-theme .mileage-tag { background: rgba(0, 0, 0, 0.06); color: #0f172a; }
.light-theme #preview-box { color: #075985; background: rgba(2, 132, 199, 0.08); }
.light-theme .item-selector-btn { background: #ffffff; border-color: rgba(0, 0, 0, 0.15); }
.light-theme .item-selector-btn:hover { border-color: #0284c7; background: #f8fafc; }
.light-theme .item-category { border-color: rgba(0, 0, 0, 0.12); }
.light-theme .item-category-header { background: rgba(0, 0, 0, 0.05); color: #0f172a; }
.light-theme .item-category-header:hover { background: rgba(0, 0, 0, 0.09); }
.light-theme .item-row { color: #1e293b; border-top-color: rgba(0, 0, 0, 0.06); }
.light-theme .btn-qty { background: rgba(0, 0, 0, 0.05); border-color: rgba(0, 0, 0, 0.18); color: #0f172a; }
.light-theme .shift-entry { background: rgba(0, 0, 0, 0.04); }
.light-theme .shift-person { color: #0f172a; }
.light-theme .calendar-day-header { color: #0f172a; }

/* =====================================================================
   REDESIGN 2026 — Phase 2: Map console (matches the Dashboard reskin).
   Appended overrides only: calm blue for actions, red reserved for
   urgency, dark instrument header in BOTH themes, quieter panels,
   attention lanes + journey spine in the Active Jobs list.
   Delete this whole block to restore the previous look.
   ===================================================================== */
:root {
    --bg-app: #0B1120;
    --bg-panel: rgba(16, 25, 41, 0.92);
    --bg-card: #101929;
    --border: rgba(143, 163, 191, 0.16);
    --text-muted: #8FA3BF;
    --brand-secondary: #4FA3F2;
    --status-free: #2BD576;
    --rail-bg: #0D1522;
}
.light-theme {
    --bg-app: #EDF1F7;
    --bg-panel: rgba(255, 255, 255, 0.94);
    --bg-card: #ffffff;
    --border: rgba(15, 23, 42, 0.12);
    --text-muted: #52627A;
    --brand-secondary: #2E5EAA;
    --status-free: #16A34A;
    --rail-bg: #0D1522;
}

/* Instrument header: dark in BOTH themes, like the Dashboard's nav rail,
   so the command strip reads as one fixed instrument across the app. */
header { background: var(--rail-bg); backdrop-filter: none; -webkit-backdrop-filter: none; border-bottom: 1px solid rgba(143, 163, 191, 0.14); box-shadow: none; }
.light-theme header { background: var(--rail-bg); color: #E6EDF7; }
.light-theme header .btn-head { background: rgba(255, 255, 255, 0.06); color: #E6EDF7; border: 1px solid rgba(255, 255, 255, 0.12); }
.light-theme header .btn-head:hover { background: rgba(255, 255, 255, 0.12); }
.light-theme #ctrl-status { color: #cbd5e1; }
.btn-head:hover { background: rgba(79, 163, 242, 0.18); border-color: rgba(79, 163, 242, 0.4); }
.brand { background: none; -webkit-background-clip: unset; -webkit-text-fill-color: #E6EDF7; color: #E6EDF7; }
.brand i { -webkit-text-fill-color: var(--brand-secondary); color: var(--brand-secondary); }
.light-theme .brand { -webkit-text-fill-color: #E6EDF7; color: #E6EDF7; }
.version-tag { -webkit-text-fill-color: #8FA3BF; color: #8FA3BF; }

/* Panels: seam borders instead of glass glow */
.sidebar { backdrop-filter: none; -webkit-backdrop-filter: none; }
.card { background: var(--bg-card); border-color: var(--border); }
.card:hover { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18); }
.light-theme .card { background: #ffffff; }
.job-row { background: var(--bg-card); border-color: var(--border); }
.light-theme .job-row { background: #ffffff; }

/* Calm-blue actions (red is for urgency only). Flat fills, no gradients. */
.btn-main { background: #2F66C8; }
.btn-main:hover { background: #3B82D8; box-shadow: 0 6px 12px rgba(47, 102, 200, 0.3); }
.btn-sec { background: #475569; }
.btn-sec:hover { background: #64748b; box-shadow: 0 6px 12px rgba(71, 85, 105, 0.3); }
.btn-warn { background: #64748b; }
.btn-warn:hover { background: #94a3b8; box-shadow: 0 6px 12px rgba(100, 116, 139, 0.3); }
.btn-danger { background: #DC2626; }
.btn-danger:hover { background: #ef4444; box-shadow: 0 6px 12px rgba(220, 38, 38, 0.3); }
.light-theme .btn-main { background: #2E5EAA; }
.light-theme .btn-main:hover { background: #3B82D8; }
/* Generic accents that were red for no reason → calm blue */
.v-resizer:hover::before, .v-resizer.dragging::before { background: var(--brand-secondary); }
.expand-head button { background: var(--brand-secondary); color: #fff; }

/* Acceptance pills: amber = waiting, green = go (matches the Dashboard) */
.job-accept.awaiting { background: rgba(245, 185, 62, 0.16); color: #F5B93E; border: 1px solid rgba(245, 185, 62, 0.45); }
.light-theme .job-accept.awaiting { color: #B45309; }
.job-accept.accepted { background: rgba(43, 213, 118, 0.14); color: #2BD576; border: 1px solid rgba(43, 213, 118, 0.4); }
.light-theme .job-accept.accepted { color: #15803D; }

/* Attention lanes inside the Active Jobs list (and its expanded overlay) */
.mlane-h { display: flex; align-items: center; gap: 7px; font-size: 0.66rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); margin: 12px 2px 7px; }
.mlane-h .mlane-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.mlane-h .mlane-cnt { margin-left: auto; font-weight: 600; opacity: 0.85; font-variant-numeric: tabular-nums; }
.mlane-empty { font-size: 0.72rem; color: var(--text-muted); opacity: 0.75; font-style: italic; padding: 2px 2px 8px; }
.expand-grid .mlane-h, .expand-grid .mlane-empty { grid-column: 1 / -1; margin-top: 2px; }

/* Journey spine: Accepted → Collecting → Delivered on accepted jobs */
.spine { display: flex; align-items: center; margin-top: 8px; }
.spine .node { width: 9px; height: 9px; border-radius: 50%; border: 2px solid var(--border); background: var(--bg-card); flex: 0 0 auto; }
.spine .node.done { background: var(--status-free); border-color: var(--status-free); }
.spine .node.now { border-color: var(--brand-secondary); box-shadow: 0 0 0 3px rgba(79, 163, 242, 0.22); }
.spine .seg { flex: 1; height: 2px; background: var(--border); }
.spine .seg.done { background: var(--status-free); }
.spine-l { display: flex; justify-content: space-between; font-size: 0.58rem; color: var(--text-muted); margin-top: 3px; letter-spacing: 0.06em; text-transform: uppercase; }

/* =====================================================================
   REDESIGN 2026 — Phase 3: Map console LAYOUT (decluttered top bar with
   View/Tools menus, ticker on its own strip, Log Request as a pinnable
   slide-over sheet, Fit-to-fleet + New-job FAB on the map).
   Appended overrides only — delete this block to restore the old layout.
   ===================================================================== */

/* --- Top bar: only the frequently-used controls stay visible --- */
header { gap: 10px; }
.btn-head.btn-newjob { background: var(--brand-secondary); border-color: var(--brand-secondary); color: #fff; font-weight: 700; }
.btn-head.btn-newjob:hover { background: #3B82D8; border-color: #3B82D8; }
.seg { display: inline-flex; background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.12); border-radius: 8px; padding: 3px; gap: 2px; }
.seg button { border: none; background: transparent; height: 28px; padding: 0 12px; border-radius: 5px; font-size: 0.8rem; font-weight: 600; color: #B9C7DB; }
.seg button.on { background: var(--brand-secondary); color: #fff; }
.seg button:not(.on):hover { background: rgba(255, 255, 255, 0.08); }

/* Grouped header menus (View / Tools) — dark like the instrument bar */
.hmenu { position: relative; }
.hmenu-panel { position: absolute; top: calc(100% + 6px); right: 0; min-width: 240px; z-index: 6500; background: #101929; border: 1px solid rgba(143, 163, 191, 0.25); border-radius: 10px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5); padding: 6px; display: none; }
.hmenu.open .hmenu-panel { display: block; }
.hmenu-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: transparent; border: none; padding: 9px 10px; border-radius: 6px; font-size: 0.85rem; color: #E6EDF7; }
.hmenu-item:hover { background: rgba(79, 163, 242, 0.14); }
.hmenu-ic { width: 20px; text-align: center; color: #8FA3BF; flex: none; }
.hmenu-label { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.09em; color: #8FA3BF; padding: 7px 10px 3px; font-weight: 800; }
.hmenu-sep { height: 1px; background: rgba(143, 163, 191, 0.18); margin: 5px 4px; }
.hmenu-row { display: flex; align-items: center; gap: 8px; padding: 6px 10px; font-size: 0.82rem; color: #E6EDF7; }
.light-theme .hmenu-panel { background: #101929; }

/* --- Ticker strip: full-width, below the header, in BOTH themes --- */
#ticker-strip { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; padding: 4px 12px; background: linear-gradient(90deg, #101A26, #0E1720); border-bottom: 1px solid rgba(143, 163, 191, 0.14); }
.ticker-live-tag { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.1em; color: #0B1120; background: var(--brand-secondary); border-radius: 4px; padding: 2px 7px; flex: none; }
.light-theme #ticker-strip { background: linear-gradient(90deg, #101A26, #0E1720); }

/* --- Desktop layout: two columns + the job form as a slide-over sheet --- */
#sheet-scrim { display: none; }
@media (min-width: 801px) {
    body { grid-template-columns: minmax(200px, var(--w-left)) 4px 1fr; grid-template-rows: auto auto 1fr; }
    header { height: 54px; }
    #resizer-right { display: none; }
    #panel-right { position: fixed; top: 0; right: 0; height: 100vh; height: 100dvh; width: min(var(--w-right, 400px), 94vw); z-index: 6000; transform: translateX(105%); transition: transform 0.28s cubic-bezier(0.22, 0.61, 0.36, 1); border-left: 1px solid var(--border); box-shadow: -16px 0 40px rgba(0, 0, 0, 0.45); }
    body.sheet-open #panel-right { transform: none; }
    #sheet-scrim { display: block; position: fixed; inset: 0; background: rgba(4, 8, 12, 0.5); z-index: 5900; opacity: 0; pointer-events: none; transition: opacity 0.25s; }
    body.sheet-open #sheet-scrim { opacity: 1; pointer-events: auto; }
    body.sheet-open.sheet-pinned #sheet-scrim { opacity: 0; pointer-events: none; }
}
.sheet-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.sheet-hbtn { background: rgba(255, 255, 255, 0.06); border: 1px solid var(--border); color: var(--text-muted); border-radius: 6px; width: 30px; height: 30px; font-size: 0.85rem; }
.sheet-hbtn:hover { background: rgba(79, 163, 242, 0.16); color: var(--text-main); }
.sheet-hbtn.pinned { background: var(--brand-secondary); border-color: var(--brand-secondary); color: #fff; }
.light-theme .sheet-hbtn { background: rgba(0, 0, 0, 0.05); }
.light-theme .sheet-hbtn.pinned { background: var(--brand-secondary); color: #fff; }

/* --- Map controls: Fit to fleet + New job FAB --- */
#btn-fit-fleet { position: absolute; top: 84px; left: 12px; z-index: 1290; display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px; background: #101929; border: 1px solid rgba(143, 163, 191, 0.35); border-radius: 8px; font-size: 0.8rem; font-weight: 650; color: #E6EDF7; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35); }
#btn-fit-fleet:hover { background: #1A2637; }
#fab-newjob { position: absolute; right: 18px; bottom: 18px; z-index: 1290; height: 46px; padding: 0 20px; border: none; border-radius: 26px; background: var(--brand-secondary); color: #fff; font-weight: 750; font-size: 0.92rem; display: inline-flex; align-items: center; gap: 9px; box-shadow: 0 8px 26px rgba(0, 0, 0, 0.4); }
#fab-newjob:hover { background: #3B82D8; }

@media (prefers-reduced-motion: reduce) {
    #panel-right, #sheet-scrim { transition: none; }
}
@media (max-width: 800px) {
    #btn-fit-fleet { top: 84px; }
    #fab-newjob { display: none; } /* mobile keeps its own Log Job tab */
    .sheet-hbtn { display: none; } /* mobile nav owns panel switching */
}

/* Urgent: a steady red ring that breathes, not a strobing card */
.urgent-pulse { animation: none; box-shadow: 0 0 0 1px rgba(225, 29, 46, 0.45), 0 6px 22px rgba(225, 29, 46, 0.10); }
@media (prefers-reduced-motion: no-preference) {
    .urgent-pulse { animation: urgent-breathe 2.6s ease-in-out infinite; }
    @keyframes urgent-breathe {
        0%, 100% { box-shadow: 0 0 0 1px rgba(225, 29, 46, 0.45), 0 6px 22px rgba(225, 29, 46, 0.10); }
        50%      { box-shadow: 0 0 0 2px rgba(225, 29, 46, 0.70), 0 6px 26px rgba(225, 29, 46, 0.22); }
    }
}

/* ---------------------------------------------------------------------------
   Header dropdowns on a phone.
   .hmenu-panel is anchored right:0 to its button and is 244px wide. In a header
   that has wrapped onto two rows the button sits near the LEFT edge, so the
   panel extends 244px further left — off the screen entirely. A controller
   working from a phone that cannot be rotated then has no way to reach Tools.
   On narrow screens the panel is anchored to the HEADER instead of the button
   and spans the full width, so it can never leave the viewport.
   --------------------------------------------------------------------------- */
@media (max-width: 800px) {
    /* The map console's <header> is a static grid item, so it has to be made a
       positioned ancestor before the panel can anchor to it. position:relative
       with no offsets moves nothing. */
    header { position: relative; }
    .hmenu { position: static; }
    .hmenu-panel {
        left: 10px;
        right: 10px;
        top: calc(100% + 6px);
        min-width: 0;
        width: auto;
        max-height: 70vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
}
