Spaces:
Running
Running
| /* ============================================ | |
| IVY'S RSS HUB — Main Stylesheet | |
| Theme: Dark/Light mode with Ivy Green accent | |
| ============================================ */ | |
| /* === CSS Variables — Dark Theme (Default) === */ | |
| :root { | |
| /* Colors */ | |
| --ivy-green: #10b981; | |
| --ivy-green-dark: #059669; | |
| --ivy-green-light: #34d399; | |
| --bg-primary: #0f0f0f; | |
| --bg-secondary: #1a1a1a; | |
| --bg-tertiary: #252525; | |
| --bg-card: #1e1e1e; | |
| --bg-hover: #2a2a2a; | |
| --text-primary: #f5f5f5; | |
| --text-secondary: #a3a3a3; | |
| --text-muted: #737373; | |
| --border-color: #333; | |
| --border-subtle: #2a2a2a; | |
| /* Zebra striping for dark theme */ | |
| --zebra-odd: rgba(255, 255, 255, 0.015); | |
| /* Category Colors */ | |
| --cat-news: #dc2626; | |
| --cat-ai: #ec4899; | |
| --cat-tech: #3b82f6; | |
| --cat-gaming: #8b5cf6; | |
| --cat-science: #06b6d4; | |
| --cat-apple: #6b7280; | |
| --cat-linux: #f59e0b; | |
| /* Shadows */ | |
| --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3); | |
| --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4); | |
| --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5); | |
| /* Spacing */ | |
| --header-height: 60px; | |
| --content-max-width: 1400px; | |
| --card-gap: 16px; | |
| /* Typography */ | |
| --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif; | |
| --font-mono: "SF Mono", Monaco, "Cascadia Code", monospace; | |
| /* Transitions */ | |
| --transition-fast: 150ms ease; | |
| --transition-normal: 250ms ease; | |
| /* Border Radius */ | |
| --radius-sm: 4px; | |
| --radius-md: 8px; | |
| --radius-lg: 12px; | |
| /* Theme indicator */ | |
| --theme-icon: "🌙"; | |
| } | |
| /* === Light Theme === */ | |
| [data-theme="light"] { | |
| --bg-primary: #f8fafc; | |
| --bg-secondary: #f1f5f9; | |
| --bg-tertiary: #e2e8f0; | |
| --bg-card: #ffffff; | |
| --bg-hover: #e2e8f0; | |
| --text-primary: #0f172a; | |
| --text-secondary: #475569; | |
| --text-muted: #64748b; | |
| --border-color: #cbd5e1; | |
| --border-subtle: #e2e8f0; | |
| /* Lighter shadows for light theme */ | |
| --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); | |
| --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07); | |
| --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); | |
| /* Zebra striping for light theme */ | |
| --zebra-odd: rgba(0, 0, 0, 0.02); | |
| /* Theme indicator */ | |
| --theme-icon: "☀️"; | |
| } | |
| /* Respect system preference if no manual override */ | |
| @media (prefers-color-scheme: light) { | |
| :root:not([data-theme="dark"]) { | |
| --bg-primary: #f8fafc; | |
| --bg-secondary: #f1f5f9; | |
| --bg-tertiary: #e2e8f0; | |
| --bg-card: #ffffff; | |
| --bg-hover: #e2e8f0; | |
| --text-primary: #0f172a; | |
| --text-secondary: #475569; | |
| --text-muted: #64748b; | |
| --border-color: #cbd5e1; | |
| --border-subtle: #e2e8f0; | |
| --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); | |
| --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07); | |
| --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); | |
| /* Zebra striping for light theme */ | |
| --zebra-odd: rgba(0, 0, 0, 0.02); | |
| --theme-icon: "☀️"; | |
| } | |
| } | |
| /* === Reset & Base === */ | |
| *, | |
| *::before, | |
| *::after { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| html { | |
| scroll-behavior: smooth; | |
| } | |
| body { | |
| font-family: var(--font-sans); | |
| background-color: var(--bg-primary); | |
| color: var(--text-primary); | |
| line-height: 1.6; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| a { | |
| color: var(--ivy-green); | |
| text-decoration: none; | |
| transition: color var(--transition-fast); | |
| } | |
| a:hover { | |
| color: var(--ivy-green-light); | |
| } | |
| /* === Header === */ | |
| .header { | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| background: var(--bg-secondary); | |
| border-bottom: 1px solid var(--border-color); | |
| height: var(--header-height); | |
| } | |
| .header-content { | |
| max-width: var(--content-max-width); | |
| margin: 0 auto; | |
| padding: 0 20px; | |
| height: 100%; | |
| display: flex; | |
| align-items: center; | |
| gap: 20px; | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| font-size: 1.25rem; | |
| font-weight: 700; | |
| color: var(--text-primary); | |
| flex-shrink: 0; | |
| } | |
| .logo-icon { | |
| font-size: 1.5rem; | |
| } | |
| /* === Navigation Categories === */ | |
| .nav-categories { | |
| display: flex; | |
| gap: 4px; | |
| flex-wrap: wrap; | |
| flex: 1; | |
| justify-content: center; | |
| } | |
| .nav-btn { | |
| background: transparent; | |
| border: 1px solid var(--border-color); | |
| color: var(--text-secondary); | |
| padding: 6px 12px; | |
| border-radius: var(--radius-md); | |
| cursor: pointer; | |
| font-size: 0.875rem; | |
| transition: all var(--transition-fast); | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .nav-btn:hover { | |
| background: var(--bg-hover); | |
| color: var(--text-primary); | |
| border-color: var(--text-muted); | |
| } | |
| .nav-btn.active { | |
| background: var(--ivy-green); | |
| border-color: var(--ivy-green); | |
| color: #fff; | |
| } | |
| /* === Header Actions === */ | |
| .header-actions { | |
| display: flex; | |
| gap: 8px; | |
| flex-shrink: 0; | |
| } | |
| .btn-icon { | |
| width: 36px; | |
| height: 36px; | |
| background: transparent; | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-md); | |
| cursor: pointer; | |
| font-size: 1rem; | |
| transition: all var(--transition-fast); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .btn-icon:hover { | |
| background: var(--bg-hover); | |
| border-color: var(--ivy-green); | |
| } | |
| .btn-icon.spinning { | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| from { | |
| transform: rotate(0deg); | |
| } | |
| to { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| /* === Main Content === */ | |
| .app-layout { | |
| display: flex; | |
| flex: 1; | |
| max-width: 1600px; | |
| margin: 0 auto; | |
| width: 100%; | |
| gap: 20px; | |
| padding: 20px; | |
| } | |
| .main-content { | |
| flex: 1; | |
| min-width: 0; | |
| } | |
| /* === Status Bar === */ | |
| .status-bar { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 8px 12px; | |
| background: var(--bg-secondary); | |
| border-radius: var(--radius-md); | |
| margin-bottom: 20px; | |
| font-size: 0.875rem; | |
| color: var(--text-secondary); | |
| gap: 12px; | |
| flex-wrap: wrap; | |
| } | |
| .status-time { | |
| color: var(--text-muted); | |
| } | |
| /* === Language Filter === */ | |
| .lang-filter { | |
| display: flex; | |
| gap: 4px; | |
| } | |
| .lang-btn { | |
| background: transparent; | |
| border: 1px solid var(--border-color); | |
| color: var(--text-muted); | |
| padding: 4px 10px; | |
| border-radius: var(--radius-md); | |
| cursor: pointer; | |
| font-size: 0.8rem; | |
| transition: all var(--transition-fast); | |
| } | |
| .lang-btn:hover { | |
| background: var(--bg-hover); | |
| color: var(--text-primary); | |
| border-color: var(--text-muted); | |
| } | |
| .lang-btn.active { | |
| background: var(--ivy-green); | |
| border-color: var(--ivy-green); | |
| color: #fff; | |
| } | |
| /* === Feeds Container === */ | |
| .feeds-container { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 24px; | |
| } | |
| /* === Source Section === */ | |
| .source-section { | |
| background: var(--bg-card); | |
| border-radius: var(--radius-lg); | |
| border: 1px solid var(--border-color); | |
| overflow: hidden; | |
| } | |
| .source-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 12px 16px; | |
| background: var(--bg-tertiary); | |
| border-bottom: 1px solid var(--border-color); | |
| cursor: pointer; | |
| transition: | |
| background var(--transition-fast), | |
| box-shadow var(--transition-fast); | |
| /* Subtle left border accent - colored per source */ | |
| border-left: 3px solid var(--source-accent, var(--ivy-green)); | |
| } | |
| .source-header:hover { | |
| background: var(--bg-hover); | |
| } | |
| .source-title { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| font-size: 1rem; | |
| font-weight: 600; | |
| } | |
| .source-icon { | |
| font-size: 1.25rem; | |
| } | |
| .source-name { | |
| color: var(--text-primary); | |
| } | |
| .source-meta { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| } | |
| .source-count { | |
| background: var(--source-accent, var(--ivy-green)); | |
| color: #fff; | |
| padding: 2px 8px; | |
| border-radius: 9999px; | |
| font-weight: 600; | |
| } | |
| .source-status { | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .source-status.fresh::before { | |
| content: ""; | |
| width: 6px; | |
| height: 6px; | |
| background: var(--ivy-green); | |
| border-radius: 50%; | |
| } | |
| .source-status.stale::before { | |
| content: ""; | |
| width: 6px; | |
| height: 6px; | |
| background: var(--text-muted); | |
| border-radius: 50%; | |
| } | |
| .source-toggle { | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| transition: transform var(--transition-fast); | |
| } | |
| .source-section.collapsed .source-toggle { | |
| transform: rotate(-90deg); | |
| } | |
| .source-section.collapsed .source-articles { | |
| display: none; | |
| } | |
| /* === Articles List === */ | |
| .source-articles { | |
| list-style: none; | |
| /* Responsive max-height: min 400px, prefer 50vh, max 1050px */ | |
| max-height: clamp(400px, 50vh, 1050px); | |
| overflow-y: auto; | |
| /* Allow scroll to propagate to parent when reaching bounds */ | |
| overscroll-behavior: auto; | |
| } | |
| .article-item-wrapper { | |
| display: flex; | |
| align-items: flex-start; | |
| border-bottom: 1px solid var(--border-subtle); | |
| transition: background var(--transition-fast); | |
| } | |
| .article-item-wrapper:last-child { | |
| border-bottom: none; | |
| } | |
| /* Subtle zebra striping for better visual distinction */ | |
| .article-item-wrapper:nth-child(odd) { | |
| background: var(--zebra-odd, rgba(255, 255, 255, 0.015)); | |
| } | |
| .article-item-wrapper:nth-child(even) { | |
| background: transparent; | |
| } | |
| .article-item-wrapper:hover { | |
| background: var(--bg-hover); | |
| } | |
| .article-item { | |
| display: block; | |
| flex: 1; | |
| padding: 12px 16px; | |
| text-decoration: none; | |
| color: inherit; | |
| } | |
| .article-item:hover .article-title { | |
| color: var(--ivy-green-light); | |
| } | |
| .article-title { | |
| color: var(--text-primary); | |
| font-size: 0.95rem; | |
| line-height: 1.4; | |
| margin-bottom: 4px; | |
| transition: color var(--transition-fast); | |
| } | |
| .article-item:hover .article-title { | |
| color: var(--ivy-green-light); | |
| } | |
| .article-description { | |
| color: var(--text-muted); | |
| font-size: 0.8rem; | |
| line-height: 1.4; | |
| margin-bottom: 6px; | |
| display: -webkit-box; | |
| -webkit-line-clamp: 2; | |
| line-clamp: 2; | |
| -webkit-box-orient: vertical; | |
| overflow: hidden; | |
| } | |
| .article-meta { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| } | |
| .article-date { | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .article-source { | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| color: var(--text-muted); | |
| font-size: 0.75rem; | |
| padding: 2px 6px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-sm); | |
| } | |
| /* === New Article Badge === */ | |
| .new-badge { | |
| display: inline-block; | |
| font-size: 0.6rem; | |
| font-weight: 700; | |
| padding: 2px 6px; | |
| background: var(--ivy-green); | |
| color: #fff; | |
| border-radius: 4px; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| margin-right: 6px; | |
| vertical-align: middle; | |
| animation: pulse-badge 2s ease-in-out infinite; | |
| } | |
| @keyframes pulse-badge { | |
| 0%, | |
| 100% { | |
| opacity: 1; | |
| } | |
| 50% { | |
| opacity: 0.7; | |
| } | |
| } | |
| /* Recent article highlight */ | |
| .article-item-wrapper.recent { | |
| border-left: 2px solid var(--ivy-green); | |
| } | |
| .article-item-wrapper.recent .article-date { | |
| color: var(--ivy-green); | |
| } | |
| /* === Loading & Empty States === */ | |
| .loading-state, | |
| .empty-state, | |
| .error-state { | |
| text-align: center; | |
| padding: 60px 20px; | |
| color: var(--text-secondary); | |
| } | |
| .loading-spinner { | |
| width: 40px; | |
| height: 40px; | |
| border: 3px solid var(--border-color); | |
| border-top-color: var(--ivy-green); | |
| border-radius: 50%; | |
| animation: spin 1s linear infinite; | |
| margin: 0 auto 16px; | |
| } | |
| .empty-icon, | |
| .error-icon { | |
| font-size: 3rem; | |
| margin-bottom: 12px; | |
| } | |
| .loading-state .hint, | |
| .empty-state .hint { | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| margin-top: 8px; | |
| opacity: 0.8; | |
| } | |
| /* === Footer === */ | |
| .footer { | |
| background: var(--bg-secondary); | |
| border-top: 1px solid var(--border-color); | |
| padding: 16px 20px; | |
| text-align: center; | |
| font-size: 0.875rem; | |
| color: var(--text-secondary); | |
| } | |
| .footer .divider { | |
| margin: 0 8px; | |
| color: var(--text-muted); | |
| } | |
| /* === Modals === */ | |
| .modal-overlay { | |
| position: fixed; | |
| inset: 0; | |
| background: rgba(0, 0, 0, 0.8); | |
| backdrop-filter: blur(4px); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| z-index: 1000; | |
| opacity: 0; | |
| visibility: hidden; | |
| transition: all var(--transition-normal); | |
| padding: 20px; | |
| } | |
| .modal-overlay.active { | |
| opacity: 1; | |
| visibility: visible; | |
| } | |
| .modal { | |
| background: var(--bg-secondary); | |
| border-radius: var(--radius-lg); | |
| border: 1px solid var(--border-color); | |
| padding: 24px; | |
| max-width: 500px; | |
| width: 100%; | |
| max-height: 80vh; | |
| overflow-y: auto; | |
| position: relative; | |
| transform: scale(0.95); | |
| transition: transform var(--transition-normal); | |
| } | |
| .modal-overlay.active .modal { | |
| transform: scale(1); | |
| } | |
| .modal-large { | |
| max-width: 700px; | |
| } | |
| .modal-close { | |
| position: absolute; | |
| top: 12px; | |
| right: 12px; | |
| width: 32px; | |
| height: 32px; | |
| background: transparent; | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-md); | |
| color: var(--text-secondary); | |
| font-size: 1.25rem; | |
| cursor: pointer; | |
| transition: all var(--transition-fast); | |
| } | |
| .modal-close:hover { | |
| background: var(--bg-hover); | |
| color: var(--text-primary); | |
| border-color: var(--ivy-green); | |
| } | |
| .modal h2 { | |
| margin-bottom: 20px; | |
| font-size: 1.5rem; | |
| color: var(--ivy-green); | |
| } | |
| .modal-section { | |
| margin-bottom: 20px; | |
| } | |
| .modal-section h3 { | |
| font-size: 1rem; | |
| color: var(--text-primary); | |
| margin-bottom: 10px; | |
| padding-bottom: 6px; | |
| border-bottom: 1px solid var(--border-subtle); | |
| } | |
| .feature-list { | |
| list-style: none; | |
| } | |
| .feature-list li { | |
| padding: 4px 0; | |
| color: var(--text-secondary); | |
| } | |
| .ivy-quote { | |
| font-style: italic; | |
| color: var(--ivy-green); | |
| padding: 12px 16px; | |
| background: var(--bg-tertiary); | |
| border-left: 3px solid var(--ivy-green); | |
| border-radius: var(--radius-sm); | |
| margin: 20px 0; | |
| } | |
| .copyright { | |
| text-align: center; | |
| color: var(--text-muted); | |
| font-size: 0.8rem; | |
| } | |
| /* === Settings Modal Specific === */ | |
| .sources-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| max-height: 300px; | |
| overflow-y: auto; | |
| } | |
| .source-toggle-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| padding: 10px 12px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-md); | |
| transition: background var(--transition-fast); | |
| } | |
| .source-toggle-item:hover { | |
| background: var(--bg-hover); | |
| } | |
| .source-toggle-item input[type="checkbox"] { | |
| width: 18px; | |
| height: 18px; | |
| accent-color: var(--ivy-green); | |
| } | |
| .source-toggle-info { | |
| flex: 1; | |
| min-width: 0; /* Allow flex child to shrink below content size */ | |
| overflow: hidden; | |
| } | |
| .source-toggle-name { | |
| font-weight: 500; | |
| color: var(--text-primary); | |
| } | |
| .source-toggle-url { | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| /* Prevent long URLs from breaking modal layout */ | |
| word-break: break-all; | |
| overflow-wrap: anywhere; | |
| max-width: 100%; | |
| display: block; | |
| } | |
| .source-toggle-category { | |
| font-size: 0.75rem; | |
| padding: 2px 8px; | |
| background: var(--bg-primary); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-secondary); | |
| } | |
| /* Add Feed Form */ | |
| .add-feed-form { | |
| display: grid; | |
| gap: 10px; | |
| } | |
| .add-feed-form input, | |
| .add-feed-form select { | |
| padding: 10px 12px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-md); | |
| color: var(--text-primary); | |
| font-size: 0.9rem; | |
| } | |
| .add-feed-form input:focus, | |
| .add-feed-form select:focus { | |
| outline: none; | |
| border-color: var(--ivy-green); | |
| } | |
| .add-feed-form input::placeholder { | |
| color: var(--text-muted); | |
| } | |
| .btn-primary { | |
| background: var(--ivy-green); | |
| border: none; | |
| color: #fff; | |
| padding: 10px 16px; | |
| border-radius: var(--radius-md); | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: background var(--transition-fast); | |
| } | |
| .btn-primary:hover { | |
| background: var(--ivy-green-dark); | |
| } | |
| .btn-danger { | |
| background: #dc2626; | |
| border: none; | |
| color: #fff; | |
| padding: 10px 16px; | |
| border-radius: var(--radius-md); | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: background var(--transition-fast); | |
| } | |
| .btn-danger:hover { | |
| background: #b91c1c; | |
| } | |
| .reset-section { | |
| border-top: 1px solid var(--border-color); | |
| padding-top: 16px; | |
| margin-top: 8px; | |
| } | |
| /* Checkbox Labels */ | |
| .checkbox-label { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| padding: 8px 0; | |
| color: var(--text-secondary); | |
| } | |
| .checkbox-label label { | |
| cursor: pointer; | |
| flex: 1; | |
| } | |
| .checkbox-label input[type="checkbox"] { | |
| width: 18px; | |
| height: 18px; | |
| accent-color: var(--ivy-green); | |
| cursor: pointer; | |
| flex-shrink: 0; | |
| } | |
| .checkbox-label input[type="number"] { | |
| width: 60px; | |
| padding: 4px 8px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-primary); | |
| margin-right: 8px; | |
| } | |
| /* Number input row (for max items) */ | |
| .number-input-row { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 12px; | |
| padding: 8px 0; | |
| color: var(--text-secondary); | |
| } | |
| .number-input-row label { | |
| flex: 1; | |
| } | |
| .number-input-row input[type="number"] { | |
| width: 70px; | |
| padding: 6px 10px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-primary); | |
| text-align: center; | |
| } | |
| .number-input-row input[type="number"]:focus { | |
| outline: none; | |
| border-color: var(--ivy-green); | |
| } | |
| .number-input-row select { | |
| padding: 6px 10px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-primary); | |
| font-size: 0.9rem; | |
| cursor: pointer; | |
| } | |
| .number-input-row select:focus { | |
| outline: none; | |
| border-color: var(--ivy-green); | |
| } | |
| .hint { | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| margin-bottom: 12px; | |
| } | |
| /* Sources Actions (Enable/Disable All) */ | |
| .sources-actions { | |
| display: flex; | |
| gap: 8px; | |
| margin-bottom: 12px; | |
| } | |
| .sources-actions .btn-small { | |
| flex: 1; | |
| } | |
| /* === Scrollbar Styling === */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| height: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: var(--bg-primary); | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: var(--border-color); | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: var(--text-muted); | |
| } | |
| /* === Responsive Design === */ | |
| @media (max-width: 900px) { | |
| .header-content { | |
| flex-wrap: wrap; | |
| height: auto; | |
| padding: 12px 16px; | |
| gap: 12px; | |
| } | |
| .nav-categories { | |
| order: 3; | |
| width: 100%; | |
| justify-content: flex-start; | |
| overflow-x: auto; | |
| flex-wrap: nowrap; | |
| padding-bottom: 4px; | |
| } | |
| .nav-btn { | |
| flex-shrink: 0; | |
| } | |
| .logo-text { | |
| font-size: 1.1rem; | |
| } | |
| } | |
| @media (max-width: 600px) { | |
| .main-content { | |
| padding: 12px; | |
| } | |
| .source-header { | |
| padding: 10px 12px; | |
| } | |
| .article-item { | |
| padding: 10px 12px; | |
| } | |
| .modal { | |
| padding: 16px; | |
| } | |
| .status-bar { | |
| flex-direction: column; | |
| gap: 8px; | |
| text-align: center; | |
| } | |
| .status-bar .lang-filter { | |
| order: -1; | |
| } | |
| .status-bar .status-text { | |
| font-size: 0.8rem; | |
| } | |
| } | |
| /* ============================================ | |
| SIDEBAR STYLES | |
| ============================================ */ | |
| /* === Sidebar Container === */ | |
| .sidebar { | |
| width: 320px; | |
| flex-shrink: 0; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 16px; | |
| position: sticky; | |
| top: calc(var(--header-height) + 20px); | |
| max-height: calc(100vh - var(--header-height) - 40px); | |
| overflow-y: auto; | |
| } | |
| /* === Sidebar Section === */ | |
| .sidebar-section { | |
| background: var(--bg-card); | |
| border-radius: var(--radius-lg); | |
| border: 1px solid var(--border-color); | |
| overflow: hidden; | |
| } | |
| .sidebar-title { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 12px 14px; | |
| margin: 0; | |
| font-size: 0.9rem; | |
| font-weight: 600; | |
| color: var(--text-primary); | |
| background: var(--bg-tertiary); | |
| border-bottom: 1px solid var(--border-color); | |
| } | |
| .sidebar-title.collapsible { | |
| cursor: pointer; | |
| transition: background var(--transition-fast); | |
| } | |
| .sidebar-title.collapsible:hover { | |
| background: var(--bg-hover); | |
| } | |
| .section-toggle { | |
| font-size: 0.7rem; | |
| color: var(--text-muted); | |
| transition: transform var(--transition-fast); | |
| } | |
| /* Bookmark count badge */ | |
| .bookmark-count { | |
| font-size: 0.75rem; | |
| color: var(--ivy-green); | |
| font-weight: 600; | |
| margin-left: 4px; | |
| } | |
| .sidebar-title.collapsed .section-toggle { | |
| transform: rotate(-90deg); | |
| } | |
| .section-content { | |
| padding: 12px; | |
| max-height: 300px; | |
| overflow: hidden; | |
| overflow-y: auto; | |
| transition: | |
| max-height var(--transition-normal), | |
| padding var(--transition-normal), | |
| opacity var(--transition-normal); | |
| } | |
| .section-content.collapsed { | |
| max-height: 0; | |
| padding: 0 12px; | |
| overflow: hidden; | |
| opacity: 0; | |
| } | |
| /* === Search Box === */ | |
| .search-box { | |
| display: flex; | |
| gap: 8px; | |
| padding: 12px; | |
| } | |
| .search-box input { | |
| flex: 1; | |
| padding: 8px 12px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-md); | |
| color: var(--text-primary); | |
| font-size: 0.9rem; | |
| transition: border-color var(--transition-fast); | |
| } | |
| .search-box input:focus { | |
| outline: none; | |
| border-color: var(--ivy-green); | |
| } | |
| .search-box input::placeholder { | |
| color: var(--text-muted); | |
| } | |
| .search-clear { | |
| width: 32px; | |
| height: 32px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-md); | |
| color: var(--text-muted); | |
| font-size: 1.1rem; | |
| cursor: pointer; | |
| transition: all var(--transition-fast); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .search-clear:hover { | |
| background: var(--bg-hover); | |
| color: var(--text-primary); | |
| border-color: var(--ivy-green); | |
| } | |
| .search-results { | |
| padding: 0 12px 12px; | |
| max-height: 200px; | |
| overflow-y: auto; | |
| } | |
| .search-hint { | |
| color: var(--text-muted); | |
| font-size: 0.8rem; | |
| font-style: italic; | |
| } | |
| .search-count { | |
| font-size: 0.75rem; | |
| color: var(--ivy-green); | |
| padding: 6px 0; | |
| margin-bottom: 6px; | |
| border-bottom: 1px solid var(--border-subtle); | |
| font-weight: 500; | |
| } | |
| .search-result-item { | |
| display: block; | |
| padding: 8px 10px; | |
| margin-bottom: 4px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-secondary); | |
| font-size: 0.85rem; | |
| line-height: 1.3; | |
| text-decoration: none; | |
| transition: all var(--transition-fast); | |
| } | |
| .search-result-item:hover { | |
| background: var(--bg-hover); | |
| color: var(--ivy-green-light); | |
| } | |
| .search-result-source { | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| margin-top: 2px; | |
| } | |
| /* Search spinner */ | |
| .search-spinner { | |
| display: inline-block; | |
| width: 12px; | |
| height: 12px; | |
| border: 2px solid var(--border-color); | |
| border-top-color: var(--ivy-green); | |
| border-radius: 50%; | |
| animation: spin 0.8s linear infinite; | |
| margin-right: 6px; | |
| vertical-align: middle; | |
| } | |
| /* === Bookmarks === */ | |
| .bookmarks-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 6px; | |
| margin-bottom: 10px; | |
| } | |
| .bookmark-item { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 8px; | |
| padding: 8px 10px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-sm); | |
| transition: background var(--transition-fast); | |
| } | |
| .bookmark-item:hover { | |
| background: var(--bg-hover); | |
| } | |
| .bookmark-link { | |
| flex: 1; | |
| color: var(--text-secondary); | |
| font-size: 0.85rem; | |
| line-height: 1.3; | |
| text-decoration: none; | |
| } | |
| .bookmark-link:hover { | |
| color: var(--ivy-green-light); | |
| } | |
| .bookmark-remove { | |
| width: 20px; | |
| height: 20px; | |
| background: transparent; | |
| border: none; | |
| color: var(--text-muted); | |
| font-size: 0.9rem; | |
| cursor: pointer; | |
| border-radius: var(--radius-sm); | |
| transition: all var(--transition-fast); | |
| flex-shrink: 0; | |
| } | |
| .bookmark-remove:hover { | |
| background: #ef4444; | |
| color: #fff; | |
| } | |
| .btn-small { | |
| width: 100%; | |
| padding: 6px 12px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-md); | |
| color: var(--text-muted); | |
| font-size: 0.8rem; | |
| cursor: pointer; | |
| transition: all var(--transition-fast); | |
| } | |
| .btn-small:hover { | |
| background: var(--bg-hover); | |
| color: var(--text-primary); | |
| border-color: var(--ivy-green); | |
| } | |
| .empty-hint { | |
| color: var(--text-muted); | |
| font-size: 0.8rem; | |
| font-style: italic; | |
| display: block; | |
| padding: 8px 0; | |
| } | |
| /* === Trending Tags === */ | |
| .trending-tags { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 6px; | |
| } | |
| .trending-tag { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 4px; | |
| padding: 4px 10px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--tag-color, var(--border-color)); | |
| border-radius: 9999px; | |
| color: var(--tag-color, var(--text-secondary)); | |
| font-size: 0.8rem; | |
| cursor: pointer; | |
| transition: all var(--transition-fast); | |
| } | |
| /* Trending tag color variations */ | |
| .trending-tag:nth-child(12n + 1) { | |
| --tag-color: #10b981; | |
| } /* Green */ | |
| .trending-tag:nth-child(12n + 2) { | |
| --tag-color: #3b82f6; | |
| } /* Blue */ | |
| .trending-tag:nth-child(12n + 3) { | |
| --tag-color: #8b5cf6; | |
| } /* Purple */ | |
| .trending-tag:nth-child(12n + 4) { | |
| --tag-color: #ec4899; | |
| } /* Pink */ | |
| .trending-tag:nth-child(12n + 5) { | |
| --tag-color: #f59e0b; | |
| } /* Amber */ | |
| .trending-tag:nth-child(12n + 6) { | |
| --tag-color: #06b6d4; | |
| } /* Cyan */ | |
| .trending-tag:nth-child(12n + 7) { | |
| --tag-color: #84cc16; | |
| } /* Lime */ | |
| .trending-tag:nth-child(12n + 8) { | |
| --tag-color: #f97316; | |
| } /* Orange */ | |
| .trending-tag:nth-child(12n + 9) { | |
| --tag-color: #14b8a6; | |
| } /* Teal */ | |
| .trending-tag:nth-child(12n + 10) { | |
| --tag-color: #a855f7; | |
| } /* Violet */ | |
| .trending-tag:nth-child(12n + 11) { | |
| --tag-color: #ef4444; | |
| } /* Red */ | |
| .trending-tag:nth-child(12n + 12) { | |
| --tag-color: #6366f1; | |
| } /* Indigo */ | |
| .trending-tag:hover { | |
| background: var(--tag-color, var(--ivy-green)); | |
| border-color: var(--tag-color, var(--ivy-green)); | |
| color: #fff; | |
| } | |
| .trending-tag:focus { | |
| outline: 2px solid var(--tag-color, var(--ivy-green)); | |
| outline-offset: 2px; | |
| } | |
| .trending-tag:focus:not(:focus-visible) { | |
| outline: none; | |
| } | |
| .trending-tag .tag-count { | |
| font-size: 0.7rem; | |
| padding: 1px 5px; | |
| background: rgba(255, 255, 255, 0.15); | |
| border-radius: 9999px; | |
| } | |
| .trending-tag.hot { | |
| border-color: #ef4444; | |
| color: #ef4444; | |
| --tag-color: #ef4444; | |
| } | |
| .trending-tag.hot:hover { | |
| background: #ef4444; | |
| color: #fff; | |
| } | |
| /* === Favorite Sources === */ | |
| .favorites-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 6px; | |
| } | |
| .favorite-source { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| padding: 8px 10px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-sm); | |
| cursor: pointer; | |
| transition: background var(--transition-fast); | |
| } | |
| .favorite-source:hover { | |
| background: var(--bg-hover); | |
| } | |
| .favorite-icon { | |
| font-size: 1rem; | |
| } | |
| .favorite-name { | |
| flex: 1; | |
| color: var(--text-secondary); | |
| font-size: 0.85rem; | |
| } | |
| .favorite-count { | |
| font-size: 0.75rem; | |
| padding: 2px 6px; | |
| background: var(--ivy-green); | |
| color: #fff; | |
| border-radius: 9999px; | |
| } | |
| .favorite-remove { | |
| width: 20px; | |
| height: 20px; | |
| background: transparent; | |
| border: none; | |
| color: var(--text-muted); | |
| font-size: 0.9rem; | |
| cursor: pointer; | |
| border-radius: var(--radius-sm); | |
| transition: all var(--transition-fast); | |
| } | |
| .favorite-remove:hover { | |
| background: #ef4444; | |
| color: #fff; | |
| } | |
| /* === Calendar === */ | |
| .calendar-grid { | |
| display: grid; | |
| grid-template-columns: repeat(7, 1fr); | |
| gap: 4px; | |
| } | |
| .calendar-day { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| padding: 6px 4px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-sm); | |
| cursor: pointer; | |
| transition: | |
| background var(--transition-fast), | |
| box-shadow var(--transition-fast), | |
| transform var(--transition-fast); | |
| min-height: 60px; | |
| border: 1px solid transparent; | |
| } | |
| .calendar-day:hover { | |
| background: var(--bg-hover); | |
| border-color: var(--border-color); | |
| transform: translateY(-1px); | |
| } | |
| .calendar-day:focus { | |
| outline: 2px solid var(--ivy-green); | |
| outline-offset: 2px; | |
| } | |
| .calendar-day:focus:not(:focus-visible) { | |
| outline: none; | |
| } | |
| .calendar-day.active { | |
| background: var(--ivy-green); | |
| } | |
| .calendar-day.active .day-name, | |
| .calendar-day.active .day-date, | |
| .calendar-day.active .day-count { | |
| color: #fff; | |
| } | |
| .day-name { | |
| font-size: 0.65rem; | |
| font-weight: 600; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| } | |
| .day-date { | |
| font-size: 0.95rem; | |
| font-weight: 700; | |
| color: var(--text-primary); | |
| margin: 2px 0; | |
| } | |
| .day-count { | |
| font-size: 0.7rem; | |
| font-weight: 600; | |
| color: var(--ivy-green); | |
| padding: 1px 5px; | |
| background: rgba(16, 185, 129, 0.15); | |
| border-radius: 9999px; | |
| } | |
| .day-count.zero { | |
| color: var(--text-muted); | |
| background: transparent; | |
| } | |
| /* === Sidebar Toggle (Mobile) === */ | |
| .sidebar-toggle { | |
| display: none; | |
| position: fixed; | |
| bottom: 20px; | |
| right: 20px; | |
| width: 50px; | |
| height: 50px; | |
| background: var(--ivy-green); | |
| border: none; | |
| border-radius: 50%; | |
| font-size: 1.3rem; | |
| cursor: pointer; | |
| box-shadow: var(--shadow-lg); | |
| z-index: 200; | |
| transition: transform var(--transition-fast); | |
| } | |
| .sidebar-toggle:hover { | |
| transform: scale(1.1); | |
| } | |
| /* === Back to Top Button === */ | |
| .back-to-top { | |
| position: fixed; | |
| bottom: 20px; | |
| right: 360px; /* Adjusted: sidebar(320) + gap(20) + button offset(20) */ | |
| width: 44px; | |
| height: 44px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: 50%; | |
| font-size: 1.2rem; | |
| color: var(--text-secondary); | |
| cursor: pointer; | |
| box-shadow: var(--shadow-md); | |
| z-index: 200; | |
| opacity: 0; | |
| visibility: hidden; | |
| transform: translateY(20px); | |
| transition: | |
| opacity var(--transition-normal), | |
| transform var(--transition-normal), | |
| background var(--transition-fast), | |
| border-color var(--transition-fast), | |
| color var(--transition-fast); | |
| transition-delay: 0s, 0s, 0s, 0s, 0s; | |
| will-change: opacity, transform; | |
| } | |
| /* Adjust position when sidebar is hidden */ | |
| .sidebar.hidden-desktop ~ .back-to-top, | |
| :has(.sidebar.hidden-desktop) .back-to-top { | |
| right: 20px; | |
| } | |
| .back-to-top.visible { | |
| opacity: 1; | |
| visibility: visible; | |
| transform: translateY(0); | |
| transition-delay: 0s; | |
| } | |
| .back-to-top:hover { | |
| background: var(--ivy-green); | |
| border-color: var(--ivy-green); | |
| color: #fff; | |
| transform: translateY(0) scale(1.1); | |
| } | |
| .back-to-top:focus { | |
| outline: 2px solid var(--ivy-green); | |
| outline-offset: 2px; | |
| } | |
| .back-to-top:focus:not(:focus-visible) { | |
| outline: none; | |
| } | |
| /* Position adjustment when keyboard hint is visible */ | |
| @media (min-width: 901px) { | |
| .back-to-top { | |
| bottom: 60px; /* Above keyboard hint */ | |
| } | |
| } | |
| /* Mobile/Tablet: position to not overlap sidebar toggle */ | |
| @media (max-width: 1100px) { | |
| .back-to-top { | |
| right: 80px; /* Left of sidebar toggle */ | |
| bottom: 20px; | |
| } | |
| } | |
| /* === Article Bookmark Button === */ | |
| .article-bookmark { | |
| width: 32px; | |
| height: 32px; | |
| background: transparent; | |
| border: none; | |
| color: var(--text-muted); | |
| font-size: 1rem; | |
| cursor: pointer; | |
| border-radius: var(--radius-sm); | |
| transition: all var(--transition-fast); | |
| flex-shrink: 0; | |
| opacity: 0; | |
| margin: 10px 8px 0 0; | |
| } | |
| .article-item-wrapper:hover .article-bookmark { | |
| opacity: 1; | |
| } | |
| .article-bookmark:hover { | |
| color: #fbbf24; | |
| } | |
| .article-bookmark.saved { | |
| color: #fbbf24; | |
| opacity: 1; | |
| } | |
| /* === Source Favorite Button === */ | |
| .source-favorite { | |
| width: 28px; | |
| height: 28px; | |
| background: transparent; | |
| border: 1px solid var(--border-color); | |
| color: var(--text-muted); | |
| font-size: 0.9rem; | |
| cursor: pointer; | |
| border-radius: var(--radius-md); | |
| transition: all var(--transition-fast); | |
| margin-right: 8px; | |
| } | |
| .source-favorite:hover { | |
| border-color: #fbbf24; | |
| color: #fbbf24; | |
| } | |
| .source-favorite.saved { | |
| background: #fbbf24; | |
| border-color: #fbbf24; | |
| color: #1a1a1a; | |
| } | |
| /* === Responsive Sidebar === */ | |
| @media (max-width: 1100px) { | |
| .sidebar { | |
| position: fixed; | |
| top: 0; | |
| right: -340px; | |
| width: 320px; | |
| height: 100vh; | |
| max-height: 100vh; | |
| padding: 20px 12px 20px; | |
| background: var(--bg-secondary); | |
| border-left: 1px solid var(--border-color); | |
| z-index: 150; | |
| transition: right var(--transition-normal); | |
| will-change: right; | |
| } | |
| .sidebar.open { | |
| right: 0; | |
| } | |
| .sidebar-toggle { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .app-layout { | |
| padding: 12px; | |
| } | |
| } | |
| @media (max-width: 600px) { | |
| .sidebar { | |
| width: 100%; | |
| right: -100%; | |
| } | |
| .sidebar.open { | |
| right: 0; | |
| } | |
| } | |
| /* ============================================ | |
| TOAST NOTIFICATIONS | |
| ============================================ */ | |
| .toast-notification { | |
| position: fixed; | |
| bottom: 80px; | |
| left: 50%; | |
| transform: translateX(-50%) translateY(20px); | |
| padding: 12px 24px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-lg); | |
| color: var(--text-primary); | |
| font-size: 0.9rem; | |
| font-weight: 500; | |
| box-shadow: var(--shadow-lg); | |
| z-index: 2000; | |
| opacity: 0; | |
| transition: | |
| opacity var(--transition-normal), | |
| transform var(--transition-normal); | |
| pointer-events: none; | |
| will-change: opacity, transform; | |
| } | |
| .toast-notification.show { | |
| opacity: 1; | |
| transform: translateX(-50%) translateY(0); | |
| } | |
| /* Position adjustment on mobile to avoid sidebar toggle */ | |
| @media (max-width: 1100px) { | |
| .toast-notification { | |
| bottom: 100px; | |
| } | |
| } | |
| .toast-success { | |
| border-color: var(--ivy-green); | |
| background: rgba(16, 185, 129, 0.15); | |
| } | |
| .toast-error { | |
| border-color: #ef4444; | |
| background: rgba(239, 68, 68, 0.15); | |
| } | |
| .toast-info { | |
| border-color: #3b82f6; | |
| background: rgba(59, 130, 246, 0.15); | |
| } | |
| /* ============================================ | |
| SEARCH HIGHLIGHT | |
| ============================================ */ | |
| .search-result-item mark { | |
| background: rgba(16, 185, 129, 0.3); | |
| color: var(--ivy-green-light); | |
| padding: 1px 3px; | |
| border-radius: 3px; | |
| } | |
| /* ============================================ | |
| KEYBOARD SHORTCUTS HINT | |
| ============================================ */ | |
| .keyboard-hint { | |
| position: fixed; | |
| bottom: 20px; | |
| left: 20px; | |
| padding: 8px 12px; | |
| background: var(--bg-tertiary); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius-md); | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| opacity: 0.7; | |
| z-index: 50; | |
| transition: opacity var(--transition-fast); | |
| } | |
| .keyboard-hint:hover { | |
| opacity: 1; | |
| } | |
| .keyboard-hint .divider { | |
| margin: 0 6px; | |
| opacity: 0.5; | |
| } | |
| .keyboard-hint kbd { | |
| display: inline-block; | |
| padding: 2px 6px; | |
| background: var(--bg-primary); | |
| border: 1px solid var(--border-color); | |
| border-radius: 4px; | |
| font-family: var(--font-mono); | |
| font-size: 0.7rem; | |
| color: var(--text-secondary); | |
| margin: 0 2px; | |
| } | |
| @media (max-width: 900px) { | |
| .keyboard-hint { | |
| display: none; | |
| } | |
| } | |
| /* ============================================ | |
| SIDEBAR HIDE TOGGLE (Desktop) | |
| ============================================ */ | |
| .sidebar.hidden-desktop { | |
| display: none; | |
| } | |
| @media (max-width: 1100px) { | |
| .sidebar.hidden-desktop { | |
| display: flex; /* On mobile, use the normal toggle behavior */ | |
| } | |
| } | |
| /* ============================================ | |
| MOBILE SCROLL INDICATOR FOR CATEGORIES | |
| ============================================ */ | |
| @media (max-width: 900px) { | |
| .nav-categories { | |
| position: relative; | |
| -webkit-overflow-scrolling: touch; | |
| scrollbar-width: none; /* Firefox */ | |
| } | |
| .nav-categories::-webkit-scrollbar { | |
| display: none; | |
| } | |
| .nav-categories::after { | |
| content: ""; | |
| position: absolute; | |
| right: 0; | |
| top: 0; | |
| height: 100%; | |
| width: 40px; | |
| background: linear-gradient(to right, transparent, var(--bg-secondary)); | |
| pointer-events: none; | |
| } | |
| } | |
| /* ============================================ | |
| SOURCE COLOR VARIATIONS (12 subtle colors) | |
| ============================================ */ | |
| /* Color palette - subtle variations that work on dark theme */ | |
| .source-section[data-color-index="0"] { | |
| --source-accent: #10b981; | |
| } /* Ivy Green (default) */ | |
| .source-section[data-color-index="1"] { | |
| --source-accent: #3b82f6; | |
| } /* Blue */ | |
| .source-section[data-color-index="2"] { | |
| --source-accent: #8b5cf6; | |
| } /* Purple */ | |
| .source-section[data-color-index="3"] { | |
| --source-accent: #ec4899; | |
| } /* Pink */ | |
| .source-section[data-color-index="4"] { | |
| --source-accent: #f59e0b; | |
| } /* Amber */ | |
| .source-section[data-color-index="5"] { | |
| --source-accent: #06b6d4; | |
| } /* Cyan */ | |
| .source-section[data-color-index="6"] { | |
| --source-accent: #84cc16; | |
| } /* Lime */ | |
| .source-section[data-color-index="7"] { | |
| --source-accent: #f97316; | |
| } /* Orange */ | |
| .source-section[data-color-index="8"] { | |
| --source-accent: #14b8a6; | |
| } /* Teal */ | |
| .source-section[data-color-index="9"] { | |
| --source-accent: #a855f7; | |
| } /* Violet */ | |
| .source-section[data-color-index="10"] { | |
| --source-accent: #ef4444; | |
| } /* Red */ | |
| .source-section[data-color-index="11"] { | |
| --source-accent: #6366f1; | |
| } /* Indigo */ | |
| /* ============================================ | |
| CACHED STATUS INDICATOR | |
| ============================================ */ | |
| .source-status.cached::before { | |
| content: ""; | |
| width: 6px; | |
| height: 6px; | |
| background: #f59e0b; | |
| border-radius: 50%; | |
| } | |
| /* ============================================ | |
| SETTINGS IMPROVEMENTS | |
| ============================================ */ | |
| /* Add Feed Row (side by side selects) */ | |
| .add-feed-row { | |
| display: flex; | |
| gap: 8px; | |
| } | |
| .add-feed-row select { | |
| flex: 1; | |
| } | |
| /* Language indicator in sources list */ | |
| .source-toggle-lang { | |
| font-size: 1rem; | |
| flex-shrink: 0; | |
| } | |
| /* Custom feed badge */ | |
| .custom-badge { | |
| display: inline-block; | |
| font-size: 0.65rem; | |
| padding: 2px 6px; | |
| background: var(--ivy-green); | |
| color: #fff; | |
| border-radius: 9999px; | |
| text-transform: uppercase; | |
| font-weight: 600; | |
| letter-spacing: 0.02em; | |
| margin-left: 6px; | |
| vertical-align: middle; | |
| } | |
| /* Delete custom feed button */ | |
| .source-delete-btn { | |
| width: 28px; | |
| height: 28px; | |
| background: transparent; | |
| border: 1px solid transparent; | |
| border-radius: var(--radius-md); | |
| cursor: pointer; | |
| font-size: 0.9rem; | |
| opacity: 0.5; | |
| transition: all var(--transition-fast); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-shrink: 0; | |
| } | |
| .source-delete-btn:hover { | |
| opacity: 1; | |
| background: rgba(239, 68, 68, 0.15); | |
| border-color: #ef4444; | |
| } | |
| /* Source toggle item improvements */ | |
| .source-toggle-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| padding: 10px 12px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-md); | |
| transition: background var(--transition-fast); | |
| } | |
| /* ============================================ | |
| FAILED FEED INDICATOR | |
| ============================================ */ | |
| .source-section.error { | |
| opacity: 0.6; | |
| border-color: #ef4444; | |
| } | |
| .source-section.error .source-header { | |
| border-left-color: #ef4444; | |
| } | |
| .source-status.error::before { | |
| content: ""; | |
| width: 6px; | |
| height: 6px; | |
| background: #ef4444; | |
| border-radius: 50%; | |
| } | |
| /* ============================================ | |
| FOCUS STATES FOR ACCESSIBILITY | |
| ============================================ */ | |
| .source-header:focus { | |
| outline: 2px solid var(--ivy-green); | |
| outline-offset: 2px; | |
| } | |
| .source-header:focus:not(:focus-visible) { | |
| outline: none; | |
| } | |
| .source-favorite:focus, | |
| .article-bookmark:focus, | |
| .nav-btn:focus, | |
| .lang-btn:focus { | |
| outline: 2px solid var(--ivy-green); | |
| outline-offset: 2px; | |
| } | |
| .source-favorite:focus:not(:focus-visible), | |
| .article-bookmark:focus:not(:focus-visible), | |
| .nav-btn:focus:not(:focus-visible), | |
| .lang-btn:focus:not(:focus-visible) { | |
| outline: none; | |
| } | |
| /* ============================================ | |
| LOADING ANIMATION FOR NEW SECTIONS | |
| ============================================ */ | |
| @keyframes fadeInUp { | |
| from { | |
| opacity: 0; | |
| transform: translateY(10px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| .source-section { | |
| animation: fadeInUp 0.3s ease-out; | |
| animation-fill-mode: backwards; | |
| } | |
| /* Stagger animation for multiple sources */ | |
| .source-section:nth-child(1) { | |
| animation-delay: 0ms; | |
| } | |
| .source-section:nth-child(2) { | |
| animation-delay: 50ms; | |
| } | |
| .source-section:nth-child(3) { | |
| animation-delay: 100ms; | |
| } | |
| .source-section:nth-child(4) { | |
| animation-delay: 150ms; | |
| } | |
| .source-section:nth-child(5) { | |
| animation-delay: 200ms; | |
| } | |
| .source-section:nth-child(6) { | |
| animation-delay: 250ms; | |
| } | |
| .source-section:nth-child(7) { | |
| animation-delay: 300ms; | |
| } | |
| .source-section:nth-child(8) { | |
| animation-delay: 350ms; | |
| } | |
| /* Article items - removed stagger animation for performance with many articles */ | |
| /* Only animate first 5 items, rest appear instantly */ | |
| .article-item-wrapper:nth-child(-n + 5) { | |
| animation: fadeInUp 0.15s ease-out; | |
| animation-fill-mode: backwards; | |
| } | |
| .article-item-wrapper:nth-child(1) { | |
| animation-delay: 0ms; | |
| } | |
| .article-item-wrapper:nth-child(2) { | |
| animation-delay: 20ms; | |
| } | |
| .article-item-wrapper:nth-child(3) { | |
| animation-delay: 40ms; | |
| } | |
| .article-item-wrapper:nth-child(4) { | |
| animation-delay: 60ms; | |
| } | |
| .article-item-wrapper:nth-child(5) { | |
| animation-delay: 80ms; | |
| } | |
| /* ============================================ | |
| IMPROVED MOBILE SIDEBAR TOGGLE | |
| ============================================ */ | |
| .sidebar-toggle:active { | |
| transform: scale(0.95); | |
| } | |
| /* Pulse effect when sidebar has new content */ | |
| @keyframes pulse { | |
| 0%, | |
| 100% { | |
| box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); | |
| } | |
| 50% { | |
| box-shadow: 0 0 0 8px rgba(16, 185, 129, 0); | |
| } | |
| } | |
| .sidebar-toggle.has-updates { | |
| animation: pulse 2s ease-in-out 3; | |
| } | |
| /* ============================================ | |
| SKIP LINK FOR ACCESSIBILITY | |
| ============================================ */ | |
| .skip-link { | |
| position: absolute; | |
| top: -40px; | |
| left: 0; | |
| background: var(--ivy-green); | |
| color: #fff; | |
| padding: 8px 16px; | |
| z-index: 1001; | |
| transition: top 0.3s ease; | |
| } | |
| .skip-link:focus { | |
| top: 0; | |
| } | |
| /* ============================================ | |
| AUTO-REFRESH STATUS INDICATOR | |
| ============================================ */ | |
| #auto-refresh-status { | |
| padding: 8px 12px; | |
| background: var(--bg-tertiary); | |
| border-radius: var(--radius-md); | |
| font-size: 0.85rem; | |
| text-align: center; | |
| transition: color var(--transition-fast); | |
| } | |
| #auto-refresh-status:not(:empty) { | |
| margin-top: 8px; | |
| } | |