Skip to content

Theme picker: per-dataset themes, font & gradient options, cursor/brightness fixes#123

Merged
vincentmakes merged 5 commits into
mainfrom
claude/enhance-theme-system-A7uIf
Apr 19, 2026
Merged

Theme picker: per-dataset themes, font & gradient options, cursor/brightness fixes#123
vincentmakes merged 5 commits into
mainfrom
claude/enhance-theme-system-A7uIf

Conversation

@vincentmakes

Copy link
Copy Markdown
Owner

Themes now live per-dataset in data.theme with a global "Apply to all saved
datasets" toggle (on by default). Loading a dataset applies its theme via
settings; a new PUT /api/theme writes the primary color, gradient endpoint,
and font family and — when the toggle is on — propagates them into every
saved dataset's snapshot in one transaction.

Picker UI adds a 7-font Google Fonts dropdown (each option rendered in its
own face), an optional custom gradient endpoint wheel, and 8 extra color
swatches (16 total). The CV content adopts the font via a new --font-family
CSS variable; admin chrome stays in Inter. The gradient endpoint drives a
new --gradient-end variable consumed by the profile-image and timeline-track
gradients. When no custom endpoint is set, --gradient-end resolves to the
previously-derived --accent value so existing installations look identical.

Two long-standing bugs are fixed: the cursor dot now moves to the current
color when the picker opens (previously stuck at the last click position),
and the brightness slider now updates the preview swatch, hex field, and
live theme in real time (previously only re-painted the wheel).

https://claude.ai/code/session_01QJ5ERQwRBc7rjsDNQQcCDi

claude added 5 commits April 19, 2026 09:02
…ghtness fixes

Themes now live per-dataset in data.theme with a global "Apply to all saved
datasets" toggle (on by default). Loading a dataset applies its theme via
settings; a new PUT /api/theme writes the primary color, gradient endpoint,
and font family and — when the toggle is on — propagates them into every
saved dataset's snapshot in one transaction.

Picker UI adds a 7-font Google Fonts dropdown (each option rendered in its
own face), an optional custom gradient endpoint wheel, and 8 extra color
swatches (16 total). The CV content adopts the font via a new --font-family
CSS variable; admin chrome stays in Inter. The gradient endpoint drives a
new --gradient-end variable consumed by the profile-image and timeline-track
gradients. When no custom endpoint is set, --gradient-end resolves to the
previously-derived --accent value so existing installations look identical.

Two long-standing bugs are fixed: the cursor dot now moves to the current
color when the picker opens (previously stuck at the last click position),
and the brightness slider now updates the preview swatch, hex field, and
live theme in real time (previously only re-painted the wheel).

https://claude.ai/code/session_01QJ5ERQwRBc7rjsDNQQcCDi
…agation

The previous gradient implementation had three issues:

1. The gradient start was hardcoded to --primary, so the gradient always
   moved with the primary color even when a custom end color was set. Add
   a --gradient-start CSS variable. The "Use custom gradient" toggle now
   reveals a Start/End tab switcher above a single second wheel that edits
   whichever endpoint is active, letting users decouple the gradient from
   the primary entirely. Default (toggle off) reproduces the prior
   primary→accent gradient exactly.

2. Gradient preset swatches carried both .gradient-preset and .color-preset
   classes, so the document-wide .color-preset listener for the primary
   wheel ALSO fired on gradient swatch clicks — which set the primary
   color to the same hex as the gradient end, making the gradient
   invisible. Scope the preset listeners by container ID (#primaryPresets,
   #gradientPresets) and drop the doubled class.

3. Apply-to-all=false applied the new theme only to the current dataset.
   Language siblings (variants in the same language_group) now also
   inherit the theme so a CV's visual identity stays consistent across
   languages. Apply-to-all=true continues to update every dataset.

Backend: PUT /api/theme accepts and persists gradientStart, dataset load
applies it to settings, and the sibling propagation runs in the same
transaction. Public site applies --gradient-start the same way as the
end. New backend test asserts sibling propagation; existing tests updated
for the gradientStart field.

No version bump per request.

https://claude.ai/code/session_01QJ5ERQwRBc7rjsDNQQcCDi
The header was previously left on its darker primary-dark → dark auto-derived
gradient regardless of the user's gradient customization. Now, when a custom
gradient is set, the header adopts the same start/end colors as the other
gradients (profile-image avatar, timeline track) so the theme feels
consistent across the whole page. When no custom gradient is set, the header
keeps its darker default aesthetic.

Implementation: add --header-gradient-start and --header-gradient-end CSS
variables with defaults that resolve to primary-dark and dark. The header
rule now uses these. applyThemeToCSS (admin) and applyColorToCSSPublic
(public) route to the custom colors when gradientStart/gradientEnd are set
on the theme, otherwise they explicitly write the auto-derived darker
values to preserve the existing look.

https://claude.ai/code/session_01QJ5ERQwRBc7rjsDNQQcCDi
Replace the eight single-color swatches in the gradient sub-picker with 12
curated gradient pairs, each rendered as its own linear-gradient. Clicking
a preset now sets both the start and end colors of the theme at once
(rather than only the currently-active endpoint), so the preset is a true
quick-select for a coherent gradient.

Each pair pairs differing start and end colors — mostly a darker variant
of the start hue (Ocean Deep, Emerald Fade, Forest, Crimson, Teal,
Graphite, Royal, Midnight, Rose) with a few complementary-hue shifts
(Aurora violet → indigo, Twilight cyan → indigo, Sunset orange → pink).
Laid out in a 4×3 grid to keep the gradient direction legible at thumbnail
size.

Single-endpoint tuning is still available via the wheel, brightness, and
hex input — the pair presets are just for quick-pick.

https://claude.ai/code/session_01QJ5ERQwRBc7rjsDNQQcCDi
The .profile-image had a 4px translucent white border and a
linear-gradient background. By default, background-clip is border-box,
so the gradient painted under the border too — leaving a thin rim of
the gradient's far-end color visible around the profile picture.

With the custom-gradient feature tying the profile-image gradient to
the same colors as the header, that rim became especially jarring: the
gradient resolved at the scale of the 110px circle, so its end-of-135°
color didn't match what the header shows at that spot. Result: a sharp
pink/red ring around the avatar on warm themes.

background-clip: padding-box confines the gradient to the area behind
the image. The translucent border now sits directly over the header,
picking up the same local color the header renders, so the edge blends
smoothly instead of banding.

https://claude.ai/code/session_01QJ5ERQwRBc7rjsDNQQcCDi
@vincentmakes vincentmakes merged commit 7c75941 into main Apr 19, 2026
3 checks passed
@vincentmakes vincentmakes deleted the claude/enhance-theme-system-A7uIf branch April 19, 2026 09:40
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