feat(theme): add Glass design language - #3130
Open
afonsojramos wants to merge 32 commits into
Open
Conversation
Drop `transparent: true` (it makes behind-window vibrancy render near-opaque over the desktop) and switch the material to `popover`; keep `visualEffectState: active` so the menubar popup stays translucent while unfocused. Sync `nativeTheme.themeSource` with the color mode via a new SET_NATIVE_THEME IPC so dark Glass gets a dark material instead of light text on a light frost. Clear the Primer `[data-color-mode]` wrapper's opaque background so the material shows through the whole window. Also removes the Increase contrast setting, which forced Glass to a solid surface and whose useAppearance/theme wiring is intertwined with the changes above.
Under translucency: row action buttons become bare icons (no hover band or button fill) with the row text fading out under them on hover so it never collides; the scrollbar track goes transparent; and the glass tints are lowered a step so more of the material shows through.
…witch applyWindowVibrancy only cleared the window background when disabling, so switching Classic (which paints an opaque backdrop) to Glass left that backdrop in place and blocked the vibrancy material from sampling the desktop. Clear it on enable too; `#00000000` works without a transparent window because the vibrancy view provides the translucency. Adds regression tests for both toggle sides.
Handle the setNativeTheme IPC rejection (log via rendererLogError) instead of leaving an unhandled promise, matching the setWindowVibrancy call, and note that the sync is intentionally not macOS-gated. Adds coverage for the Glass-clamped path (Glass + DARK_DIMMED still syncs 'dark').
setchy
requested changes
Jul 31, 2026
setchy
left a comment
Member
There was a problem hiding this comment.
Marking while I have time to review.
setchy
reviewed
Aug 1, 2026
setchy
reviewed
Aug 1, 2026
setchy
reviewed
Aug 1, 2026
Member
|
Super sharp enhancement, @afonsojramos. I love that we're able to keep the design components as Primer and apply new theme/style overrides. Nice work. Left a few inline comments for my own curiosity |
setchy
reviewed
Aug 1, 2026
…and the OS Restore the Increase contrast setting (shown for Classic only) and additionally honour the OS "Increase contrast" accessibility preference via `prefers-contrast: more`. Either one selects Primer's `*_high_contrast` schemes for Classic; Glass takes its solid fallback instead, and that same preference now also withholds Glass's vibrancy.
The inert zoom/interval/volume/shortcut value displays are self-explanatory from
`pointer-events-none` and `tabIndex={-1}`, so the repeated comment was just noise.
Member
|
Was doing more manual testing this morning - the notification type icon colors appear broken [always black] |
Member
Member
Author
Member
Yup, fairly certain - try toggling the theme - looks like several other components like the footer buttons also loose their styling when set to Screen.Recording.2026-08-04.at.5.05.37.PM.mov |
Member
The Glass tints, borders and control fills were keyed off `[data-color-mode='light'|'dark']`, but the System theme renders `data-color-mode="auto"`, so neither matched and every token resolved to nothing: form controls lost their fill and tooltips fell back to Primer's solid styling. Define them once with `light-dark()`, which resolves against the wrapper's `color-scheme` and therefore follows the OS under `auto`.
Primer declares its `--fgColor-*` tokens on the `[data-color-mode]` wrapper, not the root, so the `--gitify-icon-*` / `--gitify-link` / `--gitify-footer` indirections built on them were invalid at `:root` and every status icon fell back to inherited black — in Classic as well as Glass. Declare them on the wrapper instead, keeping the desaturated palette scoped to Glass.
The background, scrollbar and counter tokens were declared under `[data-color-mode="light"|"dark"]`, but the System theme renders `data-color-mode="auto"`, so neither matched and all of them resolved to nothing. Key them off the attribute's presence and pick each pair with `light-dark()`.
Restoring the icon tokens for Classic also activated the desaturated colour-mix palette under Glass, which had never actually applied (the tokens were invalid before the scoping fix), so Glass icons had always rendered monochrome. Make that explicit: under Glass the type icons follow the surrounding text via `currentColor`, and the accessibility degradation block still restores the full colour coding.
|
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
After simmering for 2 days @setchy 👀
Adds a second design language, Glass, next to the existing look (now Classic), selectable under Settings → Appearance. Under Glass the whole window becomes one continuous translucent material: the sidebar dissolves into icons floating on the glass, controls (buttons, selects, checkboxes, radios, count pills) render as stepped translucent tiles, notification and repo rows float as rounded cards with glass hover states, and tooltips/popovers come out frosted. Classic is pixel-unchanged: everything Glass lives behind
[data-theme='glass']plus a.gitify-translucentgate, so there is no risk to the default experience.Design decisions
popovervibrancy material, wired over IPC and ordered so switching designs at runtime never flashes black; the material also follows the app's light/dark mode vianativeThemesync. Other platforms fall back to CSSbackdrop-filter.data-color-modeboundary, so components stay stock Primer and the entire language lives inApp.css.Validation
tsc, lint and format clean.New concepts
Theme tokens that re-resolve per language (Tailwind
@theme inline)The radius/shadow/tint utilities are backed by plain CSS variables (
--gitify-*) that each design language re-points under its own[data-theme]scope. Declaring them with@theme inline(instead of@theme) makes Tailwind re-resolve the utilities against the active scope rather than freezing them at:root.This is why one component tree can serve two languages with no JS branching: the swap is a single attribute on the root. Reach for it when a whole token layer swaps at once; for one-off per-component tweaks, a direct class is simpler.
Note: I now fully prefer this theme 👀