From 18a85a30f4282b5d07528eb8e1dd8ff7617190d2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 23:48:10 +0000 Subject: Add 4 CSS style themes with runtime switcher Adds a style theme system that layers additional CSS files on top of the base stylesheet. Themes are loaded/unloaded dynamically via tags. - Default: existing look, unchanged - Refined: typographic rhythm fixes, consistent spacing on settings page - Terminal: monospace, dark phosphor CRT aesthetic (scanlines, cyan glow) - Codex: book/Tufte-inspired with warm paper tones, serif type, fleurons - Sakura: Japanese-inspired calm aesthetic (named for neko = cat) Each theme supports both light and dark mode. Style selection persists in localStorage and is independent of the light/dark toggle. https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe --- web/dist/v3/themes/terminal.css | 446 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 446 insertions(+) create mode 100644 web/dist/v3/themes/terminal.css (limited to 'web/dist/v3/themes/terminal.css') diff --git a/web/dist/v3/themes/terminal.css b/web/dist/v3/themes/terminal.css new file mode 100644 index 0000000..f497dfa --- /dev/null +++ b/web/dist/v3/themes/terminal.css @@ -0,0 +1,446 @@ +/* + * Terminal Theme + * Born-digital. CRT phosphor. The hum of the machine. + * Inspired by green-screen terminals, REZ, and the beauty of text on glass. + * Content-first -- the digital medium is the accent, not the show. + */ + +/* ---- Color System ---- */ +: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; + + color-scheme: dark; +} + +/* Override dark theme if also applied */ +.theme-dark { + --bg-color: #0a0e14; + --text-color: #b0bec5; + --sidebar-bg: #0d1117; + --link-color: #00e5ff; + --border-color: #1e2a35; + --accent-color: #00e5ff; +} + +/* ---- Typography ---- */ + +body { + font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'JetBrains Mono', 'Courier New', monospace; + font-size: 15px; + line-height: 1.65; + letter-spacing: 0.02em; + background-color: var(--bg-color); + color: var(--text-color); + -webkit-font-smoothing: antialiased; +} + +/* Subtle scanline overlay on the whole page */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 9999; + background: repeating-linear-gradient( + to bottom, + transparent, + transparent 2px, + rgba(0, 0, 0, 0.03) 2px, + rgba(0, 0, 0, 0.03) 4px + ); +} + +/* ---- Sidebar ---- */ + +.sidebar { + background: var(--sidebar-bg); + backdrop-filter: none; + -webkit-backdrop-filter: none; + border-right: 1px solid var(--border-color); + font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace; +} + +.theme-dark .sidebar { + background: var(--sidebar-bg); + border-right-color: var(--border-color); +} + +.sidebar-section h3 { + font-family: inherit; + color: var(--terminal-cyan); + opacity: 0.6; + font-size: 0.65rem; + letter-spacing: 0.2em; +} + +.theme-dark .sidebar-section h3 { + color: var(--terminal-cyan); +} + +.sidebar-section li a { + font-family: inherit; + color: var(--text-color); + border-radius: 2px; + font-size: 0.8rem; +} + +.theme-dark .sidebar-section li a { + color: var(--text-color); +} + +.sidebar-section li a:hover { + background: var(--terminal-glow); + color: var(--terminal-cyan); + transform: none; +} + +.theme-dark .sidebar-section li a:hover { + background: var(--terminal-glow); + color: var(--terminal-cyan); +} + +.sidebar-section li.active a { + background: var(--terminal-glow); + color: var(--terminal-cyan); + box-shadow: inset 2px 0 0 var(--terminal-cyan); + border: none; + border-radius: 0; + font-weight: 500; +} + +.theme-dark .sidebar-section li.active a { + background: var(--terminal-glow); + color: var(--terminal-cyan); +} + +.sidebar-footer { + border-top-color: var(--border-color); +} + +.sidebar-footer a { + font-family: inherit; + color: var(--text-color); + opacity: 0.5; + font-size: 0.8rem; +} + +.theme-dark .sidebar-footer a { + color: var(--text-color); +} + +.sidebar-footer a:hover { + color: var(--terminal-cyan); + background: var(--terminal-dim); + opacity: 1; +} + +/* Search */ +.sidebar-search input { + background: rgba(0, 229, 255, 0.05); + border: 1px solid var(--border-color); + border-radius: 2px; + color: var(--text-color); + font-family: inherit; +} + +.theme-dark .sidebar-search input { + background: rgba(0, 229, 255, 0.05); + 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); +} + +.sidebar-search input::placeholder { + color: rgba(176, 190, 197, 0.3); +} + +/* ---- Toggle ---- */ +.sidebar-toggle { + opacity: 0.6; +} + +.theme-dark .sidebar-toggle { + background: none; +} + +.sidebar-toggle:hover { + opacity: 1; +} + +/* ---- Main Content ---- */ + +.main-content { + background-color: var(--bg-color); +} + +/* ---- Feed Items ---- */ + +.feed-item { + border-radius: 0; + padding: 1.25rem 0.5rem; + margin-top: 1.5rem; + border-bottom: 1px solid var(--border-color); +} + +.feed-item.selected { + background-color: var(--terminal-dim); + box-shadow: inset 3px 0 0 var(--terminal-cyan); + border-radius: 0; +} + +.theme-dark .feed-item.selected { + background-color: var(--terminal-dim); +} + +.item-title { + font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace; + font-size: 1.4rem; + line-height: 1.35; + color: var(--terminal-cyan); + 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; +} + +.dateline { + color: rgba(176, 190, 197, 0.35); + font-family: inherit; + font-size: 0.75em; + letter-spacing: 0.04em; +} + +.dateline a { + color: rgba(176, 190, 197, 0.35); +} + +.dateline a:hover { + color: var(--terminal-cyan); +} + +.item-description { + font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace; + font-size: 0.9rem; + line-height: 1.7; + color: var(--text-color); +} + +.item-description a { + color: var(--terminal-cyan); +} + +.item-description a:hover { + text-shadow: 0 0 8px rgba(0, 229, 255, 0.2); +} + +.item-description pre { + background: rgba(0, 229, 255, 0.04); + border: 1px solid var(--border-color); + border-radius: 2px; + font-family: inherit; +} + +/* Star */ +.star-btn.is-starred { + color: var(--terminal-amber); +} + +.star-btn.is-unstarred { + color: var(--text-color); + opacity: 0.15; +} + +/* Scrape */ +.scrape-btn { + font-family: inherit; + color: var(--terminal-cyan); + 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); +} + +/* ---- Buttons ---- */ + +button, +.button { + font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace; + border-radius: 2px; + border-color: var(--border-color); + background: transparent; + color: var(--text-color); + font-size: 0.72rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +button:hover, +.button:hover { + border-color: var(--terminal-cyan); + color: var(--terminal-cyan); + background: var(--terminal-dim); +} + +.theme-dark button, +.theme-dark .button { + background: transparent; + color: var(--text-color); + border-color: var(--border-color); +} + +.theme-dark button:hover, +.theme-dark .button:hover { + border-color: var(--terminal-cyan); + color: var(--terminal-cyan); + background: var(--terminal-dim); +} + +button.active, +.theme-dark button.active { + background: var(--terminal-cyan); + color: var(--bg-color); + border-color: var(--terminal-cyan); +} + +/* ---- Settings ---- */ + +.settings-view { + font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace; +} + +.settings-view h2 { + color: var(--terminal-cyan); + font-weight: 600; + letter-spacing: 0.05em; + font-size: 1.5rem; +} + +.settings-section h3 { + color: var(--text-color); + font-family: inherit; + font-size: 1rem; + letter-spacing: 0.04em; +} + +.settings-group label, +.data-group label { + color: var(--text-color); + font-family: inherit; + letter-spacing: 0.12em; +} + +.theme-dark .settings-view, +.theme-dark .settings-view h2, +.theme-dark .settings-view h3, +.theme-dark .settings-group label, +.theme-dark .data-group label { + color: var(--text-color) !important; +} + +/* Inputs */ +input[type="text"], +input[type="url"], +input[type="search"], +select { + font-family: inherit; + background: rgba(0, 229, 255, 0.04); + border: 1px solid var(--border-color); + border-radius: 2px; + color: var(--text-color); +} + +input:focus, +select:focus { + border-color: var(--terminal-cyan); + box-shadow: 0 0 8px rgba(0, 229, 255, 0.15); +} + +/* Feed list in settings */ +.manage-feed-list { + border-top-color: var(--border-color); +} + +.manage-feed-item { + border-bottom-color: var(--border-color); +} + +.feed-title { + font-family: inherit; + color: var(--text-color); +} + +.feed-url { + font-family: inherit; + color: var(--text-color); + opacity: 0.4; +} + +/* Delete button */ +.delete-feed-btn { + color: #ff5252 !important; + border-color: rgba(255, 82, 82, 0.3) !important; +} + +.delete-feed-btn:hover { + border-color: #ff5252 !important; + box-shadow: 0 0 6px rgba(255, 82, 82, 0.2) !important; + background: rgba(255, 82, 82, 0.08) !important; +} + +/* ---- Scrollbars ---- */ + +::-webkit-scrollbar { + width: 5px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: rgba(0, 229, 255, 0.15); + border-radius: 0; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(0, 229, 255, 0.3); +} + +/* ---- Backdrop ---- */ +.sidebar-backdrop { + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(2px); +} + +/* ---- Loading/Empty States ---- */ +.loading, .empty { + color: rgba(176, 190, 197, 0.4); + font-family: inherit; +} -- cgit v1.2.3 From 042c8ba30a6cbc1915fce8910de31af86253a044 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 18 Feb 2026 01:07:17 +0000 Subject: Refine themes, add sidebar controls, and theme docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- web/dist/v3/themes/terminal.css | 169 ++++++++++++++++++++++++---------------- 1 file changed, 102 insertions(+), 67 deletions(-) (limited to 'web/dist/v3/themes/terminal.css') diff --git a/web/dist/v3/themes/terminal.css b/web/dist/v3/themes/terminal.css index f497dfa..dd9c1b2 100644 --- a/web/dist/v3/themes/terminal.css +++ b/web/dist/v3/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; } -- cgit v1.2.3