// Color palette - Broadcast control room aesthetic $bg-deep: #0a0a0f; $bg-surface: #12121a; $bg-elevated: #1a1a24; $bg-hover: #24243a; $border-subtle: rgba(255, 255, 255, 0.06); $border-medium: rgba(255, 255, 255, 0.12); // Accent colors - TV broadcast vibes $accent-primary: #00d4aa; // Cyan/teal for time $accent-secondary: #8b5cf6; // Purple for programs $accent-tertiary: #f472b6; // Pink for highlights $accent-warning: #fbbf24; // Text colors $text-primary: #f8fafc; $text-secondary: rgba(248, 250, 252, 0.7); $text-muted: rgba(248, 250, 252, 0.4); // Gradients $gradient-program: linear-gradient( 135deg, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0.05) 100% ); $gradient-program-hover: linear-gradient( 135deg, rgba(139, 92, 246, 0.3) 0%, rgba(139, 92, 246, 0.15) 100% ); $gradient-header: linear-gradient( 180deg, rgba(0, 212, 170, 0.08) 0%, transparent 100% ); // Base container .parent { display: flex; background: $bg-deep; color: $text-primary; font-family: Roboto, 'Helvetica Neue', sans-serif; position: relative; overflow-y: auto; height: calc(100vh - 56px); // Custom scrollbar for vertical scroll &::-webkit-scrollbar { width: 8px; } &::-webkit-scrollbar-track { background: $bg-surface; } &::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.4); border-radius: 4px; &:hover { background: rgba(139, 92, 246, 0.6); } } } // Navigation toolbar - Frosted glass effect #epg-navigation { display: flex; align-items: center; padding: 12px 16px 12px 80px; // Left padding for macOS traffic lights background: rgba(18, 18, 26, 0.85); backdrop-filter: blur(20px); border-bottom: 1px solid $border-medium; gap: 8px; position: relative; z-index: 100; -webkit-app-region: drag; // Subtle glow at bottom &::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 1px; background: linear-gradient( 90deg, transparent 0%, rgba(0, 212, 170, 0.3) 20%, rgba(139, 92, 246, 0.3) 80%, transparent 100% ); } // Button styling - exclude from drag region button { font-family: Roboto, 'Helvetica Neue', sans-serif; font-weight: 500; letter-spacing: 0.02em; transition: all 0.2s ease; -webkit-app-region: no-drag; &:not([disabled]):hover { background: rgba(139, 92, 246, 0.15); } &[disabled] { opacity: 0.3; } mat-icon { font-size: 20px; } } } // Search container - exclude from drag region .search-container { display: flex; align-items: center; gap: 8px; margin-left: auto; -webkit-app-region: no-drag; .channel-search { display: flex; align-items: center; gap: 8px; width: 200px; height: 36px; padding: 0 12px; background: rgba(255, 255, 255, 0.05); border: 1px solid $border-subtle; border-radius: 8px; transition: all 0.2s ease; &:focus-within { border-color: rgba(139, 92, 246, 0.5); background: rgba(255, 255, 255, 0.08); } .search-icon { font-size: 18px; width: 18px; height: 18px; color: $text-muted; flex-shrink: 0; } input { flex: 1; background: transparent; border: none; outline: none; font-size: 13px; font-family: Roboto, 'Helvetica Neue', sans-serif; color: $text-primary; min-width: 0; &::placeholder { color: $text-muted; } } .clear-btn { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; background: transparent; border: none; border-radius: 50%; cursor: pointer; color: $text-muted; transition: all 0.15s ease; flex-shrink: 0; &:hover { background: rgba(255, 255, 255, 0.1); color: $text-primary; } mat-icon { font-size: 16px; width: 16px; height: 16px; } } } .filter-count { font-size: 11px; color: $text-muted; font-family: 'JetBrains Mono', monospace; white-space: nowrap; } &.expanded { .channel-search { animation: slideIn 0.2s ease-out; } } } @keyframes slideIn { from { opacity: 0; width: 0; transform: translateX(20px); } to { opacity: 1; width: 200px; transform: translateX(0); } } // Program search container .program-search-container { display: flex; align-items: center; gap: 8px; position: relative; -webkit-app-region: no-drag; .program-search-input { display: flex; align-items: center; gap: 8px; width: 220px; height: 36px; padding: 0 12px; background: rgba(255, 255, 255, 0.05); border: 1px solid $border-subtle; border-radius: 8px; transition: all 0.2s ease; &:focus-within { border-color: rgba(139, 92, 246, 0.5); background: rgba(255, 255, 255, 0.08); } .search-icon { font-size: 18px; width: 18px; height: 18px; color: $accent-secondary; flex-shrink: 0; } input { flex: 1; background: transparent; border: none; outline: none; font-size: 13px; font-family: Roboto, 'Helvetica Neue', sans-serif; color: $text-primary; min-width: 0; &::placeholder { color: $text-muted; } } .clear-btn { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; background: transparent; border: none; border-radius: 50%; cursor: pointer; color: $text-muted; transition: all 0.15s ease; flex-shrink: 0; &:hover { background: rgba(255, 255, 255, 0.1); color: $text-primary; } mat-icon { font-size: 16px; width: 16px; height: 16px; } } .search-spinner { width: 16px; height: 16px; border: 2px solid $border-subtle; border-top-color: $accent-secondary; border-radius: 50%; animation: spin 0.8s linear infinite; flex-shrink: 0; } } .program-search-results { position: fixed; top: 60px; right: 16px; width: 320px; max-height: 400px; overflow-y: auto; background: $bg-elevated; border: 1px solid $border-medium; border-radius: 8px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); z-index: 10000; &::-webkit-scrollbar { width: 6px; } &::-webkit-scrollbar-track { background: transparent; } &::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.3); border-radius: 3px; } .search-result-item { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 12px 16px; background: transparent; border: none; border-bottom: 1px solid $border-subtle; cursor: pointer; text-align: left; transition: background 0.15s ease; &:last-child { border-bottom: none; } &:hover { background: $bg-hover; .result-arrow { opacity: 1; transform: translateX(0); } } .result-info { display: flex; flex-direction: column; gap: 4px; overflow: hidden; } .result-title { font-size: 13px; font-weight: 500; color: $text-primary; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .result-meta { display: flex; gap: 8px; font-size: 11px; color: $text-muted; } .result-time { color: $accent-primary; font-family: 'JetBrains Mono', monospace; } .result-date { color: $text-muted; } .result-arrow { font-size: 18px; width: 18px; height: 18px; color: $accent-secondary; opacity: 0; transform: translateX(-4px); transition: all 0.15s ease; } } } .program-search-empty { position: fixed; top: 60px; right: 16px; width: 220px; padding: 24px 16px; background: $bg-elevated; border: 1px solid $border-medium; border-radius: 8px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); z-index: 10000; display: flex; flex-direction: column; align-items: center; gap: 8px; color: $text-muted; mat-icon { font-size: 24px; width: 24px; height: 24px; opacity: 0.5; } span { font-size: 12px; } } &.open { .program-search-input { animation: slideIn 0.2s ease-out; } } } @keyframes spin { to { transform: rotate(360deg); } } @keyframes highlightPulse { 0%, 100% { filter: drop-shadow(0 0 8px rgba(0, 212, 170, 0.6)); } 50% { filter: drop-shadow(0 0 20px rgba(0, 212, 170, 0.9)) drop-shadow(0 0 40px rgba(0, 212, 170, 0.4)); } } // No results state .no-results { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: 16px; color: $text-muted; text-align: center; z-index: 100; mat-icon { font-size: 48px; width: 48px; height: 48px; opacity: 0.5; } p { margin: 0; font-size: 14px; } button { color: $accent-primary; } } // Today's date display .today-date { flex: 1; font-family: 'JetBrains Mono', monospace; font-size: 14px; font-weight: 500; color: $accent-primary; text-align: center; padding: 0 24px; letter-spacing: 0.05em; text-transform: uppercase; // Glowing text effect text-shadow: 0 0 20px rgba(0, 212, 170, 0.3); } // Channel column #channels-column { width: 140px; flex: none; border-right: 1px solid $border-medium; background: $bg-surface; position: relative; z-index: 10; min-height: calc(100vh - 6px); // Subtle shadow for depth box-shadow: 4px 0 20px rgba(0, 0, 0, 0.3); .channel { cursor: pointer; transition: all 0.15s ease; rect { fill: $bg-surface; stroke: $border-subtle; transition: fill 0.15s ease; } &:hover rect { fill: $bg-elevated; } &.active rect { fill: rgba(139, 92, 246, 0.2); stroke: rgba(139, 92, 246, 0.4); } &.active .channel-name { color: $accent-secondary; font-weight: 600; } } .channel-name { color: $text-primary; padding: 8px 12px; font-size: 11px; font-weight: 500; display: flex; align-items: center; height: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: 0.02em; img { border-radius: 4px; background: rgba(255, 255, 255, 0.05); padding: 2px; } span { overflow: hidden; text-overflow: ellipsis; } } image { object-fit: contain; background: $bg-elevated; } } // EPG container #epg-container { width: calc(100vw - 140px); overflow-x: scroll; overflow-y: clip; background: $bg-deep; min-height: calc(100vh - 6px); // Custom scrollbar &::-webkit-scrollbar { height: 8px; } &::-webkit-scrollbar-track { background: $bg-surface; } &::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.4); border-radius: 4px; &:hover { background: rgba(139, 92, 246, 0.6); } } } // EPG SVG container #epg-svg { // Time header styling g > rect[fill='#000'] { fill: $bg-surface !important; } g > text { font-family: 'JetBrains Mono', monospace !important; font-size: 11px !important; font-weight: 500; fill: $text-secondary !important; letter-spacing: 0.1em; } // Hour separator vertical lines .hour-separator { stroke: $border-subtle; stroke-width: 1px; pointer-events: none; } // Program blocks .program { cursor: pointer; rect { fill: $bg-elevated; stroke: $border-subtle; rx: 4; ry: 4; transition: all 0.15s ease; } &:hover rect { fill: $bg-hover; stroke: rgba(139, 92, 246, 0.4); filter: drop-shadow(0 0 8px rgba(139, 92, 246, 0.2)); } // Highlighted program (from search) &.highlighted rect { fill: rgba(0, 212, 170, 0.25); stroke: $accent-primary; stroke-width: 2px; animation: highlightPulse 1s ease-in-out 3; } &.highlighted .program-title { color: $accent-primary; font-weight: 600; } } // Active channel row highlighting .active-row .program rect { fill: rgba(139, 92, 246, 0.15); stroke: rgba(139, 92, 246, 0.3); } .active-row .program:hover rect { fill: rgba(139, 92, 246, 0.25); } .program-title { color: $text-primary; padding: 6px 10px; font-size: 11px; font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; pointer-events: none; letter-spacing: 0.01em; line-height: 1.4; // Subtle gradient text for depth display: flex; align-items: center; height: 100%; } // Current time line - glowing effect line[stroke='red'] { stroke: $accent-primary !important; stroke-width: 2px; filter: drop-shadow(0 0 8px rgba(0, 212, 170, 0.6)) drop-shadow(0 0 16px rgba(0, 212, 170, 0.3)); // Animated pulse animation: timePulse 2s ease-in-out infinite; } } // Pulse animation for time line @keyframes timePulse { 0%, 100% { opacity: 1; filter: drop-shadow(0 0 8px rgba(0, 212, 170, 0.6)) drop-shadow(0 0 16px rgba(0, 212, 170, 0.3)); } 50% { opacity: 0.8; filter: drop-shadow(0 0 12px rgba(0, 212, 170, 0.8)) drop-shadow(0 0 24px rgba(0, 212, 170, 0.4)); } } // Legacy classes cleanup .program-item { cursor: pointer; } rect { stroke: $border-subtle; cursor: pointer; } .channel > rect { stroke: $border-subtle; } .program-name, .channel-name { -webkit-line-clamp: 2; height: 32px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; padding: 6px 8px; } #current-time-line { stroke-width: 2px; stroke: $accent-primary; } // Dark theme override (already dark, but ensure consistency) ::ng-deep { .dark-theme { #epg-navigation { background: rgba(18, 18, 26, 0.85); } } // Light theme adjustments .light-theme { #epg-navigation { background: rgba(255, 255, 255, 0.9); border-bottom-color: rgba(0, 0, 0, 0.1); .today-date { color: #059669; text-shadow: none; } } .parent { background: #f8fafc; &::before { background-image: linear-gradient(rgba(0, 0, 0, 0.03) 1px, transparent 1px), linear-gradient( 90deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px ); } } #channels-column { background: #ffffff; border-right-color: rgba(0, 0, 0, 0.1); box-shadow: 4px 0 20px rgba(0, 0, 0, 0.05); .channel rect { fill: #ffffff; stroke: rgba(0, 0, 0, 0.08); } .channel:hover rect { fill: #f1f5f9; } .channel-name { color: #1e293b; } } #epg-container { background: #f8fafc; } #epg-svg { g > rect[fill='#000'] { fill: #e2e8f0 !important; } g > text { fill: #64748b !important; } .program { rect { fill: #ffffff; stroke: rgba(0, 0, 0, 0.08); } &:hover rect { fill: #f1f5f9; stroke: rgba(139, 92, 246, 0.4); } } .program-title { color: #1e293b; } line[stroke='red'] { stroke: #059669 !important; filter: drop-shadow(0 0 6px rgba(5, 150, 105, 0.4)); } } } } // Responsive adjustments @media (max-width: 768px) { #epg-navigation { padding-left: 70px; // Slightly reduced for smaller screens } #channels-column { width: 100px; .channel-name { font-size: 10px; padding: 6px 8px; } } #epg-container { width: calc(100vw - 100px); } .today-date { font-size: 12px; padding: 0 12px; } }