Backend services: - targo-hub: extract deepGetValue to helpers.js, DRY disconnect reasons lookup map, compact CAPABILITIES, consolidate vision.js prompts/schemas, extract dispatch scoring weights, trim section dividers across 9 files - modem-bridge: extract getSession() helper (6 occurrences), resetIdleTimer(), consolidate DM query factory, fix duplicate username fill bug, trim headers (server.js -36%, tplink-session.js -47%, docker-compose.yml -57%) Frontend: - useWifiDiagnostic: extract THRESHOLDS const, split processDiagnostic into 6 focused helpers (processOnlineStatus, processWanIPs, processRadios, processMeshNodes, processClients, checkRadioIssues) - EquipmentDetail: merge duplicate ROLE_LABELS, remove verbose comments Documentation (17 → 13 files, -1,400 lines): - New consolidated README.md (architecture, services, dependencies, auth) - Merge ECOSYSTEM-OVERVIEW into ARCHITECTURE.md - Merge MIGRATION-PLAN + ARCHITECTURE-COMPARE + FIELD-GAP + CHANGELOG → MIGRATION.md - Merge COMPETITIVE-ANALYSIS into PLATFORM-STRATEGY.md - Update ROADMAP.md with current phase status - Delete CONTEXT.md (absorbed into README) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
856 lines
66 KiB
SCSS
856 lines
66 KiB
SCSS
/* ── Root ── */
|
|
.sb-root {
|
|
/* Light theme — aligned with ops-app design language */
|
|
--sb-bg: #f8fafc; --sb-sidebar: #ffffff; --sb-card: #ffffff; --sb-card-h: #f1f5f9;
|
|
--sb-border: #e2e8f0; --sb-border-acc: rgba(99,102,241,0.4);
|
|
--sb-text: #1e293b; --sb-muted: #64748b;
|
|
--sb-acc: #6366f1; --sb-green: #10b981; --sb-red: #ef4444; --sb-orange: #f59e0b;
|
|
--sb-overlay: rgba(0,0,0,0.04); --sb-overlay-hover: rgba(0,0,0,0.08);
|
|
display: flex; flex-direction: column;
|
|
height: 100vh; width: 100%; overflow: hidden;
|
|
background: var(--sb-bg); color: var(--sb-text);
|
|
font-family: 'Inter', system-ui, sans-serif; font-size: 0.82rem;
|
|
}
|
|
|
|
/* ── Header ── */
|
|
.sb-header { display:flex; align-items:center; gap:0.5rem; padding:0 0.75rem; background:var(--sb-sidebar); border-bottom:1px solid var(--sb-border); box-shadow:0 1px 4px rgba(0,0,0,0.06); z-index:30; overflow:hidden; }
|
|
.sb-header-left { display:flex; align-items:center; gap:0.4rem; flex-shrink:0; }
|
|
.sb-header-center { display:flex; align-items:center; gap:0.35rem; flex:1; justify-content:center; }
|
|
.sb-header-right { display:flex; align-items:center; gap:0.35rem; flex-shrink:0; margin-left:auto; }
|
|
.sb-nlp-row { padding:0.3rem 0.5rem; border-bottom:1px solid var(--sb-border); background:var(--sb-card); }
|
|
.sb-logo-btn { background:none; border:1px solid var(--sb-border); border-radius:6px; color:var(--sb-muted); font-size:0.72rem; font-weight:700; padding:0.2rem 0.55rem; cursor:pointer; white-space:nowrap; text-decoration:none; }
|
|
.sb-logo-btn:hover { color:var(--sb-text); border-color:var(--sb-border-acc); }
|
|
.sb-tabs { display:flex; align-items:center; border-left:1px solid var(--sb-border); margin-left:0.25rem; padding-left:0.4rem; gap:0.15rem; }
|
|
.sb-tab { background:none; border:none; color:var(--sb-muted); font-size:0.72rem; font-weight:600; padding:0.3rem 0.6rem; cursor:pointer; border-bottom:2px solid transparent; transition:color 0.15s, border-color 0.15s; white-space:nowrap; }
|
|
.sb-tab.active { color:var(--sb-acc); border-bottom-color:var(--sb-acc); }
|
|
.sb-tab-add { opacity:0.45; font-size:1rem; padding:0.15rem 0.4rem; }
|
|
.sb-tab-add:hover { opacity:1; }
|
|
.sb-hbtn { background:none; border:1px solid var(--sb-border); border-radius:6px; color:var(--sb-text); font-size:0.85rem; padding:0.2rem 0.55rem; cursor:pointer; }
|
|
.sb-hbtn:hover { background:var(--sb-card); }
|
|
.sb-today-btn { font-size:0.7rem; font-weight:700; }
|
|
.sb-period-label { font-size:0.78rem; font-weight:600; min-width:180px; text-align:center; white-space:nowrap; }
|
|
.sb-view-sw { display:flex; background:var(--sb-card); border:1px solid var(--sb-border); border-radius:6px; overflow:hidden; }
|
|
.sb-view-sw button { background:none; border:none; color:var(--sb-muted); font-size:0.68rem; font-weight:700; padding:0.22rem 0.6rem; cursor:pointer; transition:color 0.12s, background 0.12s; }
|
|
.sb-view-sw button.active { background:none; color:var(--sb-acc); box-shadow:inset 0 0 0 1.5px var(--sb-acc); }
|
|
.sb-planning-toggle {
|
|
margin-left: 6px; border-radius: 6px; font-size: 0.72rem;
|
|
border: 1px solid rgba(100,180,255,0.15); transition: all 0.15s;
|
|
&.active { background: rgba(100,180,255,0.15); border-color: rgba(100,180,255,0.4); color: #4f76b8; }
|
|
}
|
|
.sb-search { background:var(--sb-card); border:1px solid var(--sb-border); border-radius:6px; color:var(--sb-text); font-size:0.72rem; padding:0.22rem 0.55rem; width:160px; outline:none; }
|
|
.sb-search::placeholder { color:var(--sb-muted); }
|
|
.sb-search:focus { border-color:var(--sb-border-acc); }
|
|
.sb-search-bar { display:flex; align-items:center; gap:4px; background:var(--sb-card); border:1px solid var(--sb-border); border-radius:6px; padding:0.2rem 0.5rem; min-width:160px; max-width:320px; cursor:pointer; transition:border-color 0.12s; flex-wrap:wrap; }
|
|
.sb-search-bar:hover { border-color:var(--sb-border-acc); }
|
|
.sb-search-icon { font-size:0.7rem; flex-shrink:0; }
|
|
.sb-search-placeholder { color:var(--sb-muted); font-size:0.72rem; }
|
|
.sb-search-chip { display:inline-flex; align-items:center; gap:3px; background:rgba(99,102,241,0.12); color:#4f46e5; border:1px solid rgba(99,102,241,0.3); border-radius:4px; font-size:0.65rem; font-weight:600; padding:1px 6px; white-space:nowrap; cursor:pointer; transition:background 0.1s; }
|
|
.sb-search-chip:hover { background:rgba(99,102,241,0.35); }
|
|
.sb-search-chip-count { background:rgba(99,102,241,0.3); }
|
|
// ── Quick preset bar (saved groups in header) ──
|
|
.sb-quick-presets {
|
|
display: flex; gap: 3px; align-items: center; flex-wrap: wrap;
|
|
}
|
|
.sb-quick-preset {
|
|
background: var(--sb-card); border: 1px solid var(--sb-border); border-radius: 5px;
|
|
color: var(--sb-muted); font-size: 0.62rem; font-weight: 600;
|
|
padding: 2px 7px; cursor: pointer; white-space: nowrap;
|
|
transition: all 0.12s; display: inline-flex; align-items: center; gap: 2px;
|
|
&:hover { border-color: var(--sb-border-acc); color: var(--sb-text); }
|
|
&.active { border-color: var(--sb-acc); color: var(--sb-acc); background: rgba(99,102,241,0.1); }
|
|
.sb-qp-icon { font-size: 0.7rem; }
|
|
}
|
|
// ── Group save button in selector ──
|
|
.sb-rsel-group-wrap {
|
|
display: inline-flex; align-items: center; gap: 0;
|
|
}
|
|
.sb-rsel-save-group {
|
|
background: none; border: none; cursor: pointer; font-size: 0.65rem;
|
|
padding: 2px 3px; opacity: 0.35; transition: opacity 0.12s;
|
|
&:hover { opacity: 1; }
|
|
}
|
|
.sb-rsel-group-count {
|
|
font-size: 0.6rem; opacity: 0.6; margin-left: 3px;
|
|
}
|
|
.sb-rsel-preset-group { border-color: rgba(74, 222, 128, 0.3); }
|
|
.sb-rsel-preset-group.active { border-color: #4ade80; background: rgba(74, 222, 128, 0.12); }
|
|
.sb-rsel-preset-icon { font-size: 0.7rem; margin-right: 2px; }
|
|
.sb-icon-btn { background:none; border:1px solid var(--sb-border); border-radius:6px; color:var(--sb-muted); font-size:0.68rem; font-weight:600; padding:0.22rem 0.55rem; cursor:pointer; white-space:nowrap; transition:color 0.12s, border-color 0.12s; }
|
|
.sb-icon-btn:hover, .sb-icon-btn.active { color:var(--sb-text); border-color:var(--sb-border-acc); background:var(--sb-card); }
|
|
.sb-user-menu { display:flex; align-items:center; gap:6px; }
|
|
.sb-user-name { font-size:11px; color:var(--sb-muted); max-width:120px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
.sb-erp-link { font-size:10px; padding:2px 6px; background:rgba(99,102,241,.15); color:var(--sb-accent); border-radius:4px; text-decoration:none; font-weight:600; }
|
|
.sb-erp-link:hover { background:rgba(99,102,241,.3); }
|
|
.sb-logout-btn { font-size:14px !important; opacity:.6; }
|
|
.sb-logout-btn:hover { opacity:1; color:var(--sb-red); }
|
|
.sb-erp-dot { width:7px; height:7px; border-radius:50%; background:var(--sb-red); transition:background 0.3s; }
|
|
.sb-erp-dot.ok { background:var(--sb-green); }
|
|
.sb-wo-btn { background:var(--sb-acc); border:none; border-radius:6px; color:var(--sb-text); font-size:0.7rem; font-weight:800; padding:0.22rem 0.65rem; cursor:pointer; white-space:nowrap; }
|
|
.sb-wo-btn:hover { filter:brightness(1.15); }
|
|
|
|
/* ── Body ── */
|
|
.sb-body { flex:1; display:flex; overflow:hidden; min-height:0; position:relative; }
|
|
|
|
/* ── Toolbar dropdown panels ── */
|
|
.sb-toolbar-panel { background:var(--sb-sidebar); border-bottom:1px solid var(--sb-border); box-shadow:0 4px 16px rgba(0,0,0,0.08); z-index:18; flex-shrink:0; }
|
|
.sb-toolbar-panel-inner { padding:0; }
|
|
.sb-slide-down-enter-active, .sb-slide-down-leave-active { transition: max-height 0.2s ease, opacity 0.2s ease; overflow:hidden; }
|
|
.sb-slide-down-enter-from, .sb-slide-down-leave-to { max-height:0; opacity:0; }
|
|
.sb-slide-down-enter-to, .sb-slide-down-leave-from { max-height:400px; opacity:1; }
|
|
|
|
/* ── Sidebar ── */
|
|
.sb-sidebar-strip { width:48px; min-width:48px; flex-shrink:0; display:flex; flex-direction:column; align-items:center; background:var(--sb-sidebar); border-right:1px solid var(--sb-border); padding:6px 0; gap:2px; z-index:20; }
|
|
.sbs-search-wrap { width:100%; padding:0 6px; margin-bottom:4px; }
|
|
.sbs-search { width:100%; background:var(--sb-card); border:1px solid var(--sb-border); border-radius:6px; color:var(--sb-text); font-size:0.72rem; padding:5px 4px; outline:none; text-align:center; box-sizing:border-box; }
|
|
.sbs-search:focus { border-color:var(--sb-border-acc); }
|
|
.sbs-icon { width:36px; height:36px; border-radius:8px; border:none; background:none; color:var(--sb-muted); cursor:pointer; display:flex; align-items:center; justify-content:center; position:relative; transition:background 0.12s, color 0.12s; text-decoration:none; }
|
|
.sbs-icon:hover, .sbs-icon.active { background:var(--sb-card); color:var(--sb-text); }
|
|
.sbs-icon svg { width:16px; height:16px; }
|
|
.sbs-badge { position:absolute; top:4px; right:4px; width:7px; height:7px; border-radius:50%; background:var(--sb-acc); }
|
|
.sbs-count { position:absolute; top:2px; right:0; min-width:14px; height:14px; border-radius:7px; background:var(--sb-acc); color:var(--sb-text); font-size:0.5rem; font-weight:700; display:flex; align-items:center; justify-content:center; padding:0 3px; }
|
|
.sbs-search-full { width:100%; background:var(--sb-card); border:1px solid var(--sb-border); border-radius:6px; color:var(--sb-text); font-size:0.72rem; padding:0.25rem 0.45rem; outline:none; box-sizing:border-box; }
|
|
.sbs-search-full:focus { border-color:var(--sb-border-acc); }
|
|
|
|
/* ── Flyout ── */
|
|
.sb-flyout { width:260px; min-width:260px; flex-shrink:0; display:flex; flex-direction:column; background:var(--sb-sidebar); border-right:1px solid var(--sb-border); overflow-y:auto; z-index:19; box-shadow:4px 0 16px rgba(0,0,0,0.3); }
|
|
.sb-flyout::-webkit-scrollbar { width:3px; }
|
|
.sb-flyout::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); }
|
|
.sb-overlay-backdrop { position:absolute; top:0; left:0; right:0; bottom:0; z-index:24; background:rgba(0,0,0,0.3); }
|
|
.sb-left-overlay { position:absolute; top:0; left:0; z-index:25; width:280px; min-width:280px; height:100%; display:flex; flex-direction:column; background:var(--sb-sidebar); color:var(--sb-text); border-right:1px solid var(--sb-border); box-shadow:4px 0 16px rgba(0,0,0,0.1); }
|
|
.sbf-section { padding:0.6rem 0.65rem; border-bottom:1px solid var(--sb-border); flex-shrink:0; }
|
|
.sbf-section-grow { flex:1; overflow-y:auto; padding:0.5rem 0.65rem; display:flex; flex-direction:column; gap:0.3rem; }
|
|
.sbf-section-grow::-webkit-scrollbar { width:3px; }
|
|
.sbf-section-grow::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); }
|
|
.sbf-title { font-size:0.58rem; font-weight:800; text-transform:uppercase; letter-spacing:0.08em; color:var(--sb-muted); margin-bottom:0.4rem; display:flex; align-items:center; justify-content:space-between; }
|
|
.sbf-count { background:var(--sb-acc); color:var(--sb-text); font-size:0.58rem; padding:0.05rem 0.35rem; border-radius:8px; font-weight:700; }
|
|
.sbf-primary-btn { width:100%; background:var(--sb-acc); border:none; border-radius:6px; color:var(--sb-text); font-size:0.7rem; font-weight:700; padding:0.35rem 0.5rem; cursor:pointer; }
|
|
.sbf-primary-btn:hover { filter:brightness(1.12); }
|
|
.sbf-chip { display:flex; align-items:center; justify-content:space-between; background:rgba(99,102,241,0.12); border:1px solid var(--sb-border-acc); border-radius:6px; padding:0.2rem 0.45rem; font-size:0.68rem; margin-top:0.3rem; color:var(--sb-acc); }
|
|
.sbf-chip button { background:none; border:none; color:var(--sb-muted); cursor:pointer; font-size:0.8rem; }
|
|
.sbf-lbl { display:block; font-size:0.62rem; color:var(--sb-muted); margin:0.3rem 0 0.15rem; }
|
|
.sbf-select { width:100%; background:var(--sb-card); border:1px solid var(--sb-border); border-radius:5px; color:var(--sb-text); font-size:0.7rem; padding:0.22rem 0.4rem; cursor:pointer; }
|
|
.sbf-clear-btn { width:100%; background:none; border:1px solid rgba(239,68,68,0.3); border-radius:5px; color:var(--sb-red); font-size:0.67rem; padding:0.22rem; cursor:pointer; margin-top:0.3rem; }
|
|
.sbf-auto-btn { background:none; border:1px solid rgba(99,102,241,0.4); border-radius:4px; color:#6366f1; font-size:0.58rem; font-weight:700; padding:1px 6px; cursor:pointer; margin-left:auto; }
|
|
.sbf-auto-btn:hover { background:rgba(99,102,241,0.12); }
|
|
.sbf-clear-btn:hover { background:rgba(239,68,68,0.08); }
|
|
.sbf-drop-active { background:rgba(99,102,241,0.07); border-radius:6px; }
|
|
.sbf-drop-hint { font-size:0.68rem; color:var(--sb-acc); font-weight:700; text-align:center; padding:0.4rem; border:1.5px dashed var(--sb-border-acc); border-radius:6px; margin-bottom:0.35rem; }
|
|
.sbf-empty { font-size:0.72rem; color:var(--sb-muted); font-style:italic; padding:0.25rem 0; }
|
|
.sbf-card { display:flex; border-radius:7px; overflow:hidden; cursor:grab; background:var(--sb-card); border:1px solid var(--sb-border); transition:border-color 0.12s, transform 0.12s; }
|
|
.sbf-card:hover { border-color:var(--sb-border-acc); transform:translateY(-1px); }
|
|
.sbf-card-stripe { width:4px; flex-shrink:0; }
|
|
.sbf-card-body { flex:1; min-width:0; padding:0.35rem 0.45rem; }
|
|
.sbf-card-title { font-size:0.72rem; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
|
.sbf-card-meta { font-size:0.62rem; color:var(--sb-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
|
|
|
/* ── Center ── */
|
|
.sb-center-col { flex:1; display:flex; flex-direction:column; min-width:0; min-height:0; overflow:hidden; }
|
|
.sb-board { flex:1; overflow:auto; min-width:0; position:relative; min-height:0; }
|
|
.sb-board::-webkit-scrollbar { width:5px; height:5px; }
|
|
.sb-board::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); border-radius:3px; }
|
|
|
|
/* ── Grid ── */
|
|
.sb-grid { display:flex; flex-direction:column; }
|
|
.sb-grid-cal { display:flex; flex-direction:column; width:100%; min-width:0; }
|
|
.sb-grid-hdr { display:flex; height:46px; flex-shrink:0; position:sticky; top:0; z-index:15; background:var(--sb-sidebar); border-bottom:1px solid var(--sb-border); }
|
|
.sb-res-hdr { width:200px; min-width:200px; flex-shrink:0; position:sticky; left:0; z-index:16; background:var(--sb-sidebar); border-right:1px solid var(--sb-border); display:flex; align-items:center; padding:0 0.75rem; font-size:0.6rem; font-weight:800; text-transform:uppercase; letter-spacing:0.07em; color:var(--sb-muted); gap:0.35rem; }
|
|
.sb-time-hdr-wrap { overflow:hidden; position:relative; }
|
|
.sb-cal-hdr { display:flex; flex:1; overflow:hidden; }
|
|
.sb-cal-hdr-cell { flex:1; min-width:0; border-left:1px solid var(--sb-border); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px; padding:2px 0; }
|
|
.sb-cal-hdr-cell.sb-col-today { background:rgba(99,102,241,0.06); }
|
|
.sb-cal-wd { font-size:0.58rem; font-weight:800; text-transform:uppercase; letter-spacing:0.05em; color:var(--sb-muted); }
|
|
.sb-cal-dn { font-size:0.82rem; font-weight:700; color:var(--sb-text); line-height:1; }
|
|
.sb-today-bubble { background:var(--sb-acc); color:var(--sb-text) !important; border-radius:50%; width:20px; height:20px; display:flex; align-items:center; justify-content:center; }
|
|
.sb-htick { position:absolute; top:0; height:100%; border-left:1px solid var(--sb-border); }
|
|
.sb-htick-lbl { position:absolute; top:6px; left:4px; font-size:0.58rem; color:var(--sb-muted); white-space:nowrap; font-weight:600; }
|
|
.sb-day-lbl { position:absolute; top:4px; left:6px; font-size:0.65rem; font-weight:700; color:var(--sb-text); white-space:nowrap; letter-spacing:0.02em; text-transform:capitalize; }
|
|
.sb-day-today { color:var(--sb-acc); }
|
|
.sb-htick.sb-day-boundary { border-left:2px solid var(--sb-border); }
|
|
|
|
/* ── Rows ── */
|
|
.sb-row { display:flex; border-bottom:1px solid var(--sb-border); transition:background 0.12s; }
|
|
.sb-row-cal { align-items:stretch; min-height:44px; height:auto !important; }
|
|
.sb-row-sel { background:rgba(99,102,241,0.04); }
|
|
.sb-row-elevated { position:relative; z-index:8; }
|
|
.sb-row-absent { opacity:0.7; }
|
|
.sb-row-absent .sb-avatar { filter: grayscale(0.6); }
|
|
.sb-row-elevated .sb-timeline { overflow:visible; }
|
|
.sb-loading-row, .sb-empty-row { padding:2rem; text-align:center; color:var(--sb-muted); font-style:italic; }
|
|
.sb-cal-row { display:flex; flex:1; min-width:0; overflow:hidden; }
|
|
.sb-cal-cell { flex:1; min-width:0; border-left:1px solid var(--sb-border); padding:2px 3px; position:relative; display:flex; flex-direction:column; gap:3px; transition:background 0.1s; }
|
|
.sb-cal-cell:hover { background:rgba(0,0,0,0.02); }
|
|
.sb-cal-drop { position:absolute; inset:1px; border:1.5px dashed var(--sb-acc); border-radius:4px; background:rgba(99,102,241,0.08); pointer-events:none; z-index:2; }
|
|
.sb-chip { font-size:0.62rem; font-weight:600; padding:4px 6px; border-radius:6px; border-left:3px solid transparent; overflow:hidden; cursor:pointer; transition:background 0.1s; color:var(--sb-text); line-height:1.5; z-index:1; position:relative; }
|
|
.sb-chip:hover { background:rgba(0,0,0,0.06); }
|
|
.sb-chip-done { opacity:0.45; text-decoration:line-through; }
|
|
.sb-chip-sel { outline:1.5px solid #6366f1; outline-offset:1px; }
|
|
.sb-chip-assist { opacity:0.7; border-left-style:dashed !important; font-style:italic; }
|
|
.sb-chip-assist-tag { font-size:0.5rem; margin-right:2px; }
|
|
.sb-chip-multi { outline:2px solid #f59e0b; outline-offset:1px; }
|
|
.sb-chip-urgent { width:6px; height:6px; border-radius:50%; background:#ef4444; flex-shrink:0; box-shadow:0 0 4px #ef4444; }
|
|
.sb-chip-line1 { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:flex; align-items:center; gap:3px; }
|
|
.sb-chip-line2 { font-size:0.52rem; color:rgba(0,0,0,0.45); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1.1; display:flex; align-items:center; gap:2px; }
|
|
.sb-chip-line2 svg { width:9px; height:9px; flex-shrink:0; }
|
|
.sb-day-load { margin-top:auto; flex-shrink:0; padding:2px 2px 1px; display:flex; align-items:center; gap:3px; }
|
|
.sb-day-load-track { flex:1; height:3px; background:rgba(0,0,0,0.05); border-radius:2px; overflow:hidden; }
|
|
.sb-day-load-fill { height:100%; border-radius:2px; transition:width 0.3s, background 0.3s; }
|
|
.sb-day-load-label { font-size:0.5rem; font-weight:700; color:var(--sb-muted); white-space:nowrap; font-variant-numeric:tabular-nums; }
|
|
.sb-res-cell { width:200px; min-width:200px; flex-shrink:0; position:sticky; left:0; z-index:5; align-self:stretch; background:var(--sb-sidebar); border-right:1px solid var(--sb-border); display:flex; align-items:center; gap:0.5rem; padding:0 0.65rem; cursor:pointer; transition:background 0.12s; }
|
|
.sb-res-cell:hover { background:var(--sb-card-h); }
|
|
.sb-avatar { width:32px; height:32px; border-radius:50%; flex-shrink:0; display:flex; align-items:center; justify-content:center; font-size:0.68rem; font-weight:700; color:#fff; }
|
|
.sb-avatar-mat { background:#e2e8f0; border:1.5px solid #cbd5e1; border-radius:8px; font-size:0.9rem; }
|
|
.sb-res-info { flex:1; min-width:0; position:relative; }
|
|
.sb-res-name { font-size:0.78rem; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:flex; align-items:center; gap:3px; }
|
|
.sb-res-tag-dot { width:6px; height:6px; border-radius:50%; flex-shrink:0; }
|
|
|
|
// Hover action overlay — floats over the name area on hover
|
|
.sb-res-actions {
|
|
position:absolute; top:0; right:0; bottom:0;
|
|
display:flex; align-items:center; gap:2px;
|
|
padding:0 4px 0 16px;
|
|
background:linear-gradient(90deg, transparent, var(--sb-sidebar) 30%);
|
|
opacity:0; transition:opacity 0.15s;
|
|
pointer-events:none;
|
|
button {
|
|
background:rgba(0,0,0,0.05); border:none; border-radius:4px;
|
|
color:#c8cce0; font-size:0.65rem; font-weight:700;
|
|
width:22px; height:22px; display:flex; align-items:center; justify-content:center;
|
|
cursor:pointer; transition:background 0.12s, color 0.12s;
|
|
&:hover { background:rgba(0,0,0,0.08); color:var(--sb-text); }
|
|
}
|
|
.sb-act-play { color:#10b981; &:hover { background:rgba(16,185,129,0.2); } }
|
|
}
|
|
.sb-res-cell:hover .sb-res-actions { opacity:1; pointer-events:auto; }
|
|
|
|
.sb-res-absence-tag { font-size:0.52rem; color:#94a3b8; font-style:italic; }
|
|
.sb-res-sub { display:flex; align-items:center; gap:0.3rem; margin:0.1rem 0; }
|
|
.sb-load { font-size:0.58rem; color:var(--sb-muted); }
|
|
.sb-util-bar { height:3px; background:rgba(0,0,0,0.04); border-radius:2px; overflow:hidden; margin-top:0.15rem; }
|
|
.sb-util-fill { height:100%; border-radius:2px; transition:width 0.3s, background 0.3s; }
|
|
.sb-capacity-line { position:absolute; top:0; bottom:0; width:1px; border-left:1px dashed rgba(0,0,0,0.1); z-index:1; pointer-events:none; }
|
|
.sb-st { font-size:0.58rem; font-weight:700; padding:0.07rem 0.3rem; border-radius:4px; white-space:nowrap; }
|
|
.st-available { background:rgba(16,185,129,0.15); color:var(--sb-green); }
|
|
.st-enroute { background:rgba(245,158,11,0.15); color:var(--sb-orange); }
|
|
.st-busy { background:rgba(99,102,241,0.15); color:#4f46e5; }
|
|
.st-off { background:rgba(239,68,68,0.1); color:var(--sb-red); }
|
|
.st-inactive { background:rgba(100,116,139,0.15); color:#64748b; }
|
|
.prio-high { color:var(--sb-red); font-weight:700; }
|
|
.prio-med { color:var(--sb-orange); font-weight:700; }
|
|
.prio-low { color:var(--sb-green); }
|
|
.sb-timeline { position:relative; flex:1; overflow:hidden; }
|
|
.sb-day-bg, .sb-month-bg { position:absolute; top:0; bottom:0; }
|
|
.sb-bg-alt { background:rgba(0,0,0,0.015); }
|
|
.sb-bg-today { background:rgba(99,102,241,0.06); }
|
|
.sb-hour-guide { position:absolute; top:0; bottom:0; width:1px; background:var(--sb-border); opacity:0.6; pointer-events:none; }
|
|
.sb-quarter-guide { position:absolute; top:0; bottom:0; width:1px; background:var(--sb-border); opacity:0.2; pointer-events:none; }
|
|
.sb-drop-line { position:absolute; top:2px; bottom:2px; width:3px; background:#6366f1; border-radius:2px; box-shadow:0 0 10px #6366f1, 0 0 4px #6366f1; pointer-events:none; z-index:20; transform:translateX(-1px); }
|
|
.sb-block { position:absolute; border-radius:6px; overflow:hidden; display:flex; align-items:center; cursor:grab; z-index:4; box-shadow:0 2px 8px rgba(0,0,0,0.35); transition:box-shadow 0.12s, transform 0.12s; min-width:18px; }
|
|
.sb-block:hover { box-shadow:0 4px 16px rgba(0,0,0,0.1); transform:translateY(-1px); z-index:5; }
|
|
.sb-block-done { opacity:0.55; }
|
|
|
|
// ── Draft (unpublished) job — hatched diagonal stripes ──
|
|
.sb-block-draft {
|
|
background-image: repeating-linear-gradient(
|
|
-45deg,
|
|
transparent,
|
|
transparent 5px,
|
|
rgba(0, 0, 0, 0.06) 5px,
|
|
rgba(0, 0, 0, 0.06) 10px
|
|
);
|
|
border: 1px dashed rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
// ── Day picker buttons (recurrence) ──
|
|
.sb-day-btn {
|
|
width: 24px; height: 24px; border-radius: 50%; border: 1px solid #cbd5e1;
|
|
background: transparent; color: #64748b; font-size: 0.62rem; cursor: pointer;
|
|
display: flex; align-items: center; justify-content: center; padding: 0;
|
|
&:hover { border-color: #6366f1; color: #4f46e5; }
|
|
&.sb-day-btn-active { background: #6366f1; border-color: #6366f1; color: #fff; }
|
|
}
|
|
|
|
// ── Ghost (recurring) block ──
|
|
.sb-block-ghost {
|
|
opacity: 0.55;
|
|
border: 2px dashed rgba(0, 0, 0, 0.2) !important;
|
|
cursor: pointer;
|
|
transition: opacity 0.15s;
|
|
&:hover { opacity: 0.85; }
|
|
.sb-ghost-icon { font-size: 0.65rem; margin-right: 2px; }
|
|
}
|
|
.sb-chip-ghost {
|
|
opacity: 0.55;
|
|
border: 1px dashed rgba(0, 0, 0, 0.25) !important;
|
|
cursor: pointer;
|
|
&:hover { opacity: 0.85; }
|
|
}
|
|
|
|
// ── Shift availability background blocks ──
|
|
.sb-block-shift {
|
|
position: absolute;
|
|
z-index: 0;
|
|
border-radius: 6px;
|
|
background: rgba(100, 180, 255, 0.08);
|
|
border: 1px solid rgba(100, 180, 255, 0.15);
|
|
pointer-events: none;
|
|
.sb-shift-label {
|
|
position: absolute;
|
|
top: 2px; left: 6px;
|
|
font-size: 0.55rem;
|
|
color: rgba(140, 190, 255, 0.5);
|
|
white-space: nowrap;
|
|
letter-spacing: 0.02em;
|
|
user-select: none;
|
|
}
|
|
}
|
|
.sb-block-shift-oncall {
|
|
background: repeating-linear-gradient(
|
|
-45deg,
|
|
rgba(255, 180, 60, 0.06),
|
|
rgba(255, 180, 60, 0.06) 5px,
|
|
rgba(255, 180, 60, 0.02) 5px,
|
|
rgba(255, 180, 60, 0.02) 10px
|
|
);
|
|
border-color: rgba(255, 180, 60, 0.2);
|
|
.sb-shift-label { color: rgba(255, 190, 80, 0.5); }
|
|
}
|
|
|
|
// ── Week calendar: schedule availability bands (planning mode) ──
|
|
.sb-sched-band {
|
|
border-radius: 4px; padding: 2px 5px; cursor: pointer;
|
|
font-size: 0.62rem; white-space: nowrap; overflow: hidden;
|
|
transition: opacity 0.12s;
|
|
&:hover { opacity: 0.9; filter: brightness(1.15); }
|
|
.sb-sched-time { opacity: 0.85; }
|
|
}
|
|
.sb-sched-available {
|
|
background: rgba(74, 222, 128, 0.12);
|
|
border: 1px solid rgba(74, 222, 128, 0.25);
|
|
color: #86efac;
|
|
}
|
|
.sb-sched-oncall {
|
|
background: rgba(251, 191, 36, 0.12);
|
|
border: 1px solid rgba(251, 191, 36, 0.25);
|
|
color: #fcd34d;
|
|
}
|
|
|
|
// ── Month calendar: selected tech availability blocks ──
|
|
.sb-month-avail {
|
|
border-radius: 4px; padding: 2px 5px; margin: 1px 0;
|
|
font-size: 0.62rem; cursor: pointer;
|
|
display: flex; align-items: center; gap: 3px;
|
|
transition: filter 0.12s;
|
|
&:hover { filter: brightness(1.2); }
|
|
.sb-month-avail-icon { font-size: 0.7rem; flex-shrink: 0; }
|
|
.sb-month-avail-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
}
|
|
.sb-month-avail-available { color: #86efac; }
|
|
.sb-month-avail-oncall { color: #fcd34d; }
|
|
.sb-month-avail-absence { color: #fca5a5; }
|
|
.sb-month-avail-dayoff { color: #9ca3af; opacity: 0.6; }
|
|
|
|
// ── Absence block (grayed-out timeline overlay) ──
|
|
.sb-block-absence {
|
|
background: repeating-linear-gradient(
|
|
-45deg,
|
|
rgba(100, 116, 139, 0.18),
|
|
rgba(100, 116, 139, 0.18) 6px,
|
|
rgba(100, 116, 139, 0.10) 6px,
|
|
rgba(100, 116, 139, 0.10) 12px
|
|
) !important;
|
|
border: 1px dashed rgba(100, 116, 139, 0.4);
|
|
border-radius: 6px;
|
|
cursor: default;
|
|
z-index: 2;
|
|
pointer-events: auto;
|
|
&:hover { box-shadow: none; transform: none; }
|
|
.sb-resize-left { left: 0; right: auto; &:hover { border-radius: 6px 0 0 6px; } &::after { right: auto; left: 2px; } }
|
|
}
|
|
.sb-absence-inner {
|
|
display: flex; align-items: center; gap: 5px;
|
|
height: 100%; padding: 0 8px;
|
|
overflow: hidden; white-space: nowrap;
|
|
color: #94a3b8; font-size: 0.65rem; font-weight: 600;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
.sb-absence-icon { font-size: 0.8rem; flex-shrink: 0; }
|
|
.sb-absence-label { opacity: 0.85; }
|
|
.sb-absence-dates { opacity: 0.6; font-size: 0.58rem; font-weight: 400; }
|
|
|
|
// Week calendar absence cell overlay
|
|
.sb-cal-absent {
|
|
background: repeating-linear-gradient(
|
|
-45deg,
|
|
rgba(100, 116, 139, 0.08),
|
|
rgba(100, 116, 139, 0.08) 4px,
|
|
transparent 4px,
|
|
transparent 8px
|
|
) !important;
|
|
}
|
|
.sb-chip-absence {
|
|
background: rgba(100, 116, 139, 0.18) !important;
|
|
border-left-color: #94a3b8 !important;
|
|
color: #94a3b8 !important;
|
|
font-style: italic;
|
|
pointer-events: none;
|
|
.sb-chip-line1 { opacity: 0.85; }
|
|
}
|
|
.sb-chip-dayoff {
|
|
background: repeating-linear-gradient(135deg, rgba(100,116,139,0.08), rgba(100,116,139,0.08) 4px, rgba(100,116,139,0.16) 4px, rgba(100,116,139,0.16) 8px) !important;
|
|
border-left-color: #64748b !important;
|
|
color: #64748b !important;
|
|
}
|
|
.sb-chip-absence-full { opacity:0.85; }
|
|
.sb-absence-detail { font-size:0.55rem !important; opacity:0.75; font-style:italic; margin-top:1px; }
|
|
.sb-block.sb-block-sel { outline:2px solid #6366f1; outline-offset:1px; z-index:6 !important; }
|
|
.sb-block.sb-block-multi { outline:2px solid #f59e0b; outline-offset:1px; z-index:6 !important; }
|
|
.sb-multi-bar { position:fixed; bottom:20px; left:50%; transform:translateX(-50%); z-index:200; background:var(--sb-card); color:var(--sb-text); border:1px solid rgba(99,102,241,0.3); border-radius:10px; padding:6px 14px; display:flex; align-items:center; gap:8px; box-shadow:0 8px 32px rgba(0,0,0,0.1); font-size:0.72rem; }
|
|
.sb-multi-count { font-weight:700; color:#f59e0b; }
|
|
.sb-multi-btn { background:none; border:1px solid rgba(0,0,0,0.06); border-radius:5px; color:var(--sb-text); font-size:0.65rem; padding:3px 8px; cursor:pointer; }
|
|
.sb-multi-btn:hover { background:rgba(0,0,0,0.05); }
|
|
.sb-multi-btn.sb-ctx-warn { color:#ef4444; border-color:rgba(239,68,68,0.3); }
|
|
.sb-multi-clear { color:#7b80a0; }
|
|
.sb-multi-sep { color:rgba(0,0,0,0.08); }
|
|
.sb-multi-lbl { color:#7b80a0; font-size:0.62rem; }
|
|
.sb-multi-tech { background:none; border:2px solid; border-radius:50%; width:24px; height:24px; display:flex; align-items:center; justify-content:center; font-size:0.5rem; font-weight:800; color:var(--sb-text); cursor:pointer; }
|
|
.sb-multi-tech:hover { filter:brightness(1.3); }
|
|
.sb-slide-up-enter-active, .sb-slide-up-leave-active { transition:transform 0.2s, opacity 0.2s; }
|
|
.sb-slide-up-enter-from, .sb-slide-up-leave-to { transform:translateX(-50%) translateY(20px); opacity:0; }
|
|
.sb-lasso { position:absolute; border:1.5px dashed #f59e0b; background:rgba(245,158,11,0.08); border-radius:3px; pointer-events:none; z-index:50; }
|
|
.sb-board:has(.sb-lasso) { user-select:none; -webkit-user-select:none; cursor:crosshair; }
|
|
.sb-block.sb-block-linked { outline:2px dashed #6366f1; outline-offset:1px; z-index:7 !important; opacity:1 !important; box-shadow:0 4px 16px rgba(99,102,241,0.3) !important; transform:translateY(-1px); }
|
|
.sb-block-status-icon { display:inline-flex; align-items:center; margin-right:5px; flex-shrink:0; }
|
|
.sb-block-status-icon svg { width:13px; height:13px; }
|
|
.sb-block-assistants { display:flex; gap:2px; position:absolute; top:2px; right:2px; }
|
|
.sb-assist-badge { width:16px; height:16px; border-radius:50%; font-size:0.45rem; font-weight:800; color:var(--sb-text); display:flex; align-items:center; justify-content:center; border:1.5px solid rgba(0,0,0,0.3); }
|
|
.sb-assist-badge-lead { border-color:rgba(0,0,0,0.25); }
|
|
.sb-block-team { outline:1.5px solid rgba(0,0,0,0.12); outline-offset:1px; }
|
|
.sb-block-drop-hover { outline:2px solid #6366f1 !important; outline-offset:1px; filter:brightness(1.3); }
|
|
.sb-block-assist { opacity:0.7; border:1.5px dashed rgba(0,0,0,0.12); cursor:pointer; z-index:3; background-image:repeating-linear-gradient(-45deg, transparent, transparent 4px, rgba(0,0,0,0.03) 4px, rgba(0,0,0,0.03) 8px) !important; }
|
|
.sb-block-assist .sb-block-meta { font-size:0.52rem; }
|
|
.sb-block-assist:hover { opacity:0.9; }
|
|
.sb-block-assist-pinned { opacity:0.85; border-style:solid; background-image:none !important; }
|
|
.sb-move-handle { position:absolute; left:0; top:0; bottom:0; width:8px; cursor:grab; z-index:6; }
|
|
.sb-move-handle:hover { background:rgba(0,0,0,0.08); border-radius:6px 0 0 6px; }
|
|
.sb-move-handle::after { content:'⠿'; position:absolute; left:1px; top:50%; transform:translateY(-50%); font-size:0.5rem; color:rgba(0,0,0,0.2); }
|
|
.sb-move-handle:active { cursor:grabbing; }
|
|
.sb-resize-handle { position:absolute; right:0; top:0; bottom:0; width:6px; cursor:ew-resize; z-index:6; }
|
|
.sb-resize-handle:hover { background:rgba(0,0,0,0.08); border-radius:0 6px 6px 0; }
|
|
.sb-resize-handle::after { content:''; position:absolute; right:2px; top:50%; transform:translateY(-50%); width:2px; height:12px; border-radius:1px; background:rgba(0,0,0,0.15); }
|
|
.sbf-team-badges { display:flex; gap:2px; margin-top:2px; }
|
|
.sb-type-icon { display:inline-flex; align-items:center; margin-right:3px; flex-shrink:0; vertical-align:middle; }
|
|
.sb-type-icon svg { width:11px; height:11px; }
|
|
.sb-block-color-bar { width:3px; height:100%; flex-shrink:0; background:rgba(0,0,0,0.25); }
|
|
.sb-block-inner { flex:1; min-width:0; padding:0 5px; }
|
|
.sb-block-title { font-size:0.68rem; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:var(--sb-text); }
|
|
.sb-block-meta { font-size:0.58rem; color:rgba(0,0,0,0.45); white-space:nowrap; }
|
|
.sb-block-addr { font-size:0.52rem; color:rgba(0,0,0,0.25); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:flex; align-items:center; gap:2px; }
|
|
.sb-block-addr svg { width:9px; height:9px; flex-shrink:0; }
|
|
.sb-block-pin { display:inline-flex; align-items:center; margin-right:2px; }
|
|
.sb-block-pin svg { width:10px; height:10px; }
|
|
.sb-travel-trail { position:absolute; border-radius:4px; z-index:2; display:flex; align-items:center; justify-content:center; pointer-events:none; transition:opacity 0.2s; }
|
|
.sb-travel-route { border-left-style:solid; }
|
|
.sb-travel-est { border-left-style:dashed; opacity:0.7; }
|
|
.sb-travel-lbl { font-size:0.55rem; color:rgba(0,0,0,0.08); white-space:nowrap; font-style:italic; }
|
|
|
|
/* ── Bottom panel ── */
|
|
.sb-bottom-panel { flex-shrink:0; border-top:1px solid var(--sb-border); display:flex; flex-direction:column; background:var(--sb-sidebar); position:relative; overflow:hidden; }
|
|
.sb-bottom-resize { position:absolute; top:0; left:0; right:0; height:4px; z-index:10; cursor:row-resize; background:transparent; }
|
|
.sb-bottom-resize:hover { background:rgba(99,102,241,0.35); }
|
|
.sb-bottom-hdr { display:flex; align-items:center; gap:0.5rem; padding:0.35rem 0.75rem; border-bottom:1px solid var(--sb-border); flex-shrink:0; }
|
|
.sb-bottom-title { font-size:0.62rem; font-weight:800; text-transform:uppercase; letter-spacing:0.07em; color:var(--sb-muted); display:flex; align-items:center; gap:0.35rem; }
|
|
.sb-bottom-close { background:none; border:none; color:var(--sb-muted); cursor:pointer; font-size:0.9rem; margin-left:auto; }
|
|
.sb-bottom-close:hover { color:var(--sb-red); }
|
|
.sb-bottom-body { flex:1; overflow-y:auto; overflow-x:auto; display:flex; flex-direction:column; }
|
|
.sb-bottom-body::-webkit-scrollbar { width:4px; height:4px; }
|
|
.sb-bottom-body::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); }
|
|
.sb-bottom-date-sep { display:flex; align-items:center; gap:0.4rem; padding:0.3rem 0.75rem; background:rgba(99,102,241,0.06); border-bottom:1px solid var(--sb-border); position:sticky; top:0; z-index:2; user-select:none; cursor:crosshair; }
|
|
.sb-bottom-date-label { font-size:0.62rem; font-weight:800; color:var(--sb-acc); text-transform:uppercase; letter-spacing:0.05em; }
|
|
.sb-bottom-date-count { font-size:0.55rem; color:var(--sb-muted); }
|
|
.sb-bottom-scroll { flex:1; overflow-y:auto; overflow-x:hidden; min-height:0; cursor:crosshair; }
|
|
.sb-bottom-scroll::-webkit-scrollbar { width:4px; }
|
|
.sb-bottom-scroll::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); }
|
|
.sb-bottom-table { width:100%; border-collapse:collapse; font-size:0.72rem; table-layout:fixed; }
|
|
.sb-bottom-table thead th { position:sticky; top:0; z-index:3; background:var(--sb-sidebar); text-align:left; font-size:0.55rem; font-weight:800; text-transform:uppercase; letter-spacing:0.06em; color:var(--sb-muted); padding:0.3rem 0.5rem; border-bottom:1px solid var(--sb-border); white-space:nowrap; overflow:hidden; }
|
|
.sb-col-resize { position:absolute; right:0; top:0; bottom:0; width:5px; cursor:col-resize; z-index:4; }
|
|
.sb-col-resize:hover { background:rgba(99,102,241,0.35); }
|
|
.sb-bottom-row { cursor:pointer; transition:background 0.1s; border-bottom:1px solid var(--sb-border); }
|
|
.sb-bottom-row:hover { background:var(--sb-card-h); }
|
|
.sb-bottom-row-sel { background:rgba(99,102,241,0.1) !important; }
|
|
.sb-bottom-row-sel:hover { background:rgba(99,102,241,0.15) !important; }
|
|
.sb-bt-lasso { position:absolute; border:1.5px dashed #f59e0b; background:rgba(245,158,11,0.08); pointer-events:none; z-index:50; border-radius:3px; }
|
|
.sb-bottom-scroll:has(.sb-bt-lasso) { user-select:none; -webkit-user-select:none; cursor:crosshair; }
|
|
.sb-bottom-row td { padding:0.3rem 0.5rem; white-space:nowrap; color:var(--sb-text); overflow:hidden; text-overflow:ellipsis; }
|
|
.sb-bt-chk { padding:0 !important; text-align:center !important; }
|
|
.sb-bt-checkbox { display:inline-block; width:14px; height:14px; border-radius:3px; border:1.5px solid var(--sb-muted); vertical-align:middle; position:relative; }
|
|
.sb-bt-checkbox.checked { background:var(--sb-acc); border-color:var(--sb-acc); }
|
|
.sb-bt-checkbox.checked::after { content:'✓'; position:absolute; inset:0; color:var(--sb-text); font-size:0.55rem; font-weight:800; display:flex; align-items:center; justify-content:center; }
|
|
.sb-bt-prio-dot { width:8px; height:8px; border-radius:50%; display:inline-block; }
|
|
.sb-bt-name-text { font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block; }
|
|
.sb-bt-addr { color:var(--sb-muted); font-size:0.65rem; overflow:hidden; text-overflow:ellipsis; }
|
|
.sb-bt-dur-wrap { display:flex; align-items:center; gap:6px; }
|
|
.sb-bt-dur-bar { flex:1; height:4px; background:rgba(0,0,0,0.04); border-radius:2px; overflow:hidden; min-width:30px; }
|
|
.sb-bt-dur-fill { height:100%; border-radius:2px; transition:width 0.2s; }
|
|
.sb-bt-dur-lbl { font-size:0.62rem; color:var(--sb-muted); font-variant-numeric:tabular-nums; white-space:nowrap; min-width:28px; }
|
|
.sb-bt-prio-tag { font-size:0.6rem; font-weight:700; padding:1px 6px; border-radius:4px; }
|
|
.sb-bt-skill-chip { display:inline-flex; align-items:center; font-size:0.55rem; font-weight:600; color:var(--sb-text); background:rgba(0,0,0,0.05); border:1px solid var(--sb-border); padding:1px 6px; border-radius:10px; margin-right:3px; white-space:nowrap; }
|
|
.sb-bt-no-tag { font-size:0.6rem; color:rgba(0,0,0,0.1); }
|
|
.sb-bottom-sel-count { font-size:0.65rem; font-weight:700; color:var(--sb-acc); }
|
|
.sb-bottom-sel-lbl { font-size:0.72rem; color:var(--sb-muted); }
|
|
.sb-bottom-sel-clear { background:none; border:none; color:var(--sb-muted); cursor:pointer; font-size:0.8rem; }
|
|
.sb-bottom-sel-clear:hover { color:var(--sb-red); }
|
|
.sb-bottom-sel-all { background:none; border:1px solid var(--sb-border); border-radius:4px; color:var(--sb-muted); font-size:0.58rem; padding:2px 6px; cursor:pointer; }
|
|
.sb-bottom-sel-all:hover { color:var(--sb-text); border-color:var(--sb-border-acc); }
|
|
.sb-crit-row { display:flex; align-items:center; gap:0.5rem; padding:0.4rem 0.5rem; border-bottom:1px solid var(--sb-border); background:var(--sb-card); border-radius:6px; margin-bottom:4px; cursor:grab; transition:background 0.12s, transform 0.12s, border-color 0.12s; }
|
|
.sb-crit-row:active { cursor:grabbing; }
|
|
.sb-crit-drag-over { border-color:var(--sb-acc); background:rgba(99,102,241,0.12); transform:scale(1.02); }
|
|
.sb-crit-order { font-size:0.65rem; font-weight:800; color:var(--sb-acc); width:18px; text-align:center; flex-shrink:0; }
|
|
.sb-crit-label { flex:1; font-size:0.72rem; color:var(--sb-text); display:flex; align-items:center; gap:0.4rem; cursor:pointer; }
|
|
.sb-crit-label input[type="checkbox"] { accent-color:var(--sb-acc); }
|
|
.sb-crit-arrows { display:flex; flex-direction:column; gap:1px; }
|
|
.sb-crit-arrows button { background:none; border:1px solid var(--sb-border); border-radius:3px; color:var(--sb-muted); font-size:0.5rem; padding:0 4px; cursor:pointer; line-height:1.2; }
|
|
.sb-crit-arrows button:hover:not(:disabled) { color:var(--sb-text); border-color:var(--sb-border-acc); }
|
|
.sb-crit-arrows button:disabled { opacity:0.25; cursor:default; }
|
|
.sb-crit-handle { color:var(--sb-muted); font-size:0.7rem; cursor:grab; user-select:none; flex-shrink:0; opacity:0.4; transition:opacity 0.12s; }
|
|
.sb-crit-row:hover .sb-crit-handle { opacity:0.8; }
|
|
|
|
/* ── Month ── */
|
|
.sb-month-wrap { flex:1; overflow-y:auto; display:flex; flex-direction:column; padding:0.5rem; gap:0.25rem; }
|
|
.sb-month-dow-hdr { display:grid; grid-template-columns:repeat(7,1fr); gap:2px; margin-bottom:2px; flex-shrink:0; }
|
|
.sb-month-dow { text-align:center; font-size:0.6rem; font-weight:800; color:var(--sb-muted); padding:0.25rem 0; text-transform:uppercase; letter-spacing:0.07em; }
|
|
.sb-month-week { display:grid; grid-template-columns:repeat(7,1fr); gap:2px; }
|
|
.sb-month-day { background:var(--sb-card); border:1px solid var(--sb-border); border-radius:6px; padding:0.3rem 0.35rem; min-height:80px; cursor:pointer; display:flex; flex-direction:column; gap:3px; transition:background 0.1s; }
|
|
.sb-month-day:hover { background:var(--sb-card-h); }
|
|
.sb-month-day-out { opacity:0.28; pointer-events:none; }
|
|
.sb-month-day-today { border-color:var(--sb-acc); }
|
|
.sb-month-day-num { font-size:0.7rem; font-weight:700; color:var(--sb-text); width:20px; height:20px; display:flex; align-items:center; justify-content:center; border-radius:50%; flex-shrink:0; }
|
|
.sb-month-day-today .sb-month-day-num { background:var(--sb-acc); color:var(--sb-text); }
|
|
.sb-month-avatars { display:flex; flex-wrap:wrap; gap:2px; }
|
|
.sb-month-avatar { width:18px; height:18px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:0.48rem; font-weight:800; color:var(--sb-text); flex-shrink:0; cursor:pointer; transition:transform 0.1s; box-shadow:0 1px 3px rgba(0,0,0,0.08); }
|
|
.sb-month-avatar:hover { transform:scale(1.3); z-index:2; position:relative; }
|
|
.sb-month-stats { display:flex; gap:6px; align-items:center; }
|
|
.sb-month-stat { font-size:0.52rem; font-weight:600; display:flex; align-items:center; gap:2px; }
|
|
.sb-month-stat-present { color:var(--sb-green); }
|
|
.sb-month-stat-absent { color:var(--sb-muted); opacity:0.7; }
|
|
.sb-month-hours { font-size:0.5rem; color:var(--sb-muted); font-weight:600; }
|
|
.sb-month-job-count { font-size:0.52rem; color:var(--sb-muted); margin-top:auto; }
|
|
|
|
/* ── Map ── */
|
|
.sb-map-backdrop { position:absolute; top:0; left:0; right:0; bottom:0; z-index:14; background:rgba(0,0,0,0.15); }
|
|
.sb-map-panel { flex-shrink:0; z-index:15; display:flex; flex-direction:column; border-left:1px solid var(--sb-border); overflow:hidden; position:relative; }
|
|
.sb-map-resize-handle { position:absolute; left:0; top:0; bottom:0; width:5px; z-index:10; cursor:col-resize; background:transparent; transition:background 0.15s; }
|
|
.sb-map-resize-handle:hover { background:rgba(99,102,241,0.35); }
|
|
.sb-map-bar { display:flex; align-items:center; gap:0.4rem; padding:0.4rem 0.65rem; background:var(--sb-sidebar); border-bottom:1px solid var(--sb-border); flex-shrink:0; }
|
|
.sb-map-title { font-size:0.62rem; font-weight:800; text-transform:uppercase; letter-spacing:0.07em; color:var(--sb-muted); }
|
|
.sb-map-tech { font-size:0.7rem; font-weight:700; }
|
|
.sb-map-route-hint { font-size:0.58rem; font-weight:400; color:rgba(0,0,0,0.18); margin-left:0.25rem; }
|
|
.sb-map-hint { font-size:0.62rem; color:var(--sb-muted); font-style:italic; flex:1; }
|
|
.sb-map-bar-geofix { background:rgba(99,102,241,0.18); border-bottom-color:var(--sb-border-acc); }
|
|
.sb-geofix-hint { flex:1; font-size:0.68rem; color:var(--sb-text); animation:sb-geofix-pulse 1.4s ease-in-out infinite; }
|
|
.sb-geofix-cancel { background:none; border:1px solid var(--sb-border-acc); border-radius:5px; color:var(--sb-muted); font-size:0.65rem; padding:0.18rem 0.45rem; cursor:pointer; }
|
|
.sb-geofix-cancel:hover { color:var(--sb-red); border-color:rgba(239,68,68,0.4); }
|
|
@keyframes sb-geofix-pulse { 0%,100%{ opacity:1 } 50%{ opacity:0.55 } }
|
|
.sb-map-close { background:none; border:none; color:var(--sb-muted); cursor:pointer; font-size:0.9rem; margin-left:auto; }
|
|
.sb-map-legend { display:flex; flex-wrap:wrap; gap:0.3rem 0.6rem; padding:0.3rem 0.65rem; background:var(--sb-sidebar); border-bottom:1px solid var(--sb-border); flex-shrink:0; }
|
|
.sb-legend-item { display:flex; align-items:center; gap:0.2rem; font-size:0.62rem; color:var(--sb-muted); }
|
|
.sb-legend-dot { width:7px; height:7px; border-radius:50%; flex-shrink:0; }
|
|
.sb-map { flex:1; min-height:0; }
|
|
.sb-map-tech-pin { width:36px; height:36px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:0.65rem; font-weight:800; color:#fff; border:2.5px solid; box-shadow:0 2px 10px rgba(0,0,0,0.25); cursor:pointer; transition:transform 0.15s; }
|
|
.sb-map-tech-pin:hover { transform:scale(1.2); }
|
|
.sb-map-tech-pin { position:relative; }
|
|
.sb-map-crew-badge { position:absolute; top:-4px; right:-6px; min-width:16px; height:16px; border-radius:8px; background:#6366f1; color:#fff; font-size:9px; font-weight:800; display:flex; align-items:center; justify-content:center; border:2px solid #fff; line-height:1; padding:0 3px; }
|
|
.sb-map-gps-active { box-shadow:0 0 0 3px rgba(16,185,129,0.5), 0 0 12px rgba(16,185,129,0.4), 0 2px 10px rgba(0,0,0,0.55); animation:gps-glow 2s infinite; }
|
|
@keyframes gps-glow { 0%,100% { box-shadow:0 0 0 3px rgba(16,185,129,0.5), 0 0 12px rgba(16,185,129,0.4), 0 2px 10px rgba(0,0,0,0.55); } 50% { box-shadow:0 0 0 6px rgba(16,185,129,0.3), 0 0 20px rgba(16,185,129,0.3), 0 2px 10px rgba(0,0,0,0.55); } }
|
|
.sb-map-drag-ghost { padding:4px 8px; border-radius:6px; background:rgba(99,102,241,0.9); color:#fff; font-size:0.68rem; font-weight:700; box-shadow:0 4px 16px rgba(0,0,0,0.2); max-width:180px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; user-select:none; }
|
|
|
|
/* ── Right panel ── */
|
|
.sb-right { width:280px; min-width:280px; flex-shrink:0; display:flex; flex-direction:column; background:var(--sb-sidebar); color:var(--sb-text); border-left:1px solid rgba(0,0,0,0.04); overflow:hidden; }
|
|
.sb-rp-hdr { display:flex; align-items:center; padding:0.55rem 0.75rem; border-bottom:1px solid rgba(0,0,0,0.04); flex-shrink:0; }
|
|
.sb-rp-title { font-size:0.68rem; font-weight:800; text-transform:uppercase; letter-spacing:0.06em; color:#7b80a0; flex:1; }
|
|
.sb-rp-close { background:none; border:none; color:#7b80a0; cursor:pointer; font-size:0.95rem; transition:color 0.12s; }
|
|
.sb-rp-close:hover { color:#ef4444; }
|
|
.sb-rp-body { flex:1; overflow-y:auto; padding:0.65rem 0.75rem; color:var(--sb-text); }
|
|
.sb-rp-body::-webkit-scrollbar { width:3px; }
|
|
.sb-rp-body::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); }
|
|
.sb-rp-color-bar { height:3px; border-radius:2px; margin-bottom:0.75rem; }
|
|
.sb-rp-urgent-tag { background:rgba(239,68,68,0.15); color:#ef4444; font-size:0.7rem; font-weight:700; padding:0.25rem 0.5rem; border-radius:6px; display:inline-block; margin-bottom:0.5rem; }
|
|
.sb-rp-field { margin-bottom:0.45rem; color:var(--sb-text); }
|
|
.sb-rp-lbl { display:block; font-size:0.58rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; color:#7b80a0; margin-bottom:0.1rem; }
|
|
.sb-rp-actions { padding:0.65rem 0.75rem; border-top:1px solid rgba(0,0,0,0.04); display:flex; flex-direction:column; gap:0.35rem; flex-shrink:0; }
|
|
.sb-rp-primary { background:#6366f1; border:none; border-radius:7px; color:var(--sb-text); font-size:0.72rem; font-weight:700; padding:0.4rem 0.75rem; cursor:pointer; }
|
|
.sb-rp-primary:hover { filter:brightness(1.12); }
|
|
.sb-rp-btn { background:none; border:1px solid rgba(0,0,0,0.04); border-radius:7px; color:#7b80a0; font-size:0.7rem; padding:0.35rem 0.75rem; cursor:pointer; transition:border-color 0.12s, color 0.12s; }
|
|
.sb-rp-btn:hover { border-color:rgba(99,102,241,0.4); color:var(--sb-text); }
|
|
.sb-assign-grid { display:flex; flex-direction:column; gap:0.3rem; }
|
|
.sb-assign-btn { display:flex; align-items:center; gap:0.4rem; background:none; border:1px solid rgba(0,0,0,0.04); border-radius:6px; color:var(--sb-text); font-size:0.7rem; padding:0.3rem 0.55rem; cursor:pointer; transition:background 0.12s; text-align:left; }
|
|
.sb-assign-btn:hover { background:var(--sb-card); }
|
|
.sb-assign-dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; }
|
|
|
|
/* ── Context menu ── */
|
|
.sb-ctx { position:fixed; z-index:200; background:var(--sb-card); color:var(--sb-text); border:1px solid rgba(99,102,241,0.25); border-radius:9px; padding:0.3rem; box-shadow:0 8px 28px rgba(0,0,0,0.15); min-width:180px; }
|
|
.sb-ctx-item { display:block; width:100%; background:none; border:none; border-radius:6px; color:var(--sb-text); font-size:0.75rem; padding:0.4rem 0.7rem; cursor:pointer; text-align:left; transition:background 0.1s; }
|
|
.sb-ctx-item:hover { background:var(--sb-card-h); }
|
|
.sb-ctx-sep { height:1px; background:rgba(0,0,0,0.04); margin:0.2rem 0; }
|
|
.sb-ctx-warn { color:#ef4444 !important; }
|
|
|
|
/* ── Modals ── */
|
|
.sb-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.65); backdrop-filter:blur(4px); z-index:100; display:flex; align-items:center; justify-content:center; }
|
|
.sb-overlay-top { z-index:110; }
|
|
.sb-modal { background:var(--sb-sidebar); color:var(--sb-text); border:1px solid rgba(0,0,0,0.04); border-radius:14px; padding:0; min-width:360px; max-width:500px; width:100%; box-shadow:0 24px 60px rgba(0,0,0,0.12); overflow:hidden; max-height:85vh; display:flex; flex-direction:column; }
|
|
.sb-modal-wide { min-width:580px; max-width:680px; }
|
|
.sb-modal-tags { min-width:420px; max-width:560px; overflow:visible; }
|
|
.sb-modal-hdr { display:flex; align-items:center; justify-content:space-between; padding:0.75rem 1rem; border-bottom:1px solid rgba(0,0,0,0.04); font-weight:700; font-size:0.85rem; color:var(--sb-text); }
|
|
.sb-modal-body { padding:0.75rem 1rem; color:var(--sb-text); overflow-y:auto; flex:1; min-height:0; }
|
|
.sb-modal-body::-webkit-scrollbar { width:4px; }
|
|
.sb-modal-body::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); border-radius:2px; }
|
|
.sb-modal-ftr { padding:0.65rem 1rem; border-top:1px solid rgba(0,0,0,0.04); display:flex; gap:0.5rem; }
|
|
.sb-modal-footer { padding:0.65rem 1rem; border-top:1px solid rgba(0,0,0,0.04); display:flex; gap:0.5rem; }
|
|
.sb-form-row { margin-bottom:0.6rem; }
|
|
.sb-form-lbl { display:block; font-size:0.62rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; color:#7b80a0; margin-bottom:0.2rem; }
|
|
.sb-form-val { font-size:0.78rem; font-weight:600; color:var(--sb-text); }
|
|
.sb-form-sel { width:100%; background:var(--sb-card); border:1px solid rgba(0,0,0,0.04); border-radius:6px; color:var(--sb-text); font-size:0.75rem; padding:0.3rem 0.5rem; cursor:pointer; }
|
|
.sb-form-input { width:100%; background:var(--sb-card); border:1px solid rgba(0,0,0,0.04); border-radius:6px; color:var(--sb-text); font-size:0.75rem; padding:0.3rem 0.5rem; box-sizing:border-box; }
|
|
.sb-form-sel:focus, .sb-form-input:focus { border-color:rgba(99,102,241,0.4); outline:none; }
|
|
.sb-addr-wrap { position:relative; }
|
|
.sb-addr-dropdown { position:absolute; top:100%; left:0; right:0; z-index:50; background:var(--sb-card); border:1px solid rgba(99,102,241,0.3); border-radius:6px; max-height:200px; overflow-y:auto; box-shadow:0 8px 24px rgba(0,0,0,0.08); }
|
|
.sb-addr-item { padding:6px 10px; cursor:pointer; font-size:0.72rem; color:var(--sb-text); border-bottom:1px solid rgba(0,0,0,0.03); }
|
|
.sb-addr-item:hover { background:rgba(99,102,241,0.12); }
|
|
.sb-addr-item strong { color:var(--sb-text); }
|
|
.sb-addr-city { float:right; font-size:0.6rem; color:#7b80a0; }
|
|
.sb-addr-confirmed { font-size:0.6rem; color:#10b981; margin-top:3px; }
|
|
.sb-addr-cp { font-size:0.6rem; color:#6366f1; margin-left:4px; }
|
|
.sb-modal-wo { min-width:500px; max-width:720px; }
|
|
.sb-wo-body { display:flex; gap:1rem; }
|
|
.sb-wo-form { flex:1; min-width:0; }
|
|
.sb-wo-minimap { width:280px; flex-shrink:0; display:flex; align-items:flex-start; }
|
|
.sb-minimap-img { width:100%; border-radius:8px; border:1px solid rgba(0,0,0,0.04); }
|
|
.sb-rsel-groups { margin-bottom:0.6rem; }
|
|
.sb-rsel-section-title { font-size:0.6rem; font-weight:800; text-transform:uppercase; letter-spacing:0.06em; color:#7b80a0; margin-bottom:0.3rem; }
|
|
.sb-rsel-chips { display:flex; flex-wrap:wrap; gap:0.3rem; }
|
|
.sb-rsel-chip { background:var(--sb-card); border:1px solid rgba(0,0,0,0.06); border-radius:6px; color:var(--sb-muted); font-size:0.7rem; font-weight:600; padding:0.25rem 0.6rem; cursor:pointer; transition:all 0.12s; }
|
|
.sb-rsel-chip:hover { border-color:rgba(99,102,241,0.4); color:var(--sb-text); }
|
|
.sb-rsel-chip.active { background:rgba(99,102,241,0.12); border-color:#6366f1; color:#4f46e5; }
|
|
.sb-rsel-group-actions { margin-top:0.4rem; }
|
|
.sb-rsel-apply-group { background:#6366f1; border:none; border-radius:6px; color:var(--sb-text); font-size:0.68rem; font-weight:600; padding:0.3rem 0.8rem; cursor:pointer; transition:background 0.12s; }
|
|
.sb-rsel-apply-group:hover { background:#4f46e5; }
|
|
.sb-rsel-search-row { margin-bottom:0.5rem; }
|
|
.sb-rsel-search { width:100%; background:var(--sb-card); border:1px solid rgba(0,0,0,0.05); border-radius:6px; color:var(--sb-text); font-size:0.72rem; padding:0.35rem 0.6rem; outline:none; }
|
|
.sb-rsel-search:focus { border-color:rgba(99,102,241,0.4); }
|
|
.sb-rsel-search::placeholder { color:#7b80a0; }
|
|
.sb-rsel-preset { position:relative; padding-right:1.4rem; }
|
|
.sb-rsel-preset-count { font-size:0.6rem; opacity:0.6; margin-left:2px; }
|
|
.sb-rsel-preset-del { position:absolute; right:4px; top:50%; transform:translateY(-50%); font-size:0.6rem; opacity:0; transition:opacity 0.1s; color:#f87171; }
|
|
.sb-rsel-preset:hover .sb-rsel-preset-del { opacity:1; }
|
|
.sb-rsel-save-row { display:flex; align-items:center; gap:4px; }
|
|
.sb-rsel-save-input { background:var(--sb-card); border:1px solid rgba(99,102,241,0.3); border-radius:4px; color:var(--sb-text); font-size:0.7rem; padding:0.22rem 0.5rem; width:140px; outline:none; }
|
|
.sb-rsel-save-input:focus { border-color:#6366f1; }
|
|
.sb-rsel-save-input::placeholder { color:#7b80a0; }
|
|
.sb-rsel-save-btn { background:#6366f1; border:none; border-radius:4px; color:var(--sb-text); font-size:0.7rem; font-weight:700; padding:0.22rem 0.5rem; cursor:pointer; }
|
|
.sb-rsel-save-btn:disabled { opacity:0.4; cursor:default; }
|
|
.sb-res-sel-name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
.sb-res-sel-grp-tag { font-size:0.55rem; color:#7b80a0; background:rgba(0,0,0,0.04); padding:1px 5px; border-radius:3px; flex-shrink:0; }
|
|
.sb-res-sel-wrap { display:flex; gap:1rem; align-items:flex-start; }
|
|
.sb-res-sel-col { flex:1; background:var(--sb-card); border:1px solid rgba(0,0,0,0.04); border-radius:8px; overflow:hidden; max-height:300px; overflow-y:auto; }
|
|
.sb-res-sel-col::-webkit-scrollbar { width:3px; }
|
|
.sb-res-sel-col::-webkit-scrollbar-thumb { background:rgba(0,0,0,0.06); }
|
|
.sb-res-sel-hdr { padding:0.4rem 0.6rem; background:var(--sb-sidebar); font-size:0.6rem; font-weight:800; text-transform:uppercase; letter-spacing:0.06em; color:#7b80a0; border-bottom:1px solid rgba(0,0,0,0.04); }
|
|
.sb-res-sel-item { display:flex; align-items:center; gap:0.45rem; padding:0.4rem 0.6rem; cursor:pointer; font-size:0.72rem; color:var(--sb-text); transition:background 0.1s; border-bottom:1px solid rgba(0,0,0,0.04); }
|
|
.sb-res-sel-item:hover { background:var(--sb-card-h); }
|
|
.sb-res-sel-active { color:#6366f1; }
|
|
.sb-res-sel-rm { margin-left:auto; color:#7b80a0; font-size:0.8rem; }
|
|
.sb-res-sel-group-hdr { padding:0.25rem 0.6rem; font-size:0.55rem; font-weight:800; text-transform:uppercase; letter-spacing:0.08em; color:#6366f1; background:rgba(99,102,241,0.08); border-bottom:1px solid rgba(0,0,0,0.04); position:sticky; top:0; z-index:1; }
|
|
.sb-res-sel-arrow { font-size:1.2rem; color:#7b80a0; align-self:center; flex-shrink:0; }
|
|
.sb-avatar-xs { width:22px; height:22px; border-radius:50%; flex-shrink:0; display:flex; align-items:center; justify-content:center; font-size:0.55rem; font-weight:700; color:#fff; }
|
|
.sb-avatar-material { background:#e2e8f0; border:1.5px solid #cbd5e1; border-radius:6px; font-size:0.7rem; }
|
|
.sb-res-sel-cat-tag { font-size:0.55rem; color:#f59e0b; background:rgba(245,158,11,0.12); padding:1px 5px; border-radius:3px; flex-shrink:0; }
|
|
|
|
/* ── Resource type toggle ── */
|
|
.sb-res-type-toggle { display:flex; gap:1px; background:var(--sb-border); border-radius:5px; overflow:hidden; flex-shrink:0; }
|
|
.sb-res-type-toggle button { background:var(--sb-card); color:var(--sb-muted); border:none; font-size:0.62rem; font-weight:600; font-family:inherit; padding:2px 8px; cursor:pointer; display:flex; align-items:center; gap:3px; transition:all 0.12s; white-space:nowrap; }
|
|
.sb-res-type-toggle button.active { background:rgba(99,102,241,0.12); color:#4f46e5; }
|
|
.sb-res-type-toggle button:hover { background:rgba(99,102,241,0.12); }
|
|
|
|
/* ── Transitions ── */
|
|
.sb-slide-left-enter-active, .sb-slide-left-leave-active { transition:width 0.18s, min-width 0.18s, opacity 0.18s; }
|
|
.sb-slide-left-enter-from, .sb-slide-left-leave-to { width:0!important; min-width:0!important; opacity:0; overflow:hidden; }
|
|
.sb-slide-right-enter-active, .sb-slide-right-leave-active { transition:width 0.18s, min-width 0.18s, opacity 0.18s; }
|
|
.sb-slide-right-enter-from, .sb-slide-right-leave-to { width:0!important; min-width:0!important; opacity:0; overflow:hidden; }
|
|
|
|
// ── Offer pool sidebar ──
|
|
.sb-offer-pool-col {
|
|
width: 320px; min-width: 320px; height: 100%;
|
|
border-left: 1px solid var(--sb-border);
|
|
overflow: hidden; flex-shrink: 0;
|
|
}
|
|
|
|
// ── Overload alert badge ──
|
|
.sb-overload-alert {
|
|
font-size: 0.68rem; font-weight: 600;
|
|
color: #b45309; background: rgba(251, 191, 36, 0.12);
|
|
border: 1px solid rgba(251, 191, 36, 0.25);
|
|
border-radius: 5px; padding: 2px 8px;
|
|
cursor: default; white-space: nowrap;
|
|
animation: sb-pulse-warn 2s infinite;
|
|
}
|
|
@keyframes sb-pulse-warn {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.7; }
|
|
}
|
|
/* GPS Settings Modal */
|
|
.sb-modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.12); z-index:200; display:flex; align-items:center; justify-content:center; }
|
|
.sb-gps-modal { background:var(--sb-card); border:1px solid var(--sb-border); border-radius:12px; width:700px; max-height:80vh; overflow:hidden; display:flex; flex-direction:column; }
|
|
.sb-gps-modal-hdr { padding:14px 20px; border-bottom:1px solid var(--sb-border); display:flex; align-items:center; justify-content:space-between; }
|
|
.sb-gps-modal-hdr h3 { font-size:15px; margin:0; }
|
|
.sb-gps-close { background:none; border:none; color:var(--sb-muted); cursor:pointer; font-size:20px; }
|
|
.sb-gps-modal-body { padding:16px 20px; overflow-y:auto; }
|
|
.sb-gps-desc { color:var(--sb-muted); font-size:12px; margin-bottom:14px; }
|
|
.sb-gps-table { width:100%; border-collapse:collapse; }
|
|
.sb-gps-table th { text-align:left; font-size:11px; text-transform:uppercase; color:var(--sb-muted); padding:6px 8px; border-bottom:1px solid var(--sb-border); }
|
|
.sb-gps-table td { padding:8px; border-bottom:1px solid var(--sb-border); font-size:13px; }
|
|
.sb-gps-select { width:100%; padding:5px 8px; background:var(--sb-bg); border:1px solid var(--sb-border); border-radius:5px; color:var(--sb-text); font-size:12px; }
|
|
.sb-gps-badge { padding:2px 8px; border-radius:10px; font-size:11px; font-weight:600; }
|
|
.sb-gps-online { background:rgba(16,185,129,0.15); color:#10b981; }
|
|
.sb-gps-offline { background:rgba(245,158,11,0.15); color:#f59e0b; }
|
|
.sb-gps-none { background:rgba(107,114,128,0.15); color:#6b7280; }
|
|
.sb-gps-coords { font-size:11px; color:var(--sb-muted); font-family:monospace; }
|
|
.sb-gps-footer { display:flex; align-items:center; justify-content:space-between; margin-top:12px; padding-top:12px; border-top:1px solid var(--sb-border); }
|
|
.sb-gps-info { font-size:11px; color:var(--sb-muted); }
|
|
.sb-gps-refresh { padding:5px 12px; background:var(--sb-acc); border:none; border-radius:6px; color:var(--sb-text); font-size:12px; cursor:pointer; }
|
|
.sb-gps-input { width:100%; padding:4px 8px; background:var(--sb-bg); border:1px solid var(--sb-border); border-radius:6px; color:var(--sb-fg); font-size:12px; }
|
|
.sb-gps-add-row td { padding-top:8px; border-top:1px solid var(--sb-border); }
|
|
.sb-gps-add-btn { padding:4px 14px; background:var(--sb-acc); border:none; border-radius:6px; color:var(--sb-text); font-size:12px; cursor:pointer; white-space:nowrap; }
|
|
.sb-gps-add-btn:disabled { opacity:.5; cursor:not-allowed; }
|
|
.sb-gps-actions { white-space:nowrap; }
|
|
.sb-gps-absence-btn { background:none; border:none; color:var(--sb-muted); font-size:14px; cursor:pointer; padding:2px 6px; border-radius:4px; }
|
|
.sb-gps-absence-btn:hover { color:#f59e0b; background:rgba(245,158,11,0.1); }
|
|
.sb-gps-react-btn { background:none; border:none; color:#22c55e; font-size:14px; cursor:pointer; padding:2px 6px; border-radius:4px; }
|
|
.sb-gps-react-btn:hover { background:rgba(34,197,94,0.1); }
|
|
.sb-gps-inactive-row { opacity:0.45; }
|
|
.sb-gps-inactive-row:hover { opacity:0.75; }
|
|
.sb-gps-toggle-row { margin-bottom:10px; }
|
|
.sb-gps-toggle-label { display:flex; align-items:center; gap:6px; font-size:12px; color:var(--sb-muted); cursor:pointer; }
|
|
.sb-gps-toggle-label input[type="checkbox"] { accent-color:var(--sb-acc); }
|
|
.sb-gps-inactive-count { color:#f59e0b; font-weight:600; }
|
|
.sb-gps-absence-info { font-size:10px; color:#f59e0b; margin-top:2px; }
|
|
.sb-gps-absence-date { color:var(--sb-muted); margin-left:4px; }
|
|
.sb-gps-editable { cursor:pointer; border-bottom:1px dashed transparent; }
|
|
.sb-gps-editable:hover { border-bottom-color:var(--sb-muted); }
|
|
|
|
/* ── Absence Modal ── */
|
|
.sb-absence-modal { min-width:480px; max-width:560px; }
|
|
.sb-absence-form { display:flex; flex-direction:column; gap:14px; }
|
|
.sb-absence-lbl { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; color:var(--sb-muted); margin-bottom:4px; display:block; }
|
|
.sb-absence-opt { font-weight:400; text-transform:none; color:rgba(0,0,0,0.12); }
|
|
.sb-absence-reasons { display:flex; flex-wrap:wrap; gap:6px; }
|
|
.sb-absence-reason-btn {
|
|
padding:5px 12px; border-radius:6px; font-size:12px; cursor:pointer;
|
|
background:var(--sb-bg); border:1px solid var(--sb-border); color:var(--sb-fg);
|
|
transition:all 0.15s;
|
|
}
|
|
.sb-absence-reason-btn:hover { border-color:var(--sb-acc); }
|
|
.sb-absence-reason-btn.active { background:rgba(99,102,241,0.12); border-color:var(--sb-acc); color:#4f46e5; }
|
|
.sb-absence-dates { display:flex; gap:12px; }
|
|
.sb-absence-dates > div { flex:1; }
|
|
.sb-absence-jobs { background:rgba(239,68,68,0.06); border:1px solid rgba(239,68,68,0.15); border-radius:8px; padding:10px; }
|
|
.sb-absence-job-actions { display:flex; flex-direction:column; gap:6px; margin:6px 0; }
|
|
.sb-absence-radio { display:flex; align-items:center; gap:6px; font-size:12px; color:var(--sb-fg); cursor:pointer; }
|
|
.sb-absence-radio input { accent-color:var(--sb-acc); }
|
|
.sb-absence-job-list { max-height:120px; overflow-y:auto; margin-top:6px; }
|
|
.sb-absence-job-item { display:flex; align-items:center; gap:6px; padding:3px 0; font-size:11px; color:var(--sb-fg); border-bottom:1px solid rgba(0,0,0,0.03); }
|
|
.sb-absence-job-dot { width:6px; height:6px; border-radius:50%; flex-shrink:0; }
|
|
.sb-absence-job-date { color:var(--sb-muted); margin-left:auto; font-size:10px; }
|
|
.sb-absence-no-jobs { font-size:12px; color:var(--sb-muted); font-style:italic; }
|
|
.sb-gps-edit-name { font-weight:600; }
|
|
.sb-gps-status-sel { min-width:100px; }
|
|
.sb-gps-phone { width:110px; font-variant-numeric:tabular-nums; }
|
|
/* ── Login Overlay ── */
|
|
.sb-login-overlay { position:fixed; inset:0; background:var(--sb-bg); z-index:9999; display:flex; align-items:center; justify-content:center; }
|
|
.sb-login-modal { background:var(--sb-card); border:1px solid var(--sb-border); border-radius:14px; padding:40px 36px; width:340px; display:flex; flex-direction:column; align-items:center; gap:16px; box-shadow:0 8px 40px rgba(0,0,0,0.12); }
|
|
.sb-login-logo { font-size:1.6rem; font-weight:800; color:var(--sb-acc); letter-spacing:-0.5px; }
|
|
.sb-login-sub { font-size:11px; color:var(--sb-muted); margin:0; text-align:center; }
|
|
.sb-login-sub a { color:var(--sb-acc); text-decoration:none; }
|
|
.sb-login-form { width:100%; display:flex; flex-direction:column; gap:10px; }
|
|
.sb-login-input { width:100%; padding:9px 12px; background:var(--sb-bg); border:1px solid var(--sb-border); border-radius:7px; color:var(--sb-text); font-size:13px; outline:none; box-sizing:border-box; }
|
|
.sb-login-input:focus { border-color:var(--sb-acc); }
|
|
.sb-login-btn { width:100%; padding:10px; background:var(--sb-acc); border:none; border-radius:7px; color:var(--sb-text); font-size:13px; font-weight:600; cursor:pointer; transition:opacity 0.15s; }
|
|
.sb-login-btn:disabled { opacity:0.6; cursor:not-allowed; }
|
|
.sb-login-error { color:var(--sb-red); font-size:12px; margin:0; text-align:center; }
|
|
|
|
/* ── Schedule editor modal ── */
|
|
.sb-schedule-modal { width:520px; max-width:95vw; }
|
|
.sb-schedule-presets { display:flex; gap:6px; padding:0.5rem 1rem; flex-wrap:wrap; }
|
|
.sb-preset-btn { background:var(--sb-card); border:1px solid var(--sb-border); border-radius:5px; color:var(--sb-text); font-size:0.68rem; padding:4px 10px; cursor:pointer; transition:border-color 0.15s, background 0.15s; }
|
|
.sb-preset-btn:hover { border-color:var(--sb-acc); background:rgba(99,102,241,0.12); }
|
|
.sb-schedule-grid { padding:0.5rem 1rem; display:flex; flex-direction:column; gap:6px; }
|
|
.sb-schedule-day { display:flex; align-items:center; gap:8px; padding:6px 10px; border-radius:6px; background:rgba(0,0,0,0.02); transition:background 0.15s; }
|
|
.sb-schedule-day:hover { background:rgba(0,0,0,0.04); }
|
|
.sb-schedule-off { opacity:0.5; }
|
|
.sb-schedule-toggle { display:flex; align-items:center; gap:6px; cursor:pointer; min-width:60px; }
|
|
.sb-schedule-toggle input[type="checkbox"] { accent-color:var(--sb-acc); width:14px; height:14px; cursor:pointer; }
|
|
.sb-schedule-day-label { font-size:0.75rem; font-weight:600; color:var(--sb-text); }
|
|
.sb-schedule-time { background:var(--sb-bg); border:1px solid var(--sb-border); border-radius:4px; color:var(--sb-text); font-size:0.72rem; padding:3px 6px; width:85px; outline:none; }
|
|
.sb-schedule-time:focus { border-color:var(--sb-acc); }
|
|
.sb-schedule-sep { color:var(--sb-muted); font-size:0.72rem; }
|
|
.sb-schedule-hours { color:var(--sb-muted); font-size:0.68rem; min-width:30px; text-align:right; }
|
|
.sb-schedule-off-label { color:var(--sb-muted); font-size:0.72rem; font-style:italic; }
|
|
// ── Extra shifts (on-call / garde) editor ──
|
|
.sb-extra-shifts-section { padding: 0.5rem 1rem; border-top: 1px solid var(--sb-border); }
|
|
.sb-extra-shifts-hdr {
|
|
display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px;
|
|
span { font-size: 0.78rem; font-weight: 600; color: var(--sb-text); }
|
|
}
|
|
.sb-rp-btn-sm { font-size: 0.68rem !important; padding: 2px 8px !important; }
|
|
.sb-extra-shifts-empty { font-size: 0.72rem; color: var(--sb-muted); font-style: italic; padding: 4px 0; }
|
|
.sb-extra-shift-row {
|
|
display: flex; align-items: center; gap: 6px; padding: 5px 8px; margin-bottom: 4px;
|
|
border-radius: 6px; background: rgba(251, 191, 36, 0.06); border: 1px solid rgba(251, 191, 36, 0.12);
|
|
}
|
|
.sb-extra-shift-label {
|
|
background: var(--sb-bg); border: 1px solid var(--sb-border); border-radius: 4px;
|
|
color: var(--sb-text); font-size: 0.72rem; padding: 3px 6px; width: 70px; outline: none;
|
|
&:focus { border-color: #f59e0b; }
|
|
}
|
|
.sb-extra-shift-recurrence {
|
|
display: flex; align-items: center; gap: 4px; flex: 1; min-width: 0;
|
|
}
|
|
.sb-extra-shift-pattern {
|
|
background: var(--sb-bg); border: 1px solid var(--sb-border); border-radius: 4px;
|
|
color: var(--sb-text); font-size: 0.68rem; padding: 3px 4px; min-width: 0; outline: none;
|
|
&:focus { border-color: #f59e0b; }
|
|
}
|
|
.sb-extra-shift-sep { color: var(--sb-muted); font-size: 0.68rem; white-space: nowrap; }
|
|
.sb-extra-shift-interval {
|
|
background: var(--sb-bg); border: 1px solid var(--sb-border); border-radius: 4px;
|
|
color: var(--sb-text); font-size: 0.72rem; padding: 3px 4px; width: 42px; text-align: center; outline: none;
|
|
&:focus { border-color: #f59e0b; }
|
|
}
|
|
.sb-extra-shift-del {
|
|
background: none; border: none; color: #f87171; cursor: pointer; font-size: 0.85rem;
|
|
padding: 2px 4px; border-radius: 3px; transition: background 0.12s;
|
|
&:hover { background: rgba(248, 113, 113, 0.15); }
|
|
}
|
|
|
|
/* ── Confirm unassign dialog ── */
|
|
.sb-confirm-dialog {
|
|
background: var(--sb-card); border-radius: 14px; padding: 24px;
|
|
max-width: 380px; width: 90%; text-align: center;
|
|
border: 1px solid var(--sb-border-acc);
|
|
box-shadow: 0 20px 60px rgba(0,0,0,0.1);
|
|
}
|
|
.sb-confirm-icon { font-size: 2rem; margin-bottom: 8px; }
|
|
.sb-confirm-title { font-size: 1rem; font-weight: 700; color: var(--sb-text); margin-bottom: 10px; }
|
|
.sb-confirm-body { font-size: 0.82rem; color: var(--sb-muted); line-height: 1.5; margin-bottom: 16px; }
|
|
.sb-confirm-tag {
|
|
display: inline-block; font-size: 0.68rem; font-weight: 600; padding: 1px 8px;
|
|
border-radius: 4px; margin: 4px 2px;
|
|
}
|
|
.sb-confirm-tag-pub { background: rgba(99,102,241,0.12); color: #4f46e5; }
|
|
.sb-confirm-tag-ip { background: rgba(251,191,36,0.15); color: #b45309; }
|
|
.sb-confirm-tag-asg { background: rgba(59,130,246,0.2); color: #60a5fa; }
|
|
.sb-confirm-warn { font-size: 0.75rem; color: #f59e0b; font-style: italic; }
|
|
.sb-confirm-actions { display: flex; gap: 8px; justify-content: center; }
|
|
.sb-confirm-danger {
|
|
background: #dc2626 !important; color: white !important;
|
|
&:hover { background: #b91c1c !important; }
|
|
}
|