grade calendar, brain-graph and CoS state colors for the active theme - #4801
Merged
Conversation
…theme (#4760) Calendar event chips painted the Google subcalendar color verbatim as text over a low-alpha wash of the same color. Google's palette includes several pale entries and the color is external API data, so on the day themes a pale subcalendar landed around 1.1:1 against a white card — invisible. Everything that renders a data-supplied color as TEXT now goes through the existing `chipColors()` helper, which keeps the hue and moves only the lightness until it clears WCAG AA on the active theme mode: - Month/Week/Day event chips and timed blocks, via one shared `eventChipStyle()` in `calendar/calendarUtils.js` - Chronotype zone labels (the amber zone was a live ~2.1:1 AA failure); the band fills stay the raw zone color, since the tint is the signal - Brain-graph type badges, whose `BRAIN_TYPE_HEX` palette is tuned for the near-black canvas but is also rendered on theme-following panels - The CoS terminal panel's ASCII art — the #1909 follow-up, where `thinking`'s amber sat at ~2.1:1 on a day theme's terminal surface Two follow-on fixes fell out of the same pass. The timed-event titles carried a hardcoded `text-white`, which day mode remaps with `!important` and would therefore have overridden the graded color outright; they now inherit it. And the colorless-event fallback was `var(--port-accent, #3b82f6)` — `--port-accent` is a bare RGB triple, so that resolved to `59 130 246`, not a color, and the browser dropped the declaration; it is now wrapped in `rgb()`. Two sites listed on the issue are deliberately untouched: ScoreSheet's ink is already theme CSS variables, and RoundSheetMusic's swatch is an aria-hidden legend key for a canvas whose background is explicitly non-theme-following.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Calendar event chips rendered the Google Calendar subcalendar color verbatim as text over a low-alpha wash of the same color. Google's palette includes several pale entries and the color is external API data, so on the day themes a pale subcalendar landed around 1.1:1 against a white card — invisible. Every site that paints a data-supplied color as text now runs it through the existing
chipColors(color, mode)helper (client/src/lib/chipContrast.js), which keeps the hue and moves only the lightness until it clears WCAG AA on the active theme mode.eventChipStyle()incalendar/calendarUtils.js(five call sites, one fallback).BRAIN_TYPE_HEXis tuned for the near-black canvas but is also rendered on the theme-following tooltip and detail panels.thinking's amber sat at ~2.1:1 on a day theme's terminal surface. Every theme's terminal surface is at least as favorable as the reference surfacechipContrastgrades against, so the AA guarantee carries.Two follow-on fixes fell out of the same pass:
text-white.index.cssremaps that with!importanton day mode, and author!importantbeats an inline declaration — so it would have overridden the graded color outright. They now inherit it.var(--port-accent, #3b82f6).--port-accentis a bare RGB triple, so that resolved to the literal59 130 246— not a color — and the browser dropped the declaration, leaving the text inherited rather than accent. It is nowrgb(var(--port-accent, 59 130 246)).Two sites listed on the issue are deliberately untouched, with the reasoning recorded on #4760:
songs/ScoreSheet.jsx— itsinkis already theme CSS variables (rgb(var(--port-text)),rgb(var(--port-success)), …), not a fixed palette.parseColorcan't resolve avar()anyway, so grading would be a no-op.songs/RoundSheetMusic.jsx— the swatch isaria-hiddendecoration beside a real checkbox and text label, and it is a legend key for the piano roll, whose canvas background is explicitly non-theme-following. Grading it would desync the legend from what it labels.meatspace/post/PostCognitiveDrillRunner.jsx(the Stroop stimulus) is untouched, as the issue requires.Test plan
client/src/components/calendar/calendarUtils.test.js—eventChipStylegrading per mode, AA against the chip's own backdrop, and the accent-fallback shape (regression guard on thevar(--port-accent, #hex)idiom).client/src/components/calendar/calendarEventChips.test.jsx— one suite over Month/Week/Day: the rendered inlinecolorequalschipColors(color, mode).colorfor the ACTIVE mode and differs from the other mode's (compared viaparseColor, since jsdom normalizes inline hex torgb()), the colorless path falls back to the accent chip, and no element ships a graded inline style alongside an!importanttheme utility — including a check that the element owning the title text carries notext-white/text-gray-*. Plus the chronotype zone labels, and that the band fill keeps its raw color.client/src/components/cos/TerminalCoSPanel.test.jsx— per-mode grading of the ASCII art, and AA for all seven agent states in both modes.client/src/components/brain/tabs/BrainGraph.test.jsx— per-mode grading of the detail-panel type badge, reached through the existing search → focus → connection path.text-whiteto the DayView title fails the new guard, so it isn't vacuous.cd client && npm test— 729 files / 9315 tests green.npm run lintclean. No server-side changes.Closes #4760