| author | |
| committer | |
| log | 0a7c662d39329eeb3cffe00d66a31f1a8241b3d7 |
| tree | 5c7080cb67e84ec872983324d950140f7a286d52 |
| parent | b91a000a17ddb4937397151a0a39a07990ad6473 |
| signature | Signed by PGP key B5690EEEBB952194 |
8 files changed, 51 insertions(+), 36 deletions(-)
apps/web/index.html+2-2| ... | @@ -37,7 +37,7 @@ | ... | @@ -37,7 +37,7 @@ |
| 37 | light: { | 37 | light: { |
| 38 | background: "#fdf7fd", | 38 | background: "#fdf7fd", |
| 39 | foreground: "#501854", | 39 | foreground: "#501854", |
| 40 | accent: "#e33f86", | 40 | accent: "#db2777", |
| 41 | chrome: "#fdf7fd", | 41 | chrome: "#fdf7fd", |
| 42 | }, | 42 | }, |
| 43 | dark: { | 43 | dark: { |
| ... | @@ -54,7 +54,7 @@ | ... | @@ -54,7 +54,7 @@ |
| 54 | light: { | 54 | light: { |
| 55 | background: "#fdf7fd", | 55 | background: "#fdf7fd", |
| 56 | foreground: "#501854", | 56 | foreground: "#501854", |
| 57 | accent: "#e33f86", | 57 | accent: "#db2777", |
| 58 | chrome: "#fdf7fd", | 58 | chrome: "#fdf7fd", |
| 59 | }, | 59 | }, |
| 60 | dark: { | 60 | dark: { |
apps/web/src/components/chat/ModelPickerSidebar.tsx+1-1| ... | @@ -29,7 +29,7 @@ const SELECTED_INDICATOR_CLASS = | ... | @@ -29,7 +29,7 @@ const SELECTED_INDICATOR_CLASS = |
| 29 | "pointer-events-none absolute -right-1 top-1/2 z-10 h-5 w-0.75 -translate-y-1/2 rounded-l-full bg-primary"; | 29 | "pointer-events-none absolute -right-1 top-1/2 z-10 h-5 w-0.75 -translate-y-1/2 rounded-l-full bg-primary"; |
| 30 | const BADGE_BASE_CLASS = | 30 | const BADGE_BASE_CLASS = |
| 31 | "pointer-events-none absolute -right-0.5 top-0.5 z-10 flex size-3.5 items-center justify-center rounded-full bg-transparent shadow-sm "; | 31 | "pointer-events-none absolute -right-0.5 top-0.5 z-10 flex size-3.5 items-center justify-center rounded-full bg-transparent shadow-sm "; |
| 32 | const NEW_BADGE_CLASS = `${BADGE_BASE_CLASS} text-update `; | 32 | const NEW_BADGE_CLASS = `${BADGE_BASE_CLASS} text-update-foreground `; |
| 33 | 33 | ||
| 34 | /** Opens toward the rail so the list stays readable (not over the model names). */ | 34 | /** Opens toward the rail so the list stays readable (not over the model names). */ |
| 35 | const PICKER_TOOLTIP_SIDE = "left" as const; | 35 | const PICKER_TOOLTIP_SIDE = "left" as const; |
apps/web/src/components/settings/ProviderInstanceCard.tsx+1-1| ... | @@ -619,7 +619,7 @@ export function ProviderInstanceCard({ | ... | @@ -619,7 +619,7 @@ export function ProviderInstanceCard({ |
| 619 | "size-5 rounded-sm p-0", | 619 | "size-5 rounded-sm p-0", |
| 620 | versionAdvisory.emphasis === "strong" | 620 | versionAdvisory.emphasis === "strong" |
| 621 | ? "text-warning hover:text-warning" | 621 | ? "text-warning hover:text-warning" |
| 622 | : "text-update hover:text-update", | 622 | : "text-update-foreground hover:text-update-foreground", |
| 623 | )} | 623 | )} |
| 624 | aria-label="Update available — view details" | 624 | aria-label="Update available — view details" |
| 625 | > | 625 | > |
apps/web/src/components/settings/themeInspector.test.ts+3| ... | @@ -31,6 +31,9 @@ describe("changedThemePaintKinds", () => { | ... | @@ -31,6 +31,9 @@ describe("changedThemePaintKinds", () => { |
| 31 | describe("themeRoleFromUtilityClass", () => { | 31 | describe("themeRoleFromUtilityClass", () => { |
| 32 | it("maps semantic utilities to their actual palette role", () => { | 32 | it("maps semantic utilities to their actual palette role", () => { |
| 33 | expect(themeRoleFromUtilityClass("text-foreground", "foreground")).toBe("text"); | 33 | expect(themeRoleFromUtilityClass("text-foreground", "foreground")).toBe("text"); |
| 34 | expect(themeRoleFromUtilityClass("text-muted-foreground", "foreground")).toBe( | ||
| 35 | "mutedForeground", | ||
| 36 | ); | ||
| 34 | expect(themeRoleFromUtilityClass("bg-primary/90", "background")).toBe("messageAction"); | 37 | expect(themeRoleFromUtilityClass("bg-primary/90", "background")).toBe("messageAction"); |
| 35 | expect(themeRoleFromUtilityClass("ring-ring", "border")).toBe("focus"); | 38 | expect(themeRoleFromUtilityClass("ring-ring", "border")).toBe("focus"); |
| 36 | }); | 39 | }); |
apps/web/src/components/settings/themeInspector.ts+1-1| ... | @@ -38,7 +38,7 @@ const THEME_UTILITY_ROLES: Readonly<Partial<Record<string, ThemeColorRole>>> = { | ... | @@ -38,7 +38,7 @@ const THEME_UTILITY_ROLES: Readonly<Partial<Record<string, ThemeColorRole>>> = { |
| 38 | secondary: "secondary", | 38 | secondary: "secondary", |
| 39 | "secondary-foreground": "secondaryForeground", | 39 | "secondary-foreground": "secondaryForeground", |
| 40 | muted: "muted", | 40 | muted: "muted", |
| 41 | "muted-foreground": "textMuted", | 41 | "muted-foreground": "mutedForeground", |
| 42 | placeholder: "placeholder", | 42 | placeholder: "placeholder", |
| 43 | "secondary-label": "secondaryLabel", | 43 | "secondary-label": "secondaryLabel", |
| 44 | "icon-muted": "iconMuted", | 44 | "icon-muted": "iconMuted", |
apps/web/src/index.css+5-5| ... | @@ -932,7 +932,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil | ... | @@ -932,7 +932,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil |
| 932 | --destructive: var(--error); | 932 | --destructive: var(--error); |
| 933 | --border: var(--color-zinc-200); | 933 | --border: var(--color-zinc-200); |
| 934 | --input: var(--color-zinc-300); | 934 | --input: var(--color-zinc-300); |
| 935 | --ring: oklch(0.488 0.217 264); | 935 | --ring: var(--primary); |
| 936 | --destructive-foreground: var(--error-foreground); | 936 | --destructive-foreground: var(--error-foreground); |
| 937 | --info: var(--color-blue-500); | 937 | --info: var(--color-blue-500); |
| 938 | --info-foreground: var(--color-blue-700); | 938 | --info-foreground: var(--color-blue-700); |
| ... | @@ -976,7 +976,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil | ... | @@ -976,7 +976,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil |
| 976 | --card-foreground: var(--color-neutral-100); | 976 | --card-foreground: var(--color-neutral-100); |
| 977 | --popover: color-mix(in srgb, var(--background) 94%, var(--color-white)); | 977 | --popover: color-mix(in srgb, var(--background) 94%, var(--color-white)); |
| 978 | --popover-foreground: var(--color-neutral-100); | 978 | --popover-foreground: var(--color-neutral-100); |
| 979 | --primary: oklch(0.588 0.217 264); | 979 | --primary: oklch(0.571 0.21 264); |
| 980 | --primary-foreground: var(--color-white); | 980 | --primary-foreground: var(--color-white); |
| 981 | --secondary: --alpha(var(--color-white) / 4%); | 981 | --secondary: --alpha(var(--color-white) / 4%); |
| 982 | --secondary-foreground: var(--color-neutral-100); | 982 | --secondary-foreground: var(--color-neutral-100); |
| ... | @@ -998,7 +998,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil | ... | @@ -998,7 +998,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil |
| 998 | --destructive: var(--error); | 998 | --destructive: var(--error); |
| 999 | --border: --alpha(var(--color-white) / 6%); | 999 | --border: --alpha(var(--color-white) / 6%); |
| 1000 | --input: --alpha(var(--color-white) / 8%); | 1000 | --input: --alpha(var(--color-white) / 8%); |
| 1001 | --ring: oklch(0.588 0.217 264); | 1001 | --ring: var(--primary); |
| 1002 | --destructive-foreground: var(--error-foreground); | 1002 | --destructive-foreground: var(--error-foreground); |
| 1003 | --info: var(--color-blue-500); | 1003 | --info: var(--color-blue-500); |
| 1004 | --info-foreground: var(--color-blue-400); | 1004 | --info-foreground: var(--color-blue-400); |
| ... | @@ -1109,7 +1109,7 @@ html.dark[data-theme-id] { | ... | @@ -1109,7 +1109,7 @@ html.dark[data-theme-id] { |
| 1109 | --secondary: var(--app-theme-secondary); | 1109 | --secondary: var(--app-theme-secondary); |
| 1110 | --secondary-foreground: var(--app-theme-secondary-foreground); | 1110 | --secondary-foreground: var(--app-theme-secondary-foreground); |
| 1111 | --muted: var(--app-theme-muted); | 1111 | --muted: var(--app-theme-muted); |
| 1112 | --muted-foreground: var(--app-theme-text-muted); | 1112 | --muted-foreground: var(--app-theme-muted-foreground); |
| 1113 | --placeholder: var(--app-theme-placeholder); | 1113 | --placeholder: var(--app-theme-placeholder); |
| 1114 | --secondary-label: var(--app-theme-secondary-label); | 1114 | --secondary-label: var(--app-theme-secondary-label); |
| 1115 | --icon-muted: var(--app-theme-icon-muted); | 1115 | --icon-muted: var(--app-theme-icon-muted); |
| ... | @@ -1359,7 +1359,7 @@ html[data-theme-id] [data-app-sidebar] { | ... | @@ -1359,7 +1359,7 @@ html[data-theme-id] [data-app-sidebar] { |
| 1359 | --accent: var(--app-theme-accent-surface); | 1359 | --accent: var(--app-theme-accent-surface); |
| 1360 | --accent-foreground: var(--app-theme-accent-surface-foreground); | 1360 | --accent-foreground: var(--app-theme-accent-surface-foreground); |
| 1361 | --muted: var(--app-theme-muted); | 1361 | --muted: var(--app-theme-muted); |
| 1362 | --muted-foreground: var(--app-theme-text-muted); | 1362 | --muted-foreground: var(--app-theme-muted-foreground); |
| 1363 | --border: var(--app-theme-border); | 1363 | --border: var(--app-theme-border); |
| 1364 | --input: var(--app-theme-input); | 1364 | --input: var(--app-theme-input); |
| 1365 | --sidebar: var(--app-theme-sidebar); | 1365 | --sidebar: var(--app-theme-sidebar); |
apps/web/src/themePalette.test.ts+13-8| ... | @@ -113,6 +113,8 @@ describe("theme files", () => { | ... | @@ -113,6 +113,8 @@ describe("theme files", () => { |
| 113 | expect(contrastRatio(colors.text, colors.canvas)).toBeGreaterThanOrEqual(7); | 113 | expect(contrastRatio(colors.text, colors.canvas)).toBeGreaterThanOrEqual(7); |
| 114 | expect(contrastRatio(colors.textMuted, colors.canvas)).toBeGreaterThanOrEqual(4.5); | 114 | expect(contrastRatio(colors.textMuted, colors.canvas)).toBeGreaterThanOrEqual(4.5); |
| 115 | expect(contrastRatio(colors.textMuted, colors.canvas)).toBeLessThan(5.5); | 115 | expect(contrastRatio(colors.textMuted, colors.canvas)).toBeLessThan(5.5); |
| 116 | expect(contrastRatio(colors.mutedForeground, colors.muted)).toBeGreaterThanOrEqual(4.5); | ||
| 117 | expect(contrastRatio(colors.placeholder, colors.surfaceRaised)).toBeGreaterThanOrEqual(4.5); | ||
| 116 | expect(colors.secondaryLabel).toBe(colors.textMuted); | 118 | expect(colors.secondaryLabel).toBe(colors.textMuted); |
| 117 | expect(contrastRatio(colors.accentForeground, colors.accent)).toBeGreaterThanOrEqual(4.5); | 119 | expect(contrastRatio(colors.accentForeground, colors.accent)).toBeGreaterThanOrEqual(4.5); |
| 118 | expect( | 120 | expect( |
| ... | @@ -169,7 +171,7 @@ describe("theme files", () => { | ... | @@ -169,7 +171,7 @@ describe("theme files", () => { |
| 169 | colors: { | 171 | colors: { |
| 170 | canvas: "#07152f", | 172 | canvas: "#07152f", |
| 171 | accent: "#67c2ff", | 173 | accent: "#67c2ff", |
| 172 | placeholder: "#8f8699", | 174 | placeholder: "#968d9f", |
| 173 | }, | 175 | }, |
| 174 | }); | 176 | }); |
| 175 | }); | 177 | }); |
| ... | @@ -315,9 +317,7 @@ describe("theme files", () => { | ... | @@ -315,9 +317,7 @@ describe("theme files", () => { |
| 315 | 4.5, | 317 | 4.5, |
| 316 | ); | 318 | ); |
| 317 | expect(contrastRatio(colors.sidebarForeground, colors.sidebar)).toBeGreaterThanOrEqual(4.5); | 319 | expect(contrastRatio(colors.sidebarForeground, colors.sidebar)).toBeGreaterThanOrEqual(4.5); |
| 318 | // The live light primary is intended for filled controls and clears the | 320 | expect(contrastRatio(colors.accentForeground, colors.accent)).toBeGreaterThanOrEqual(4.5); |
| 319 | // non-text UI-component threshold rather than normal-text AA. | ||
| 320 | expect(contrastRatio(colors.accentForeground, colors.accent)).toBeGreaterThanOrEqual(3); | ||
| 321 | } | 321 | } |
| 322 | }); | 322 | }); |
| 323 | 323 | ||
| ... | @@ -340,9 +340,7 @@ describe("theme files", () => { | ... | @@ -340,9 +340,7 @@ describe("theme files", () => { |
| 340 | 1, | 340 | 1, |
| 341 | ); | 341 | ); |
| 342 | } | 342 | } |
| 343 | expect(contrastRatio(colors!.accentForeground, colors!.accent)).toBeGreaterThanOrEqual( | 343 | expect(contrastRatio(colors!.accentForeground, colors!.accent)).toBeGreaterThanOrEqual(4.5); |
| 344 | theme === T3_CHAT_THEME ? 3 : 4.5, | ||
| 345 | ); | ||
| 346 | expect( | 344 | expect( |
| 347 | contrastRatio(colors!.toolbarControlForeground, colors!.toolbarControl), | 345 | contrastRatio(colors!.toolbarControlForeground, colors!.toolbarControl), |
| 348 | ).toBeGreaterThanOrEqual(4.5); | 346 | ).toBeGreaterThanOrEqual(4.5); |
| ... | @@ -351,7 +349,14 @@ describe("theme files", () => { | ... | @@ -351,7 +349,14 @@ describe("theme files", () => { |
| 351 | ).toBeGreaterThanOrEqual(4.5); | 349 | ).toBeGreaterThanOrEqual(4.5); |
| 352 | expect( | 350 | expect( |
| 353 | contrastRatio(colors!.messageActionForeground, colors!.messageAction), | 351 | contrastRatio(colors!.messageActionForeground, colors!.messageAction), |
| 354 | ).toBeGreaterThanOrEqual(theme === T3_CHAT_THEME ? 3 : 4.5); | 352 | ).toBeGreaterThanOrEqual(4.5); |
| 353 | expect( | ||
| 354 | contrastRatio(colors!.messageActionForeground, colors!.messageActionHover), | ||
| 355 | ).toBeGreaterThanOrEqual(4.5); | ||
| 356 | expect(contrastRatio(colors!.mutedForeground, colors!.muted)).toBeGreaterThanOrEqual(4.5); | ||
| 357 | expect(contrastRatio(colors!.placeholder, colors!.surfaceRaised)).toBeGreaterThanOrEqual( | ||
| 358 | 4.5, | ||
| 359 | ); | ||
| 355 | } | 360 | } |
| 356 | } | 361 | } |
| 357 | }); | 362 | }); |
apps/web/src/themePalette.ts+25-18| ... | @@ -325,6 +325,7 @@ function legacyThemeMode(theme: ThemePreference): ThemeAppearance | null { | ... | @@ -325,6 +325,7 @@ function legacyThemeMode(theme: ThemePreference): ThemeAppearance | null { |
| 325 | // Measured from the live t3.chat default theme. Translucent chat surfaces are | 325 | // Measured from the live t3.chat default theme. Translucent chat surfaces are |
| 326 | // flattened over --chat-background so this opaque palette reproduces the | 326 | // flattened over --chat-background so this opaque palette reproduces the |
| 327 | // pixels users see after T3 Chat's blur and noise layers are composited. | 327 | // pixels users see after T3 Chat's blur and noise layers are composited. |
| 328 | // Foreground pairs deviate where necessary to keep normal text at WCAG AA. | ||
| 328 | const T3_CHAT_LIGHT_COLORS: ThemeColors = { | 329 | const T3_CHAT_LIGHT_COLORS: ThemeColors = { |
| 329 | canvas: "#fdf7fd", | 330 | canvas: "#fdf7fd", |
| 330 | // T3 Code's workspace header belongs to the chat panel, so keep it seamless | 331 | // T3 Code's workspace header belongs to the chat panel, so keep it seamless |
| ... | @@ -346,31 +347,31 @@ const T3_CHAT_LIGHT_COLORS: ThemeColors = { | ... | @@ -346,31 +347,31 @@ const T3_CHAT_LIGHT_COLORS: ThemeColors = { |
| 346 | border: "#eee1ed", | 347 | border: "#eee1ed", |
| 347 | input: "#e7c1dc", | 348 | input: "#e7c1dc", |
| 348 | focus: "#db2777", | 349 | focus: "#db2777", |
| 349 | accent: "#e33f86", | 350 | accent: "#db2777", |
| 350 | accentForeground: "#ffffff", | 351 | accentForeground: "#ffffff", |
| 351 | secondary: "#f1c4e6", | 352 | secondary: "#f1c4e6", |
| 352 | secondaryForeground: "#77347c", | 353 | secondaryForeground: "#77347c", |
| 353 | muted: "#eaa7cb", | 354 | muted: "#eaa7cb", |
| 354 | mutedForeground: "#ac1668", | 355 | mutedForeground: "#8d1255", |
| 355 | placeholder: "#ad83b0", | 356 | placeholder: "#8b5f90", |
| 356 | secondaryLabel: "#ac1668", | 357 | secondaryLabel: "#ac1668", |
| 357 | iconMuted: "#ac1668", | 358 | iconMuted: "#ac1668", |
| 358 | error: "#f7086c", | 359 | error: "#f7086c", |
| 359 | errorForeground: "#9d174d", | 360 | errorForeground: "#9d174d", |
| 360 | errorSurface: "#fde4f1", | 361 | errorSurface: "#fde4f1", |
| 361 | warning: "#f59e0b", | 362 | warning: "#f59e0b", |
| 362 | warningForeground: "#b45309", | 363 | warningForeground: "#b05109", |
| 363 | warningSurface: "#fcf0ea", | 364 | warningSurface: "#fcf0ea", |
| 364 | update: "#e33f86", | 365 | update: "#db2777", |
| 365 | updateForeground: "#ac1668", | 366 | updateForeground: "#ac1668", |
| 366 | updateSurface: "#fadfef", | 367 | updateSurface: "#fadfef", |
| 367 | accentSurface: "#f3e6f5", | 368 | accentSurface: "#f3e6f5", |
| 368 | accentSurfaceForeground: "#454554", | 369 | accentSurfaceForeground: "#454554", |
| 369 | messageSurface: "#f7def2", | 370 | messageSurface: "#f7def2", |
| 370 | messageForeground: "#492c61", | 371 | messageForeground: "#492c61", |
| 371 | messageAction: "#e33f86", | 372 | messageAction: "#db2777", |
| 372 | messageActionForeground: "#ffffff", | 373 | messageActionForeground: "#ffffff", |
| 373 | messageActionHover: "#d56698", | 374 | messageActionHover: "#c12269", |
| 374 | // T3 Chat uses a light lavender code surface in light mode. Keeping the | 375 | // T3 Chat uses a light lavender code surface in light mode. Keeping the |
| 375 | // dark plum pair here also leaked the dark palette into T3 Code's diffs. | 376 | // dark plum pair here also leaked the dark palette into T3 Code's diffs. |
| 376 | codeBackground: "#f5ecf9", | 377 | codeBackground: "#f5ecf9", |
| ... | @@ -422,7 +423,7 @@ const T3_CHAT_DARK_COLORS: ThemeColors = { | ... | @@ -422,7 +423,7 @@ const T3_CHAT_DARK_COLORS: ThemeColors = { |
| 422 | secondaryForeground: "#d4c7e1", | 423 | secondaryForeground: "#d4c7e1", |
| 423 | muted: "#423a45", | 424 | muted: "#423a45", |
| 424 | mutedForeground: "#e7d0dd", | 425 | mutedForeground: "#e7d0dd", |
| 425 | placeholder: "#8f8699", | 426 | placeholder: "#968d9f", |
| 426 | secondaryLabel: "#e7d0dd", | 427 | secondaryLabel: "#e7d0dd", |
| 427 | iconMuted: "#d4c7e1", | 428 | iconMuted: "#d4c7e1", |
| 428 | error: "#9d174d", | 429 | error: "#9d174d", |
| ... | @@ -549,8 +550,8 @@ const T3_CODE_DARK_THEME_COLORS: ThemeColors = { | ... | @@ -549,8 +550,8 @@ const T3_CODE_DARK_THEME_COLORS: ThemeColors = { |
| 549 | textMuted: "#818181", | 550 | textMuted: "#818181", |
| 550 | border: "#191919", | 551 | border: "#191919", |
| 551 | input: "#1e1e1e", | 552 | input: "#1e1e1e", |
| 552 | focus: "#366ffb", | 553 | focus: "#346bf1", |
| 553 | accent: "#366ffb", | 554 | accent: "#346bf1", |
| 554 | accentForeground: "#ffffff", | 555 | accentForeground: "#ffffff", |
| 555 | secondary: "#141414", | 556 | secondary: "#141414", |
| 556 | secondaryForeground: "#f5f5f5", | 557 | secondaryForeground: "#f5f5f5", |
| ... | @@ -565,16 +566,16 @@ const T3_CODE_DARK_THEME_COLORS: ThemeColors = { | ... | @@ -565,16 +566,16 @@ const T3_CODE_DARK_THEME_COLORS: ThemeColors = { |
| 565 | warning: "#fe9a00", | 566 | warning: "#fe9a00", |
| 566 | warningForeground: "#ffb900", | 567 | warningForeground: "#ffb900", |
| 567 | warningSurface: "#312108", | 568 | warningSurface: "#312108", |
| 568 | update: "#366ffb", | 569 | update: "#346bf1", |
| 569 | updateForeground: "#51a2ff", | 570 | updateForeground: "#51a2ff", |
| 570 | updateSurface: "#121c35", | 571 | updateSurface: "#121b34", |
| 571 | accentSurface: "#141414", | 572 | accentSurface: "#141414", |
| 572 | accentSurfaceForeground: "#f5f5f5", | 573 | accentSurfaceForeground: "#f5f5f5", |
| 573 | messageSurface: "#141414", | 574 | messageSurface: "#141414", |
| 574 | messageForeground: "#f5f5f5", | 575 | messageForeground: "#f5f5f5", |
| 575 | messageAction: "#366ffb", | 576 | messageAction: "#346bf1", |
| 576 | messageActionForeground: "#ffffff", | 577 | messageActionForeground: "#ffffff", |
| 577 | messageActionHover: "#3265e3", | 578 | messageActionHover: "#3061d9", |
| 578 | codeBackground: "#111111", | 579 | codeBackground: "#111111", |
| 579 | codeForeground: "#f5f5f5", | 580 | codeForeground: "#f5f5f5", |
| 580 | sidebar: "#000000", | 581 | sidebar: "#000000", |
| ... | @@ -941,12 +942,14 @@ export function createVividThemeColors( | ... | @@ -941,12 +942,14 @@ export function createVividThemeColors( |
| 941 | const sidebarRgb = themeOklchToRgb(sidebar); | 942 | const sidebarRgb = themeOklchToRgb(sidebar); |
| 942 | const surface = surfaceAt(0.015); | 943 | const surface = surfaceAt(0.015); |
| 943 | const surfaceRaised = surfaceAt(0.05); | 944 | const surfaceRaised = surfaceAt(0.05); |
| 945 | const surfaceRaisedRgb = themeOklchToRgb(surfaceRaised); | ||
| 944 | const surfaceOverlay = surfaceAt(0.075); | 946 | const surfaceOverlay = surfaceAt(0.075); |
| 945 | const border = surfaceAt(dark ? 0.16 : 0.12, Math.min(0.07, accent.C * 0.35)); | 947 | const border = surfaceAt(dark ? 0.16 : 0.12, Math.min(0.07, accent.C * 0.35)); |
| 946 | const input = surfaceAt(dark ? 0.21 : 0.16, Math.min(0.08, accent.C * 0.4)); | 948 | const input = surfaceAt(dark ? 0.21 : 0.16, Math.min(0.08, accent.C * 0.4)); |
| 947 | const secondary = surfaceAt(dark ? 0.1 : 0.06, Math.min(0.09, accent.C * 0.5)); | 949 | const secondary = surfaceAt(dark ? 0.1 : 0.06, Math.min(0.09, accent.C * 0.5)); |
| 948 | const secondaryRgb = themeOklchToRgb(secondary); | 950 | const secondaryRgb = themeOklchToRgb(secondary); |
| 949 | const muted = surfaceAt(dark ? 0.06 : 0.04, Math.min(0.06, accent.C * 0.35)); | 951 | const muted = surfaceAt(dark ? 0.06 : 0.04, Math.min(0.06, accent.C * 0.35)); |
| 952 | const mutedRgb = themeOklchToRgb(muted); | ||
| 950 | const accentSurface = surfaceAt(dark ? 0.13 : 0.08, Math.min(0.11, accent.C * 0.55)); | 953 | const accentSurface = surfaceAt(dark ? 0.13 : 0.08, Math.min(0.11, accent.C * 0.55)); |
| 951 | const accentSurfaceRgb = themeOklchToRgb(accentSurface); | 954 | const accentSurfaceRgb = themeOklchToRgb(accentSurface); |
| 952 | const messageSurface = surfaceAt(dark ? 0.16 : 0.1, Math.min(0.13, accent.C * 0.6)); | 955 | const messageSurface = surfaceAt(dark ? 0.16 : 0.1, Math.min(0.13, accent.C * 0.6)); |
| ... | @@ -958,6 +961,8 @@ export function createVividThemeColors( | ... | @@ -958,6 +961,8 @@ export function createVividThemeColors( |
| 958 | themeRgbToHexColor( | 961 | themeRgbToHexColor( |
| 959 | themeOklchToRgb(solveOklchLightness(textBase, surfaceRgb, 4.6, dark ? "lighter" : "darker")), | 962 | themeOklchToRgb(solveOklchLightness(textBase, surfaceRgb, 4.6, dark ? "lighter" : "darker")), |
| 960 | ); | 963 | ); |
| 964 | const mutedForeground = foregroundOn(mutedRgb); | ||
| 965 | const placeholder = foregroundOn(surfaceRaisedRgb); | ||
| 961 | 966 | ||
| 962 | const actionHover: ThemeOklch = { ...action, L: action.L + (dark ? 0.06 : -0.06) }; | 967 | const actionHover: ThemeOklch = { ...action, L: action.L + (dark ? 0.06 : -0.06) }; |
| 963 | 968 | ||
| ... | @@ -986,8 +991,8 @@ export function createVividThemeColors( | ... | @@ -986,8 +991,8 @@ export function createVividThemeColors( |
| 986 | secondary: hex(secondary), | 991 | secondary: hex(secondary), |
| 987 | secondaryForeground: foregroundOn(secondaryRgb), | 992 | secondaryForeground: foregroundOn(secondaryRgb), |
| 988 | muted: hex(muted), | 993 | muted: hex(muted), |
| 989 | mutedForeground: themeRgbToHexColor(textMutedRgb), | 994 | mutedForeground, |
| 990 | placeholder: themeRgbToHexColor(textMutedRgb), | 995 | placeholder, |
| 991 | secondaryLabel: themeRgbToHexColor(textMutedRgb), | 996 | secondaryLabel: themeRgbToHexColor(textMutedRgb), |
| 992 | iconMuted: themeRgbToHexColor(textMutedRgb), | 997 | iconMuted: themeRgbToHexColor(textMutedRgb), |
| 993 | update: themeRgbToHexColor(accentRgb), | 998 | update: themeRgbToHexColor(accentRgb), |
| ... | @@ -1174,6 +1179,8 @@ export function createManagedThemeColors( | ... | @@ -1174,6 +1179,8 @@ export function createManagedThemeColors( |
| 1174 | const surfaceOverlay = mixThemeRgbColors(canvas, text, appearance === "dark" ? 0.18 : 0.06); | 1179 | const surfaceOverlay = mixThemeRgbColors(canvas, text, appearance === "dark" ? 0.18 : 0.06); |
| 1175 | const secondary = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.2 : 0.08); | 1180 | const secondary = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.2 : 0.08); |
| 1176 | const muted = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.13 : 0.06); | 1181 | const muted = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.13 : 0.06); |
| 1182 | const mutedForeground = readableThemeText(muted, text, 1, 4.6); | ||
| 1183 | const placeholder = readableThemeText(surfaceRaised, text, 1, 4.6); | ||
| 1177 | const accentSurface = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.3 : 0.14); | 1184 | const accentSurface = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.3 : 0.14); |
| 1178 | const messageSurface = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.36 : 0.18); | 1185 | const messageSurface = mixThemeRgbColors(canvas, accent, appearance === "dark" ? 0.36 : 0.18); |
| 1179 | const toolbarControl = mixThemeRgbColors(chrome, accent, appearance === "dark" ? 0.2 : 0.08); | 1186 | const toolbarControl = mixThemeRgbColors(chrome, accent, appearance === "dark" ? 0.2 : 0.08); |
| ... | @@ -1244,8 +1251,8 @@ export function createManagedThemeColors( | ... | @@ -1244,8 +1251,8 @@ export function createManagedThemeColors( |
| 1244 | secondary: themeRgbToHexColor(secondary), | 1251 | secondary: themeRgbToHexColor(secondary), |
| 1245 | secondaryForeground: themeRgbToHexColor(readableThemeForeground(secondary)), | 1252 | secondaryForeground: themeRgbToHexColor(readableThemeForeground(secondary)), |
| 1246 | muted: themeRgbToHexColor(muted), | 1253 | muted: themeRgbToHexColor(muted), |
| 1247 | mutedForeground: themeRgbToHexColor(textMuted), | 1254 | mutedForeground: themeRgbToHexColor(mutedForeground), |
| 1248 | placeholder: themeRgbToHexColor(textMuted), | 1255 | placeholder: themeRgbToHexColor(placeholder), |
| 1249 | secondaryLabel: themeRgbToHexColor(textMuted), | 1256 | secondaryLabel: themeRgbToHexColor(textMuted), |
| 1250 | iconMuted: themeRgbToHexColor(textMuted), | 1257 | iconMuted: themeRgbToHexColor(textMuted), |
| 1251 | accentSurface: themeRgbToHexColor(accentSurface), | 1258 | accentSurface: themeRgbToHexColor(accentSurface), |