/** * Dashboard CSS - Refined Novel Theme * Monochromatic warm palette with single accent color * Clean, professional, premium aesthetic */ /* ======================================== Custom Properties - Warm Monochrome ======================================== */ :root { /* Warm palette aligned with novel-theme.css */ --dash-bg: #FAF8F3; --dash-surface: #FFFFFF; --dash-surface-hover: #F5F3EE; --dash-border: #E8E4DC; --dash-border-subtle: #F0EDE6; --dash-text: #2D2A26; --dash-text-secondary: #7A756D; --dash-text-muted: #A8A29E; /* Single accent - warm brown */ --dash-accent: #8B4513; --dash-accent-hover: #6B3410; --dash-accent-subtle: rgba(139, 69, 19, 0.08); --dash-accent-glow: rgba(139, 69, 19, 0.15); /* Status - monochrome approach */ --dash-status-done: var(--dash-accent); --dash-status-active: var(--dash-accent); --dash-status-pending: var(--dash-text-muted); /* Layout */ --dash-radius: 12px; --dash-radius-sm: 8px; --dash-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06); --dash-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.08); /* Typography */ --dash-font: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; --dash-font-heading: 'Libre Baskerville', Georgia, serif; /* Animation */ --dash-ease: cubic-bezier(0.4, 0, 0.2, 1); --dash-duration: 200ms; } [data-theme="dark"] { --dash-bg: #1A1A1A; --dash-surface: #242424; --dash-surface-hover: #2A2A2A; --dash-border: #333333; --dash-border-subtle: #2A2A2A; --dash-text: #FAF8F3; --dash-text-secondary: #A8A198; --dash-text-muted: #6B6560; /* Single accent - warm gold */ --dash-accent: #D4A574; --dash-accent-hover: #E5B885; --dash-accent-subtle: rgba(212, 165, 116, 0.1); --dash-accent-glow: rgba(212, 165, 116, 0.2); --dash-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); --dash-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.3); } /* ======================================== Base Layout ======================================== */ .dashboard-view { min-height: 100vh; background: var(--dash-bg); font-family: var(--dash-font); color: var(--dash-text); } /* ======================================== Header - Single Row Compact Layout ======================================== */ .dashboard-header { position: sticky; top: 0; display: flex; justify-content: space-between; align-items: center; gap: 1.5rem; padding: 0.75rem 1.5rem; background: var(--dash-surface); border-bottom: 1px solid var(--dash-border); z-index: 100; } .header-left { display: flex; align-items: center; gap: 1.5rem; flex-shrink: 0; } .dashboard-header h1 { font-family: var(--dash-font-heading); font-size: 1.25rem; font-weight: 400; color: var(--dash-text); margin: 0; letter-spacing: -0.01em; } /* Inline stats in header */ .header-stats { display: flex; align-items: center; gap: 0.75rem; font-size: 0.8125rem; color: var(--dash-text-secondary); } .header-stat strong { color: var(--dash-text); font-weight: 600; } .header-stat-divider { width: 1px; height: 12px; background: var(--dash-border); } /* Header controls - all in one row */ .header-controls { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; } /* Theme Toggle */ #theme-toggle { width: 32px; height: 32px; border-radius: var(--dash-radius-sm); background: transparent; border: 1px solid var(--dash-border); cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--dash-text-secondary); transition: all var(--dash-duration) var(--dash-ease); flex-shrink: 0; } #theme-toggle:hover { background: var(--dash-surface-hover); color: var(--dash-text); border-color: var(--dash-accent); } #theme-toggle svg { width: 16px; height: 16px; } /* ======================================== Controls (in header) ======================================== */ /* Search */ .search-box { position: relative; min-width: 160px; max-width: 220px; } .search-box input { width: 100%; padding: 0.5rem 0.75rem 0.5rem 2rem; border: 1px solid var(--dash-border); border-radius: var(--dash-radius-sm); background: var(--dash-bg); color: var(--dash-text); font-size: 0.8125rem; font-family: var(--dash-font); transition: all var(--dash-duration) var(--dash-ease); } .search-box input::placeholder { color: var(--dash-text-muted); } .search-box input:focus { outline: none; border-color: var(--dash-accent); box-shadow: 0 0 0 3px var(--dash-accent-subtle); } .search-icon { position: absolute; left: 0.625rem; top: 50%; transform: translateY(-50%); color: var(--dash-text-muted); pointer-events: none; width: 14px; height: 14px; } /* Sort Select */ #sort-select { padding: 0.5rem 1.75rem 0.5rem 0.75rem; border: 1px solid var(--dash-border); border-radius: var(--dash-radius-sm); background: var(--dash-bg); color: var(--dash-text); font-size: 0.8125rem; font-family: var(--dash-font); cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%237A756D' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 0.5rem center; transition: all var(--dash-duration) var(--dash-ease); } #sort-select:hover { border-color: var(--dash-accent); } #sort-select:focus { outline: none; border-color: var(--dash-accent); box-shadow: 0 0 0 3px var(--dash-accent-subtle); } /* Filter Pills - Simplified */ .filter-pills { display: flex; gap: 0.25rem; padding: 3px; background: var(--dash-bg); border-radius: var(--dash-radius-sm); border: 1px solid var(--dash-border); } .filter-pill { padding: 0.3rem 0.625rem; border: none; border-radius: 5px; background: transparent; color: var(--dash-text-secondary); font-size: 0.75rem; font-weight: 500; font-family: var(--dash-font); cursor: pointer; transition: all var(--dash-duration) var(--dash-ease); } .filter-pill:hover { color: var(--dash-text); background: var(--dash-surface-hover); } .filter-pill.active { background: var(--dash-accent); color: white; } /* Result Count */ .result-count { font-size: 0.75rem; color: var(--dash-text-muted); } .result-count strong { color: var(--dash-text); font-weight: 600; } /* View Toggle */ .view-toggle { display: flex; gap: 2px; padding: 2px; background: var(--dash-bg); border-radius: 6px; border: 1px solid var(--dash-border); } .view-toggle-btn { padding: 0.3rem; border: none; border-radius: 4px; background: transparent; color: var(--dash-text-muted); cursor: pointer; transition: all var(--dash-duration) var(--dash-ease); display: flex; align-items: center; justify-content: center; } .view-toggle-btn:hover { color: var(--dash-text); background: var(--dash-surface-hover); } .view-toggle-btn.active { background: var(--dash-accent); color: white; } .view-toggle-btn svg { width: 16px; height: 16px; } /* ======================================== Stats Hero - Minimal Version ======================================== */ .stats-hero { display: none; /* Hidden - using inline stats instead */ } /* ======================================== Kanban Board Layout (Vibe-Kanban Style) ======================================== */ .kanban-board { display: grid; grid-template-columns: repeat(5, minmax(240px, 1fr)); gap: 0; min-height: calc(100vh - 160px); overflow-x: auto; } .kanban-column { display: flex; flex-direction: column; border-right: 1px solid var(--dash-border); background: var(--dash-bg); min-height: 100%; } .kanban-column:last-child { border-right: none; } /* Column Header - Sticky */ .kanban-column-header { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.875rem 1rem; background: var(--dash-surface); border-bottom: 1px dashed var(--dash-border); } .kanban-column-title { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; font-weight: 500; color: var(--dash-text); } .kanban-status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; } .kanban-status-dot.pending { background: var(--dash-text-muted); } .kanban-status-dot.in-progress { background: #3B82F6; } .kanban-status-dot.in-review { background: #F59E0B; } .kanban-status-dot.completed { background: #10B981; } .kanban-status-dot.cancelled { background: #EF4444; } .kanban-column-count { font-size: 0.75rem; font-weight: 500; color: var(--dash-text-muted); background: var(--dash-bg); padding: 0.125rem 0.5rem; border-radius: 100px; } /* Column Cards Container */ .kanban-cards { flex: 1; display: flex; flex-direction: column; gap: 0.5rem; padding: 0.75rem; overflow-y: auto; } /* Kanban Card - Compact */ .kanban-card { background: var(--dash-surface); border: 1px solid var(--dash-border); border-radius: var(--dash-radius-sm); padding: 0.875rem 1rem; cursor: pointer; transition: all var(--dash-duration) var(--dash-ease); text-decoration: none; color: inherit; display: block; } .kanban-card:hover { border-color: var(--dash-accent); box-shadow: var(--dash-shadow-hover); transform: translateY(-1px); } .kanban-card-title { font-size: 0.875rem; font-weight: 600; color: var(--dash-text); margin: 0 0 0.375rem 0; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .kanban-card-meta { display: flex; align-items: center; gap: 0.5rem; font-size: 0.75rem; color: var(--dash-text-muted); } .kanban-card-progress { display: flex; align-items: center; gap: 0.375rem; } .kanban-card-progress-bar { width: 40px; height: 3px; background: var(--dash-border); border-radius: 2px; overflow: hidden; } .kanban-card-progress-fill { height: 100%; background: var(--dash-accent); border-radius: 2px; transition: width 0.3s var(--dash-ease); } .kanban-card-date { margin-left: auto; } /* Kanban Card Enhanced - Description */ .kanban-card-description { font-size: 0.75rem; color: var(--dash-text-secondary); line-height: 1.4; margin: 0.25rem 0 0.5rem; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } /* Kanban Card Enhanced - Header with priority */ .kanban-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.25rem; } .kanban-card-header .kanban-card-title { margin: 0; flex: 1; } /* Kanban Card Priority Badge */ .kanban-card-priority { font-size: 0.625rem; font-weight: 600; padding: 0.125rem 0.375rem; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.02em; flex-shrink: 0; } .kanban-card-priority.priority-high { background: #FEE2E2; color: #B91C1C; } .kanban-card-priority.priority-medium { background: #FEF3C7; color: #B45309; } .kanban-card-priority.priority-low { background: #D1FAE5; color: #047857; } [data-theme="dark"] .kanban-card-priority.priority-high { background: rgba(185, 28, 28, 0.2); color: #FCA5A5; } [data-theme="dark"] .kanban-card-priority.priority-medium { background: rgba(180, 83, 9, 0.2); color: #FCD34D; } [data-theme="dark"] .kanban-card-priority.priority-low { background: rgba(4, 120, 87, 0.2); color: #6EE7B7; } /* Kanban Card Tags */ .kanban-card-tags { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.5rem; } .kanban-card-tag { font-size: 0.625rem; padding: 0.125rem 0.375rem; background: var(--dash-accent-subtle); color: var(--dash-accent); border-radius: 3px; white-space: nowrap; } .kanban-card-tag.tag-more { background: var(--dash-border); color: var(--dash-text-muted); } /* Kanban Card Footer (effort + phases) */ .kanban-card-footer { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--dash-border-subtle); font-size: 0.6875rem; color: var(--dash-text-muted); } .kanban-card-effort { display: flex; align-items: center; gap: 0.25rem; } .kanban-card-effort svg { width: 10px; height: 10px; opacity: 0.7; } .kanban-card-phases { display: flex; align-items: center; gap: 0.25rem; } /* Empty Column State */ .kanban-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 2rem 1rem; color: var(--dash-text-muted); font-size: 0.8125rem; text-align: center; } .kanban-empty-icon { width: 32px; height: 32px; margin-bottom: 0.5rem; opacity: 0.4; } /* ======================================== Plans Grid (Card View - Alternative) ======================================== */ .plans-grid { display: none; /* Hidden when kanban is active */ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 1rem; padding: 1.5rem 2rem 2rem; } /* Show grid when view mode is grid */ .view-mode-grid .plans-grid { display: grid; } .view-mode-grid .kanban-board { display: none; } /* Hide filter pills in kanban view - they only apply to grid view */ body:not(.view-mode-grid) .filter-pills { display: none; } /* ======================================== Plan Cards - Clean Minimal Design ======================================== */ .plan-card { background: var(--dash-surface); border: 1px solid var(--dash-border); border-radius: var(--dash-radius); padding: 1.25rem 1.5rem; cursor: pointer; transition: all var(--dash-duration) var(--dash-ease); position: relative; } .plan-card:hover { border-color: var(--dash-accent); box-shadow: var(--dash-shadow-hover); transform: translateY(-2px); } .plan-card:active { transform: translateY(0); } /* Subtle accent indicator */ .plan-card::before { content: ''; position: absolute; top: 0; left: 0; width: 3px; height: 100%; background: transparent; border-radius: var(--dash-radius) 0 0 var(--dash-radius); transition: background var(--dash-duration) var(--dash-ease); } .plan-card:hover::before { background: var(--dash-accent); } /* Card completed state - always show accent */ .plan-card[data-status="completed"]::before { background: var(--dash-accent); } /* Card Header */ .card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; gap: 1rem; } .card-header-content { flex: 1; min-width: 0; } .plan-name { font-family: var(--dash-font); font-size: 1rem; font-weight: 600; color: var(--dash-text); margin: 0 0 0.375rem 0; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .plan-date { font-size: 0.75rem; color: var(--dash-text-muted); display: flex; align-items: center; gap: 0.25rem; } .plan-date svg { width: 12px; height: 12px; opacity: 0.6; } /* Status Icon - Monochrome */ .status-icon { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; color: var(--dash-text-muted); } .status-icon.completed { color: var(--dash-accent); } .status-icon.in-progress { color: var(--dash-accent); } /* Status badge - simplified */ .status-badge { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.25rem 0.625rem; border-radius: 100px; font-size: 0.6875rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; background: var(--dash-accent-subtle); color: var(--dash-accent); } .status-badge.pending { background: var(--dash-bg); color: var(--dash-text-muted); } .status-badge::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; } .status-badge.in-progress::before { animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } /* Card Body */ .card-body { margin-bottom: 1rem; } /* Progress Bar - Simple horizontal */ .progress-bar { display: flex; height: 4px; border-radius: 2px; background: var(--dash-border); overflow: hidden; margin-bottom: 0.625rem; } .bar-segment { height: 100%; background: var(--dash-accent); transition: width 0.4s var(--dash-ease); } .bar-segment.in-progress { background: var(--dash-accent); opacity: 0.6; } .bar-segment.pending { background: transparent; } /* Phase count */ .phase-count { font-size: 0.75rem; color: var(--dash-text-secondary); } .phase-count strong { color: var(--dash-text); font-weight: 600; } /* Hide progress ring - using bar instead */ .progress-visual, .progress-ring-container { display: none; } /* Status counts - simplified */ .status-counts { display: none; /* Hidden in new design */ } /* Card Footer */ .card-footer { display: flex; justify-content: space-between; align-items: center; padding-top: 1rem; border-top: 1px solid var(--dash-border-subtle); } .phases-summary { font-size: 0.75rem; color: var(--dash-text-muted); } /* View Button - Ghost style */ .view-btn { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.5rem 0.875rem; background: transparent; color: var(--dash-accent); text-decoration: none; border: 1px solid var(--dash-accent); border-radius: var(--dash-radius-sm); font-size: 0.8125rem; font-weight: 500; transition: all var(--dash-duration) var(--dash-ease); } .view-btn:hover { background: var(--dash-accent); color: white; } .view-btn svg { width: 14px; height: 14px; transition: transform var(--dash-duration) var(--dash-ease); } .view-btn:hover svg { transform: translateX(2px); } /* ======================================== Empty State ======================================== */ .empty-state { text-align: center; padding: 4rem 2rem; color: var(--dash-text-muted); } .empty-state[hidden] { display: none; } .empty-icon { width: 80px; height: 80px; margin: 0 auto 1.5rem; background: var(--dash-bg); border: 1px solid var(--dash-border); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--dash-text-muted); } .empty-icon svg { width: 32px; height: 32px; } .empty-state h2 { font-family: var(--dash-font); font-size: 1.125rem; font-weight: 600; color: var(--dash-text-secondary); margin-bottom: 0.5rem; } .empty-state p { font-size: 0.875rem; max-width: 320px; margin: 0 auto; line-height: 1.5; } /* ======================================== Loading Skeleton ======================================== */ .loading-skeleton { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 1rem; padding: 1.5rem 2rem 2rem; } .plans-loaded .loading-skeleton { display: none; } .skeleton-card { height: 160px; background: var(--dash-surface); border: 1px solid var(--dash-border); border-radius: var(--dash-radius); position: relative; overflow: hidden; } .skeleton-card::before { content: ''; position: absolute; inset: 0; background: linear-gradient( 90deg, transparent 0%, var(--dash-surface-hover) 50%, transparent 100% ); transform: translateX(-100%); animation: shimmer 1.5s infinite; } @keyframes shimmer { 100% { transform: translateX(100%); } } /* ======================================== Accessibility ======================================== */ .plan-card:focus, .filter-pill:focus, .view-btn:focus, #sort-select:focus, #plan-search:focus, #theme-toggle:focus { outline: none; } .plan-card:focus-visible, .filter-pill:focus-visible, .view-btn:focus-visible, #sort-select:focus-visible, #plan-search:focus-visible, #theme-toggle:focus-visible { outline: 2px solid var(--dash-accent); outline-offset: 2px; } .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .skip-link { position: absolute; top: -100%; left: 50%; transform: translateX(-50%); background: var(--dash-accent); color: white; padding: 0.75rem 1.5rem; border-radius: 0 0 var(--dash-radius-sm) var(--dash-radius-sm); z-index: 1000; transition: top var(--dash-duration); } .skip-link:focus { top: 0; } /* ======================================== Card Meta Tags (Duration, Effort, Priority, Issue) ======================================== */ .card-meta { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--dash-border-subtle); } .meta-tag { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.5rem; font-size: 0.75rem; font-weight: 500; color: var(--dash-text-secondary); background: var(--dash-bg); border-radius: 4px; text-decoration: none; transition: all var(--dash-duration) var(--dash-ease); } .meta-tag svg { flex-shrink: 0; opacity: 0.7; } .meta-tag.duration { color: var(--dash-text-secondary); } .meta-tag.effort { color: var(--dash-accent); background: var(--dash-accent-subtle); } .meta-tag.priority { font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em; } .meta-tag.priority.p1, .meta-tag.priority.high, .meta-tag.priority-high { color: #fff; background: #dc2626; } .meta-tag.priority.p2, .meta-tag.priority.medium, .meta-tag.priority-medium { color: #000; background: #facc15; } .meta-tag.priority.p3, .meta-tag.priority.low, .meta-tag.priority-low { color: #fff; background: #16a34a; } .meta-tag.issue { color: var(--dash-text-secondary); cursor: pointer; text-decoration: none; } .meta-tag.issue:hover { color: var(--dash-accent); background: var(--dash-accent-subtle); } /* Card Description */ .card-description { font-size: 0.85rem; color: var(--dash-text-secondary); margin: 0.5rem 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* Card Tags */ .card-tags { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.5rem; } .tag-pill { font-size: 0.7rem; padding: 0.15rem 0.5rem; border-radius: 9999px; background: var(--dash-surface-hover); color: var(--dash-text-secondary); font-weight: 500; } .tag-pill:hover { background: var(--dash-accent-subtle); color: var(--dash-accent); } .tag-more { background: var(--dash-border); color: var(--dash-text-muted); font-style: italic; } /* ======================================== Timeline Section - Layered Gantt (Minimal) ======================================== */ .timeline-section { padding: 1rem 1.5rem; margin: 1rem 1.5rem; background: var(--dash-surface); border-radius: var(--dash-radius); border: 1px solid var(--dash-border); } .timeline-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; } .timeline-title { font-family: var(--dash-font); font-size: 0.75rem; font-weight: 600; color: var(--dash-text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin: 0; display: inline; } /* Remove decorative lines from novel-theme h2 */ .timeline-title::before, .timeline-title::after { display: none; } .timeline-controls { display: flex; gap: 0.5rem; } .timeline-zoom-btn { padding: 0.25rem 0.625rem; font-size: 0.6875rem; font-weight: 500; color: var(--dash-text-muted); background: transparent; border: 1px solid var(--dash-border); border-radius: 4px; cursor: pointer; transition: all var(--dash-duration) var(--dash-ease); } .timeline-zoom-btn:hover, .timeline-zoom-btn.active { color: var(--dash-accent); border-color: var(--dash-accent); background: var(--dash-accent-subtle); } .timeline-stats { display: flex; gap: 1rem; font-size: 0.75rem; color: var(--dash-text-muted); } .timeline-stat { display: flex; align-items: center; gap: 0.25rem; } .timeline-stat strong { color: var(--dash-text-secondary); font-weight: 600; } /* Gantt Container */ .gantt-container { position: relative; margin-top: 0.25rem; } /* Date Axis */ .gantt-axis { display: flex; justify-content: space-between; padding: 0 0 0.375rem; border-bottom: 1px solid var(--dash-border-subtle); margin-bottom: 0.5rem; } .gantt-axis-label { font-size: 0.6875rem; font-weight: 500; color: var(--dash-text-muted); text-transform: uppercase; letter-spacing: 0.03em; } .gantt-axis-label.today { color: var(--dash-accent); font-weight: 600; } /* Gantt Track (where bars live) */ .gantt-track { position: relative; min-height: 60px; max-height: 220px; overflow-y: auto; overflow-x: hidden; background: repeating-linear-gradient( 90deg, transparent, transparent calc(100% / 7 - 1px), var(--dash-border-subtle) calc(100% / 7 - 1px), var(--dash-border-subtle) calc(100% / 7) ); } .gantt-track::-webkit-scrollbar { width: 4px; } .gantt-track::-webkit-scrollbar-thumb { background: var(--dash-border); border-radius: 2px; } /* Gantt Bar - Compact 18px height, clickable link */ .gantt-bar { position: absolute; height: 18px; border-radius: 4px; cursor: pointer; transition: all 0.15s var(--dash-ease); display: flex; align-items: center; padding: 0 0.375rem; overflow: hidden; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); text-decoration: none; color: inherit; } .gantt-bar:hover { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); z-index: 10; } .gantt-bar.completed { background: var(--dash-accent); color: #fff; font-weight: 600; } .gantt-bar.in-progress { background: var(--dash-accent); color: #fff; font-weight: 600; } .gantt-bar.in-progress::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient( 90deg, transparent 0%, rgba(255, 255, 255, 0.2) 50%, transparent 100% ); animation: shimmer 2s ease-in-out infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } .gantt-bar.pending { background: var(--dash-bg); border: 1px solid var(--dash-border); color: var(--dash-text); font-weight: 500; } .gantt-bar-label { font-size: 0.625rem; font-weight: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; position: relative; z-index: 1; } .gantt-bar-status { margin-left: auto; font-size: 0.5625rem; opacity: 0.8; flex-shrink: 0; } /* Gantt Tooltip */ .gantt-tooltip { position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: var(--dash-text); color: var(--dash-bg); padding: 0.5rem 0.75rem; border-radius: 6px; font-size: 0.75rem; white-space: nowrap; opacity: 0; visibility: hidden; transition: all 0.15s ease; z-index: 100; pointer-events: none; } .gantt-tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--dash-text); } .gantt-bar:hover .gantt-tooltip { opacity: 1; visibility: visible; } .gantt-tooltip-title { font-weight: 600; margin-bottom: 0.25rem; } .gantt-tooltip-meta { display: flex; gap: 0.75rem; opacity: 0.8; font-size: 0.6875rem; } /* Today Marker */ .gantt-today-marker { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--dash-accent); z-index: 5; opacity: 0.6; } .gantt-today-marker::before { content: 'Today'; position: absolute; top: -1.25rem; left: 50%; transform: translateX(-50%); font-size: 0.5625rem; font-weight: 600; color: var(--dash-accent); text-transform: uppercase; letter-spacing: 0.05em; } /* Empty State */ .gantt-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 80px; color: var(--dash-text-muted); font-size: 0.8125rem; } /* Compact Summary */ .timeline-summary { display: flex; gap: 0.75rem; margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--dash-border-subtle); font-size: 0.6875rem; color: var(--dash-text-muted); } .timeline-summary-item { display: flex; align-items: center; gap: 0.375rem; } .timeline-summary-dot { width: 6px; height: 6px; border-radius: 50%; } .timeline-summary-dot.completed { background: var(--dash-accent); } .timeline-summary-dot.in-progress { background: var(--dash-accent); opacity: 0.6; } .timeline-summary-dot.pending { background: var(--dash-border); } /* ======================================== Reduced Motion ======================================== */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } /* ======================================== Responsive ======================================== */ @media (max-width: 768px) { .dashboard-header { padding: 1rem 1.25rem; flex-wrap: wrap; gap: 0.75rem; } .header-left { flex-direction: column; align-items: flex-start; gap: 0.5rem; } .header-stats { font-size: 0.8125rem; } .dashboard-controls { padding: 1rem 1.25rem; gap: 0.75rem; } .search-box { min-width: 100%; max-width: 100%; } #sort-select { flex: 1; } .filter-pills { width: 100%; justify-content: center; } .result-count { width: 100%; text-align: center; margin-left: 0; } .plans-grid { grid-template-columns: 1fr; padding: 1rem 1.25rem; } } @media (max-width: 480px) { .dashboard-header h1 { font-size: 1.25rem; } .header-stat-divider { display: none; } .header-stats { flex-wrap: wrap; gap: 0.5rem 1rem; } .filter-pill { padding: 0.375rem 0.625rem; font-size: 0.75rem; } .plan-card { padding: 1rem 1.25rem; } } /* ======================================== Print Styles ======================================== */ @media print { .dashboard-header, .dashboard-controls, .loading-skeleton, #theme-toggle { display: none !important; } .dashboard-view { background: white; } .plans-grid { display: block; padding: 0; } .plan-card { break-inside: avoid; margin-bottom: 1rem; box-shadow: none; border: 1px solid #ddd; } .plan-card:hover { transform: none; box-shadow: none; } .plan-card::before { display: none; } }