feat: add dark mode and audit viewer-frontend accessibility
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 11s

Add next-themes light/dark/system theming with an accessible toggle
in every header, and close out an a11y pass across the viewer app:
skip-to-content link, main landmarks and heading hierarchy on every
route, focus-trapped dialog semantics for the photo viewer modals,
aria-label/live-region coverage for dynamic messages and icon
buttons, and dark: variants for previously light-only colors.
This commit is contained in:
2026-07-14 16:24:51 -04:00
parent e54c60912c
commit c011c8078e
32 changed files with 371 additions and 146 deletions
+1 -1
View File
@@ -350,7 +350,7 @@ export function UploadContent() {
</div>
{allSuccess && (
<div className="rounded-lg bg-green-50 dark:bg-green-900/20 p-4">
<div role="status" className="rounded-lg bg-green-50 dark:bg-green-900/20 p-4">
<div className="flex items-center space-x-2">
<CheckCircle2 className="h-5 w-5 text-green-600 dark:text-green-400" />
<p className="text-sm font-medium text-green-800 dark:text-green-200">
+18 -20
View File
@@ -7,6 +7,7 @@ import { UploadContent } from './UploadContent';
import Image from 'next/image';
import Link from 'next/link';
import UserMenu from '@/components/UserMenu';
import { ThemeToggle } from '@/components/ThemeToggle';
export function UploadPageClient() {
const router = useRouter();
@@ -17,38 +18,35 @@ export function UploadPageClient() {
return (
<div className="fixed inset-0 z-50 bg-background overflow-y-auto">
<div className="w-full px-4 py-8">
{/* Close button */}
<div className="mb-4 flex items-center justify-end">
<Button
variant="ghost"
size="icon"
onClick={handleClose}
className="h-9 w-9"
aria-label="Close upload"
>
<X className="h-5 w-5" />
</Button>
</div>
<main id="main-content" className="w-full px-4 pt-3 pb-8">
{/* Header */}
<div className="sticky top-0 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 pb-4 mb-4 border-b">
<div className="mb-4 flex items-center justify-between">
<div className="sticky top-0 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 pb-2 mb-3 border-b">
<div className="mb-2 flex items-center justify-between">
<Link href="/" aria-label="Home">
<Image
src="/logo.png"
alt="PunimTag"
width={300}
height={80}
className="h-20 w-auto cursor-pointer hover:opacity-80 transition-opacity"
className="h-11 w-auto cursor-pointer hover:opacity-80 transition-opacity"
priority
/>
</Link>
<div className="flex items-center gap-2">
<div className="flex items-center gap-1">
<ThemeToggle />
<UserMenu />
<Button
variant="ghost"
size="icon"
onClick={handleClose}
className="h-9 w-9"
aria-label="Close upload"
>
<X className="h-5 w-5" />
</Button>
</div>
</div>
<p className="text-lg font-medium text-orange-600 dark:text-orange-500 tracking-wide">
<p className="text-sm font-medium text-orange-600 dark:text-orange-500 tracking-wide">
Browse our photo collection
</p>
</div>
@@ -65,7 +63,7 @@ export function UploadPageClient() {
</div>
<UploadContent />
</div>
</div>
</main>
</div>
);
}