Theme picker: per-dataset themes, font & gradient options, cursor/brightness fixes#123
Merged
Merged
Conversation
…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
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.
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