From a light/dark/system review. The picker and the preferredColorScheme wiring already exist;
these are the gaps around them. #79 is the separate persistence bug and should land first.
Verified working today
SettingsView picker → user.theme → RootView.swift:19 .preferredColorScheme. ILColor ships a
full dual palette. AccentColor.colorset has a dark variant. Info.plist has no
UIUserInterfaceStyle lock and UILaunchScreen is empty, so both appearances are permitted. The
masthead teal adapts correctly (0x184860 → 0x0C2C3A), confirmed on device.
Gaps
1. The preference is server-only
RootView reads authState.user?.theme, and user is nil until GET /api/user returns. So:
- the login screen always renders in the OS appearance, ignoring the saved theme;
- a cold launch flashes the OS appearance and then snaps to the preference;
- an offline cold start loses the preference entirely.
Mirror the theme to UserDefaults and read it in RootView as the startup value, with the server
value as the authority once it arrives. It is a display preference, not a secret — the
Keychain-only rule does not apply.
2. Logo.imageset has no dark variant
The logo has a baked-in cream #F4EEE2 backing square that floats as a bright block on a dark
background. Visible at LoginView.swift:26 and FeedView.swift:348. Add a dark-appearance image
to the imageset (or ship it with a transparent background).
3. Links render iOS system blue, not ILColor.link
Visible on the login screen in both appearances ("Forgot password?", "Create account"). No
global .tint() is set on RootView.
4. Dark mode is Apple's dark, not InterlinedList's
ILColor.background / .surface / .surface2 appear in ~12 places across 54 view files, and only
MainTabView.swift:31 sets a screen background. Everything else uses system materials, so dark mode
renders as generic iOS black/grey and the Strata dark palette (0x121317 / 0x17191F) is
effectively unused. This is the bulk of the work and is design-dependent — worth splitting out if
1–3 are wanted sooner.
5. Unverified
- Whether the app-level deep-link sheet (
InterlinedListApp.swift:48) inherits the override — the
.sheet modifier sits outside where preferredColorScheme is set.
- Feed / tab bar / lists / documents in dark. Needs a keychain-seeded logged-in run.
Acceptance criteria
Files: Views/RootView.swift, Views/SettingsView.swift, Assets.xcassets/Logo.imageset,
Services/ILColor.swift adoption across Views/.
From a light/dark/system review. The picker and the
preferredColorSchemewiring already exist;these are the gaps around them. #79 is the separate persistence bug and should land first.
Verified working today
SettingsViewpicker →user.theme→RootView.swift:19.preferredColorScheme.ILColorships afull dual palette.
AccentColor.colorsethas a dark variant.Info.plisthas noUIUserInterfaceStylelock andUILaunchScreenis empty, so both appearances are permitted. Themasthead teal adapts correctly (
0x184860→0x0C2C3A), confirmed on device.Gaps
1. The preference is server-only
RootViewreadsauthState.user?.theme, anduseris nil untilGET /api/userreturns. So:Mirror the theme to
UserDefaultsand read it inRootViewas the startup value, with the servervalue as the authority once it arrives. It is a display preference, not a secret — the
Keychain-only rule does not apply.
2.
Logo.imagesethas no dark variantThe logo has a baked-in cream
#F4EEE2backing square that floats as a bright block on a darkbackground. Visible at
LoginView.swift:26andFeedView.swift:348. Add a dark-appearance imageto the imageset (or ship it with a transparent background).
3. Links render iOS system blue, not
ILColor.linkVisible on the login screen in both appearances ("Forgot password?", "Create account"). No
global
.tint()is set onRootView.4. Dark mode is Apple's dark, not InterlinedList's
ILColor.background/.surface/.surface2appear in ~12 places across 54 view files, and onlyMainTabView.swift:31sets a screen background. Everything else uses system materials, so dark moderenders as generic iOS black/grey and the Strata dark palette (
0x121317/0x17191F) iseffectively unused. This is the bulk of the work and is design-dependent — worth splitting out if
1–3 are wanted sooner.
5. Unverified
InterlinedListApp.swift:48) inherits the override — the.sheetmodifier sits outside wherepreferredColorSchemeis set.Acceptance criteria
ILColor.link.Files:
Views/RootView.swift,Views/SettingsView.swift,Assets.xcassets/Logo.imageset,Services/ILColor.swiftadoption acrossViews/.