/* Fleet Operations Dashboard */

:root {
    --bg-primary: #0f1117;
    --bg-card: #1a1d27;
    --bg-card-hover: #22253a;
    --border: #2a2d3a;
    --text-primary: #e8e8e8;
    --text-secondary: #888;
    --text-muted: #555;
    --blue: #4a9eff;
    --green: #4ade80;
    --red: #ef4444;
    --yellow: #facc15;
    --orange: #fb923c;

    /* State colors */
    --state-recording: #2d1216;
    --state-recording-border: #7f1d1d;
    --state-idle: #121a2d;
    --state-idle-border: #1e3a5f;
    --state-preview: #121a2d;
    --state-preview-border: #1e3a5f;
    --state-starting: #2d2512;
    --state-starting-border: #78350f;
    --state-stopping: #2d2512;
    --state-stopping-border: #78350f;
    --state-error: #2d1612;
    --state-error-border: #9a3412;
    --state-offline: #1a1a1a;
    --state-offline-border: #333;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
    background: var(--bg-primary);
    color: var(--text-primary);
    min-height: 100vh;
    overflow-x: hidden;
}

/* ---------- Topbar ---------- */

.topbar {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    padding: 0 20px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.topbar-left { display: flex; align-items: center; gap: 16px; }
.topbar-center { display: flex; align-items: center; gap: 20px; font-size: 0.8rem; }
.topbar-right { display: flex; align-items: center; gap: 12px; }

.logo {
    font-size: 1.1rem;
    font-weight: 700;
    color: #fff;
    letter-spacing: -0.5px;
}

.summary-stat {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
}

.summary-stat .count {
    font-weight: 600;
    font-size: 1rem;
}

.summary-stat .count.online { color: var(--green); }
.summary-stat .count.recording { color: var(--red); }
.summary-stat .count.offline { color: var(--text-muted); }

.poll-indicator {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--green);
    display: inline-block;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
}

.logout-link {
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.8rem;
}
.logout-link:hover { color: var(--text-primary); }

/* Subtle device-naming entry point — muted until hovered */
.naming-link {
    display: inline-flex;
    align-items: center;
    color: var(--text-muted);
    opacity: 0.5;
    transition: opacity 0.15s, color 0.15s;
}
.naming-link:hover { opacity: 1; color: var(--text-secondary); }

/* ---------- Device Grid ---------- */

.grid-container {
    padding: 16px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 12px;
    max-width: 1800px;
    margin: 0 auto;
}

/* 5-column layout on wide screens */
@media (min-width: 1600px) {
    .grid-container {
        grid-template-columns: repeat(5, 1fr);
    }
}

/* 4-column layout */
@media (min-width: 1280px) and (max-width: 1599px) {
    .grid-container {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* 3-column */
@media (min-width: 960px) and (max-width: 1279px) {
    .grid-container {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* ---------- Device Card ---------- */

.device-card {
    position: relative;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
    cursor: pointer;
    transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}

/* Invisible link overlay — covers entire card for right-click "Open in new tab" */
.card-link-overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
}

/* Pin button sits above the overlay */
.pin-btn {
    position: relative;
    z-index: 2;
}

.device-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}

/* State-specific backgrounds and borders */
.device-card.state-recording {
    background: var(--state-recording);
    border-color: var(--state-recording-border);
}
.device-card.state-recording:hover { border-color: var(--red); }

.device-card.state-idle,
.device-card.state-preview {
    background: var(--state-idle);
    border-color: var(--state-idle-border);
}
.device-card.state-idle:hover,
.device-card.state-preview:hover { border-color: var(--blue); }

.device-card.state-starting,
.device-card.state-stopping {
    background: var(--state-starting);
    border-color: var(--state-starting-border);
}
.device-card.state-starting:hover,
.device-card.state-stopping:hover { border-color: var(--yellow); }

.device-card.state-error {
    background: var(--state-error);
    border-color: var(--state-error-border);
}
.device-card.state-error:hover { border-color: var(--orange); }

.device-card.state-offline {
    background: var(--state-offline);
    border-color: var(--state-offline-border);
    opacity: 0.6;
}
.device-card.state-offline:hover { opacity: 0.8; border-color: #555; }

/* ---------- Card Header ---------- */

.card-header {
    padding: 8px 12px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid rgba(255,255,255,0.05);
}

.device-id {
    font-size: 0.82rem;
    font-weight: 600;
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: #fff;
    letter-spacing: -0.3px;
}

.status-badge {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 2px 8px;
    border-radius: 10px;
}

.badge-recording { background: rgba(239,68,68,0.2); color: var(--red); }
.badge-idle, .badge-preview { background: rgba(74,158,255,0.15); color: var(--blue); }
.badge-starting, .badge-stopping { background: rgba(250,204,21,0.15); color: var(--yellow); }
.badge-error { background: rgba(251,146,60,0.15); color: var(--orange); }
.badge-offline { background: rgba(255,255,255,0.05); color: var(--text-muted); }
.badge-unknown { background: rgba(255,255,255,0.05); color: var(--text-muted); }

/* ---------- Preview Grid ---------- */

.preview-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    gap: 2px;
    padding: 2px;
    aspect-ratio: 16 / 9;
    background: #000;
}

.preview-cell {
    position: relative;
    overflow: hidden;
    background: #111;
}

.preview-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.preview-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.65rem;
    color: var(--text-muted);
    background: #111;
}

.preview-label {
    position: absolute;
    bottom: 2px;
    left: 4px;
    font-size: 0.55rem;
    color: rgba(255,255,255,0.5);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}

.preview-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #111;
    color: var(--text-muted);
    font-size: 0.8rem;
    gap: 4px;
    aspect-ratio: 16 / 9;
}

.preview-empty .camera-count {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.offline-msg .last-seen {
    font-size: 0.7rem;
    color: var(--text-muted);
}

/* ---------- Card Stats ---------- */

.card-stats {
    padding: 8px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.stat-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.stat {
    font-size: 0.72rem;
    color: var(--text-secondary);
}

.recording-stat {
    display: flex;
    align-items: center;
    gap: 5px;
    color: var(--red);
    font-weight: 600;
}

.rec-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--red);
    animation: rec-blink 1s infinite;
}

@keyframes rec-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.2; }
}

.cam-stat { color: var(--blue); }
.upload-stat { color: var(--yellow); }
.commit-stat { color: var(--text-muted); font-family: monospace; font-size: 0.75rem; }
.offline-stat { color: var(--text-muted); }

.task-row {
    border-top: 1px solid rgba(255,255,255,0.05);
    padding-top: 4px;
    margin-top: 2px;
}

.task-label {
    color: var(--text-primary);
    font-weight: 500;
    max-width: 150px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.operator-label {
    color: var(--text-muted);
    font-style: italic;
}

/* ---------- Pin button ---------- */

.pin-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px 4px;
    border-radius: 4px;
    opacity: 0.3;
    transition: opacity 0.15s, color 0.15s;
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.pin-btn:hover { opacity: 0.7; }

.device-card.pinned .pin-btn,
.pin-btn.active {
    opacity: 1;
    color: var(--yellow);
}

.device-card.pinned {
    box-shadow: 0 0 0 1px var(--yellow), 0 0 8px rgba(250, 204, 21, 0.1);
}

/* ---------- Header alerts dropdown (bell) ---------- */

.fdash-alerts { position: relative; display: flex; align-items: center; }
.fdash-alert-btn { position: relative; }

/* Unread-count bubble on the bell: how many active alerts the viewer hasn't
   seen yet (dashboard.js clears it when the panel opens). */
.fdash-alert-badge {
    position: absolute; top: 2px; right: -1px;
    min-width: 15px; height: 15px; padding: 0 4px; box-sizing: border-box;
    display: flex; align-items: center; justify-content: center;
    border-radius: 999px; background: #ef4444; color: #fff;
    font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; line-height: 1;
    box-shadow: 0 0 0 2px var(--bg-surface);
    pointer-events: none;
}
.fdash-alert-badge[hidden] { display: none; }

.fdash-alert-panel {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 200;
    width: 380px; max-width: calc(100vw - 32px);
    background: var(--bg-surface); border: 1px solid var(--border-subtle);
    border-radius: 12px; box-shadow: 0 8px 28px rgba(16,24,40,0.16), var(--shadow-sm);
    overflow: hidden;
}
.fdash-alert-panel[hidden] { display: none; }

.fdash-alert-panel-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    padding: 12px 14px; border-bottom: 1px solid var(--border-subtle);
}
.fdash-alert-panel-title { font-size: 13.5px; font-weight: 800; color: var(--fg-1); }
.fdash-alert-panel-count { font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: var(--fg-3); }

.fdash-alert-list { max-height: min(440px, 70vh); overflow-y: auto; }

.fdash-alert-row {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 10px 14px; border-bottom: 1px solid var(--border-subtle);
    text-decoration: none; cursor: pointer; transition: background 110ms;
}
.fdash-alert-row:last-child { border-bottom: 0; }
a.fdash-alert-row:hover { background: var(--ws-gray-50); }
.fdash-alert-row-go { color: var(--fg-4); flex-shrink: 0; align-self: center; }
a.fdash-alert-row:hover .fdash-alert-row-go { color: var(--fg-2); }

.fdash-alert-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; }
.fdash-alert-dot.critical { background: var(--ws-danger-500); }
.fdash-alert-dot.warning { background: var(--ws-warning-500); }

.fdash-alert-row-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.fdash-alert-row-dev { font-family: var(--font-mono); font-size: 11.5px; font-weight: 700; color: var(--fg-1); }
.fdash-alert-row-msg { font-size: 12.5px; line-height: 1.35; color: var(--fg-2); }
.fdash-alert-row.critical .fdash-alert-row-msg { color: var(--ws-danger-700); }

.fdash-alert-empty { padding: 22px 14px; text-align: center; font-size: 12.5px; color: var(--fg-3); }
.fdash-alert-empty[hidden] { display: none; }

/* ---------- Fleet Summary Stats ---------- */

.summary-stat {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
}

.summary-stat .count {
    font-weight: 600;
    font-size: 1rem;
}

.summary-stat .count.online { color: var(--green); }
.summary-stat .count.recording { color: var(--red); }
.summary-stat .count.offline { color: var(--text-muted); }

.summary-divider {
    width: 1px;
    height: 20px;
    background: var(--border);
}

