Skip to content

Phase 1: extended category colour roles (quaternary/quinary/senary) + fixed-colour picker - #177

Open
mapgie wants to merge 4 commits into
mainfrom
claude/logging-redesign-phase-1-f08e0o
Open

Phase 1: extended category colour roles (quaternary/quinary/senary) + fixed-colour picker#177
mapgie wants to merge 4 commits into
mainfrom
claude/logging-redesign-phase-1-f08e0o

Conversation

@mapgie

@mapgie mapgie commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Phase 1 of the logging & category-system redesign (build guide). Fully additive: no DB migration (colorToken is free-form), no screen removed, DB stays at v23.

Now merged with main's theme palette reconciliation (#176) and re-verified against the reconciled palettes.

What's in here

  • Color.kt: ExtendedRoles holder + deriveExtendedRoles(scheme), HSL house style (no HCT/TonalPalette dependency). Each extra role hue-rotates one of the scheme's own accents (primary +30, secondary -30, tertiary +45 degrees), keeping its saturation/lightness so the result sits in the scheme's accent band.
  • Theme.kt: LocalExtendedRoles static CompositionLocal provided by GoFloTheme around MaterialTheme, derived once per theme. Runs on the CUSTOM (buildCustomColorScheme) path too. colorSchemeFor's signature untouched.
  • CategoryAppearance.kt: QUATERNARY/QUINARY/SENARY added to CategoryColor; branches in both resolvers. The local is read only inside the new branches, so primary/secondary/tertiary/hex tokens resolve exactly as before, including outside GoFloTheme.
  • ManageCategoriesScreen.kt: colour picker reworked to the row-6 mock: "In-theme roles" is six pill chips (unselected = hairline + colour dot + label; selected = tonal fill + check + bold label), and the hex section is reframed as "Fixed colour / Stays put on theme change".
  • wcag_check_roles.py (new): mirrors the derivation in Python over every palette's accent trio in wcag_check.py's THEMES table (all 27 themes after themes: reconcile 12 palettes + WCAG mirror to the finalised colour spec #176) and asserts derived on-colour contrast >= 3:1.
  • wcag_check.py restored to plain text: it had been committed as a single base64-encoded line in 84624bc and was unrunnable by its canonical name; themes: reconcile 12 palettes + WCAG mirror to the finalised colour spec #176 re-encoded its update the same way, resolved in the merge by decoding main's updated content. The byte-identical plain-text workaround copy wcag_check_real.py is removed now that the canonical file runs. LESSONS.md entry added; consider wiring the checkers into CI so this can't recur.
  • Changelog fragment (minor), PLAN.md §7 progress log updated, subsystem map 03 drift note added.

Deviations from the phase guide's sketch (documented in PLAN.md §7)

  1. Greyscale fallback: hue-rotating a grey is a no-op, so both High Contrast themes would have produced three roles identical to the base accents. Accents with saturation < 0.10 instead shift lightness toward mid-tone with distinct magnitudes (0.25/0.45/0.65), giving three clearly distinct greys per High Contrast theme.
  2. On-colour selection: the sketch's fixed 0.35 luminance threshold has a band (luminance 0.30 to 0.35) where it picks white and white fails 3:1. On-colours instead pick near-black vs white by whichever contrasts more, which guarantees at least ~4.1:1 on any background.

Acceptance criteria (phase-1-color-roles.md)

  • A category set to each of quaternary/quinary/senary renders that colour and re-themes when the palette changes — tokens resolve from LocalExtendedRoles, which is rebuilt from the active scheme on every theme change (verified by inspection; spot-check script exercises all light + dark palettes)
  • A category set to a Fixed colour does not change on theme switch — hex path untouched
  • Derived on-colours pass contrast in all 12 palettes — wcag_check_roles.py green: 81 roles across all 27 themes (12 families light+dark, High Contrast x2, Blue & Orange), worst ratio 4.21:1 on the reconciled palettes
  • wcag_check.py and a11y_check.py both green (405 pairs / 27 themes post-themes: reconcile 12 palettes + WCAG mirror to the finalised colour spec #176; 95 files clean)
  • Picker chips carry Role.RadioButton, are >= 48dp tall, and selection is not colour-only (tonal fill + check mark + bold label)

Feature-preservation checklist

  • Existing primary/secondary/tertiary/hex tokens resolve exactly as before — old branches and the hex fallback are unchanged; isCustomColorToken's length-8 guard already excludes the new 7-10 char keys
  • Calendar dots, DayLogSheet bubbles, Stats colour usage unchanged — calendar reads MaterialTheme.colorScheme directly; the other 7 consumers of toCategoryColor only gain new branches; widgets never call the Compose resolvers
  • CUSTOM theme path still works — deriveExtendedRoles runs on whatever scheme GoFloTheme resolved, including buildCustomColorScheme output

CI is the build check for this environment; both Python checkers were run locally and pass.


🤖 Generated with Claude Code

https://claude.ai/code/session_01TCyUnDhCFcXP9yr3FuywuV

claude added 2 commits August 22, 2026 18:51
The script was committed as a single base64-encoded line in 84624bc,
making it unrunnable. Decoded content verified: 345 pairs across 23
themes, all passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TCyUnDhCFcXP9yr3FuywuV
…xed-colour framing

Phase 1 of the logging redesign (docs/design/logging-redesign):

- Color.kt: ExtendedRoles + deriveExtendedRoles(scheme), HSL hue rotation
  of the scheme's own accents (+30/-30/+45 degrees). Near-greyscale
  accents (High Contrast themes) shift lightness instead, since hue
  rotation of grey is a no-op. On-colours pick near-black or white by
  max contrast, guaranteeing at least ~4.1:1 on any derived role.
- Theme.kt: LocalExtendedRoles CompositionLocal provided by GoFloTheme,
  derived once per theme; covers the CUSTOM scheme path too.
- CategoryAppearance.kt: QUATERNARY/QUINARY/SENARY tokens and resolver
  branches; the local is read only inside the new branches so existing
  tokens resolve unchanged.
- ManageCategoriesScreen.kt: colour picker reworked to the row-6 mock:
  six in-theme role pill chips (Role.RadioButton, 48dp min, selection
  shown by fill + check, never colour alone) and a relabelled fixed
  colour section that stays put on theme change.
- wcag_check_roles.py: mirrors the derivation over every palette
  (including Dragon Fire and Midnight Neon, absent from wcag_check.py's
  tables) and asserts on-colour contrast >= 3:1. Worst ratio 4.24:1.
- Changelog fragment, PLAN.md progress log, subsystem map 03 drift note.

No DB change; colorToken is free-form so the new tokens need no
migration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TCyUnDhCFcXP9yr3FuywuV
@mapgie
mapgie marked this pull request as ready for review August 22, 2026 19:35
claude added 2 commits August 23, 2026 18:53
Conflict in wcag_check.py: main re-encoded the updated checker as a
single base64 line (the same mangling this branch fixes). Resolved by
taking main's updated content decoded to plain text. Also removed
wcag_check_real.py, a byte-identical duplicate kept as a workaround
while the canonical file was unrunnable, and dropped the roles
spot-check's extra accent table now that the THEMES table covers all
27 themes. Re-verified against the reconciled palettes: 405 palette
pairs and 81 derived roles all pass (worst 4.21:1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TCyUnDhCFcXP9yr3FuywuV
…drift note

The reconciled wcag_check.py THEMES table now carries Dragon Fire and
Midnight Neon, so wcag_check_roles.py no longer needs its own copies of
their accent trios (which were stale after the reconciliation anyway).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TCyUnDhCFcXP9yr3FuywuV
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