# 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 `` tag: ```html ``` 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 |