fix(a11y): raise inactive tab-trigger contrast on dark theme

The inactive tab text used --muted-foreground (#9aa3b3) on the muted
(#44475a) tab strip, reading 3.6:1 — below the WCAG AA 4.5:1 floor that
axe flags on /settings/integrations. Add a --tab-inactive token (#b3bccd
dark, 4.79:1 on the strip; light mirrors the existing 4.58:1 muted tone)
and point the dark-mode inactive trigger color at it. The active trigger
keeps --foreground.
This commit is contained in:
Marc-André Bombeck committed 2026-06-16 16:51:56 +02:00
1 parent 4fe5a984de
commit f0614a8080
2 files changed
+10 -1

No files matched your search

+9
View File
@@ -58,6 +58,7 @@
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-tab-inactive: var(--tab-inactive);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
@@ -171,6 +172,11 @@
--secondary-foreground: #f8f8f2;
--muted: #44475a;
--muted-foreground: #9aa3b3;
/* Inactive tab-trigger text. `--muted-foreground` (#9aa3b3) on the
* muted (#44475a) tab-strip reads 3.6:1 — below WCAG AA. This brighter
* tone clears 4.5:1 on the muted strip while staying within the Dracula
* palette; the active trigger keeps `--foreground`. */
--tab-inactive: #b3bccd;
/* NativeSelect chevron — a data-URI background-image cannot resolve
* `currentColor` (it falls back to black per the SVG spec), so the
* muted-foreground value is baked into the stroke per theme. Keep in
@@ -275,6 +281,9 @@
--secondary-foreground: #1f1f1f;
--muted: #dcdeef;
--muted-foreground: #5b6273;
/* Inactive tab-trigger text — the light muted-foreground already clears
* AA (4.58:1) on the light muted strip, so the token mirrors it. */
--tab-inactive: #5b6273;
/* Light-theme counterpart of the NativeSelect chevron (see dark block). */
--native-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235b6273' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
--accent: #dcdeef;
+1 -1
View File
@@ -86,7 +86,7 @@ function TabsTrigger({
<TabsPrimitive.Trigger
data-slot="tabs-trigger"
className={cn(
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/75 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/75 hover:text-foreground dark:text-tab-inactive dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground",
"after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",