Skip to content

Fix custom theme dark mode and rebuild the custom colour model#24

Draft
mapgie wants to merge 2 commits into
mainfrom
claude/colour-theme-settings-analysis-xattai
Draft

Fix custom theme dark mode and rebuild the custom colour model#24
mapgie wants to merge 2 commits into
mainfrom
claude/colour-theme-settings-analysis-xattai

Conversation

@mapgie

@mapgie mapgie commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

The template's custom theme had four compounding problems that made it a poor plug-and-play base for the other apps:

  • MyAppTheme called buildCustomColorScheme(..., isDark = false) unconditionally, so custom themes were permanently light; the builder's dark branch was dead code.
  • Tapping Light/Dark/Auto while Custom was active fell back to the Teal palette, silently deselecting the custom theme.
  • The custom model was hue-only (fixed saturation/lightness), and preview swatches used different S/L constants than the builder, so the picked colours never matched the applied theme.
  • Backgrounds were derived from the primary hue with no way to change them directly.

Changes

Theme engine (Color.kt, Theme.kt)

  • New customThemeMode preference (LIGHT/DARK/SYSTEM); the custom scheme is built for the right mode, and the status-bar icon logic now covers all system-following palettes and Custom.
  • buildCustomColorScheme accepts exact ARGBs per role plus a per-mode background override. Picked colours are applied verbatim; on-colours are chosen by relative luminance so text stays legible on any pick; containers/neutrals derive from the resolved colours. Legacy hue values remain as fallbacks so existing installs and old saved profiles keep working.
  • New resolveCustomRoleColor() helper is shared by the builder, picker previews, and saved-theme swatches, so previews show exactly what the theme applies.

Picker UI (CompactThemePicker.kt, new ColorPickerDialog.kt)

  • Each role (primary/secondary/tertiary) opens a full colour picker dialog: HSV saturation/brightness square, hue bar, and hex entry.
  • New "Background (light)" and "Background (dark)" rows with an Auto option that restores derivation from the primary colour.
  • The mode row drives the custom theme's own mode while Custom is selected instead of switching away from it. The WCAG toggle is hidden for Custom (it only affects the pre-built palettes).

Saved themes (CustomColorTheme, AppDatabase, SavedThemesList.kt, SettingsViewModel.kt)

  • Profiles persist the exact colours, background overrides, and mode (Room v1 → v2, additive columns with defaults; no destructive migration) and restore them faithfully on load. The mode column, previously always written "LIGHT" and never read, is now honoured.
  • Tapping a saved-theme row loads it (previously a no-op); swatches show the saved colours.

Docs

  • CLAUDE.md and the CHANGELOG.md policy header still described the old manual version-bump flow; both now match the changelog-fragment flow that changelog-check.yml actually enforces.
  • Added a LESSONS.md entry about theme-builder parameters and preview/builder drift.

Changelog fragment: changelog/unreleased/custom-theme-overhaul.json (minor).

a11y_check.py passes (27 files, clean).

🤖 Generated with Claude Code

https://claude.ai/code/session_01YEGQ585q9wtogd9G1v7Ef1


Generated by Claude Code

The custom theme was permanently light: MyAppTheme called
buildCustomColorScheme with a hardcoded isDark = false, and switching
Light/Dark/Auto while Custom was active silently jumped to the Teal
palette. The picker also only offered hue sliders with fixed
saturation/lightness, previews used different S/L constants than the
builder, and backgrounds were not user-controllable.

- Custom themes now honour a Light/Dark/System mode of their own
  (customThemeMode preference); the mode row drives it while Custom is
  active instead of deselecting the custom theme.
- Each colour role (primary/secondary/tertiary) opens a full colour
  picker dialog (HSV square, hue bar, hex entry) and the exact picked
  ARGB is applied verbatim; on-colours are chosen by relative luminance
  so text stays legible on any pick. Legacy hue values remain as
  fallbacks for existing installs.
- Light and dark background colours can be set directly, with an Auto
  option deriving them from the primary colour as before.
- Previews and saved-theme swatches resolve through the same helper the
  scheme builder uses, so what you pick is what you get.
- Saved themes persist the exact colours and mode (Room v1 -> v2
  migration, additive columns), restore them on load, and rows load on
  tap.
- Refresh stale versioning docs (CLAUDE.md, CHANGELOG.md policy) to
  match the changelog-fragment flow enforced by CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YEGQ585q9wtogd9G1v7Ef1
CompactThemePicker's mode row uses Modifier.height(IntrinsicSize.Min);
the layout.height import was dropped when the custom section was
rewritten, failing compileDebugKotlin. Also drop the now-unused
semantics contentDescription import.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YEGQ585q9wtogd9G1v7Ef1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants