Skip to content

Commit f479f39

Browse files
committed
Merge develop into main: release v1.6.1
2 parents d0080b2 + 28063b6 commit f479f39

21 files changed

Lines changed: 1643 additions & 252 deletions

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## [1.6.1] - 2026-06-08
4+
5+
### Added
6+
7+
- Black & white (grayscale) filter with G hotkey (#221)
8+
- "Always show OCR" toggle with T shortcut (#220, @jakobnator)
9+
10+
### Fixed
11+
12+
- Firefox now requests storage upfront so imports succeed (#223)
13+
- Achievement badges stay consistent across themes
14+
315
## [1.6.0] - 2026-05-29
416

517
### Added

docs/superpowers/plans/2026-05-29-theme-system.md

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Tailwind v4 compiles `bg-gray-950` → `background-color: var(--color-gray-950)`
3939
## Task 1: Color math helpers
4040

4141
**Files:**
42+
4243
- Create: `src/lib/settings/color.ts`
4344
- Test: `src/lib/settings/color.test.ts`
4445

@@ -113,12 +114,7 @@ export function parseHex(hex: string): RGB {
113114
}
114115

115116
export function toHex(rgb: RGB): string {
116-
return (
117-
'#' +
118-
rgb
119-
.map((c) => clampChannel(c).toString(16).padStart(2, '0'))
120-
.join('')
121-
);
117+
return '#' + rgb.map((c) => clampChannel(c).toString(16).padStart(2, '0')).join('');
122118
}
123119

124120
/** Linear blend: t=0 returns a, t=1 returns b. */
@@ -151,6 +147,7 @@ git commit -m "feat(theme): add hex color math helpers"
151147
## Task 2: Theme model, presets, and resolution
152148

153149
**Files:**
150+
154151
- Create: `src/lib/settings/theme.ts`
155152
- Test: `src/lib/settings/theme.test.ts`
156153

@@ -418,6 +415,7 @@ git commit -m "feat(theme): add theme presets, token derivation, and active-them
418415
## Task 3: Settings type, defaults, migration, and barrel export
419416

420417
**Files:**
418+
421419
- Modify: `src/lib/settings/settings.ts` (type ~133, defaults ~251, migration ~426, end of file)
422420
- Test: `src/lib/settings/settings.test.ts` (create)
423421

@@ -426,9 +424,9 @@ git commit -m "feat(theme): add theme presets, token derivation, and active-them
426424
In `src/lib/settings/settings.ts`, in the `Settings` type, immediately after the `backgroundColor: string;` line (currently line 133), add:
427425

428426
```ts
429-
backgroundColor: string;
430-
theme: string; // preset id ('dark' | 'eink' | 'paper' | 'sepia' | 'nord' | 'custom')
431-
customTheme: import('./theme').CustomTheme; // edited by the Custom theme mode
427+
backgroundColor: string;
428+
theme: string; // preset id ('dark' | 'eink' | 'paper' | 'sepia' | 'nord' | 'custom')
429+
customTheme: import('./theme').CustomTheme; // edited by the Custom theme mode
432430
```
433431

434432
- [ ] **Step 2: Add the defaults**
@@ -456,26 +454,26 @@ In `defaultSettings`, immediately after the `backgroundColor: '#030712',` line (
456454
In `migrateProfiles`, after the `migratedProfile.catalogSettings = { ... }` block and before the `// Add timestamp if missing` comment (currently ~line 430), add:
457455

458456
```ts
459-
// Theme migration. The `...defaultSettings, ...profile` spread above already
460-
// applies `theme`/`customTheme` defaults or carries existing values forward.
461-
migratedProfile.customTheme = {
462-
...defaultSettings.customTheme,
463-
...(profile.customTheme || {})
464-
};
465-
// Legacy: a profile predating themes that deliberately changed the reader
466-
// background keeps its look via a seeded Custom theme.
467-
if (
468-
profile.theme === undefined &&
469-
typeof profile.backgroundColor === 'string' &&
470-
profile.backgroundColor !== defaultSettings.backgroundColor
471-
) {
472-
migratedProfile.theme = 'custom';
473-
migratedProfile.customTheme = {
474-
...migratedProfile.customTheme,
475-
base: 'dark',
476-
background: profile.backgroundColor
477-
};
478-
}
457+
// Theme migration. The `...defaultSettings, ...profile` spread above already
458+
// applies `theme`/`customTheme` defaults or carries existing values forward.
459+
migratedProfile.customTheme = {
460+
...defaultSettings.customTheme,
461+
...(profile.customTheme || {})
462+
};
463+
// Legacy: a profile predating themes that deliberately changed the reader
464+
// background keeps its look via a seeded Custom theme.
465+
if (
466+
profile.theme === undefined &&
467+
typeof profile.backgroundColor === 'string' &&
468+
profile.backgroundColor !== defaultSettings.backgroundColor
469+
) {
470+
migratedProfile.theme = 'custom';
471+
migratedProfile.customTheme = {
472+
...migratedProfile.customTheme,
473+
base: 'dark',
474+
background: profile.backgroundColor
475+
};
476+
}
479477
```
480478

481479
- [ ] **Step 4: Import theme helpers and define the active-theme store**
@@ -571,6 +569,7 @@ git commit -m "feat(theme): store theme per-profile with backgroundColor migrati
571569
## Task 4: ThemeController and global CSS wiring
572570

573571
**Files:**
572+
574573
- Create: `src/lib/components/ThemeController.svelte`
575574
- Modify: `src/app.css` (after the `@theme { ... }` block)
576575
- Modify: `src/app.html` (`<body>` class, line 39)
@@ -650,13 +649,13 @@ body {
650649
In `src/app.html`, change the `<body>` tag (line 39) from:
651650

652651
```html
653-
<body data-sveltekit-preload-data="hover" class="bg-white dark:bg-gray-950 dark:text-white">
652+
<body data-sveltekit-preload-data="hover" class="bg-white dark:bg-gray-950 dark:text-white"></body>
654653
```
655654

656655
to:
657656

658657
```html
659-
<body data-sveltekit-preload-data="hover" class="dark:text-white">
658+
<body data-sveltekit-preload-data="hover" class="dark:text-white"></body>
660659
```
661660

662661
(The `bg-white dark:bg-gray-950` classes are removed because `body { background-color: var(--app-bg) }` now owns the canvas color across all themes.)
@@ -668,8 +667,8 @@ In `src/routes/+layout.svelte`:
668667
Add the import alongside the other component imports (after the `NightModeFilter` import on line 18):
669668

670669
```ts
671-
import NightModeFilter from '$lib/components/NightModeFilter.svelte';
672-
import ThemeController from '$lib/components/ThemeController.svelte';
670+
import NightModeFilter from '$lib/components/NightModeFilter.svelte';
671+
import ThemeController from '$lib/components/ThemeController.svelte';
673672
```
674673

675674
Change the main content wrapper (line 117) from:
@@ -687,13 +686,14 @@ to:
687686
Add the controller next to `<NightModeFilter />` (line 123):
688687

689688
```svelte
690-
<NightModeFilter />
691-
<ThemeController />
689+
<NightModeFilter />
690+
<ThemeController />
692691
```
693692

694693
- [ ] **Step 5: Manual verification**
695694

696695
Run: `npm run dev`
696+
697697
- App still loads in Dark (default) with no visible change vs. before.
698698
- In the browser console: `document.documentElement.style.setProperty('--app-bg', '#ffffff'); document.documentElement.classList.remove('dark')` → canvas turns white, text/components switch to light styling. Re-add `dark` and reset to confirm reversibility.
699699

@@ -709,6 +709,7 @@ git commit -m "feat(theme): apply themes via ThemeController and canvas backgrou
709709
## Task 5: Reader viewport follows the theme
710710

711711
**Files:**
712+
712713
- Modify: `src/lib/components/Reader/Reader.svelte:1386`
713714
- Modify: `src/lib/components/Reader/VerticalScrollReader.svelte:573`
714715
- Modify: `src/lib/components/Reader/HorizontalScrollReader.svelte:635`
@@ -732,27 +733,27 @@ to:
732733
Change line 573 from:
733734

734735
```svelte
735-
style:background-color={$settings.backgroundColor}
736+
style:background-color={$settings.backgroundColor}
736737
```
737738

738739
to:
739740

740741
```svelte
741-
style:background-color="var(--reader-bg)"
742+
style:background-color="var(--reader-bg)"
742743
```
743744

744745
- [ ] **Step 3: HorizontalScrollReader.svelte**
745746

746747
Change line 635 from:
747748

748749
```svelte
749-
style:background-color={$settings.backgroundColor}
750+
style:background-color={$settings.backgroundColor}
750751
```
751752

752753
to:
753754

754755
```svelte
755-
style:background-color="var(--reader-bg)"
756+
style:background-color="var(--reader-bg)"
756757
```
757758

758759
- [ ] **Step 4: Verify**
@@ -771,25 +772,26 @@ git commit -m "feat(theme): drive reader viewport background from theme"
771772
## Task 6: Remove the migrated background-color control
772773

773774
**Files:**
775+
774776
- Modify: `src/lib/components/Settings/Reader/ReaderSelects.svelte` (fn ~52, control ~95-96)
775777

776778
- [ ] **Step 1: Remove the control markup**
777779

778780
Delete these two lines (currently 95-96):
779781

780782
```svelte
781-
<Label class="text-gray-900 dark:text-white">Background color:</Label>
782-
<Input type="color" onchange={onBackgroundColor} value={$settings.backgroundColor} />
783+
<Label class="text-gray-900 dark:text-white">Background color:</Label>
784+
<Input type="color" onchange={onBackgroundColor} value={$settings.backgroundColor} />
783785
```
784786

785787
- [ ] **Step 2: Remove the now-unused handler**
786788

787789
Delete the function (currently lines 52-54):
788790

789791
```ts
790-
function onBackgroundColor(event: Event) {
791-
updateSetting('backgroundColor', (event.target as HTMLInputElement).value);
792-
}
792+
function onBackgroundColor(event: Event) {
793+
updateSetting('backgroundColor', (event.target as HTMLInputElement).value);
794+
}
793795
```
794796

795797
- [ ] **Step 3: Check for unused imports**
@@ -809,6 +811,7 @@ git commit -m "feat(theme): drop standalone reader background-color control (mig
809811
## Task 7: Appearance settings UI
810812

811813
**Files:**
814+
812815
- Create: `src/lib/components/Settings/AppearanceSettings.svelte`
813816
- Modify: `src/lib/components/Settings/Settings.svelte` (import + mount in the Accordion)
814817

@@ -928,16 +931,16 @@ git commit -m "feat(theme): drop standalone reader background-color control (mig
928931
In `src/lib/components/Settings/Settings.svelte`, add the import after the `QuickAccess` import:
929932

930933
```ts
931-
import QuickAccess from './QuickAccess.svelte';
932-
import AppearanceSettings from './AppearanceSettings.svelte';
934+
import QuickAccess from './QuickAccess.svelte';
935+
import AppearanceSettings from './AppearanceSettings.svelte';
933936
```
934937

935938
Add the section to the `<Accordion>` after `<CatalogSettings />` and before `<Stats />`:
936939

937940
```svelte
938-
<CatalogSettings />
939-
<AppearanceSettings />
940-
<Stats />
941+
<CatalogSettings />
942+
<AppearanceSettings />
943+
<Stats />
941944
```
942945

943946
- [ ] **Step 3: Type-check**
@@ -948,6 +951,7 @@ Expected: No errors in `AppearanceSettings.svelte`.
948951
- [ ] **Step 4: Manual verification (the core of this feature)**
949952

950953
Run: `npm run dev`. Open Settings → Appearance:
954+
951955
- Click each preset (Dark, E-ink, Paper, Sepia, Nord) → entire UI re-colors live: navbar, drawer, accordion, buttons, toggles, range sliders, the catalog, and the reader viewport.
952956
- Click **Custom…** → editor appears seeded from the active preset; changing each of the six swatches and the base toggle updates the UI live.
953957
- Switch profiles → theme follows the profile.
@@ -973,7 +977,7 @@ Light themes expose components that hardcode light-on-dark colors with **no ligh
973977
Run:
974978

975979
```bash
976-
grep -rn "text-white" src/lib/components src/routes | grep -v "dark:text-white" | grep -v "bg-primary\|bg-blue\|bg-green\|bg-red\|hover:"
980+
grep -rn "text-white" src/lib/components src/routes | grep -v "dark:text-white" | grep -v "bg-primary\|bg-blue\|bg-green\|bg-red\|hover:"
977981
```
978982

979983
and
@@ -1008,6 +1012,7 @@ git commit -m "fix(theme): add light-mode color counterparts where missing"
10081012
## Task 9: Full verification and changelog
10091013

10101014
**Files:**
1015+
10111016
- Modify: changelog file (check repo for `CHANGELOG.md` or the pattern used by recent releases, e.g. commit `1a50b3d`).
10121017

10131018
- [ ] **Step 1: Test suite**
@@ -1033,6 +1038,7 @@ Expected: Builds successfully.
10331038
- [ ] **Step 5: Full manual matrix**
10341039

10351040
`npm run preview`, then for each preset (Dark, E-ink, Paper, Sepia, Nord) and one Custom config, with night mode both OFF and ON:
1041+
10361042
- Catalog grid + list, series view, reader (page + continuous scroll modes), settings drawer, and at least one modal (e.g. Volume Editor) — confirm legible, correctly themed, buttons clickable.
10371043
- Confirm a legacy profile with a custom `backgroundColor` (simulate by editing localStorage `profiles` to add `backgroundColor: "#123456"` and removing `theme`, then reload) migrates to a Custom theme preserving that background.
10381044

0 commit comments

Comments
 (0)