fix(theme): 浅色主题标签强调色改为按 WCAG 加深(实测 4.0:1 -> 4.9:1)
浅色分支此前固定 mix(accent, #000, 0.35),默认绿 #3fb950 得 #297834:在强调色 染过的激活标签底(≈#dae8df)上只有 4.0:1,低于 AA,用户自定义的浅色强调色还会 更差。改用 darkenToRatio(accent, chromeBg, 5.5)——对 chrome 底色保证 5.5:1, 落到更深的染色底上仍有 4.9:1。深色分支(mix 白 0.18)不动。 chrome.ts 新增 chromeBg 记录当前 chrome 底色(applyTabAccent 可能在 applyChromeTheme 之前被设置变更单独调用);#181818 是 pre-JS 深色默认值, 登记进 css-theme-vars 白名单(与 global.css 的 --chrome-bg 同值)。
This commit is contained in:
1 parent
3b86d62111
commit
81748e4470
2 files changed
+15
-3
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
import type { ThemeColors } from '@shared/theme'
|
import type { ThemeColors } from '@shared/theme'
|
||||||
import { contrast, isLightTheme, mix, semanticCssVars } from './semantic'
|
import { contrast, darkenToRatio, isLightTheme, mix, semanticCssVars } from './semantic'
|
||||||
|
|
||||||
// 兼容既有导入方(main.tsx 的 mix);新代码请直接从 ./semantic 导入。
|
// 兼容既有导入方(main.tsx 的 mix);新代码请直接从 ./semantic 导入。
|
||||||
export { contrast, luminance, mix } from './semantic'
|
export { contrast, luminance, mix } from './semantic'
|
||||||
@@ -8,6 +8,10 @@ export { contrast, luminance, mix } from './semantic'
|
|||||||
* from it flip their overlay direction (white-on-dark vs black-on-light). */
|
* from it flip their overlay direction (white-on-dark vs black-on-light). */
|
||||||
let chromeIsLight = false
|
let chromeIsLight = false
|
||||||
|
|
||||||
|
/** Last chrome background; applyTabAccent() needs it to derive a readable
|
||||||
|
* accent foreground for light themes. */
|
||||||
|
let chromeBg = '#181818'
|
||||||
|
|
||||||
/** Dark-chrome tab label: the background mixed toward the theme's own foreground
|
/** Dark-chrome tab label: the background mixed toward the theme's own foreground
|
||||||
* (the light branch is the same mix toward black), but never below 4.5:1 against
|
* (the light branch is the same mix toward black), but never below 4.5:1 against
|
||||||
* the background, since a theme foreground dimmed by 0.68 can land unreadable. */
|
* the background, since a theme foreground dimmed by 0.68 can land unreadable. */
|
||||||
@@ -32,6 +36,7 @@ export function applyChromeTheme(colors: ThemeColors): void {
|
|||||||
set('--chrome-bg', colors.background)
|
set('--chrome-bg', colors.background)
|
||||||
set('--chrome-fg', colors.foreground)
|
set('--chrome-fg', colors.foreground)
|
||||||
chromeIsLight = isLightTheme(colors.background)
|
chromeIsLight = isLightTheme(colors.background)
|
||||||
|
chromeBg = colors.background
|
||||||
if (chromeIsLight) {
|
if (chromeIsLight) {
|
||||||
// Light chrome: keep the bar close to the background (a big mix toward
|
// Light chrome: keep the bar close to the background (a big mix toward
|
||||||
// black turns pale themes into a muddy gray strip) and overlay tabs with
|
// black turns pale themes into a muddy gray strip) and overlay tabs with
|
||||||
@@ -82,6 +87,12 @@ export function applyTabAccent(color: string): void {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
style.setProperty('--tab-accent', color)
|
style.setProperty('--tab-accent', color)
|
||||||
const fg = chromeIsLight ? mix(color, '#000000', 0.35) : mix(color, '#ffffff', 0.18)
|
// Light chrome: a fixed 0.35 mix toward black left the default green
|
||||||
|
// (#3fb950 -> #297834) at 4.0:1 on the accent-tinted tab, just under AA, and
|
||||||
|
// arbitrary user accents could be far worse. darkenToRatio() guarantees the
|
||||||
|
// ratio against the chrome background; the tinted surfaces it also lands on
|
||||||
|
// are slightly darker, hence the margin above 4.5. Dark chrome keeps the
|
||||||
|
// existing lighten mix (its accents sit on dark tabs).
|
||||||
|
const fg = chromeIsLight ? darkenToRatio(color, chromeBg, 5.5) : mix(color, '#ffffff', 0.18)
|
||||||
style.setProperty('--tab-accent-fg', fg ?? color)
|
style.setProperty('--tab-accent-fg', fg ?? color)
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,9 @@ const WHITELIST = {
|
|||||||
// The layer that DEFINES the anchors and derives per-theme values.
|
// The layer that DEFINES the anchors and derives per-theme values.
|
||||||
'theme/semantic.ts': null,
|
'theme/semantic.ts': null,
|
||||||
// Pre-existing --chrome-* derivation anchors (mix targets / overlay bases).
|
// Pre-existing --chrome-* derivation anchors (mix targets / overlay bases).
|
||||||
|
// #181818 = global.css --chrome-bg, the pre-JS chromeBg default.
|
||||||
'theme/chrome.ts': new Set([
|
'theme/chrome.ts': new Set([
|
||||||
'#000000', '#ffffff',
|
'#000000', '#ffffff', '#181818',
|
||||||
'rgba(0, 0, 0, 0.045)', 'rgba(0, 0, 0, 0.09)', 'rgba(0, 0, 0, 0.18)', 'rgba(0, 0, 0, 0.32)',
|
'rgba(0, 0, 0, 0.045)', 'rgba(0, 0, 0, 0.09)', 'rgba(0, 0, 0, 0.18)', 'rgba(0, 0, 0, 0.32)',
|
||||||
'rgba(255, 255, 255, 0.04)', 'rgba(255, 255, 255, 0.07)', 'rgba(255, 255, 255, 0.1)', 'rgba(255, 255, 255, 0.2)'
|
'rgba(255, 255, 255, 0.04)', 'rgba(255, 255, 255, 0.07)', 'rgba(255, 255, 255, 0.1)', 'rgba(255, 255, 255, 0.2)'
|
||||||
]),
|
]),
|
||||||
|
|||||||
Reference in new issue
Block a user