aboutsummaryrefslogtreecommitdiffstats
path: root/frontend-vanilla/src
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-02-18 01:07:17 +0000
committerClaude <noreply@anthropic.com>2026-02-18 01:07:17 +0000
commit042c8ba30a6cbc1915fce8910de31af86253a044 (patch)
tree210b3a649b3921e4e7f23793e5a8485c6cd4058a /frontend-vanilla/src
parent18a85a30f4282b5d07528eb8e1dd8ff7617190d2 (diff)
downloadneko-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/src')
-rw-r--r--frontend-vanilla/src/main.ts28
-rw-r--r--frontend-vanilla/src/style.css41
2 files changed, 69 insertions, 0 deletions
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%;