From 7827438d9203038c0f2396a3675b6a159229c584 Mon Sep 17 00:00:00 2001 From: Offending Commit Date: Tue, 12 May 2026 09:49:27 -0500 Subject: [PATCH] fix: improve dark mode accessibility contrast --- packages/web/src/components/shared/Badge.tsx | 2 +- packages/web/src/components/ui/button.tsx | 4 +- packages/web/src/components/ui/typography.tsx | 4 +- packages/web/src/index.css | 60 +++++++++++++------ packages/web/src/lib/constants.ts | 30 +++++----- 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/packages/web/src/components/shared/Badge.tsx b/packages/web/src/components/shared/Badge.tsx index e15b149..1e473c8 100644 --- a/packages/web/src/components/shared/Badge.tsx +++ b/packages/web/src/components/shared/Badge.tsx @@ -25,7 +25,7 @@ const variantStyles: Record = { border: "1px solid rgba(239,68,68,0.2)", }, blue: { - background: "rgba(99,102,241,0.08)", + background: "var(--accent-subtle)", color: "var(--accent-text)", border: "1px solid var(--accent-border)", }, diff --git a/packages/web/src/components/ui/button.tsx b/packages/web/src/components/ui/button.tsx index 81c4775..d5e8204 100644 --- a/packages/web/src/components/ui/button.tsx +++ b/packages/web/src/components/ui/button.tsx @@ -6,7 +6,7 @@ import { cn } from "@/lib/utils"; const buttonVariants = cva( [ "inline-flex items-center justify-center gap-1.5 rounded-lg font-medium transition-all", - "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-1)]", + "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg)]", "disabled:opacity-50 disabled:pointer-events-none", ], { @@ -24,7 +24,7 @@ const buttonVariants = cva( "focus-visible:ring-[var(--border)]", ], ghost: [ - "[color:var(--text-3)]", + "[color:var(--text-2)]", "hover:[background:var(--surface)]", "focus-visible:ring-[var(--border)]", ], diff --git a/packages/web/src/components/ui/typography.tsx b/packages/web/src/components/ui/typography.tsx index 943ff10..eeb03ec 100644 --- a/packages/web/src/components/ui/typography.tsx +++ b/packages/web/src/components/ui/typography.tsx @@ -85,7 +85,7 @@ export function Caption({ }: Props) { const Tag = (as ?? "span") as React.ElementType; return ( - + {children} ); @@ -101,7 +101,7 @@ export function MonoCaption({ return ( {children} diff --git a/packages/web/src/index.css b/packages/web/src/index.css index 47566f0..21ca813 100644 --- a/packages/web/src/index.css +++ b/packages/web/src/index.css @@ -28,28 +28,41 @@ /* ─── Theme tokens ─── */ :root, [data-theme="dark"] { - --bg: #0c0c10; - --bg-2: #111118; - --bg-3: #1a1a24; - --surface: rgba(255, 255, 255, 0.03); - --border: rgba(255, 255, 255, 0.08); - --border-2: rgba(255, 255, 255, 0.13); - --text-1: #e8e8f4; - --text-2: #94a3b8; - --text-3: #64748b; - --text-4: #475569; + color-scheme: dark; + --bg: #0b0d12; + --bg-2: #121722; + --bg-3: #1b2331; + --surface: rgba(148, 163, 184, 0.08); + --border: rgba(148, 163, 184, 0.18); + --border-2: rgba(148, 163, 184, 0.28); + --text-1: #f3f6ff; + --text-2: #c3cddd; + --text-3: #95a4bb; + --text-4: #7787a0; --accent: #6366f1; - --accent-dim: rgba(99, 102, 241, 0.15); - --accent-border: rgba(99, 102, 241, 0.35); - --accent-text: #a5b4fc; - --sidebar-bg: linear-gradient(180deg, #111118 0%, #0e0e15 100%); - --grid-line: rgba(99, 102, 241, 0.03); - --glow: rgba(79, 70, 229, 0.08); + --accent-text: #d6ddff; + --accent-soft: #c7d2fe; + --accent-dim: rgba(129, 140, 248, 0.18); + --accent-dim-hover: rgba(129, 140, 248, 0.24); + --accent-subtle: rgba(129, 140, 248, 0.14); + --accent-muted: #a5b4fc; + --accent-glow: rgba(129, 140, 248, 0.4); + --accent-border: rgba(129, 140, 248, 0.4); + --accent-border-strong: rgba(165, 180, 252, 0.56); + --accent-spinner-track: rgba(129, 140, 248, 0.26); + --dim-text: #a7b4c8; + --dim-icon: rgba(167, 180, 200, 0.75); + --card-base-bg: rgba(148, 163, 184, 0.08); + --card-base-border: rgba(148, 163, 184, 0.18); + --sidebar-bg: linear-gradient(180deg, #121722 0%, #0d1017 100%); + --grid-line: rgba(129, 140, 248, 0.05); + --glow: rgba(99, 102, 241, 0.1); --scrollbar: rgba(99, 102, 241, 0.2); - --card-hover: rgba(99, 102, 241, 0.06); + --card-hover: rgba(129, 140, 248, 0.12); } [data-theme="light"] { + color-scheme: light; --bg: #f8f8fc; --bg-2: #ffffff; --bg-3: #f0f0f8; @@ -61,9 +74,20 @@ --text-3: #6b7280; --text-4: #9ca3af; --accent: #4f46e5; + --accent-text: #4f46e5; + --accent-soft: #6366f1; --accent-dim: rgba(79, 70, 229, 0.08); + --accent-dim-hover: rgba(79, 70, 229, 0.12); + --accent-subtle: rgba(79, 70, 229, 0.1); + --accent-muted: #6366f1; + --accent-glow: rgba(79, 70, 229, 0.28); --accent-border: rgba(79, 70, 229, 0.25); - --accent-text: #4f46e5; + --accent-border-strong: rgba(79, 70, 229, 0.35); + --accent-spinner-track: rgba(79, 70, 229, 0.18); + --dim-text: #4b5563; + --dim-icon: rgba(75, 85, 99, 0.6); + --card-base-bg: rgba(15, 23, 42, 0.03); + --card-base-border: rgba(15, 23, 42, 0.08); --sidebar-bg: linear-gradient(180deg, #ffffff 0%, #f4f4fc 100%); --grid-line: rgba(79, 70, 229, 0.04); --glow: rgba(79, 70, 229, 0.06); diff --git a/packages/web/src/lib/constants.ts b/packages/web/src/lib/constants.ts index 3b5779b..c40bf77 100644 --- a/packages/web/src/lib/constants.ts +++ b/packages/web/src/lib/constants.ts @@ -17,27 +17,27 @@ export const COLOR = { destructiveBorder: "rgba(239,68,68,0.2)", // Accent (indigo — matches --accent CSS var) - accent: "#6366f1", - accentText: "#818cf8", - accentSoft: "#c7d2fe", - accentDim: "rgba(99,102,241,0.08)", - accentDimHover: "rgba(99,102,241,0.06)", - accentSubtle: "rgba(99,102,241,0.1)", - accentMuted: "rgba(99,102,241,0.6)", - accentGlow: "rgba(99,102,241,0.4)", - accentBorder: "rgba(99,102,241,0.2)", - accentBorderStrong: "rgba(99,102,241,0.15)", - accentSpinnerTrack: "rgba(99,102,241,0.15)", + accent: "var(--accent)", + accentText: "var(--accent-text)", + accentSoft: "var(--accent-soft)", + accentDim: "var(--accent-dim)", + accentDimHover: "var(--accent-dim-hover)", + accentSubtle: "var(--accent-subtle)", + accentMuted: "var(--accent-muted)", + accentGlow: "var(--accent-glow)", + accentBorder: "var(--accent-border)", + accentBorderStrong: "var(--accent-border-strong)", + accentSpinnerTrack: "var(--accent-spinner-track)", // Neutral dim (slate-300 at opacity) - dimText: "rgba(148,163,184,0.5)", - dimIcon: "rgba(148,163,184,0.3)", + dimText: "var(--dim-text)", + dimIcon: "var(--dim-icon)", // Error detail text destructiveMuted: "rgba(248,113,113,0.6)", destructiveBorderStrong: "rgba(239,68,68,0.25)", // Framer-motion hover card base state (inline only — CSS vars can't be animated) - cardBaseBg: "rgba(255,255,255,0.02)", - cardBaseBorder: "rgba(255,255,255,0.06)", + cardBaseBg: "var(--card-base-bg)", + cardBaseBorder: "var(--card-base-border)", } as const;