diff options
| author | Claude <noreply@anthropic.com> | 2026-02-18 01:07:17 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-02-18 01:07:17 +0000 |
| commit | 042c8ba30a6cbc1915fce8910de31af86253a044 (patch) | |
| tree | 210b3a649b3921e4e7f23793e5a8485c6cd4058a /frontend-vanilla | |
| parent | 18a85a30f4282b5d07528eb8e1dd8ff7617190d2 (diff) | |
| download | neko-042c8ba30a6cbc1915fce8910de31af86253a044.tar.gz neko-042c8ba30a6cbc1915fce8910de31af86253a044.tar.bz2 neko-042c8ba30a6cbc1915fce8910de31af86253a044.zip | |
Refine themes, add sidebar controls, and theme docs
Refined: softer dark-mode link color (#a0c4e8), fix export button
vertical alignment with inline-flex, tighten settings page spacing
(reduce gaps from 3rem to 1.5rem).
Terminal: switch accent from cyan to green (#4ae54a dark / #1a7a2e
light), add proper light mode with pale steel background, scanlines
only in dark mode.
Sidebar: add quick-access controls in footer — moon/sun icon toggles
light/dark, circle icon cycles through style themes showing current
name. Both update reactively on state change.
Add THEMES.md with full documentation on creating new themes:
variable reference, selector guide, light/dark mode tips, and the
registration process.
https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
Diffstat (limited to 'frontend-vanilla')
| -rw-r--r-- | frontend-vanilla/THEMES.md | 151 | ||||
| -rw-r--r-- | frontend-vanilla/public/themes/refined.css | 33 | ||||
| -rw-r--r-- | frontend-vanilla/public/themes/terminal.css | 169 | ||||
| -rw-r--r-- | frontend-vanilla/src/main.ts | 28 | ||||
| -rw-r--r-- | frontend-vanilla/src/style.css | 41 |
5 files changed, 342 insertions, 80 deletions
diff --git a/frontend-vanilla/THEMES.md b/frontend-vanilla/THEMES.md new file mode 100644 index 0000000..8367046 --- /dev/null +++ b/frontend-vanilla/THEMES.md @@ -0,0 +1,151 @@ +# Creating a New Theme + +Neko's style theme system layers an additional CSS file on top of the base +stylesheet. The base `style.css` defines CSS custom properties (variables) and +all component styles. A theme file overrides whichever of those it wants. + +## Quick Start + +1. Create a new CSS file in `frontend-vanilla/public/themes/yourtheme.css` +2. Register the theme name in `frontend-vanilla/src/main.ts` — add it to the + `STYLE_THEMES` array: + ```ts + const STYLE_THEMES = ['default', 'refined', 'terminal', 'codex', 'sakura', 'yourtheme'] as const; + ``` +3. Rebuild: `cd frontend-vanilla && npm run build` +4. Copy output: `cp -r dist/* ../web/dist/v3/` + +That's it. The theme will appear in Settings > Style and in the sidebar cycle +button. + +## How it works + +When a user picks a style theme, JavaScript inserts a `<link>` tag: + +```html +<link id="style-theme-link" rel="stylesheet" href="/v3/themes/yourtheme.css"> +``` + +This loads *after* the base stylesheet, so any rules you write will override +the defaults via normal CSS cascade (same specificity = last one wins). When +the user switches to "Default," the link tag is removed entirely. + +The theme CSS files live in `public/themes/` so Vite copies them as-is into the +build output (no hashing, no bundling). They're plain CSS — no build step +required for the theme file itself. + +## CSS Variables You Can Override + +The base stylesheet defines these custom properties on `:root` (light mode) +and `.theme-dark` (dark mode): + +```css +/* Colors */ +--bg-color /* Page background */ +--text-color /* Primary text */ +--sidebar-bg /* Sidebar background */ +--link-color /* Links and titles */ +--border-color /* Borders, rules, dividers */ +--accent-color /* Interactive accent (selection, focus) */ + +/* Fonts */ +--font-body /* Body/article text (default: Palatino stack) */ +--font-heading /* Dynamic heading font (user-selectable) */ +--font-heading-system /* System heading font (Helvetica Neue stack) */ +--font-sans /* Sans-serif stack (Inter/system-ui) */ +--font-mono /* Monospace stack (Courier New) */ +``` + +### Supporting both light and dark mode + +Your theme should define colors for both modes: + +```css +/* Light mode */ +:root { + --bg-color: #faf8f4; + --text-color: #2c2c2c; + --link-color: #8b4513; + /* ... */ +} + +/* Dark mode */ +.theme-dark { + --bg-color: #1c1a17; + --text-color: #d4cfc6; + --link-color: #c9956b; + /* ... */ +} +``` + +The light/dark toggle adds/removes the `theme-dark` class on `#app`. Your +theme's `.theme-dark` rules will override your `:root` rules when active. + +**Important:** The base stylesheet has some `.theme-dark .sidebar` rules that +set the sidebar to a grey background with dark text. If your theme wants a +different dark-mode sidebar, you'll need to override those specifically: + +```css +.theme-dark .sidebar { background: ...; } +.theme-dark .sidebar-section li a { color: ...; } +.theme-dark .sidebar-section h3 { color: ...; } +.theme-dark .sidebar-footer a { color: ...; } +``` + +## Key Selectors Reference + +### Layout +- `.sidebar` — Fixed sidebar (11rem wide) +- `.main-content` — Scrollable content area +- `.main-content > *` — Content max-width container (default: 35em) + +### Feed items +- `.feed-item` — Individual article wrapper +- `.item-title` — Article title/link +- `.dateline` — Date + feed source line +- `.item-description` — Article body content +- `.star-btn` / `.star-btn.is-starred` / `.star-btn.is-unstarred` — Star toggle +- `.scrape-btn` — "text" button for full-content fetch + +### Settings page +- `.settings-view` — Settings container +- `.settings-section` / `.settings-section h3` — Section blocks +- `.settings-group` / `.data-group` — Form groups +- `.theme-options` — Button row for theme/style selectors +- `.button-group` — Button row for export/import +- `.manage-feed-list` / `.manage-feed-item` — Feed management list + +### Buttons +- `button` / `.button` — All buttons and button-styled links +- `button.active` — Currently selected option + +### Sidebar details +- `.sidebar-section h3` — Section headers (FEEDS, TAGS) +- `.sidebar-section li a` — Feed/filter links +- `.sidebar-section li.active a` — Selected item +- `.sidebar-footer` — Bottom area (settings, logout, controls) +- `.sidebar-quick-controls` / `.sidebar-icon-btn` — Theme toggle icons + +## Tips + +- **Override fonts broadly.** Set `font-family` on `body` for article text and + on `.sidebar`, `.settings-view`, `button` for UI elements. +- **Use the cascade.** You don't need `!important` — your theme loads after the + base stylesheet. Just match or exceed the specificity of the base rule. +- **Keep it to overrides.** Don't redefine layout or structural properties + unless you have a reason. Focus on colors, typography, and spacing. +- **Test both modes.** Always check your theme in both light and dark. +- **Note on font overrides:** The user can independently select heading and body + fonts in Settings > Fonts. These apply CSS classes like `.font-sans`, + `.heading-font-serif`, etc. Your theme's font choices will be the "default" + that users see before changing font settings. + +## Existing Themes + +| Theme | Character | +|------------|-----------| +| `default` | No extra CSS — the base stylesheet as-is | +| `refined` | Tightened spacing, better typographic rhythm, polished details | +| `terminal` | Monospace, green phosphor accent, CRT scanlines in dark mode | +| `codex` | Book-inspired: warm cream paper, serif type, fleuron separators | +| `sakura` | Japanese aesthetic: restrained palette, muted rose accent, calm spacing | diff --git a/frontend-vanilla/public/themes/refined.css b/frontend-vanilla/public/themes/refined.css index 9143552..fab2b96 100644 --- a/frontend-vanilla/public/themes/refined.css +++ b/frontend-vanilla/public/themes/refined.css @@ -14,7 +14,12 @@ --spacing-md: 1rem; --spacing-lg: 1.5rem; --spacing-xl: 2rem; - --spacing-2xl: 3rem; +} + +/* Dark mode: a warmer, softer link color */ +.theme-dark { + --link-color: #a0c4e8; + --accent-color: #6fa8d6; } /* Slightly refined base typography */ @@ -114,22 +119,21 @@ body { } /* ---- Settings Page Refinements ---- */ -/* This is where the biggest improvements are needed */ .settings-view { - padding-top: var(--spacing-xl); + padding-top: var(--spacing-lg); } .settings-view h2 { font-size: 1.8rem; font-weight: 700; - margin-bottom: var(--spacing-2xl); + margin-bottom: var(--spacing-xl); letter-spacing: -0.025em; } .settings-grid { - gap: var(--spacing-2xl); - margin-bottom: var(--spacing-2xl); + gap: var(--spacing-lg); + margin-bottom: var(--spacing-lg); } .settings-section { @@ -140,28 +144,28 @@ body { .settings-section h3 { font-size: 1.1rem; font-weight: 700; - margin-bottom: var(--spacing-lg); - padding-bottom: var(--spacing-sm); + margin-bottom: var(--spacing-sm); + padding-bottom: var(--spacing-xs); border-bottom: 1px solid var(--border-color); } .settings-group, .data-group { - margin-bottom: var(--spacing-lg); + margin-bottom: var(--spacing-sm); } .settings-group label, .data-group label { font-size: 0.75rem; letter-spacing: 0.1em; - margin-bottom: var(--spacing-sm); + margin-bottom: var(--spacing-xs); } .theme-options { gap: var(--spacing-sm); } -/* Consistent button sizing */ +/* Consistent button sizing & vertical centering fix */ button, .button { height: 2.2rem; @@ -169,12 +173,15 @@ button, font-size: 0.75rem; letter-spacing: 0.06em; border-radius: 5px; + display: inline-flex; + align-items: center; + justify-content: center; } /* Add feed form alignment */ .add-feed-form { gap: var(--spacing-sm); - margin-bottom: var(--spacing-xl); + margin-bottom: var(--spacing-lg); } .add-feed-form input { @@ -183,7 +190,7 @@ button, /* Manage feeds list consistency */ .manage-feeds-section { - margin-top: var(--spacing-2xl); + margin-top: var(--spacing-xl); } .manage-feed-item { diff --git a/frontend-vanilla/public/themes/terminal.css b/frontend-vanilla/public/themes/terminal.css index f497dfa..dd9c1b2 100644 --- a/frontend-vanilla/public/themes/terminal.css +++ b/frontend-vanilla/public/themes/terminal.css @@ -6,32 +6,38 @@ */ /* ---- Color System ---- */ +/* Light mode: bright terminal on a pale steel background */ :root { - --bg-color: #0a0e14; - --text-color: #b0bec5; - --sidebar-bg: #0d1117; - --link-color: #00e5ff; - --border-color: #1e2a35; - --accent-color: #00e5ff; - - --terminal-glow: rgba(0, 229, 255, 0.08); - --terminal-dim: rgba(0, 229, 255, 0.03); - --terminal-green: #39ff14; - --terminal-cyan: #00e5ff; - --terminal-magenta: #ff00ff; - --terminal-amber: #ffab00; + --bg-color: #f0f2f0; + --text-color: #1e2d1e; + --sidebar-bg: #e4e8e4; + --link-color: #1a7a2e; + --border-color: #c4cec4; + --accent-color: #1a7a2e; + + --terminal-accent: #1a7a2e; + --terminal-glow: rgba(26, 122, 46, 0.08); + --terminal-dim: rgba(26, 122, 46, 0.03); + --terminal-amber: #a66800; + --terminal-red: #c62828; - color-scheme: dark; + color-scheme: light dark; } -/* Override dark theme if also applied */ +/* Dark mode: phosphor green on black */ .theme-dark { - --bg-color: #0a0e14; - --text-color: #b0bec5; - --sidebar-bg: #0d1117; - --link-color: #00e5ff; - --border-color: #1e2a35; - --accent-color: #00e5ff; + --bg-color: #0a0e0a; + --text-color: #b0bfb0; + --sidebar-bg: #0d110d; + --link-color: #4ae54a; + --border-color: #1e2a1e; + --accent-color: #4ae54a; + + --terminal-accent: #4ae54a; + --terminal-glow: rgba(74, 229, 74, 0.08); + --terminal-dim: rgba(74, 229, 74, 0.03); + --terminal-amber: #ffab00; + --terminal-red: #ff5252; } /* ---- Typography ---- */ @@ -46,8 +52,8 @@ body { -webkit-font-smoothing: antialiased; } -/* Subtle scanline overlay on the whole page */ -body::after { +/* Subtle scanline overlay -- only in dark mode */ +.theme-dark body::after { content: ''; position: fixed; top: 0; @@ -82,14 +88,14 @@ body::after { .sidebar-section h3 { font-family: inherit; - color: var(--terminal-cyan); + color: var(--terminal-accent); opacity: 0.6; font-size: 0.65rem; letter-spacing: 0.2em; } .theme-dark .sidebar-section h3 { - color: var(--terminal-cyan); + color: var(--terminal-accent); } .sidebar-section li a { @@ -105,19 +111,19 @@ body::after { .sidebar-section li a:hover { background: var(--terminal-glow); - color: var(--terminal-cyan); + color: var(--terminal-accent); transform: none; } .theme-dark .sidebar-section li a:hover { background: var(--terminal-glow); - color: var(--terminal-cyan); + color: var(--terminal-accent); } .sidebar-section li.active a { background: var(--terminal-glow); - color: var(--terminal-cyan); - box-shadow: inset 2px 0 0 var(--terminal-cyan); + color: var(--terminal-accent); + box-shadow: inset 2px 0 0 var(--terminal-accent); border: none; border-radius: 0; font-weight: 500; @@ -125,7 +131,7 @@ body::after { .theme-dark .sidebar-section li.active a { background: var(--terminal-glow); - color: var(--terminal-cyan); + color: var(--terminal-accent); } .sidebar-footer { @@ -144,14 +150,14 @@ body::after { } .sidebar-footer a:hover { - color: var(--terminal-cyan); + color: var(--terminal-accent); background: var(--terminal-dim); opacity: 1; } /* Search */ .sidebar-search input { - background: rgba(0, 229, 255, 0.05); + background: var(--terminal-dim); border: 1px solid var(--border-color); border-radius: 2px; color: var(--text-color); @@ -159,18 +165,22 @@ body::after { } .theme-dark .sidebar-search input { - background: rgba(0, 229, 255, 0.05); + background: var(--terminal-dim); color: var(--text-color); border-color: var(--border-color); } .sidebar-search input:focus { - border-color: var(--terminal-cyan); - box-shadow: 0 0 8px rgba(0, 229, 255, 0.15); + border-color: var(--terminal-accent); + box-shadow: 0 0 8px rgba(74, 229, 74, 0.15); } .sidebar-search input::placeholder { - color: rgba(176, 190, 197, 0.3); + color: rgba(0, 0, 0, 0.25); +} + +.theme-dark .sidebar-search input::placeholder { + color: rgba(176, 191, 176, 0.3); } /* ---- Toggle ---- */ @@ -203,7 +213,7 @@ body::after { .feed-item.selected { background-color: var(--terminal-dim); - box-shadow: inset 3px 0 0 var(--terminal-cyan); + box-shadow: inset 3px 0 0 var(--terminal-accent); border-radius: 0; } @@ -215,30 +225,35 @@ body::after { font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace; font-size: 1.4rem; line-height: 1.35; - color: var(--terminal-cyan); + color: var(--terminal-accent); font-weight: 600; letter-spacing: -0.01em; } .item-title:hover { - color: #ffffff; - text-shadow: 0 0 12px rgba(0, 229, 255, 0.3); text-decoration: none; } +.theme-dark .item-title:hover { + color: #ffffff; + text-shadow: 0 0 12px rgba(74, 229, 74, 0.3); +} + .dateline { - color: rgba(176, 190, 197, 0.35); + color: var(--text-color); + opacity: 0.35; font-family: inherit; font-size: 0.75em; letter-spacing: 0.04em; } .dateline a { - color: rgba(176, 190, 197, 0.35); + color: inherit; } .dateline a:hover { - color: var(--terminal-cyan); + color: var(--terminal-accent); + opacity: 1; } .item-description { @@ -249,15 +264,15 @@ body::after { } .item-description a { - color: var(--terminal-cyan); + color: var(--terminal-accent); } -.item-description a:hover { - text-shadow: 0 0 8px rgba(0, 229, 255, 0.2); +.theme-dark .item-description a:hover { + text-shadow: 0 0 8px rgba(74, 229, 74, 0.2); } .item-description pre { - background: rgba(0, 229, 255, 0.04); + background: var(--terminal-dim); border: 1px solid var(--border-color); border-radius: 2px; font-family: inherit; @@ -276,15 +291,18 @@ body::after { /* Scrape */ .scrape-btn { font-family: inherit; - color: var(--terminal-cyan); + color: var(--terminal-accent); border-color: var(--border-color); background: transparent; border-radius: 2px; } .scrape-btn:hover { - border-color: var(--terminal-cyan); - box-shadow: 0 0 6px rgba(0, 229, 255, 0.15); + border-color: var(--terminal-accent); +} + +.theme-dark .scrape-btn:hover { + box-shadow: 0 0 6px rgba(74, 229, 74, 0.15); } /* ---- Buttons ---- */ @@ -303,8 +321,8 @@ button, button:hover, .button:hover { - border-color: var(--terminal-cyan); - color: var(--terminal-cyan); + border-color: var(--terminal-accent); + color: var(--terminal-accent); background: var(--terminal-dim); } @@ -317,16 +335,16 @@ button:hover, .theme-dark button:hover, .theme-dark .button:hover { - border-color: var(--terminal-cyan); - color: var(--terminal-cyan); + border-color: var(--terminal-accent); + color: var(--terminal-accent); background: var(--terminal-dim); } button.active, .theme-dark button.active { - background: var(--terminal-cyan); + background: var(--terminal-accent); color: var(--bg-color); - border-color: var(--terminal-cyan); + border-color: var(--terminal-accent); } /* ---- Settings ---- */ @@ -336,7 +354,7 @@ button.active, } .settings-view h2 { - color: var(--terminal-cyan); + color: var(--terminal-accent); font-weight: 600; letter-spacing: 0.05em; font-size: 1.5rem; @@ -364,13 +382,17 @@ button.active, color: var(--text-color) !important; } +.theme-dark .settings-view h2 { + color: var(--terminal-accent) !important; +} + /* Inputs */ input[type="text"], input[type="url"], input[type="search"], select { font-family: inherit; - background: rgba(0, 229, 255, 0.04); + background: var(--terminal-dim); border: 1px solid var(--border-color); border-radius: 2px; color: var(--text-color); @@ -378,8 +400,8 @@ select { input:focus, select:focus { - border-color: var(--terminal-cyan); - box-shadow: 0 0 8px rgba(0, 229, 255, 0.15); + border-color: var(--terminal-accent); + box-shadow: 0 0 8px rgba(74, 229, 74, 0.15); } /* Feed list in settings */ @@ -404,12 +426,16 @@ select:focus { /* Delete button */ .delete-feed-btn { - color: #ff5252 !important; - border-color: rgba(255, 82, 82, 0.3) !important; + color: var(--terminal-red) !important; + border-color: rgba(198, 40, 40, 0.3) !important; } .delete-feed-btn:hover { - border-color: #ff5252 !important; + border-color: var(--terminal-red) !important; + background: rgba(198, 40, 40, 0.06) !important; +} + +.theme-dark .delete-feed-btn:hover { box-shadow: 0 0 6px rgba(255, 82, 82, 0.2) !important; background: rgba(255, 82, 82, 0.08) !important; } @@ -425,22 +451,31 @@ select:focus { } ::-webkit-scrollbar-thumb { - background: rgba(0, 229, 255, 0.15); + background: rgba(74, 229, 74, 0.15); border-radius: 0; } +.theme-dark ::-webkit-scrollbar-thumb { + background: rgba(74, 229, 74, 0.15); +} + ::-webkit-scrollbar-thumb:hover { - background: rgba(0, 229, 255, 0.3); + background: rgba(74, 229, 74, 0.3); } /* ---- Backdrop ---- */ .sidebar-backdrop { - background: rgba(0, 0, 0, 0.6); + background: rgba(240, 242, 240, 0.6); backdrop-filter: blur(2px); } +.theme-dark .sidebar-backdrop { + background: rgba(0, 0, 0, 0.6); +} + /* ---- Loading/Empty States ---- */ .loading, .empty { - color: rgba(176, 190, 197, 0.4); + color: var(--text-color); + opacity: 0.4; font-family: inherit; } diff --git a/frontend-vanilla/src/main.ts b/frontend-vanilla/src/main.ts index fa74274..56ae91a 100644 --- a/frontend-vanilla/src/main.ts +++ b/frontend-vanilla/src/main.ts @@ -76,6 +76,10 @@ export function renderLayout() { --> </div> <div class="sidebar-footer"> + <div class="sidebar-quick-controls"> + <button id="sidebar-theme-toggle" class="sidebar-icon-btn" title="${store.theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'}">${store.theme === 'light' ? '☽' : '☀'}</button> + <button id="sidebar-style-cycle" class="sidebar-icon-btn" title="Style: ${store.styleTheme}">${store.styleTheme === 'default' ? '◯' : '◉'} ${store.styleTheme}</button> + </div> <a href="/v3/settings" data-nav="settings">Settings</a> <a href="#" id="logout-button">Logout</a> </div> @@ -104,6 +108,18 @@ export function attachLayoutListeners() { logout(); }); + // Sidebar quick controls: light/dark toggle + document.getElementById('sidebar-theme-toggle')?.addEventListener('click', () => { + store.setTheme(store.theme === 'light' ? 'dark' : 'light'); + }); + + // Sidebar quick controls: cycle style theme + document.getElementById('sidebar-style-cycle')?.addEventListener('click', () => { + const idx = STYLE_THEMES.indexOf(store.styleTheme as typeof STYLE_THEMES[number]); + const next = STYLE_THEMES[(idx + 1) % STYLE_THEMES.length]; + store.setStyleTheme(next); + }); + document.getElementById('sidebar-toggle-btn')?.addEventListener('click', () => { store.toggleSidebar(); }); @@ -864,6 +880,12 @@ store.on('theme-updated', () => { // Re-apply classes with proper specificity logic appEl.className = `theme-${store.theme} font-${store.fontTheme} heading-font-${store.headingFontTheme}`; } + // Update sidebar toggle icon + const toggleBtn = document.getElementById('sidebar-theme-toggle'); + if (toggleBtn) { + toggleBtn.textContent = store.theme === 'light' ? '☽' : '☀'; + toggleBtn.title = store.theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'; + } // Also re-render settings if we are on settings page to update active state of buttons if (router.getCurrentRoute().path === '/settings') { renderSettings(); @@ -885,6 +907,12 @@ store.on('sidebar-toggle', () => { store.on('style-theme-updated', () => { loadStyleTheme(store.styleTheme); + // Update sidebar style cycle button + const cycleBtn = document.getElementById('sidebar-style-cycle'); + if (cycleBtn) { + cycleBtn.textContent = `${store.styleTheme === 'default' ? '◯' : '◉'} ${store.styleTheme}`; + cycleBtn.title = `Style: ${store.styleTheme}`; + } // Re-render settings if on settings page to update active state if (router.getCurrentRoute().path === '/settings') { renderSettings(); diff --git a/frontend-vanilla/src/style.css b/frontend-vanilla/src/style.css index e9512b7..3061948 100644 --- a/frontend-vanilla/src/style.css +++ b/frontend-vanilla/src/style.css @@ -215,6 +215,47 @@ html { opacity: 1; } +/* Quick controls row in sidebar footer */ +.sidebar-quick-controls { + display: flex; + gap: 0.4rem; + margin-bottom: 0.25rem; +} + +.sidebar-icon-btn { + background: none; + border: none; + cursor: pointer; + font-size: 0.75rem; + padding: 0.3rem 0.6rem; + border-radius: 6px; + color: var(--text-color); + opacity: 0.5; + transition: opacity 0.15s, background 0.15s; + font-family: var(--font-sans); + text-transform: none; + font-weight: 500; + height: auto; + line-height: 1.3; +} + +.sidebar-icon-btn:hover { + opacity: 1; + background: rgba(255, 255, 255, 0.08); + border: none; +} + +.theme-dark .sidebar-icon-btn { + color: rgba(0, 0, 0, 0.87); + border: none; + background: none; +} + +.theme-dark .sidebar-icon-btn:hover { + background: rgba(0, 0, 0, 0.06); + border: none; +} + /* Main Content area - always fills full width (sidebar overlays) */ .main-content { width: 100%; |
