/* ============================================ NEXT-GEN HOTLINE PLANNER — Design System Dense Outline | Light | Mobile-First ============================================ */ /* --- Google Font --- */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); /* --- Design Tokens --- */ :root { /* Typography */ --font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; --font-size-xs: 0.675rem; --font-size-sm: 0.75rem; --font-size-md: 0.8125rem; --font-size-lg: 0.9375rem; --font-size-xl: 1.125rem; /* Spacing */ --space-xxs: 2px; --space-xs: 4px; --space-sm: 6px; --space-md: 10px; --space-lg: 16px; --space-xl: 24px; /* Border */ --border-radius: 4px; --border-radius-lg: 8px; --border-color: #E2E8F0; --border-color-hover: #CBD5E1; --border-color-focus: #1976D2; /* Colors — Surfaces */ --bg-page: #F8FAFC; --bg-surface: #FFFFFF; --bg-surface-hover: #F1F5F9; --bg-surface-active: #E8F0FE; --bg-frozen: #FDFDFE; /* Colors — Text */ --text-primary: #1A1A2E; --text-secondary: #64748B; --text-muted: #94A3B8; --text-inverse: #FFFFFF; /* Colors — Brand */ --color-primary: #1976D2; --color-primary-light: #E3F2FD; --color-primary-dark: #1565C0; /* Colors — Semantic */ --color-success: #16A34A; --color-success-bg: #F0FDF4; --color-warning: #D97706; --color-warning-bg: #FFFBEB; --color-error: #DC2626; --color-error-bg: #FEF2F2; /* Colors — Coverage Traffic Light */ --coverage-ok: #22C55E; --coverage-ok-bg: #DCFCE7; --coverage-warn: #F59E0B; --coverage-warn-bg: #FEF3C7; --coverage-critical: #EF4444; --coverage-critical-bg: #FEE2E2; /* Colors — ExNet */ --exnet-bg: #FCE7F3; --exnet-text: #9D174D; --exnet-border: #F9A8D4; /* Colors — Cell Lock */ --lock-border: #60A5FA; --lock-bg: rgba(96, 165, 250, 0.06); /* Shadows */ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04); --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.08); --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.1); /* Grid */ --frozen-col-width: 220px; --frozen-col-width-mobile: 120px; --cell-min-width: 100px; --cell-height: 40px; --header-height: 36px; --row-gap: 0px; } /* --- Global Reset & Base --- */ *, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; font-family: var(--font-family); font-size: var(--font-size-md); color: var(--text-primary); background: var(--bg-page); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* --- Quasar Dense Overrides --- */ .q-field--outlined .q-field__control { border-radius: var(--border-radius) !important; } .q-btn { border-radius: var(--border-radius) !important; text-transform: none !important; font-weight: 500 !important; letter-spacing: 0 !important; } .q-chip { border-radius: var(--border-radius) !important; } .q-card { border-radius: var(--border-radius-lg) !important; box-shadow: var(--shadow-sm) !important; } .q-dialog .q-card { border-radius: var(--border-radius-lg) !important; } .q-drawer { border-right: 1px solid var(--border-color) !important; } .q-header { background: var(--bg-surface) !important; color: var(--text-primary) !important; border-bottom: 1px solid var(--border-color) !important; box-shadow: none !important; } .q-toolbar { min-height: 48px !important; padding: 0 var(--space-lg) !important; } /* --- Layout --- */ .page-bg { background: var(--bg-page); min-height: 100vh; } /* --- Planner Grid --- */ .planner-container { display: flex; flex-direction: column; height: calc(100vh - 108px); /* header + filter bar */ overflow: hidden; } .planner-grid-wrapper { display: flex; flex: 1; overflow: hidden; position: relative; } /* Frozen Left Panel */ .frozen-left { width: var(--frozen-col-width); min-width: var(--frozen-col-width); flex-shrink: 0; background: var(--bg-frozen); border-right: 2px solid var(--border-color); overflow-y: auto; overflow-x: hidden; z-index: 10; } /* Scrollable Right Grid */ .scrollable-grid { flex: 1; overflow-x: auto; overflow-y: auto; -webkit-overflow-scrolling: touch; } .scrollable-grid-inner { display: inline-flex; flex-direction: column; min-width: max-content; } /* --- Grid Rows --- */ .grid-row { display: flex; align-items: stretch; min-height: var(--cell-height); border-bottom: 1px solid var(--border-color); } .grid-row:hover { background: var(--bg-surface-hover); } /* --- Header Rows --- */ .header-row { display: flex; align-items: center; min-height: var(--header-height); background: var(--bg-surface); border-bottom: 1px solid var(--border-color); font-weight: 600; font-size: var(--font-size-sm); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.03em; position: sticky; top: 0; z-index: 5; } /* --- Date Header Cell --- */ .date-header-cell { width: var(--cell-min-width); min-width: var(--cell-min-width); padding: var(--space-xs) var(--space-sm); display: flex; flex-direction: column; align-items: center; justify-content: center; border-right: 1px solid var(--border-color); font-size: var(--font-size-xs); } .date-header-cell .day-name { font-weight: 600; color: var(--text-secondary); } .date-header-cell .day-date { font-weight: 400; color: var(--text-muted); font-size: 0.625rem; } .date-header-cell.is-today { background: var(--color-primary-light); border-bottom: 2px solid var(--color-primary); } .date-header-cell.is-weekend { background: #F8FAFC; color: var(--text-muted); } /* --- ExNet Header Row --- */ .exnet-row { background: var(--exnet-bg) !important; border-bottom: 1px solid var(--exnet-border); min-height: 28px; } .exnet-cell { width: var(--cell-min-width); min-width: var(--cell-min-width); padding: var(--space-xxs) var(--space-xs); display: flex; align-items: center; justify-content: center; border-right: 1px solid var(--exnet-border); font-size: var(--font-size-xs); font-weight: 500; color: var(--exnet-text); } /* --- Coverage Indicator Row --- */ .coverage-row { min-height: 24px; border-bottom: 2px solid var(--border-color); } .coverage-cell { width: var(--cell-min-width); min-width: var(--cell-min-width); display: flex; align-items: center; justify-content: center; border-right: 1px solid var(--border-color); } .coverage-dot { width: 10px; height: 10px; border-radius: 50%; transition: background-color 0.2s; } .coverage-dot.ok { background: var(--coverage-ok); } .coverage-dot.warn { background: var(--coverage-warn); } .coverage-dot.critical { background: var(--coverage-critical); } /* --- Agent Row (Frozen) --- */ .agent-row-frozen { display: flex; flex-direction: column; justify-content: center; padding: var(--space-xs) var(--space-sm); min-height: var(--cell-height); border-bottom: 1px solid var(--border-color); gap: 1px; } .agent-name { font-weight: 600; font-size: var(--font-size-sm); color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .agent-email { font-size: var(--font-size-xs); color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .agent-skills { display: flex; gap: var(--space-xxs); margin-top: 1px; flex-wrap: wrap; } /* --- Skill Badge --- */ .skill-badge { display: inline-flex; align-items: center; padding: 0 var(--space-xs); height: 16px; font-size: 0.6rem; font-weight: 500; border-radius: 3px; background: var(--color-primary-light); color: var(--color-primary); white-space: nowrap; } /* --- Shift Cell --- */ .shift-cell { width: var(--cell-min-width); min-width: var(--cell-min-width); min-height: var(--cell-height); padding: var(--space-xxs) var(--space-xs); display: flex; flex-wrap: wrap; align-items: center; gap: 2px; border-right: 1px solid var(--border-color); cursor: pointer; position: relative; transition: background-color 0.15s, border-color 0.15s; } .shift-cell:hover { background: var(--bg-surface-hover); border-color: var(--border-color-hover); } .shift-cell.is-invalid { background: var(--color-error-bg); outline: 1.5px solid var(--color-error); outline-offset: -1.5px; } .shift-cell.is-warning { background: var(--color-warning-bg); outline: 1.5px solid var(--color-warning); outline-offset: -1.5px; } .shift-cell.is-locked { background: var(--lock-bg); outline: 1.5px solid var(--lock-border); outline-offset: -1.5px; cursor: not-allowed; } /* --- Shift Chip --- */ .shift-chip { display: inline-flex; align-items: center; height: 18px; padding: 0 var(--space-xs); font-size: 0.6rem; font-weight: 500; border-radius: 3px; white-space: nowrap; max-width: 90px; overflow: hidden; text-overflow: ellipsis; } .shift-chip.morning { background: #DBEAFE; color: #1E40AF; } .shift-chip.afternoon { background: #FEF3C7; color: #92400E; } .shift-chip.night { background: #E0E7FF; color: #3730A3; } .shift-chip.allday { background: #F3E8FF; color: #6B21A8; } .shift-chip.training { background: #D1FAE5; color: #065F46; } .shift-chip.exnet { background: var(--exnet-bg); color: var(--exnet-text); } /* --- Cell Menu Button --- */ .cell-menu-btn { position: absolute; top: 2px; right: 2px; opacity: 0; transition: opacity 0.15s; } .shift-cell:hover .cell-menu-btn { opacity: 1; } /* --- Cell Lock Overlay --- */ .cell-lock-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none; } .cell-lock-overlay .lock-avatar { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--lock-border); font-size: 0.5rem; display: flex; align-items: center; justify-content: center; background: var(--bg-surface); color: var(--lock-border); font-weight: 600; } /* --- Validation Icon --- */ .validation-icon { position: absolute; bottom: 2px; right: 2px; font-size: 10px; } /* --- Sidebar --- */ .sidebar-section { padding: var(--space-md) var(--space-lg); border-bottom: 1px solid var(--border-color); } .sidebar-section-title { font-size: var(--font-size-xs); font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: var(--space-sm); } /* --- Edit History --- */ .history-item { display: flex; gap: var(--space-sm); padding: var(--space-xs) 0; font-size: var(--font-size-xs); border-bottom: 1px solid var(--border-color); } .history-item:last-child { border-bottom: none; } .history-avatar { width: 20px; height: 20px; border-radius: 50%; background: var(--color-primary-light); color: var(--color-primary); display: flex; align-items: center; justify-content: center; font-size: 0.55rem; font-weight: 600; flex-shrink: 0; } .history-content { flex: 1; min-width: 0; } .history-user { font-weight: 600; color: var(--text-primary); } .history-action { color: var(--text-secondary); } .history-time { color: var(--text-muted); font-size: 0.6rem; } /* --- Users Online --- */ .users-online { display: flex; align-items: center; gap: 0; } .users-online .user-avatar-wrapper { margin-left: -6px; } .users-online .user-avatar-wrapper:first-child { margin-left: 0; } .user-avatar-circle { width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--bg-surface); display: flex; align-items: center; justify-content: center; font-size: 0.625rem; font-weight: 600; cursor: pointer; transition: transform 0.15s; } .user-avatar-circle:hover { transform: scale(1.1); z-index: 2; } .overflow-count { background: var(--text-muted); color: var(--text-inverse); } /* --- Filter Bar --- */ .filter-bar { display: flex; align-items: center; gap: var(--space-sm); padding: var(--space-sm) var(--space-lg); background: var(--bg-surface); border-bottom: 1px solid var(--border-color); flex-wrap: wrap; } /* --- Frozen Header --- */ .frozen-header { display: flex; align-items: center; padding: var(--space-xs) var(--space-sm); min-height: var(--header-height); border-bottom: 1px solid var(--border-color); font-weight: 600; font-size: var(--font-size-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.03em; background: var(--bg-surface); position: sticky; top: 0; z-index: 5; } .frozen-exnet-spacer { min-height: 28px; border-bottom: 1px solid var(--exnet-border); background: var(--exnet-bg); display: flex; align-items: center; padding: 0 var(--space-sm); font-size: var(--font-size-xs); font-weight: 500; color: var(--exnet-text); } .frozen-coverage-spacer { min-height: 24px; border-bottom: 2px solid var(--border-color); display: flex; align-items: center; padding: 0 var(--space-sm); font-size: var(--font-size-xs); font-weight: 500; color: var(--text-muted); } /* --- Scrollbar Styling --- */ .scrollable-grid::-webkit-scrollbar { height: 6px; width: 6px; } .scrollable-grid::-webkit-scrollbar-track { background: transparent; } .scrollable-grid::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 3px; } .scrollable-grid::-webkit-scrollbar-thumb:hover { background: var(--text-muted); } .frozen-left::-webkit-scrollbar { width: 4px; } .frozen-left::-webkit-scrollbar-track { background: transparent; } .frozen-left::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 2px; } /* --- Mobile Responsive --- */ @media (max-width: 599px) { :root { --frozen-col-width: var(--frozen-col-width-mobile); --cell-min-width: 90px; --cell-height: 44px; } .q-toolbar { padding: 0 var(--space-sm) !important; } .filter-bar { padding: var(--space-xs) var(--space-sm); gap: var(--space-xs); } .agent-email, .agent-skills { display: none; } .frozen-header span.hide-mobile { display: none; } } @media (min-width: 600px) and (max-width: 1023px) { :root { --frozen-col-width: 180px; } .agent-email { display: none; } } /* --- Utility --- */ .text-xs { font-size: var(--font-size-xs); } .text-sm { font-size: var(--font-size-sm); } .text-md { font-size: var(--font-size-md); } .text-lg { font-size: var(--font-size-lg); } .text-muted { color: var(--text-muted); } .text-secondary { color: var(--text-secondary); } .gap-xs { gap: var(--space-xs); } .gap-sm { gap: var(--space-sm); } .gap-md { gap: var(--space-md); } /* Synced scroll between frozen and scrollable panels */ .scroll-sync { scrollbar-width: none; } .scroll-sync::-webkit-scrollbar { display: none; }