feat: Complete light mode implementation with semantic theme system (#450)

- Add comprehensive light/dark mode CSS variables with semantic naming
- Implement theme-aware scrollbars using CSS variables
- Add light mode backgrounds: --bg-base, --bg-elevated, --bg-surface, etc.
- Add theme-aware borders: --border-base, --border-panel, --border-subtle
- Add semantic text colors: --foreground-secondary, --foreground-subtle
- Convert oklch colors to hex for better compatibility
- Add theme awareness to CodeMirror editors
- Update dark mode colors for consistency (background, sidebar, card, muted, input)
- Add Tailwind color mappings for semantic classes

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
This commit was merged in pull request #450.
This commit is contained in:
Peet McKinney
2025-12-23 15:35:49 -07:00
committed by GitHub
parent 186ba34c66
commit e6a70e3a02
84 changed files with 1084 additions and 664 deletions

View File

@@ -750,7 +750,7 @@ export function AdminSettings({
return (
<div
style={wrapperStyle}
className="bg-dark-bg text-white rounded-lg border-2 border-dark-border overflow-hidden"
className="bg-canvas text-foreground rounded-lg border-2 border-edge overflow-hidden"
>
<div className="h-full w-full flex flex-col">
<div className="flex items-center justify-between px-3 pt-2 pb-2">
@@ -758,69 +758,69 @@ export function AdminSettings({
</div>
<Separator className="p-0.25 w-full" />
<div className="px-6 py-4 overflow-auto">
<div className="px-6 py-4 overflow-auto thin-scrollbar">
<Tabs defaultValue="registration" className="w-full">
<TabsList className="mb-4 bg-dark-bg border-2 border-dark-border">
<TabsList className="mb-4 bg-elevated border-2 border-edge">
<TabsTrigger
value="registration"
className="flex items-center gap-2"
className="flex items-center gap-2 bg-elevated data-[state=active]:bg-button data-[state=active]:border data-[state=active]:border-edge"
>
<Users className="h-4 w-4" />
{t("admin.general")}
</TabsTrigger>
<TabsTrigger value="oidc" className="flex items-center gap-2">
<TabsTrigger value="oidc" className="flex items-center gap-2 bg-elevated data-[state=active]:bg-button data-[state=active]:border data-[state=active]:border-edge">
<Shield className="h-4 w-4" />
OIDC
</TabsTrigger>
<TabsTrigger value="users" className="flex items-center gap-2">
<TabsTrigger value="users" className="flex items-center gap-2 bg-elevated data-[state=active]:bg-button data-[state=active]:border data-[state=active]:border-edge">
<Users className="h-4 w-4" />
{t("admin.users")}
</TabsTrigger>
<TabsTrigger value="sessions" className="flex items-center gap-2">
<TabsTrigger value="sessions" className="flex items-center gap-2 bg-elevated data-[state=active]:bg-button data-[state=active]:border data-[state=active]:border-edge">
<Clock className="h-4 w-4" />
Sessions
</TabsTrigger>
<TabsTrigger value="roles" className="flex items-center gap-2">
<TabsTrigger value="roles" className="flex items-center gap-2 bg-elevated data-[state=active]:bg-button data-[state=active]:border data-[state=active]:border-edge">
<Shield className="h-4 w-4" />
{t("rbac.roles.label")}
</TabsTrigger>
<TabsTrigger value="security" className="flex items-center gap-2">
<TabsTrigger value="security" className="flex items-center gap-2 bg-elevated data-[state=active]:bg-button data-[state=active]:border data-[state=active]:border-edge">
<Database className="h-4 w-4" />
{t("admin.databaseSecurity")}
</TabsTrigger>
</TabsList>
<TabsContent value="registration" className="space-y-6">
<div className="space-y-4">
<div className="rounded-lg border-2 border-border bg-card p-4 space-y-4">
<h3 className="text-lg font-semibold">
{t("admin.userRegistration")}
</h3>
<label className="flex items-center gap-2">
<Checkbox
checked={allowRegistration}
onCheckedChange={handleToggleRegistration}
disabled={regLoading || !allowPasswordLogin}
/>
{t("admin.allowNewAccountRegistration")}
{!allowPasswordLogin && (
<span className="text-xs text-muted-foreground">
({t("admin.requiresPasswordLogin")})
</span>
)}
</label>
<label className="flex items-center gap-2">
<Checkbox
checked={allowPasswordLogin}
onCheckedChange={handleTogglePasswordLogin}
disabled={passwordLoginLoading}
/>
{t("admin.allowPasswordLogin")}
</label>
<label className="flex items-center gap-2">
<Checkbox
checked={allowRegistration}
onCheckedChange={handleToggleRegistration}
disabled={regLoading || !allowPasswordLogin}
/>
{t("admin.allowNewAccountRegistration")}
{!allowPasswordLogin && (
<span className="text-xs text-muted-foreground">
({t("admin.requiresPasswordLogin")})
</span>
)}
</label>
<label className="flex items-center gap-2">
<Checkbox
checked={allowPasswordLogin}
onCheckedChange={handleTogglePasswordLogin}
disabled={passwordLoginLoading}
/>
{t("admin.allowPasswordLogin")}
</label>
</div>
</TabsContent>
<TabsContent value="oidc" className="space-y-6">
<div className="space-y-3">
<div className="rounded-lg border-2 border-border bg-card p-4 space-y-3">
<h3 className="text-lg font-semibold">
{t("admin.externalAuthentication")}
</h3>
@@ -1075,7 +1075,7 @@ export function AdminSettings({
</TabsContent>
<TabsContent value="users" className="space-y-6">
<div className="space-y-4">
<div className="rounded-lg border-2 border-border bg-card p-4 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold">
{t("admin.userManagement")}
@@ -1187,7 +1187,7 @@ export function AdminSettings({
</TabsContent>
<TabsContent value="sessions" className="space-y-6">
<div className="space-y-4">
<div className="rounded-lg border-2 border-border bg-card p-4 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold">{t("admin.sessionManagement")}</h3>
<Button
@@ -1247,7 +1247,7 @@ export function AdminSettings({
session.isRevoked ? "opacity-50" : undefined
}
>
<TableCell>
<TableCell className="px-4">
<div className="flex items-center gap-2">
<DeviceIcon className="h-4 w-4" />
<div className="flex flex-col">
@@ -1262,19 +1262,19 @@ export function AdminSettings({
</div>
</div>
</TableCell>
<TableCell>
<TableCell className="px-4">
{session.username || session.userId}
</TableCell>
<TableCell className="text-sm text-muted-foreground">
<TableCell className="px-4 text-sm text-muted-foreground">
{formatDate(createdDate)}
</TableCell>
<TableCell className="text-sm text-muted-foreground">
<TableCell className="px-4 text-sm text-muted-foreground">
{formatDate(lastActiveDate)}
</TableCell>
<TableCell className="text-sm text-muted-foreground">
<TableCell className="px-4 text-sm text-muted-foreground">
{formatDate(expiresDate)}
</TableCell>
<TableCell>
<TableCell className="px-4">
<div className="flex gap-2">
<Button
variant="ghost"
@@ -1318,15 +1318,13 @@ export function AdminSettings({
</TabsContent>
<TabsContent value="security" className="space-y-6">
<div className="space-y-4">
<div className="flex items-center gap-3">
<h3 className="text-lg font-semibold">
{t("admin.databaseSecurity")}
</h3>
</div>
<div className="rounded-lg border-2 border-border bg-card p-4 space-y-4">
<h3 className="text-lg font-semibold">
{t("admin.databaseSecurity")}
</h3>
<div className="grid gap-3 md:grid-cols-2">
<div className="p-4 border rounded-lg bg-dark-bg-panel">
<div className="p-4 border rounded-lg bg-surface">
<div className="space-y-3">
<div className="flex items-center gap-2">
<Download className="h-4 w-4 text-blue-500" />
@@ -1377,7 +1375,7 @@ export function AdminSettings({
</div>
</div>
<div className="p-4 border rounded-lg bg-dark-bg-panel">
<div className="p-4 border rounded-lg bg-surface">
<div className="space-y-3">
<div className="flex items-center gap-2">
<Upload className="h-4 w-4 text-green-500" />
@@ -1457,7 +1455,7 @@ export function AdminSettings({
open={linkAccountAlertOpen}
onOpenChange={setLinkAccountAlertOpen}
>
<DialogContent className="sm:max-w-[500px] bg-dark-bg border-2 border-dark-border">
<DialogContent className="sm:max-w-[500px] bg-canvas border-2 border-edge">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Link2 className="w-5 h-5" />