.summary-stat .label {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* ---------- Today stats on cards ---------- */

.today-row {
    border-top: 1px solid rgba(255,255,255,0.04);
    padding-top: 3px;
    margin-top: 1px;
}

.today-stat {
    color: var(--green) !important;
    font-size: 0.68rem !important;
    opacity: 0.8;
}

/* ---------- Empty state ---------- */

.empty-state {
    grid-column: 1 / -1;
    text-align: center;
    padding: 80px 20px;
    color: var(--text-muted);
}

.empty-state code {
    background: var(--bg-card);
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 0.85rem;
}

/* ========================================================================
   UVC fleet card (FleetCardA3) — light card for hardware_type=='uvc' rigs.
   Ported from the workstream-fleetboard design (recordings-fleet.css).
   Tokens are scoped to .flc so they don't touch the dark fleet board theme.
   ======================================================================== */
.device-card.flc-card { background: transparent; border: none; box-shadow: none; padding: 0; overflow: visible; }
.device-card.flc-card:hover { box-shadow: none; }  /* lift comes from .device-card:hover; .flc carries its own light shadow */
.flc {
    --fg-1:#2F3340; --fg-2:#4B5563; --fg-3:#6B7280; --fg-4:#9CA3AF;
    --bg-sunken:#F9FAFB; --border-subtle:#E5E7EE; --border-strong:#D1D5DE;
    --ws-gray-100:#F3F4F7; --ws-gray-200:#E5E7EE; --ws-gray-300:#D1D5DE;
    --ws-success-50:#ECFDF3; --ws-success-500:#12B76A; --ws-success-700:#027A48;
    --ws-warning-50:#FFFAEB; --ws-warning-500:#F79009; --ws-warning-700:#B54708;
    --ws-danger-50:#FEF3F2; --ws-danger-500:#F04438; --ws-danger-700:#B42318;
    --ws-blue-50:#EEF4FF; --ws-blue-100:#DCE8FF; --ws-blue-400:#4583FF; --ws-blue-500:#1B66FF; --ws-blue-700:#0F40A8; --ws-standby:#F79009;
    --ws-live-500:#15B870; --ws-live-glow:rgba(21,184,112,.30); --ws-rec-500:#0C9A5C; --ws-rec-50:#E4F8EF;
    --font-mono:'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
    background:#fff; border:1px solid var(--border-subtle); border-radius:16px;
    box-shadow:0 1px 2px rgba(16,24,40,.05); overflow:hidden; color:var(--fg-1);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
    transition:box-shadow 130ms, border-color 130ms;
}
.flc-card:hover .flc { box-shadow:0 4px 8px -2px rgba(16,24,40,.08),0 2px 4px -2px rgba(16,24,40,.04); border-color:var(--border-strong); }
.flc-head { display:flex; align-items:center; gap:9px; padding:13px 15px 8px; }
.flc-head .pin-btn { background:none; border:none; padding:0; cursor:pointer; color:var(--fg-4); display:flex; }
.flc-head .pin-btn.active { color:var(--ws-standby); }
.flc-name { font-family:inherit; font-size:15px; font-weight:700; color:var(--fg-1); letter-spacing:-0.01em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.flc-id { font-weight:500; color:var(--fg-4); font-size:13px; }
.flc-name-devid { font-weight:600; color:var(--fg-4); font-size:12.5px; letter-spacing:0.02em; }
.flc-name-id { font-weight:600; color:var(--fg-4); font-size:12.5px; }
/* </> build indicator: green = on main's tip, gray = behind/diverged. Sits above
   the full-card link overlay (z-index:2, like .pin-btn) so its tooltip shows. */
.flc-build { display:inline-flex; align-items:center; position:relative; z-index:2; flex:none; }
.flc-build svg { width:15px; height:15px; display:block; }
.flc-build.off-latest { color:var(--fg-4); }
.flc-off .flc-build { opacity:0.55; }
/* Ethernet plug icon — shown when a cable is physically plugged in. */
/* Ethernet indicator — small green "ETH" pill. The gap before it matches the
   device-name → device-id spacing (~3.5px). .flc-head sets a 9px flex gap, so a
   negative margin trims it back to that single-space width. */
.flc-eth { display:inline-flex; align-items:center; flex:none; position:relative; z-index:2; margin-left:-5.5px; padding:1px 5px; border-radius:999px; background:var(--ws-success-50); color:var(--ws-success-700); font-size:9px; font-weight:600; letter-spacing:0.04em; line-height:1.5; }
.flc-off .flc-eth { opacity:0.55; }
.flc-pill { display:inline-flex; align-items:center; gap:6px; padding:4px 10px; border-radius:999px; font-size:11.5px; font-weight:700; letter-spacing:0.02em; white-space:nowrap; }
.flc-pill[hidden] { display:none !important; }
.flc-pill-dot { width:6px; height:6px; border-radius:50%; flex:none; }
.flc-pill.pill-online { background:var(--ws-success-50); color:var(--ws-success-700); }
.flc-pill.pill-online .flc-pill-dot { background:var(--ws-success-500); }
.flc-pill.pill-recording { background:var(--ws-rec-50); color:var(--ws-rec-500); }
.flc-pill.pill-recording .flc-pill-dot { background:var(--ws-live-500); box-shadow:0 0 0 3px var(--ws-live-glow); }
@keyframes flc-pill-blink { 0%,48%{ opacity:1; } 49%,100%{ opacity:0.18; } }
.flc-pill-dot.blink { animation: flc-pill-blink 1.1s steps(1,end) infinite; }
.flc-pill.pill-offline { background:var(--ws-gray-100); color:var(--fg-4); }
.flc-pill.pill-offline .flc-pill-dot { background:var(--ws-gray-300); }
.flc-prev { position:relative; margin:0 12px; aspect-ratio:16 / 9; border-radius:11px; overflow:hidden; background:#14161b; }
.flc-prev img { width:100%; height:100%; object-fit:cover; display:block; }
.flc-prev .preview-placeholder { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; color:#8b94a6; font-size:12px; font-weight:600; }
.flc-prev.empty { display:flex; align-items:center; justify-content:center; background:var(--bg-sunken); border:1px dashed var(--border-strong); color:var(--fg-3); }
.flc-prev.relay { display:flex; align-items:center; justify-content:center; background:var(--ws-blue-50); color:var(--ws-blue-500); }
.flc-mobile { display:inline-flex; align-items:center; position:relative; z-index:2; flex:none; padding:3px 9px; border-radius:999px; font-size:11px; font-weight:700; letter-spacing:0.02em; white-space:nowrap; color:var(--ws-blue-700); background:var(--ws-blue-50); margin-right:8px; }
.flc-prev.empty span { font-size:13px; font-weight:600; }
.flc-prev-rec { position:absolute; top:9px; left:10px; display:inline-flex; align-items:center; gap:6px; padding:3px 8px; border-radius:6px; background:rgba(0,0,0,0.5); color:#fff; font-size:10.5px; font-weight:700; letter-spacing:0.06em; z-index:1; }
.flc-rec-dot { width:6px; height:6px; border-radius:50%; background:var(--ws-danger-500); box-shadow:0 0 0 3px rgba(240,68,56,.30); }
.flc-a3-foot { padding:14px 16px 0; }
/* When no recording strip follows (idle/uploading/offline), the chips are the
   card's last row — give them a matching bottom pad so the card is even all around. */
.flc-a3-foot:last-child { padding-bottom:14px; }
.flc-chips { display:flex; gap:8px; }
.flc-chip { flex:1; display:flex; flex-direction:row; align-items:center; justify-content:space-between; gap:8px; padding:9px 12px; border-radius:11px; min-width:0; }
.flc-chip-l { font-size:10.5px; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; opacity:0.9; white-space:nowrap; }
.flc-chip-v { font-family:var(--font-mono); font-size:16px; font-weight:800; display:flex; align-items:baseline; gap:4px; white-space:nowrap; min-width:0; }
.flc-chip-sub { font-family:var(--font-mono); font-size:10px; font-weight:600; opacity:0.7; width:100%; }
.flc-chip.tone-ok { background:var(--ws-success-50); color:var(--ws-success-700); }
.flc-chip.tone-warn { background:var(--ws-warning-50); color:var(--ws-warning-700); }
.flc-chip.tone-bad { background:var(--ws-danger-50); color:var(--ws-danger-700); }
.flc-chip.tone-gray { background:var(--ws-gray-100); color:var(--fg-4); }
.flc-chip.tone-bad-solid { background:var(--ws-danger-500); color:#fff; }
.flc-chip.tone-blue { background:var(--ws-blue-50); color:var(--ws-blue-700); }
.flc-chip-rec { font-family:var(--font-mono); font-size:11px; font-weight:600; opacity:0.6; white-space:nowrap; }
.flc-recbar { display:flex; align-items:center; gap:8px; margin:14px 16px 12px; padding:11px 14px; border-radius:11px; background:var(--ws-gray-100); border:1px solid var(--border-subtle); }
.flc-recbar-time { font-family:var(--font-mono); font-size:14px; font-weight:800; color:var(--fg-1); letter-spacing:-0.01em; }
.flc-recbar-meta { font-size:12px; font-weight:600; color:var(--fg-3); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:62%; }
.flc-svc-action {
    position:relative; z-index:2; flex:none;
    display:inline-flex; align-items:center; gap:6px;
    height:30px; padding:0 13px; border-radius:9px;
    font-family:inherit; font-size:12.5px; font-weight:700; letter-spacing:-0.01em;
    color:var(--ws-warning-700); background:#FFF7ED;
    border:1px solid color-mix(in srgb, var(--ws-warning-500) 45%, transparent);
    cursor:pointer; transition:background .12s, border-color .12s, box-shadow .12s;
}
.flc-svc-action svg { width:14px; height:14px; }
.flc-svc-action:hover { background:#FFEED9; border-color:var(--ws-warning-500); box-shadow:0 1px 3px rgba(247,144,9,.25); }
/* Header-placed service action (offline cards) — compact square icon button
   sitting inline with the status pill, since the recbar is recording-only now. */
.flc-head .flc-svc-head { flex:none; height:26px; width:26px; padding:0; justify-content:center; }
/* "Take back online" on offline In-Service cards — green = return to rotation.
   z-index sits it above the card-link overlay; full-width below the issue meta. */
.flc-svc-online {
    position:relative; z-index:2;
    display:flex; align-items:center; justify-content:center; gap:7px;
    width:100%; margin-top:12px; height:34px; border-radius:9px;
    font-family:inherit; font-size:12.5px; font-weight:700; letter-spacing:-0.01em;
    color:#fff; background:var(--ws-success-600, #079455);
    border:1px solid var(--ws-success-700, #067647);
    cursor:pointer; transition:background .12s, box-shadow .12s, opacity .12s;
}
.flc-svc-online svg { width:15px; height:15px; }
.flc-svc-online:hover { background:var(--ws-success-700, #067647); box-shadow:0 1px 4px rgba(6,118,71,.3); }
.flc-svc-online:disabled { opacity:.65; cursor:default; }
.flc-uphdr { display:inline-flex; align-items:center; gap:6px; font-size:11.5px; font-weight:700; color:var(--ws-blue-700); white-space:nowrap; margin-right:8px; }
.flc-uprate { font-variant-numeric:tabular-nums; }
.flc-spin { width:13px; height:13px; border-radius:50%; flex:none; border:2px solid var(--ws-blue-100); border-top-color:var(--ws-blue-500); animation: flc-spin 0.8s linear infinite; }
@keyframes flc-spin { to { transform: rotate(360deg); } }
/* No `opacity` here: it would create a stacking context that traps the footer's
   Service button (z-index:2) BELOW the full-card link overlay (z-index:1), so
   clicks land on the overlay and navigate instead of opening the modal. The
   sunken bg + dashed border + muted content already read as offline. */
.flc-off { background:var(--bg-sunken); border-style:dashed; }
.flc-off .flc-name { color:var(--fg-3); }
/* Offline cards collapse to just the header — no preview, no vitals chips.
   The header's own padding gives an even border all around. */
.flc-off .flc-prev,
.flc-off .flc-a3-foot { display:none; }
.flc-off .flc-head { padding:14px 15px; }

/* ---- Servicing card: flagged out of rotation for repair (design: Out of Service) ---- */
.flc-pill.pill-servicing { background:var(--ws-warning-50); color:var(--ws-warning-700); }
.flc-svc { background:linear-gradient(180deg, var(--ws-warning-50), #fff 56%); border-color:color-mix(in srgb, var(--ws-warning-500) 30%, var(--border-subtle)); }
.flc-svc .flc-svc-prev { flex-direction:column; gap:6px; height:150px; background:var(--ws-warning-50); border:1px dashed color-mix(in srgb, var(--ws-warning-500) 42%, transparent); color:var(--ws-warning-700); }
.flc-svc .flc-svc-prev span { color:var(--ws-warning-700); font-weight:700; margin-top:2px; }
.flc-svc .flc-svc-prev .flc-prev-sub { font-size:12px; color:var(--ws-warning-700); opacity:0.78; font-weight:500; margin-top:0; }
.flc-svc-body { padding:14px 16px 8px; display:flex; flex-direction:column; }
.flc-svc-issue { display:flex; flex-direction:column; gap:5px; padding-bottom:13px; }
.flc-svc-issue-l { display:inline-flex; align-items:center; gap:6px; font-size:10.5px; font-weight:700; letter-spacing:0.06em; text-transform:uppercase; color:var(--ws-warning-700); }
.flc-svc-issue-h { font-size:14.5px; font-weight:700; color:var(--fg-1); letter-spacing:-0.01em; }
.flc-svc-issue-b { font-size:12.5px; line-height:1.45; color:var(--fg-3); }
.flc-svc-meta { display:flex; align-items:stretch; border-top:1px solid color-mix(in srgb, var(--ws-warning-500) 18%, var(--ws-gray-100)); }
.flc-svc-meta-c { flex:1; min-width:0; display:flex; flex-direction:column; gap:4px; padding:12px 0; }
.flc-svc-meta-c + .flc-svc-meta-c { padding-left:14px; border-left:1px solid color-mix(in srgb, var(--ws-warning-500) 18%, var(--ws-gray-100)); }
.flc-svc-meta-k { font-size:10px; font-weight:700; letter-spacing:0.07em; text-transform:uppercase; color:var(--fg-4); }
.flc-svc-meta-v { font-size:13.5px; font-weight:700; color:var(--fg-1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* =====================================================================
   Tabs (Fleet devices / Hours) + Hours panel
   The Hours tab is a light "analytics" view (matches the design mockup);
   the device grid stays on the existing dark theme. The tab bar and page
   background follow the active view via body.view-hours.
   ===================================================================== */

.tabbar {
    display: flex;
    align-items: stretch;
    gap: 4px;
    height: 46px;
    padding: 0 16px;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 50px;            /* sits directly under the 50px topbar */
    z-index: 90;
}
.tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 0 14px;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-secondary);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
}
.tab svg { width: 16px; height: 16px; }
.tab:hover { color: var(--text-primary); }
.tab.active { color: #fff; border-bottom-color: var(--blue); }

/* Per-tab device count "(N)" shown inline in the tab label */
.tab-count { margin-left: -3px; font-weight: 600; color: var(--text-secondary); }
.tab.active .tab-count { color: #cfe0ff; }
.tab-count.svc { color: #fb923c; }
.tab.active .tab-count.svc { color: #fdba74; }
body.view-hours .tab-count { color: #6b7280; }
body.view-hours .tab.active .tab-count { color: #3b56e0; }
body.view-hours .tab-count.svc { color: #b45309; }

/* Panels */
.panel { display: none; }
.panel.active { display: block; }

/* Light theme for the Hours view */
body.view-hours { background: #f3f5f7; }
body.view-hours .tabbar { background: #fff; border-bottom-color: #e7eaee; }
body.view-hours .tab { color: #6b7280; }
body.view-hours .tab:hover { color: #1f2937; }
body.view-hours .tab.active { color: #1f2937; border-bottom-color: #3b56e0; }

.hours-wrap {
    max-width: 1500px;
    margin: 0 auto;
    padding: 22px 24px 40px;
    color: #1f2937;
}

.hours-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}
.hours-title { font-size: 1.15rem; font-weight: 700; color: #1f2937; letter-spacing: -0.2px; }
.hours-title-note { font-weight: 500; font-size: 0.82rem; color: #9aa3af; white-space: nowrap; }
.hours-sub { font-size: 0.84rem; color: #9aa3af; margin-top: 3px; }
.hours-controls { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.loc-filter {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 12px;
    background: #fff;
    border: 1px solid #e2e6ec;
    border-radius: 10px;
}
.loc-filter svg { width: 15px; height: 15px; color: #9aa3af; }
.loc-filter-label { font-size: 0.8rem; color: #8a93a0; }
.loc-select {
    border: none;
    background: transparent;
    color: #1f2937;
    font-size: 0.85rem;
    font-weight: 600;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    cursor: pointer;
    outline: none;
    max-width: 180px;
}

.seg {
    display: inline-flex;
    background: #ebedf1;
    border-radius: 10px;
    padding: 3px;
}
.seg-btn {
    border: none;
    background: none;
    padding: 6px 16px;
    border-radius: 8px;
    font-size: 0.85rem;
    color: #6b7280;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.seg-btn.active {
    background: #fff;
    color: #1f2937;
    font-weight: 600;
    box-shadow: 0 1px 2px rgba(0,0,0,0.10);
}
/* Compact variant — fits inside a panel head (e.g. the leaderboard switcher) */
.seg-sm { padding: 2px; border-radius: 9px; }
.seg-sm .seg-btn { padding: 4px 12px; font-size: 0.8rem; }

/* Data-source switcher (Supabase ⇄ Device tally) at the top of the Hours page */
.src-switch { display: inline-flex; align-items: center; gap: 8px; }
.src-switch-label {
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em;
    text-transform: uppercase; color: #6b7280;
}
body.src-device .hours-refresh { background: var(--ws-gold-500, #d98e04); border-color: var(--ws-gold-500, #d98e04); color: #fff; }

/* Refresh-from-DB button */
.hours-refresh {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 13px; background: #fff; border: 1px solid #e2e6ec;
    border-radius: 10px; color: #4b5563; font-size: 0.82rem; font-weight: 600;
    cursor: pointer; transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.hours-refresh svg { width: 15px; height: 15px; }
.hours-refresh:hover { color: #3b56e0; border-color: #c7d2fe; background: #f5f7ff; }
.hours-refresh:focus-visible { outline: 2px solid #3b56e0; outline-offset: 2px; }
.hours-refresh:disabled { cursor: default; opacity: 0.75; }
.hours-refresh.spinning svg { animation: hours-refresh-spin 0.8s linear infinite; }
@keyframes hours-refresh-spin { to { transform: rotate(360deg); } }

/* Stat cards */
.stat-cards {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin-bottom: 16px;
}
.scard {
    position: relative;   /* anchors the .scard-hint on the clickable card */
    background: #fff;
    border: 1px solid #e9ebef;
    border-radius: 14px;
    padding: 18px 18px 16px;
    box-shadow: 0 1px 2px rgba(16,24,40,0.04);
}
.scard-icon {
    width: 34px; height: 34px;
    border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 14px;
}
.scard-icon svg { width: 18px; height: 18px; }
.tint-green { background: #e6f6ee; color: #1f9d57; }
.tint-blue  { background: #e9edfd; color: #3b56e0; }
.tint-gray  { background: #eef1f4; color: #6b7280; }
.tint-amber { background: #fdf0e0; color: #d97706; }
.scard-label {
    font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em;
    color: #8a93a0; text-transform: uppercase;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.scard-value {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 2rem; font-weight: 700; color: #1f2937;
    line-height: 1.15; margin: 4px 0 3px;
}
.scard-value.val-green { color: #1f9d57; }
.scard-value.val-blue  { color: #3b56e0; }
.scard-value.val-amber { color: #d97706; }
.scard-value.val-red   { color: #dc2626; }
.scard-foot { font-size: 0.8rem; color: #9aa3af; }

/* Uploads tab (admin) — period pager + throughput stat cards */
/* All 5 stat cards flow in one row at full width, wrapping when the screen narrows. */
/* Two-tier layout: a 2-up hero row (Hours recorded + Productivity) over a
   full-width Uploading progress card. Hero cards use an inline icon+label
   header and a large figure. */
.up-cards-hero { grid-template-columns: repeat(2, 1fr); }
.uph-card { padding: 20px 22px 18px; }
.uph-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.uph-icon { width: 30px; height: 30px; border-radius: 9px; display: flex; align-items: center; justify-content: center; flex: none; }
.uph-icon svg { width: 16px; height: 16px; }
.uph-label { font-size: 0.74rem; font-weight: 700; letter-spacing: 0.09em; color: #8a93a0; text-transform: uppercase; }
.uph-value { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 2.9rem; font-weight: 700; line-height: 1.1; color: #1f2937; }
.uph-value.val-blue { color: #3b56e0; }
.uph-value-sm { font-size: 1.7rem; }
.uph-sub { margin-top: 12px; font-size: 0.85rem; color: #6b7280; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.uph-div { width: 1px; height: 15px; background: #e5e7eb; flex: none; }
/* Productivity: big % (row tier colors) + donut ring on the right. */
.uph-prod-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.uph-value.pv-good { color: #16794c; }
.uph-value.pv-mid { color: #a16207; }
.uph-value.pv-low { color: #b91c1c; }
.uph-ring { width: 84px; height: 84px; flex: none; }
.uph-ring-track { fill: none; stroke: #e9ebef; stroke-width: 9; }
.uph-ring-fill { fill: none; stroke-width: 9; stroke-linecap: round; transform: rotate(-90deg); transform-origin: center; transition: stroke-dasharray 0.35s ease; stroke: #cbd5e1; }
.uph-ring-fill.pv-good { stroke: #34c77b; }
.uph-ring-fill.pv-mid { stroke: #f4b942; }
.uph-ring-fill.pv-low { stroke: #ef7070; }
/* Chevron affordance on the hero cards: "this clicks into a chart".
   Rotates while the card's chart is open. */
.uph-chev { width: 18px; height: 18px; margin-left: auto; color: #b6bdc7; flex: none; transition: transform 0.15s ease; }
.scard-click:hover .uph-chev { color: #3b56e0; }
.scard-click.sel .uph-chev { transform: rotate(180deg); color: #3b56e0; }
.up-pager { display: flex; align-items: center; gap: 14px; margin: 6px 0 20px; }
.up-nav {
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; padding: 0; flex: none;
    border: 1px solid #e2e6ec; border-radius: 10px; background: #fff; color: #6b7280;
    cursor: pointer; transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.up-nav:hover:not(:disabled) { background: #f5f7ff; border-color: #c7d2fe; color: #3b56e0; }
.up-nav:disabled { opacity: 0.4; cursor: default; }
.up-nav svg { width: 17px; height: 17px; }
.up-period { display: flex; flex-direction: column; gap: 5px; min-width: 150px; line-height: 1.2; }
.up-period-label { font-size: 1.05rem; font-weight: 700; color: #1f2937; }
.up-period-range { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.78rem; color: #9aa3af; }
.up-note { font-size: 0.8rem; color: #9aa3af; margin-top: 14px; }

/* Uploads tab — "Who recorded" operator list */
.up-ops { margin-top: 4px; }
.up-ops-head { display: flex; align-items: baseline; gap: 10px; margin: 0 2px 10px; }
.up-ops-sort { margin-left: auto; align-self: center; }
.up-ops-title { font-size: 0.95rem; font-weight: 700; color: #1f2937; }
.up-ops-sub { font-size: 0.8rem; color: #9aa3af; }
.up-ops-list { display: flex; flex-direction: column; background: #fff; border: 1px solid #e9ebef; border-radius: 14px; overflow: hidden; box-shadow: 0 1px 2px rgba(16,24,40,0.04); }
.up-op-row { position: relative; display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-top: 1px solid #f0f2f5; }
.up-op-row:first-child { border-top: none; }
.up-op-bar { position: absolute; left: 0; top: 0; bottom: 0; background: #eef2ff; z-index: 0; }
.up-op-rank, .up-op-name, .up-op-sessions, .up-op-hours { position: relative; z-index: 1; }
.up-op-rank { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.8rem; color: #9aa3af; width: 20px; flex: none; }
.up-op-name { font-size: 0.9rem; font-weight: 600; color: #1f2937; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.up-op-sessions { font-size: 0.8rem; color: #9aa3af; flex: none; }
.up-op-hours { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.95rem; font-weight: 700; color: #3b56e0; flex: none; min-width: 56px; text-align: right; }
.up-ops-empty { padding: 18px 16px; text-align: center; color: #9aa3af; font-size: 0.85rem; }
/* Who-recorded hours cell: "captured / scheduled (productivity%)" — scheduled
   from /api/fleet/uploads/funnel/people; productivity = captured ÷ scheduled.
   Just the captured hours while the roster loads or for unrostered people. */
.up-op-hours-sched { color: #1f2937; font-weight: 600; }
.up-op-pct { font-weight: 700; }
.up-op-pct-good { color: #16794c; }
.up-op-pct-mid { color: #a16207; }
.up-op-pct-low { color: #b91c1c; }

/* Loading skeleton (shimmer) — per-card values/foots + operator rows while a
   period loads, so the tab never briefly reads as "all zero". */
.sk-bar {
    display: inline-block; height: 0.9em; width: 54px; border-radius: 6px; vertical-align: middle;
    background: linear-gradient(90deg, #eef1f4 25%, #e2e7ec 37%, #eef1f4 63%);
    background-size: 400% 100%; animation: sk-shimmer 1.4s ease infinite;
}
.sk-bar.sk-lg { height: 1.5rem; width: 92px; border-radius: 8px; }
@keyframes sk-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* Vertical shimmer bar for the click-through chart panels (metric-over-time
   + speed distribution) so they animate while their fetch is in flight rather
   than sitting blank. Heights are staggered inline so it reads as a chart. */
.sk-col { width: 100%; max-width: 54px; min-height: 3px; border-radius: 6px 6px 0 0;
    background: linear-gradient(180deg, #eef1f4 25%, #e2e7ec 37%, #eef1f4 63%);
    background-size: 100% 400%; animation: sk-shimmer-v 1.4s ease infinite; }
@keyframes sk-shimmer-v { 0% { background-position: 0 100%; } 100% { background-position: 0 0; } }

/* Clickable stat cards → metric-over-time chart */
.scard-click { cursor: pointer; transition: box-shadow 0.12s, border-color 0.12s, transform 0.12s; }
.scard-click:hover { border-color: #c7d2fe; box-shadow: 0 3px 10px rgba(16,24,40,0.08); }
.scard-click:focus-visible { outline: 2px solid #3b56e0; outline-offset: 2px; }
.scard-click.sel { border-color: #3b56e0; box-shadow: 0 0 0 1px #3b56e0, 0 4px 12px rgba(59,86,224,0.14); }

/* Click-through chart panel (metric over time) */
.ups-panel { background: #fff; border: 1px solid #e9ebef; border-radius: 14px; box-shadow: 0 1px 2px rgba(16,24,40,0.04); padding: 16px 18px 14px; margin-bottom: 16px; }
.ups-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.ups-title { font-size: 0.95rem; font-weight: 700; color: #1f2937; }
.ups-title small { font-weight: 500; color: #9aa3af; margin-left: 6px; }
.ups-close { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 0; background: none; color: #9aa3af; cursor: pointer; border-radius: 8px; }
.ups-close:hover { background: #f3f4f7; color: #4b5563; }
.ups-close svg { width: 16px; height: 16px; }
.ups-chart { display: flex; align-items: flex-end; gap: 8px; height: 150px; }
.ups-col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; min-width: 0; }
.ups-val { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.72rem; font-weight: 600; color: #4b5563; margin-bottom: 5px; white-space: nowrap; }
.ups-bar { width: 100%; max-width: 46px; min-height: 3px; border-radius: 6px 6px 0 0; background: #cbd5e1; transition: height 0.35s ease; }
.ups-xaxis { display: flex; gap: 8px; margin-top: 7px; }
.ups-xlabel { flex: 1 1 0; min-width: 0; text-align: center; font-size: 0.68rem; color: #9aa3af; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ups-chart.m-uploaded .ups-bar { background: #34c77b; }
.ups-chart.m-uploading .ups-bar { background: #f4b942; }
.ups-chart.m-scheduled .ups-bar { background: #475569; }
/* Productivity bars are tier-colored per bucket (same thresholds as the cards). */
.ups-bar.pb-good { background: #34c77b; }
.ups-bar.pb-mid { background: #f4b942; }
.ups-bar.pb-low { background: #ef7070; }
/* Emphasize the bar for the pager-selected period; dim the rest. */
.ups-chart.has-sel .ups-bar { opacity: 0.38; }
.ups-chart.has-sel .ups-col.sel .ups-bar { opacity: 1; box-shadow: inset 0 0 0 2px rgba(31,41,55,0.14); }
.ups-col.sel .ups-val { color: #1f2937; font-weight: 700; }
.ups-xlabel.sel { color: #1f2937; font-weight: 700; }

/* Avg-upload-speed card (clickable → distribution) */
#up-speed-card { cursor: pointer; transition: box-shadow 0.12s, border-color 0.12s; }
#up-speed-card:hover { border-color: #c7d2fe; box-shadow: 0 3px 10px rgba(16,24,40,0.08); }
#up-speed-card:focus-visible { outline: 2px solid #3b56e0; outline-offset: 2px; }
#up-speed-card.sel { border-color: #3b56e0; box-shadow: 0 0 0 1px #3b56e0, 0 4px 12px rgba(59,86,224,0.14); }

/* Upload-speed distribution panel */
.uspd-panel { background: #fff; border: 1px solid #e9ebef; border-radius: 14px; box-shadow: 0 1px 2px rgba(16,24,40,0.04); padding: 16px 18px 14px; margin-bottom: 16px; }
.uspd-hist { display: flex; align-items: flex-end; gap: 10px; height: 132px; margin-top: 6px; }
.uspd-bar-col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; min-width: 0; }
.uspd-bar-n { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.72rem; font-weight: 600; color: #4b5563; margin-bottom: 5px; }
.uspd-bar { width: 100%; max-width: 54px; min-height: 3px; border-radius: 6px 6px 0 0; background: #7b8cff; transition: height 0.35s ease; }
.uspd-xaxis { display: flex; gap: 10px; margin-top: 7px; align-items: baseline; }
.uspd-xlabel { flex: 1 1 0; min-width: 0; text-align: center; font-size: 0.68rem; color: #9aa3af; white-space: nowrap; }
.uspd-xunit { font-size: 0.66rem; color: #c2c8d2; flex: none; }
.uspd-empty { padding: 26px 8px; text-align: center; color: #9aa3af; font-size: 0.85rem; line-height: 1.4; }
.uspd-list-head { display: flex; align-items: baseline; gap: 8px; margin: 16px 0 8px; font-size: 0.8rem; font-weight: 700; color: #1f2937; }
.uspd-list-hint { font-weight: 500; color: #9aa3af; font-size: 0.72rem; }
.uspd-list { display: flex; flex-direction: column; border: 1px solid #e9ebef; border-radius: 12px; overflow: hidden; }
.uspd-dev { position: relative; display: flex; align-items: center; gap: 12px; padding: 9px 14px; border-top: 1px solid #f0f2f5; }
.uspd-dev:first-child { border-top: none; }
.uspd-dev-bar { position: absolute; left: 0; top: 0; bottom: 0; background: #eef2ff; z-index: 0; }
.uspd-dev-name, .uspd-dev-peak, .uspd-dev-avg { position: relative; z-index: 1; }
.uspd-dev-name { font-size: 0.88rem; font-weight: 600; color: #1f2937; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.uspd-dev-peak { font-size: 0.72rem; color: #9aa3af; flex: none; }
.uspd-dev-avg { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.9rem; font-weight: 700; color: #3b56e0; flex: none; min-width: 74px; text-align: right; }

/* Devices-still-uploading list (Uploading card click-through) — reuses .uspd-dev */
.upif-meta { position: relative; z-index: 1; font-size: 0.72rem; color: #9aa3af; flex: none; white-space: nowrap; }
.upif-rate { position: relative; z-index: 1; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.78rem; font-weight: 700; color: #16a34a; flex: none; min-width: 66px; text-align: right; }
.upif-rate.upif-stalled { color: #d0842a; font-family: inherit; font-weight: 600; font-size: 0.72rem; }
.upif-rate.upif-recording { color: #9aa3af; font-family: inherit; font-weight: 600; font-size: 0.72rem; }

/* Sessions-recorded card click-through → per-session checkbox list. The card is
   clickable on its own (not via the .scard-click chart path), so it carries its
   own affordance + selected highlight, mirroring .scard-click. */
#up-sessions-card { cursor: pointer; transition: box-shadow 0.12s, border-color 0.12s, transform 0.12s; }
#up-sessions-card:hover { border-color: #c7d2fe; box-shadow: 0 3px 10px rgba(16,24,40,0.08); }
#up-sessions-card:focus-visible { outline: 2px solid #3b56e0; outline-offset: 2px; }
#up-sessions-card.sel { border-color: #3b56e0; box-shadow: 0 0 0 1px #3b56e0, 0 4px 12px rgba(59,86,224,0.14); }

/* Session list rows (checkbox to hide from totals) — reuses the .uspd-list frame. */
.upsess-list { max-height: 60vh; overflow-y: auto; }
.upsess-row { display: flex; align-items: center; gap: 12px; padding: 8px 14px; border-top: 1px solid #f0f2f5; cursor: pointer; }
.upsess-row:first-child { border-top: none; }
.upsess-row:hover { background: #f7f8fb; }
.upsess-cb { flex: none; width: 16px; height: 16px; margin: 0; accent-color: #3b56e0; cursor: pointer; }
.upsess-body { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.upsess-body .uspd-dev-name { flex: none; }
.upsess-meta { position: static; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.upsess-when { flex: none; font-size: 0.75rem; color: #6b7280; white-space: nowrap; }
.upsess-dur { flex: none; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.8rem; font-weight: 700; color: #1f2937; min-width: 52px; text-align: right; }
.upsess-klass { flex: none; font-size: 0.68rem; font-weight: 700; padding: 2px 7px; border-radius: 999px; white-space: nowrap; min-width: 62px; text-align: center; }
.upsess-klass.k-ok { color: #15803d; background: #dcfce7; }
.upsess-klass.k-ing { color: #1d4ed8; background: #dbeafe; }
.upsess-klass.k-bad { color: #b91c1c; background: #fee2e2; }
.upsess-klass.k-na { color: #6b7280; background: #f1f3f5; }
/* A hidden (un-checked) session — dimmed + struck so it reads as "not counted". */
.upsess-row.is-hidden { opacity: 0.5; }
.upsess-row.is-hidden .uspd-dev-name { text-decoration: line-through; }

/* "Who recorded" row expand → sessions */
.up-op-expandable .up-op-row { cursor: pointer; }
.up-op-expandable .up-op-row:hover { background: #f8f9fc; }
.up-op-caret { position: relative; z-index: 1; width: 14px; height: 14px; flex: none; color: #9aa3af; transition: transform 0.15s ease; }
.up-op.open .up-op-caret { transform: rotate(90deg); }
.up-op-caret-spacer { width: 14px; flex: none; }
.up-op:not(:first-child) .up-op-row { border-top: 1px solid #f0f2f5; }
.up-op.open { background: #fbfcfe; }
.up-op-detail { padding: 4px 16px 12px 46px; background: #fbfcfe; border-top: 1px solid #f0f2f5; }
.up-sd-head, .up-sd-row { display: grid; grid-template-columns: 1.4fr 1.3fr 0.7fr 0.9fr; gap: 10px; align-items: center; }
.up-sd-head { padding: 8px 0 6px; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: #b0b6c0; }
.up-sd-row { padding: 6px 0; border-top: 1px solid #f0f2f5; }
.up-sd-rig { font-size: 0.84rem; font-weight: 600; color: #1f2937; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.up-sd-time { font-size: 0.8rem; color: #6b7280; }
.up-sd-dur { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.8rem; color: #4b5563; }
.up-sd-pill { justify-self: start; font-size: 0.7rem; font-weight: 700; padding: 2px 9px; border-radius: 999px; white-space: nowrap; }
.up-sd-pill.sd-uploaded { background: #e7f7ee; color: #067647; }
.up-sd-pill.sd-uploading { background: #eef2ff; color: #3b56e0; }
.up-sd-pill.sd-failed { background: #fdecec; color: #c0392b; }
.up-sd-more { padding: 8px 0 2px; font-size: 0.74rem; color: #9aa3af; }

/* Chart */
.chart-card {
    background: #fff;
    border: 1px solid #e9ebef;
    border-radius: 14px;
    padding: 20px 24px 22px;
    box-shadow: 0 1px 2px rgba(16,24,40,0.04);
}
.chart-title { font-size: 1rem; font-weight: 600; color: #1f2937; }
.chart-sub { font-size: 0.82rem; color: #9aa3af; margin-top: 2px; margin-bottom: 22px; }
.bars {
    display: flex;
    align-items: flex-end;
    gap: 14px;
    height: 320px;
}
.bar-col {
    flex: 1 1 0;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    min-width: 0;
}
.bar-val {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.78rem;
    color: #6b7280;
    margin-bottom: 8px;
}
.bar-fill {
    width: 100%;
    max-width: 78px;
    border-radius: 8px 8px 0 0;
    background: linear-gradient(180deg, #46a86e 0%, #88d4a4 100%);
    transition: height 0.35s ease;
}
.bar-labels {
    display: flex;
    gap: 14px;
    margin-top: 10px;
}
.bar-x {
    flex: 1 1 0;
    text-align: center;
    font-size: 0.78rem;
    color: #9aa3af;
    min-width: 0;
}
.hours-empty {
    padding: 60px 0;
    text-align: center;
    color: #9aa3af;
    font-size: 0.9rem;
}

@media (max-width: 900px) {
    .stat-cards { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
    .stat-cards { grid-template-columns: 1fr; }
    .bar-val, .bar-x { font-size: 0.68rem; }
}

/* Beta callout — small but obvious pill next to the title */
.beta-badge {
    display: inline-block;
    vertical-align: middle;
    position: relative;
    top: -2px;
    margin-left: 8px;
    padding: 3px 9px;
    border-radius: 999px;
    background: #fff4d6;
    color: #b45309;
    border: 1px solid #f6c453;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* ---- Extras section (ops Event Reporting API analytics) ---- */
.extras { margin-top: 28px; }
.extras[hidden] { display: none; }
.extras-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
    padding-top: 22px; border-top: 1px solid #e4e7ec;
}
.extras-title { font-size: 1.1rem; font-weight: 700; color: #1f2937; letter-spacing: -0.2px; }
.extras-badge {
    display: inline-block; vertical-align: middle; position: relative; top: -2px;
    margin-left: 8px; padding: 3px 9px; border-radius: 999px;
    background: #e9edfd; color: #3b56e0; border: 1px solid #c7d2fe;
    font-size: 0.6rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
}
.extras-sub { font-size: 0.84rem; color: #9aa3af; margin-top: 4px; }
.extras-stamp { font-size: 0.76rem; color: #9aa3af; font-family: ui-monospace, "SF Mono", Menlo, monospace; white-space: nowrap; }
.extras-head-right { display: flex; flex-direction: column; align-items: flex-end; gap: 7px; }

.extras-rawbtn {
    appearance: none; border: 1px solid #e2e6ec; background: #fff;
    color: #6b7280; font-size: 0.76rem; font-weight: 600;
    padding: 5px 11px; border-radius: 8px; cursor: pointer; white-space: nowrap;
    transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.extras-rawbtn:hover { color: #3b56e0; border-color: #c7d2fe; background: #f5f7ff; }
.extras-rawbtn[aria-expanded="true"] { color: #3b56e0; border-color: #c7d2fe; background: #eef2ff; }

/* Raw per-session table */
.extras-raw { margin-top: 18px; background: #fff; border: 1px solid #e9ebef; border-radius: 14px; padding: 14px 16px 16px; box-shadow: 0 1px 2px rgba(16,24,40,0.04); }
.extras-raw[hidden] { display: none; }
.extras-raw-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.extras-raw-count { font-size: 0.78rem; color: #8a93a0; }
.extras-raw-csv { appearance: none; border: 1px solid #e2e6ec; background: #fff; color: #6b7280; font-size: 0.74rem; font-weight: 600; padding: 5px 11px; border-radius: 8px; cursor: pointer; }
.extras-raw-csv:hover { color: #3b56e0; border-color: #c7d2fe; background: #f5f7ff; }
.extras-raw-scroll { overflow: auto; max-height: 420px; border: 1px solid #eef1f4; border-radius: 10px; }
.extras-raw-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.extras-raw-table th {
    position: sticky; top: 0; background: #f7f9fb; color: #6b7280; font-weight: 700;
    text-align: left; padding: 8px 10px; border-bottom: 1px solid #e6e9ee; white-space: nowrap; z-index: 1;
}
.extras-raw-table td {
    padding: 7px 10px; border-bottom: 1px solid #f0f2f5; color: #36404c;
    white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis;
}
.extras-raw-table tr:last-child td { border-bottom: none; }
.extras-raw-table tbody tr:hover td { background: #fafbfc; }
.extras-raw-table .raw-empty { text-align: center; color: #9aa3af; padding: 18px 0; white-space: normal; }
.extras-note {
    background: #fff; border: 1px dashed #d7dbe2; border-radius: 12px;
    padding: 22px; text-align: center; color: #8a93a0; font-size: 0.9rem;
}
.extras-note[hidden], .extras-body[hidden] { display: none; }

/* Headline stat tiles */
.xstat-grid {
    display: grid; grid-template-columns: repeat(4, 1fr);
    gap: 14px; margin-bottom: 20px;
}
.xstat {
    background: #fff; border: 1px solid #e9ebef; border-radius: 13px;
    padding: 14px 16px 13px; box-shadow: 0 1px 2px rgba(16,24,40,0.04);
}
.xstat-label {
    font-size: 0.68rem; font-weight: 600; letter-spacing: 0.04em;
    color: #8a93a0; text-transform: uppercase;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.xstat-value {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 1.55rem; font-weight: 700; color: #1f2937; line-height: 1.15; margin: 5px 0 2px;
}
.xstat-value.val-green { color: #1f9d57; }
.xstat-value.val-blue  { color: #3b56e0; }
.xstat-value.val-gray  { color: #1f2937; }
.xstat-foot { font-size: 0.74rem; color: #9aa3af; min-height: 1em; }

/* Leaderboards */
.lboard-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.lboard {
    background: #fff; border: 1px solid #e9ebef; border-radius: 14px;
    padding: 18px 20px 16px; box-shadow: 0 1px 2px rgba(16,24,40,0.04);
}
.lboard-title { font-size: 0.95rem; font-weight: 700; color: #1f2937; display: flex; align-items: center; gap: 8px; }
.lboard-ic { font-size: 1rem; }
.lboard-cap { font-size: 0.78rem; color: #9aa3af; margin: 2px 0 14px; }
.lboard-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.lboard-empty { color: #9aa3af; font-size: 0.84rem; padding: 8px 0; }
.lrow { display: grid; grid-template-columns: 20px minmax(0, 1fr) 90px auto; align-items: center; gap: 10px; }
.lrank { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.78rem; font-weight: 700; color: #c0c6cf; text-align: center; }
.lname { font-size: 0.86rem; font-weight: 600; color: #1f2937; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lbar { height: 7px; background: #eef1f4; border-radius: 999px; overflow: hidden; }
.lbar-fill { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, #3b56e0, #6f86f0); }
.lval { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.88rem; font-weight: 700; color: #1f2937; text-align: right; white-space: nowrap; }
.lsub { color: #9aa3af; font-weight: 600; font-size: 0.74rem; margin-left: 6px; }
.lsub::before { content: ""; }

@media (max-width: 900px) {
    .xstat-grid { grid-template-columns: repeat(2, 1fr); }
    .lboard-grid { grid-template-columns: 1fr; }
}
@media (max-width: 520px) {
    .xstat-grid { grid-template-columns: 1fr; }
    .lrow { grid-template-columns: 18px minmax(0, 1fr) auto; }
    .lrow .lbar { display: none; }
}

/* Clickable Devices Used card */
.scard-clickable { cursor: pointer; transition: box-shadow 0.15s, border-color 0.15s, transform 0.05s; }
.scard-clickable:hover { border-color: #c7d2fe; box-shadow: 0 3px 12px rgba(59,86,224,0.13); }
.scard-clickable:active { transform: translateY(1px); }
.scard-clickable:focus-visible { outline: 2px solid #3b56e0; outline-offset: 2px; }
.scard-hint {
    position: absolute;
    top: 16px;
    right: 16px;
    font-size: 0.7rem;
    font-weight: 600;
    color: #3b56e0;
    opacity: 0.65;
    transition: opacity 0.15s;
}
.scard-clickable:hover .scard-hint,
.scard-clickable:focus-visible .scard-hint { opacity: 1; }

/* Modal */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(17,24,39,0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.modal-overlay[hidden] { display: none; }
.modal {
    background: #fff;
    border-radius: 14px;
    width: 100%;
    max-width: 420px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 24px 60px rgba(0,0,0,0.28);
    overflow: hidden;
}
.modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 18px 20px 4px;
}
.modal-title { font-size: 1.05rem; font-weight: 700; color: #1f2937; }
.modal-close {
    border: none;
    background: none;
    font-size: 1.6rem;
    line-height: 1;
    color: #9aa3af;
    cursor: pointer;
    padding: 0 4px;
}
.modal-close:hover { color: #1f2937; }
.modal-sub { padding: 0 20px 12px; font-size: 0.8rem; color: #9aa3af; }
.modal-body { padding: 0 20px 20px; overflow-y: auto; }
.dev-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 0;
    border-top: 1px solid #eef1f4;
}
.dev-row:first-child { border-top: none; }
.dev-name { font-weight: 600; color: #1f2937; font-size: 0.9rem; }
.dev-id {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.78rem;
    color: #8a93a0;
    white-space: nowrap;
}
.modal-empty { padding: 24px 0; text-align: center; color: #9aa3af; font-size: 0.88rem; }

/* ===== Edit Cohort (Data tab) =====
   Button sits inline with the Day|Week|Month toggle; the modal lists everyone
   who recorded over the past month with a checkbox + their program(s). */
.cohort-btn {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 13px; background: #fff; border: 1px solid #e2e6ec;
    border-radius: 10px; color: #4b5563; font-size: 0.82rem; font-weight: 600;
    cursor: pointer; transition: color 0.12s, border-color 0.12s, background 0.12s;
    white-space: nowrap;
}
.cohort-btn svg { width: 15px; height: 15px; }
.cohort-btn:hover { color: #3b56e0; border-color: #c7d2fe; background: #f5f7ff; }
.cohort-btn:focus-visible { outline: 2px solid #3b56e0; outline-offset: 2px; }
/* A saved (non-everyone) cohort is an active filter — make it visible. */
.cohort-btn.filtered { color: #3b56e0; border-color: #c7d2fe; background: #f0f3ff; }
/* Icon-only reset button beside Edit Cohort (same white-box language). */
.cohort-reset-btn { padding: 7px 9px; }

.cohort-modal { max-width: 520px; }
.cohort-search {
    display: flex; align-items: center; gap: 8px;
    margin: 0 20px 10px;
    padding: 7px 11px;
    background: #f6f7f9;
    border: 1px solid #e2e6ec;
    border-radius: 10px;
    color: #9aa3af;
}
.cohort-search:focus-within { border-color: #c7d2fe; background: #fff; }
.cohort-search svg { flex: none; }
.cohort-search input {
    flex: 1; min-width: 0;
    border: none; background: transparent; outline: none;
    font: inherit; font-size: 0.86rem; color: #1f2937;
}
.cohort-search input::placeholder { color: #9aa3af; }
.cohort-search-clear {
    display: inline-flex; align-items: center; justify-content: center;
    border: none; background: none; padding: 2px; color: #9aa3af; cursor: pointer;
}
.cohort-search-clear:hover { color: #1f2937; }
/* The explicit display on these rules beats the UA [hidden] rule / the plain
   .cohort-row rule below, so the hidden states need their own higher-
   specificity display:none — without it search "filtering" changes nothing. */
.cohort-search-clear[hidden] { display: none; }
.cohort-row.cohort-row-hidden { display: none; }
.cohort-tools {
    display: flex; align-items: center; gap: 8px;
    padding: 0 20px 10px;
    border-bottom: 1px solid #eef1f4;
}
.cohort-tool {
    border: 1px solid #e2e6ec; background: #fff; border-radius: 8px;
    padding: 5px 11px; font-size: 0.78rem; font-weight: 600; color: #4b5563;
    cursor: pointer; transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.cohort-tool:hover { color: #3b56e0; border-color: #c7d2fe; background: #f5f7ff; }
.cohort-count { margin-left: auto; font-size: 0.78rem; color: #8a93a0; white-space: nowrap; }

.cohort-list { padding: 4px 20px; min-height: 120px; }
.cohort-row {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 2px;
    border-top: 1px solid #eef1f4;
    cursor: pointer;
}
.cohort-row:first-child { border-top: none; }
.cohort-row:hover { background: #fafbfc; }
.cohort-cb { width: 16px; height: 16px; accent-color: #3b56e0; cursor: pointer; flex: none; }
.cohort-who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cohort-name {
    font-weight: 600; color: #1f2937; font-size: 0.9rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cohort-meta { font-size: 0.75rem; color: #9aa3af; }
.cohort-progs {
    margin-left: auto; display: flex; flex-wrap: wrap; gap: 4px;
    justify-content: flex-end; flex: none; max-width: 46%;
}
.cohort-prog {
    display: inline-block; padding: 2px 9px; border-radius: 999px;
    background: #eef2ff; color: #3b56e0;
    font-size: 0.72rem; font-weight: 600; white-space: nowrap;
}
.cohort-prog-none { background: #f3f4f6; color: #9aa3af; }

.cohort-foot {
    display: flex; justify-content: flex-end; gap: 10px;
    padding: 14px 20px;
    border-top: 1px solid #eef1f4;
    background: #fafbfc;
}
.cohort-btn-cancel {
    border: 1px solid #e2e6ec; background: #fff; border-radius: 9px;
    padding: 8px 16px; font-size: 0.84rem; font-weight: 600; color: #4b5563;
    cursor: pointer; transition: color 0.12s, border-color 0.12s;
}
.cohort-btn-cancel:hover { color: #1f2937; border-color: #cbd2dc; }
.cohort-btn-save {
    border: none; background: #3b56e0; border-radius: 9px;
    padding: 8px 20px; font-size: 0.84rem; font-weight: 700; color: #fff;
    cursor: pointer; transition: background 0.12s;
}
.cohort-btn-save:hover { background: #3049c4; }
.cohort-btn-save:focus-visible { outline: 2px solid #3b56e0; outline-offset: 2px; }

/* ===== Service-mode flag modal (offline-card "Service" action) =====
   Light card, amber accents — matches the rig device-page modal and the light
   flc cards. Rendered at page level (outside the .flc var scope), so explicit. */
.svc-modal { position:fixed; inset:0; z-index:1000; display:flex; align-items:flex-start; justify-content:center; padding:76px 20px 20px; }
.svc-modal[aria-hidden="true"] { display:none; }
.svc-modal-backdrop { position:absolute; inset:0; background:rgba(16,18,26,0.55); backdrop-filter:blur(3px); }
.svc-modal-card {
    position:relative; width:100%; max-width:460px; background:#fff; color:#2F3340;
    border-radius:18px; box-shadow:0 24px 60px rgba(0,0,0,0.32); overflow:hidden;
    animation:svc-pop .15s cubic-bezier(.2,.8,.2,1);
}
@keyframes svc-pop { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
.svc-modal-x { position:absolute; top:12px; right:12px; width:30px; height:30px; border:none; background:transparent; color:#6B7280; font-size:22px; line-height:1; border-radius:8px; cursor:pointer; }
.svc-modal-x:hover { background:#F3F4F7; }
.svc-modal-head { display:flex; gap:13px; padding:20px 40px 16px 22px; border-bottom:1px solid #E5E7EE; background:linear-gradient(180deg, #FFF6EA, transparent); }
.svc-modal-ic { width:40px; height:40px; border-radius:12px; flex:none; display:flex; align-items:center; justify-content:center; background:#FFF3E2; border:1px solid rgba(247,144,9,0.4); color:#B25E09; }
.svc-modal-ic svg { width:20px; height:20px; }
.svc-modal-title { font-size:17px; font-weight:700; color:#2F3340; margin:0; }
.svc-modal-sub { font-size:13px; color:#6B7280; margin:4px 0 0; line-height:1.5; }
.svc-modal-body { padding:18px 22px 6px; display:flex; flex-direction:column; gap:14px; }
.svc-field { display:flex; flex-direction:column; gap:6px; }
.svc-label { font-size:12px; font-weight:700; letter-spacing:0.02em; color:#2F3340; }
.svc-input {
    font-family:inherit; font-size:14px; color:#2F3340; padding:10px 12px; border-radius:10px;
    border:1px solid #D1D5DE; background:#fff; outline:none; width:100%; box-sizing:border-box;
    transition:border-color .12s, box-shadow .12s;
}
.svc-input::placeholder { color:#9CA3AF; }
.svc-input:focus { border-color:#F79009; box-shadow:0 0 0 3px rgba(247,144,9,0.18); }
.svc-textarea { resize:vertical; min-height:76px; line-height:1.5; }
.svc-modal-err { color:#B42318; font-size:13px; font-weight:600; }
.svc-modal-err[hidden] { display:none; }
.svc-modal-foot { display:flex; align-items:center; justify-content:flex-end; gap:10px; padding:14px 22px 20px; }
.svc-btn { display:inline-flex; align-items:center; gap:6px; height:36px; padding:0 15px; border-radius:10px; font-size:13px; font-weight:600; cursor:pointer; border:none; font-family:inherit; white-space:nowrap; }
.svc-btn svg { width:14px; height:14px; }
.svc-btn.ghost { background:#fff; color:#2F3340; border:1px solid #D1D5DE; }
.svc-btn.ghost:hover { background:#F3F4F7; }
.svc-btn.amber { background:#F79009; color:#fff; box-shadow:0 4px 12px rgba(247,144,9,0.3); }
.svc-btn.amber:hover { background:#E07C00; }
.svc-btn:disabled { opacity:.55; cursor:not-allowed; }
body.svc-modal-open { overflow:hidden; }

/* ════════════════════════════════════════════════════════════════════════
   FLEET DASHBOARD REDESIGN — light shell (Fleet Dashboard.html, 2026-06-19)
   Light design tokens (ws-tokens.css subset). New names — NO collision with the
   dark v1 palette above (--bg-primary/--blue/--state-*), which the oak4 black
   cards still depend on. The light look applies to the page chrome + uvc cards;
   oak4 cards keep their own dark surfaces as intentional dark islands.
   ════════════════════════════════════════════════════════════════════════ */
:root {
  --ws-blue-50:#EEF4FF; --ws-blue-100:#DCE8FF; --ws-blue-200:#B8D1FF; --ws-blue-300:#7FAAFF;
  --ws-blue-400:#4583FF; --ws-blue-500:#1B66FF; --ws-blue-600:#1453D6; --ws-blue-700:#0F40A8;
  --ws-gray-50:#F9FAFB; --ws-gray-100:#F3F4F7; --ws-gray-200:#E5E7EE; --ws-gray-300:#D1D5DE;
  --ws-gray-400:#9CA3AF; --ws-gray-500:#6B7280; --ws-gray-600:#4B5563; --ws-gray-700:#2F3340;
  --ws-success-50:#ECFDF3; --ws-success-500:#12B76A; --ws-success-600:#079455; --ws-success-700:#027A48;
  --ws-warning-50:#FFFAEB; --ws-warning-500:#F79009; --ws-warning-700:#B54708;
  --ws-danger-50:#FEF3F2; --ws-danger-500:#F04438; --ws-danger-700:#B42318;
  --ws-gold-500:#E6A23C; --ws-live-500:#15B870; --ws-live-glow:rgba(21,184,112,.30);
  --ws-rec-500:#0C9A5C; --ws-rec-50:#E4F8EF; --ws-standby:#F79009; --ws-stream:#1B66FF;
  --bg-app:var(--ws-gray-100); --bg-surface:#fff; --bg-sunken:var(--ws-gray-50);
  --fg-1:var(--ws-gray-700); --fg-2:var(--ws-gray-600); --fg-3:var(--ws-gray-500); --fg-4:var(--ws-gray-400);
  --border-subtle:var(--ws-gray-200); --border-strong:var(--ws-gray-300);
  --font-sans:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --shadow-xs:0 1px 2px rgba(16,24,40,0.05); --shadow-sm:0 1px 3px rgba(16,24,40,0.08),0 1px 2px rgba(16,24,40,0.04);
}
@keyframes ws-pulse { 0%,100%{opacity:1} 50%{opacity:.35} }

/* Light shell: the whole board goes light; oak4 .device-card carry their own
   dark bg (set in the dark block above) so they read as intentional dark cards. */
body.fleet-light { background: var(--bg-app); color: var(--fg-2); font-family: var(--font-sans); }

.fdash-header { position: sticky; top: 0; z-index: 100; background: #fff; border-bottom: 1px solid var(--border-subtle); }
.fdash-bar { max-width: 1440px; margin: 0 auto; display: flex; align-items: center; gap: 24px; padding: 0 28px; height: 58px; }
.fdash-logo { display: flex; align-items: center; gap: 11px; }
.fdash-logo-text { font-size: 16px; font-weight: 800; letter-spacing: -0.01em; white-space: nowrap; color: var(--fg-1); }
.fdash-actions { display: flex; align-items: center; gap: 8px; }
.fdash-icon-btn { width: 32px; height: 36px; border: 0; background: none; display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: .75; transition: opacity .12s; }
.fdash-icon-btn:hover { opacity: 1; }
.fdash-logout { display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 6px; border: 0; background: none; font-family: var(--font-sans); font-size: 13.5px; font-weight: 600; color: var(--fg-2); cursor: pointer; white-space: nowrap; text-decoration: none; }
.fdash-logout:hover { color: var(--fg-1); }
/* Program filter — pill select, same convention as .fd-sort (rounded surface
   pill, native chevron replaced with the shared inline-SVG caret). */
.fdash-program { display: inline-flex; align-items: center; height: 36px; padding: 0 12px; border-radius: 999px; background: var(--bg-surface); border: 1px solid var(--border-subtle); transition: border-color .12s; }
.fdash-program:hover { border-color: var(--border-strong); }
.fdash-program:focus-within { border-color: var(--ws-blue-400); box-shadow: 0 0 0 3px var(--ws-blue-50); }
.fdash-program select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  border: 0; outline: 0;
  font-family: var(--font-sans); font-size: 13px; font-weight: 700; color: var(--fg-2);
  cursor: pointer;
  padding: 0 20px 0 0;
  background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2398a2b3' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 1px center;
  background-size: 13px;
}
.fdash-program select::-ms-expand { display: none; }
.fdash-program select option { font-weight: 600; color: var(--fg-1); background: var(--bg-surface); }
.fdash-poll { width: 8px; height: 8px; border-radius: 50%; background: var(--ws-success-500); display: inline-block; animation: ws-pulse 2s infinite; margin: 0 4px; }
.fdash-tabs-row { background: #fff; border-bottom: 1px solid var(--border-subtle); }
.fdash-tabs { max-width: 1440px; margin: 0 auto; display: flex; align-items: center; gap: 4px; padding: 0 28px; }
.fdash-tab { display: inline-flex; align-items: center; gap: 8px; border: 0; background: none; cursor: pointer; padding: 12px 4px; margin-right: 22px; font-family: var(--font-sans); font-size: 14px; font-weight: 700; color: var(--fg-3); border-bottom: 2.5px solid transparent; transition: color 120ms; }
.fdash-tab:hover { color: var(--fg-1); }
.fdash-tab.active { color: var(--fg-1); border-bottom-color: var(--ws-blue-500); }
.fdash-body { max-width: 1440px; margin: 0 auto; padding: 24px 28px 64px; }

/* ════ Devices page ════ */
.fd-page { display: flex; flex-direction: column; gap: 20px; }
.fd-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fd-chip { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--border-subtle); background: var(--bg-surface); border-radius: 999px; padding: 8px 14px; font-family: var(--font-sans); font-size: 13px; font-weight: 700; color: var(--fg-2); cursor: pointer; transition: all 120ms; }
.fd-chip:hover { border-color: var(--border-strong); }
.fd-chip.active { background: var(--ws-blue-50); border-color: var(--ws-blue-300); color: var(--ws-blue-700); }
.fd-chip-n { font-family: var(--font-mono); font-size: 11.5px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--ws-gray-100); color: var(--fg-3); }
.fd-chip.active .fd-chip-n { background: rgba(27,102,255,0.14); color: var(--ws-blue-700); }
.fd-chip-alertdot { width: 7px; height: 7px; border-radius: 50%; background: var(--ws-danger-500); flex: none; }
.fd-chip.alerts { color: var(--ws-danger-700); border-color: rgba(240,68,56,0.32); }
.fd-chip.alerts:hover { border-color: var(--ws-danger-500); }
.fd-chip.alerts .fd-chip-n { background: var(--ws-danger-50); color: var(--ws-danger-700); }
.fd-chip.alerts.active { background: var(--ws-danger-500); border-color: var(--ws-danger-500); color: #fff; }
.fd-chip.alerts.active .fd-chip-alertdot { background: #fff; }
.fd-chip.alerts.active .fd-chip-n { background: rgba(255,255,255,0.20); color: #fff; }
.fd-chip.svc { color: var(--ws-warning-700); border-color: color-mix(in srgb, var(--ws-warning-500) 32%, var(--border-subtle)); }
.fd-chip.svc:hover { border-color: var(--ws-warning-500); }
.fd-chip.svc .fd-chip-n { background: var(--ws-warning-50); color: var(--ws-warning-700); }
.fd-chip.svc.active { background: var(--ws-warning-500); border-color: var(--ws-warning-500); color: #fff; }
.fd-chip.svc.active .fd-chip-n { background: rgba(255,255,255,0.22); color: #fff; }
.fd-sort { display: flex; align-items: center; height: 38px; padding: 0 12px; border-radius: 999px; background: var(--bg-surface); border: 1px solid var(--border-subtle); flex: none; }
.fd-sort:hover { border-color: var(--border-strong); }
.fd-sort select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  border: 0; outline: 0;
  font-family: var(--font-sans); font-size: 13px; font-weight: 700; color: var(--fg-2);
  cursor: pointer;
  padding: 0 20px 0 0;
  background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2398a2b3' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 1px center;
  background-size: 13px;
}
.fd-sort select::-ms-expand { display: none; }
.fd-sort select option { font-weight: 600; color: var(--fg-1); background: var(--bg-surface); }
.fd-search { display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px; border-radius: 999px; background: var(--bg-surface); border: 1px solid var(--border-subtle); width: 280px; cursor: text; overflow: hidden; transition: width 160ms ease; }
.fd-search input { flex: 1; border: 0; outline: 0; background: transparent; font-family: var(--font-sans); font-size: 13.5px; color: var(--fg-1); min-width: 0; }
.fd-search input::placeholder { color: var(--fg-4); }
/* Collapsed: just the search icon; click to expand into the full input. */
.fd-search.collapsed { width: 38px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
/* Keep the input rendered (width:0, not display:none) so focus() always lands and
   the very first keystroke isn't dropped by a display:none→focus render race. */
.fd-search.collapsed input { width: 0; min-width: 0; flex: 0 0 0; padding: 0; }
.fd-search.collapsed .fd-search-clear { display: none; }
.fd-search.collapsed:hover { border-color: var(--border-strong); }
.fd-search-clear { width: 22px; height: 22px; border-radius: 6px; border: 0; background: var(--ws-gray-100); display: flex; align-items: center; justify-content: center; cursor: pointer; flex: none; }
.fd-search-clear:hover { background: var(--ws-gray-200); }

/* Preview toggle — show/hide live camera previews on every card at once. */
.fd-prev-toggle { display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 14px 0 10px; border-radius: 999px; background: var(--bg-surface); border: 1px solid var(--border-subtle); cursor: pointer; flex: none; }
.fd-prev-toggle:hover { border-color: var(--border-strong); }
.fd-prev-track { position: relative; width: 30px; height: 18px; border-radius: 999px; background: var(--ws-gray-200); transition: background .15s ease; flex: none; }
.fd-prev-knob { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.25); transition: transform .15s ease; }
.fd-prev-toggle[aria-checked="true"] .fd-prev-track { background: var(--ws-success-500, var(--ws-blue-500)); }
.fd-prev-toggle[aria-checked="true"] .fd-prev-knob { transform: translateX(12px); }
.fd-prev-label { font-family: var(--font-sans); font-size: 13.5px; font-weight: 600; color: var(--fg-2); }
/* Previews are hidden until the toggle is on. The servicing card's
   "out of rotation" status box (.flc-svc-prev) reuses .flc-prev but is repair
   info, not a camera feed — keep it visible. */
body:not(.previews-on) .flc-prev:not(.flc-svc-prev),
body:not(.previews-on) .preview-grid { display: none; }
.fd-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 1100px) { .fd-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 720px) { .fd-grid { grid-template-columns: 1fr; } }
.fd-empty { text-align: center; padding: 70px 0; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.fd-empty-title { font-size: 16px; font-weight: 700; color: var(--fg-2); text-transform: capitalize; }
.fd-empty-sub { font-size: 13.5px; color: var(--fg-4); }
.fd-guide { display: grid; grid-template-columns: 1fr auto 1fr; align-items: stretch; gap: 0; background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: 14px; padding: 16px 20px; box-shadow: var(--shadow-xs); }
.fd-guide-item { display: flex; align-items: flex-start; gap: 12px; }
.fd-guide-ic { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; flex: none; }
.fd-guide-h { font-size: 13.5px; font-weight: 700; color: var(--fg-1); }
.fd-guide-h span { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; color: var(--fg-3); }
.fd-guide-b { font-size: 12.5px; line-height: 1.5; color: var(--fg-3); margin-top: 3px; max-width: 440px; }
.fd-guide-sep { width: 1px; background: var(--border-subtle); margin: 2px 20px; }
/* [hidden] must beat the display:grid/flex class rules above (UA [hidden] has
   lower specificity than a class selector, so the guide/empty/clear would
   otherwise show through their hidden attribute). */
.fd-guide[hidden], .fd-empty[hidden], .fd-search-clear[hidden] { display: none !important; }

/* Hours page beta notice — amber callout at the top of the Hours panel. */
.hours-beta { display:flex; align-items:flex-start; gap:13px; padding:14px 16px; margin-bottom:18px; border-radius:13px; background:var(--ws-warning-50); border:1px solid color-mix(in srgb, var(--ws-warning-500) 34%, transparent); }
.hours-beta-ic { width:34px; height:34px; flex:none; border-radius:9px; display:flex; align-items:center; justify-content:center; background:color-mix(in srgb, var(--ws-warning-500) 16%, #fff); color:var(--ws-warning-700); }
.hours-beta-h { font-size:13.5px; font-weight:700; color:var(--ws-warning-700); letter-spacing:-0.01em; }
.hours-beta-b { font-size:12.5px; line-height:1.5; color:var(--fg-2); margin-top:3px; max-width:680px; }
/* Service button is icon-only now (wrench, no "Service" label) — square it up. */
.flc-svc-action { padding: 0; width: 30px; justify-content: center; }
/* Service modal matches the rig web-app: no icon/sub, so center the title in the
   amber head (mirrors the rig's #svc-modal .svc-modal-head override). */
#svc-modal .svc-modal-head { align-items: center; padding-top: 16px; padding-bottom: 16px; }

/* Toast notifications (e.g. device put into service). Bottom-center, auto-dismiss. */
.toasts { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 1100; display: flex; flex-direction: column; align-items: center; gap: 10px; pointer-events: none; }
.toast { display: inline-flex; align-items: center; gap: 9px; max-width: 460px; padding: 12px 16px; border-radius: 11px; background: #fff; color: var(--fg-1); font-size: 13.5px; font-weight: 600; border: 1px solid var(--border-subtle); box-shadow: var(--shadow-lg, 0 12px 28px rgba(16,24,40,0.16)); opacity: 0; transform: translateY(10px); transition: opacity .2s, transform .2s; }
.toast.show { opacity: 1; transform: none; }
.toast::before { content: ""; width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--ws-blue-500); }
.toast.warn::before { background: var(--ws-warning-500); }
.toast.ok::before { background: var(--ws-success-500); }
.toast.err::before { background: var(--ws-danger-500); }

/* ════════════════════════════════════════════════════════════════════════
   HOURS TAB — redesign (2026-06-29). Ported from the workstream-fleetboard
   "Fleet Dashboard" mocks (fleet-hours.jsx / fleet-operators.jsx) and adapted
   to the real /api/fleet/hours + /api/fleet/extras data. Uses the global light
   --ws-*/--fg-* tokens. Only renders inside the (light) Hours tab.
   ════════════════════════════════════════════════════════════════════════ */
.da-page { display: flex; flex-direction: column; gap: 18px; }
.dc-mono { font-family: var(--font-mono); }
.da-sec-h { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; color: var(--fg-1); margin: 6px 0 0; }

/* KPI roll-up */
.da-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.da-kpis-5 { grid-template-columns: repeat(5, 1fr); }
.da-kpi { position: relative; background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: 14px; padding: 16px 18px; box-shadow: var(--shadow-xs); }
.da-kpi-icon { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; margin-bottom: 12px; }
.da-kpi-icon svg { width: 18px; height: 18px; }
.da-kpi-label { font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg-3); }
.da-kpi-value { font-size: 28px; font-weight: 800; letter-spacing: -0.02em; margin-top: 7px; line-height: 1; color: var(--fg-1); }
.da-kpi-sub { font-size: 12.5px; color: var(--fg-4); margin-top: 6px; display: inline-flex; align-items: center; gap: 4px; }
.da-kpi-sub.kpi-up { color: var(--ws-success-700); font-weight: 600; }
.da-kpi-sub.kpi-down { color: var(--ws-danger-700); font-weight: 600; }
.kpi-arrow { font-size: 9px; line-height: 1; }
.kpi-arrow.down { display: inline-block; transform: rotate(180deg); }
.da-kpi-click { cursor: pointer; transition: border-color 120ms, box-shadow 120ms; }
.da-kpi-click:hover { border-color: var(--ws-blue-300, #b9d0ff); box-shadow: var(--shadow-sm); }
.da-kpi-hint { position: absolute; top: 15px; right: 16px; font-size: 11.5px; font-weight: 700; color: var(--ws-blue-600); opacity: 0; transition: opacity 120ms; }
.da-kpi-click:hover .da-kpi-hint { opacity: 1; }
@media (max-width: 1200px) { .da-kpis, .da-kpis-5 { grid-template-columns: repeat(2, 1fr); } }

/* panels */
.da-panel { background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: 16px; box-shadow: var(--shadow-xs); overflow: hidden; }
.da-panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 20px 14px; }
.da-panel-title { font-size: 15.5px; font-weight: 800; color: var(--fg-1); margin: 0; }
.da-panel-sub { font-size: 12.5px; color: var(--fg-3); margin: 4px 0 0; }

/* hours bar chart */
.hr-chart { padding: 6px 4px 0; }
.hr-plot { position: relative; }
.hr-cols { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 16px; padding: 0 6px; }
.hr-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 8px; min-width: 0; }
.hr-colval { font-size: 13px; font-weight: 700; white-space: nowrap; }
.hr-bar2 { width: 100%; max-width: 62px; min-height: 3px; border-radius: 7px 7px 3px 3px; background: linear-gradient(180deg, var(--ws-success-500), color-mix(in srgb, var(--ws-success-500) 72%, #fff)); transition: height 320ms cubic-bezier(.2,.8,.2,1); }
.hr-bar2.prog { background: repeating-linear-gradient(45deg, var(--ws-gray-100) 0, var(--ws-gray-100) 5px, #fff 5px, #fff 10px); box-shadow: inset 0 0 0 1.5px var(--ws-gray-200); }
.hr-xaxis { display: flex; gap: 16px; padding: 11px 6px 0; border-top: 1px solid var(--ws-gray-100); margin-top: 2px; }
.hr-xaxis > span { flex: 1; text-align: center; font-size: 12px; font-weight: 600; color: var(--fg-3); display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.hr-xaxis > span.prog { color: var(--fg-4); }
.hr-xaxis em { font-style: normal; font-size: 10px; color: var(--fg-4); }

/* chart legend */
.hr-legend { display: flex; align-items: center; gap: 18px; flex: none; }
.hr-legend > span { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; color: var(--fg-3); white-space: nowrap; }
.hr-leg { width: 14px; height: 14px; border-radius: 4px; flex: none; }
.hr-leg.sq { background: var(--ws-success-500); }
.hr-leg.hatch { background: repeating-linear-gradient(45deg, var(--ws-gray-100) 0, var(--ws-gray-100) 3px, #fff 3px, #fff 6px); box-shadow: inset 0 0 0 1.5px var(--ws-gray-200); }

/* highlights ("AI analysis"-styled, by-the-numbers only) */
.hr-ai { background: linear-gradient(180deg, #fff, var(--bg-sunken)); border: 1px solid var(--border-subtle); border-radius: 16px; box-shadow: var(--shadow-sm); padding: 20px 22px; }
.hr-ai-head { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }
.hr-ai-badge { width: 30px; height: 30px; border-radius: 9px; background: linear-gradient(135deg, var(--ws-blue-500), var(--ws-stream)); display: flex; align-items: center; justify-content: center; flex: none; }
.hr-ai-title { font-size: 16px; font-weight: 800; letter-spacing: -0.01em; color: var(--fg-1); margin: 0; }
.hr-ai-tag { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ws-blue-700); background: var(--ws-blue-50); padding: 3px 9px; border-radius: 999px; }
.hr-ai-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 28px; }
@media (max-width: 1100px) { .hr-ai-grid { grid-template-columns: 1fr; } }
.hr-ai-col { display: contents; }
.hr-ai-row { display: flex; align-items: flex-start; gap: 10px; font-size: 13.5px; line-height: 1.5; color: var(--fg-1); padding: 6px 0; }
.hr-ai-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; margin-top: 7px; }
.hr-ai-dot.num { background: var(--ws-blue-500); }

/* operators & breakdown panels */
.op-charts { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 1100px) { .op-charts { grid-template-columns: 1fr; } }
.optop-list { padding: 4px 14px 14px; display: flex; flex-direction: column; gap: 2px; }
.optop-empty, .op-sitelist .optop-empty { padding: 14px 8px; font-size: 13px; color: var(--fg-3); }
.optop-row { width: 100%; display: flex; align-items: center; gap: 12px; padding: 9px 8px; border-radius: 11px; transition: background 140ms; }
.optop-row:hover { background: var(--ws-gray-50); }
.optop-rank { width: 16px; flex: none; font-size: 12px; font-weight: 700; color: var(--fg-4); text-align: center; }
.optop-av { width: 32px; height: 32px; border-radius: 50%; background: var(--ws-gray-100); color: var(--fg-1); display: flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 800; flex: none; }
.optop-mid { flex: 1; min-width: 0; }
.optop-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.optop-name { font-size: 13.5px; font-weight: 600; color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.optop-val { font-size: 12.5px; font-weight: 700; color: var(--fg-2); flex: none; white-space: nowrap; }
.optop-rec { color: var(--fg-4); font-weight: 600; }
.optop-track { display: block; height: 8px; border-radius: 999px; background: var(--ws-gray-100); overflow: hidden; }
.optop-track i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, color-mix(in srgb, var(--ws-blue-500) 70%, #fff), var(--ws-blue-500)); transition: width 320ms cubic-bezier(.2,.8,.2,1); }

.op-sitelist { padding: 8px 20px 20px; display: flex; flex-direction: column; gap: 14px; }
.op-siterow { display: grid; grid-template-columns: 130px 1fr 56px; align-items: center; gap: 14px; }
.op-site-name { font-size: 13.5px; font-weight: 600; color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.op-site-track { height: 10px; border-radius: 999px; background: var(--ws-gray-100); overflow: hidden; }
.op-site-track i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, color-mix(in srgb, var(--ws-blue-500) 65%, #fff), var(--ws-blue-500)); }
.op-site-val { font-size: 13px; font-weight: 700; color: var(--fg-2); text-align: right; }

/* ════════════ HOURS TAB v2 — metric explorer, interactive chart, analysis,
   operators roster (faithful port of fleet-hours.jsx / fleet-operators.jsx) ════════════ */

/* metric explorer: selectable cards integrated with the chart */
.hr-explorer { padding: 0; overflow: hidden; }
.hr-mcards { display: grid; gap: 0; }
.hr-mcard { position: relative; text-align: left; background: var(--bg-sunken); border: none; border-right: 1px solid var(--border-subtle); padding: 18px 20px 20px; cursor: pointer; transition: background 130ms; font-family: var(--font-sans); }
.hr-mcard:last-child { border-right: none; }
.hr-mcard:hover { background: var(--ws-gray-50); }
.hr-mcard.sel { background: #fff; cursor: default; }
.hr-mcard-top { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.hr-mcard-label { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
.hr-mcard-radio { margin-left: auto; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--border-strong); display: flex; align-items: center; justify-content: center; flex: none; transition: all 130ms; }
.hr-mcard-val { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; color: var(--fg-1); line-height: 1; }
.hr-mcard-sub { font-size: 12.5px; font-weight: 600; margin-top: 8px; display: inline-flex; align-items: center; }
.hr-explorer-chart { padding-top: 4px; }
.hr-explorer-chart .da-panel-head { padding: 18px 22px 6px; }
.kpi-arrow { font-size: 9px; line-height: 1; }
.kpi-arrow.down { display: inline-block; transform: rotate(180deg); }

/* chart interactions: grouped bars, selection dimming, hover */
.hr-bar2 { border: none; padding: 0; cursor: pointer; }
.hr-bar2:hover { filter: brightness(1.05) saturate(1.05); }
.hr-plot.has-sel .hr-col:not(.active) .hr-bar2 { opacity: 0.4; }
.hr-plot.dense .hr-cols { gap: 7px; }
.hr-plot.dense .hr-bar2 { max-width: none; border-radius: 5px 5px 2px 2px; }
.hr-col { cursor: pointer; }
.hr-bargroup { display: flex; align-items: flex-end; justify-content: center; gap: 5px; width: 100%; height: 100%; }
.hr-barwrap { flex: 1; max-width: 30px; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; }
.hr-barwrap .hr-bar2 { max-width: 30px; }
.hr-colval.sm { font-size: 10.5px; }
.hr-xaxis > span.sel { color: var(--fg-1); font-weight: 800; }

/* bar click-in breakdown */
.hr-bardetail { margin-top: 16px; border-top: 1px solid var(--border-subtle); padding-top: 16px; }
.hr-bd-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.hr-bd-period { font-size: 12px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--fg-3); display: flex; align-items: center; gap: 9px; }
.hr-bd-prog { font-size: 10px; font-weight: 700; text-transform: none; color: var(--fg-4); background: var(--ws-gray-100); padding: 2px 7px; border-radius: 5px; }
.hr-bd-val { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; color: var(--fg-1); margin-top: 5px; }
.hr-bd-delta { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; font-weight: 700; padding: 5px 10px; border-radius: 999px; white-space: nowrap; }
.hr-bd-delta.up { color: var(--ws-success-700); background: var(--ws-success-50); }
.hr-bd-delta.down { color: var(--ws-danger-700); background: var(--ws-danger-50); }
.hr-bd-sublabel { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-4); margin: 16px 0 10px; }
.hr-bd-rows { display: flex; flex-direction: column; gap: 9px; }
.hr-bd-row { display: grid; grid-template-columns: 150px 1fr 64px; align-items: center; gap: 14px; }
.hr-bd-site { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hr-bd-site i { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.hr-bd-track { height: 8px; border-radius: 999px; background: var(--ws-gray-100); overflow: hidden; }
.hr-bd-track i { display: block; height: 100%; border-radius: 999px; }
.hr-bd-rowval { font-size: 13px; font-weight: 700; color: var(--fg-1); text-align: right; }

/* analysis — two columns */
.hr-ai-grid { grid-template-columns: 1fr 1fr; gap: 12px 28px; }
.hr-ai-col { display: block; }
.hr-ai-col-h { font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--fg-4); margin-bottom: 8px; }
.hr-ai-dot.read { background: var(--ws-gold-500); }
@media (max-width: 1100px) { .hr-ai-grid { grid-template-columns: 1fr; } }

/* top operators — expandable */
.optop { border-radius: 11px; transition: background 140ms; }
.optop.open { background: var(--ws-gray-50); }
.optop-row { border: 0; background: transparent; width: 100%; text-align: left; font-family: var(--font-sans); cursor: pointer; }
.optop.open .optop-row:hover { background: transparent; }
.optop-caretwrap { flex: none; display: inline-flex; }
.optop-live { position: absolute; right: -1px; bottom: -1px; width: 9px; height: 9px; border-radius: 50%; background: var(--ws-success-500); border: 2px solid #fff; }
.optop-av { position: relative; }
.optop-detail { display: flex; gap: 18px; align-items: flex-end; padding: 2px 12px 14px 60px; flex-wrap: wrap; }
.optop-stats { display: grid; grid-template-columns: repeat(2, auto); gap: 8px 28px; flex: 1; min-width: 0; }
.optop-stat { display: flex; flex-direction: column; gap: 2px; }
.optop-stat-l { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--fg-4); }
.optop-stat-v { font-size: 13px; font-weight: 600; color: var(--fg-1); }
.optop-spark { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; flex: none; }
.optop-spark-l { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--fg-4); }

/* search box */
.fd-search { display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px; border-radius: 999px; background: var(--bg-surface); border: 1px solid var(--border-subtle); }
.fd-search input { flex: 1; border: 0; outline: 0; background: transparent; font-family: var(--font-sans); font-size: 13.5px; color: var(--fg-1); min-width: 0; }
.fd-search input::placeholder { color: var(--fg-4); }
.fd-search-clear { width: 22px; height: 22px; border-radius: 6px; border: 0; background: var(--ws-gray-100); display: flex; align-items: center; justify-content: center; cursor: pointer; flex: none; }
.fd-search-clear:hover { background: var(--ws-gray-200); }

/* roster table */
.op-table { display: flex; flex-direction: column; }
.op-tr { display: grid; align-items: center; gap: 14px; padding: 12px 20px; border-top: 1px solid var(--border-subtle); }
.op-th { border-top: 0; padding: 4px 20px 10px; }
.op-thcell { display: inline-flex; align-items: center; gap: 4px; border: 0; background: none; padding: 0; cursor: pointer; font-family: var(--font-sans); font-size: 11px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--fg-4); }
.op-thcell:disabled { cursor: default; }
.op-thcell.num { justify-content: flex-end; }
.op-thcell.active { color: var(--fg-2); }
.op-row:hover { background: var(--ws-gray-50); }
.op-row.open { background: var(--ws-gray-50); }
.op-cell { font-size: 13.5px; color: var(--fg-2); min-width: 0; }
.op-cell.num { text-align: right; justify-self: end; }
.op-opcell { display: flex; align-items: center; gap: 11px; }
.op-avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--ws-gray-100); color: var(--fg-1); display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 800; flex: none; }
.op-name { display: block; font-size: 14px; font-weight: 700; color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.op-role { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--fg-3); margin-top: 1px; }
.op-loc { display: block; font-size: 13px; font-weight: 600; color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.op-dev { display: block; font-size: 11.5px; color: var(--fg-4); margin-top: 1px; }
.op-task { display: inline-block; font-size: 12.5px; font-weight: 600; color: var(--ws-blue-700); background: var(--ws-blue-50); padding: 3px 10px; border-radius: 999px; }
.op-dash { color: var(--fg-4); }
.op-sub { color: var(--fg-4); font-weight: 600; }
.op-trend { display: flex; justify-content: flex-end; }
.op-empty-row { display: flex; align-items: center; gap: 9px; padding: 18px 20px; font-size: 13.5px; font-weight: 600; color: var(--fg-3); }
.op-rowdetail { display: flex; gap: 24px; align-items: flex-end; flex-wrap: wrap; padding: 4px 20px 18px 51px; background: var(--ws-gray-50); border-top: 1px solid var(--border-subtle); }
.op-rd-stats { display: flex; flex-wrap: wrap; gap: 10px 32px; flex: 1; min-width: 0; }
.op-rd-stat { display: flex; flex-direction: column; gap: 2px; }
.op-rd-l { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--fg-4); }
.op-rd-v { font-size: 13.5px; font-weight: 600; color: var(--fg-1); }
.op-rd-spark { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; flex: none; }
