Change overall look for dark mode and Timelapse View

This commit is contained in:
2026-02-01 15:08:34 +01:00
parent 3e6d045cbd
commit 1940867519
7 changed files with 54 additions and 145 deletions

View File

@ -38,17 +38,18 @@ export default async function CommissionsPage() {
<DialogTrigger asChild> <DialogTrigger asChild>
<Button variant="secondary">View example</Button> <Button variant="secondary">View example</Button>
</DialogTrigger> </DialogTrigger>
<DialogContent className="w-[min(95vw,1200px)] max-w-300 p-4 sm:p-6"> <DialogContent className="flex w-auto! max-w-[95vw]! flex-col p-4 sm:p-6">
<DialogHeader> <DialogHeader className="sr-only">
<DialogTitle></DialogTitle> <DialogTitle>Commission example</DialogTitle>
</DialogHeader> </DialogHeader>
<div className="relative w-full h-[80vh] max-h-[80vh] overflow-hidden rounded-xl border-2 border-border/60 bg-muted shadow-2xl"> <div className="flex max-h-[85vh] max-w-[85vw] items-center justify-center rounded-xl border-border/60 bg-muted p-2 shadow-2xl">
<Image <Image
src={guidelines.exampleImageUrl} src={guidelines.exampleImageUrl}
alt="Commission example" alt="Commission example"
fill width={1600}
sizes="(max-width: 640px) 95vw, 1200px" height={1200}
className="object-contain" sizes="85vw"
className="h-auto max-h-[85vh] w-auto max-w-[85vw] rounded-lg object-contain"
/> />
</div> </div>
</DialogContent> </DialogContent>

View File

@ -48,119 +48,33 @@
--color-hover-foreground: var(--hover-foreground); --color-hover-foreground: var(--hover-foreground);
} }
/* :root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
} */
:root { :root {
--radius: 0.625rem; --radius: 0.625rem;
--background: oklch(0.985 0.012 85);
/* Light: warm paper + graphite */ --foreground: oklch(0.18 0.02 35);
--background: oklch(0.985 0.012 85); /* warm off-white */ --card: oklch(0.992 0.008 85);
--foreground: oklch(0.18 0.02 35); /* graphite */
--card: oklch(0.992 0.008 85); /* slightly lifted paper */
--card-foreground: var(--foreground); --card-foreground: var(--foreground);
--popover: oklch(0.992 0.008 85); --popover: oklch(0.992 0.008 85);
--popover-foreground: var(--foreground); --popover-foreground: var(--foreground);
/* Primary: deep ink / indigo (artist-y but still neutral enough) */
--primary: oklch(0.32 0.06 260); --primary: oklch(0.32 0.06 260);
--primary-foreground: oklch(0.985 0.012 85); --primary-foreground: oklch(0.985 0.012 85);
/* Secondary/muted/accent: warm washes */
--secondary: oklch(0.96 0.015 85); --secondary: oklch(0.96 0.015 85);
--secondary-foreground: oklch(0.22 0.02 35); --secondary-foreground: oklch(0.22 0.02 35);
--muted: oklch(0.955 0.012 85); --muted: oklch(0.955 0.012 85);
--muted-foreground: oklch(0.46 0.02 35); --muted-foreground: oklch(0.46 0.02 35);
--accent: oklch(0.95 0.02 110);
--accent: oklch(0.95 0.02 110); /* subtle “wash” */
--accent-foreground: oklch(0.22 0.02 35); --accent-foreground: oklch(0.22 0.02 35);
--destructive: oklch(0.58 0.22 27.325); --destructive: oklch(0.58 0.22 27.325);
--border: oklch(0.90 0.02 85);
--border: oklch(0.90 0.02 85); /* warm border */
--input: oklch(0.90 0.02 85); --input: oklch(0.90 0.02 85);
--ring: oklch(0.55 0.07 260); /* ties to primary */ --ring: oklch(0.55 0.07 260);
--hover: oklch(0.94 0.015 255);
--hover: oklch(0.94 0.015 255); /* subtle cool lift */
--hover-foreground: var(--foreground); --hover-foreground: var(--foreground);
/* charts can stay, or we can harmonize later */
--chart-1: oklch(0.646 0.222 41.116); --chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704); --chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392); --chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429); --chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08); --chart-5: oklch(0.769 0.188 70.08);
/* sidebar inherits the same “paper” idea */
--sidebar: oklch(0.975 0.012 85); --sidebar: oklch(0.975 0.012 85);
--sidebar-foreground: var(--foreground); --sidebar-foreground: var(--foreground);
--sidebar-primary: var(--primary); --sidebar-primary: var(--primary);
@ -172,36 +86,38 @@
} }
.dark { .dark {
/* Inky navy background (clearly not neutral) */ --background: oklch(0.2223 0.0060 271.1393);
--background: oklch(15.774% 0.03835 263.588); --foreground: oklch(0.9551 0 0);
--foreground: oklch(0.95 0.012 85); --card: oklch(0.2568 0.0076 274.6528);
--card-foreground: oklch(0.9551 0 0);
/* Surfaces */ --popover: oklch(0.2568 0.0076 274.6528);
--card: oklch(0.155 0.03 255); --popover-foreground: oklch(0.9551 0 0);
--card-foreground: var(--foreground); --primary: oklch(0.6132 0.2294 291.7437);
--primary-foreground: oklch(1.0000 0 0);
--popover: oklch(0.155 0.03 255); --secondary: oklch(0.2940 0.0130 272.9312);
--popover-foreground: var(--foreground); --secondary-foreground: oklch(0.9551 0 0);
--muted: oklch(0.2940 0.0130 272.9312);
/* Primary accent stays “artist ink” */ --muted-foreground: oklch(0.7058 0 0);
--primary: oklch(0.78 0.11 255); --accent: oklch(0.2795 0.0368 260.0310);
--primary-foreground: oklch(0.13 0.03 255); --accent-foreground: oklch(0.7857 0.1153 246.6596);
--destructive: oklch(0.7106 0.1661 22.2162);
--secondary: oklch(0.19 0.025 255); --destructive-foreground: oklch(1.0000 0 0);
--secondary-foreground: var(--foreground); --border: oklch(0.3289 0.0092 268.3843);
--input: oklch(0.3289 0.0092 268.3843);
--muted: oklch(0.19 0.025 255); --ring: oklch(0.6132 0.2294 291.7437);
--muted-foreground: oklch(0.74 0.02 85); --chart-1: oklch(0.8003 0.1821 151.7110);
--chart-2: oklch(0.6132 0.2294 291.7437);
--accent: oklch(0.22 0.03 110); --chart-3: oklch(0.8077 0.1035 19.5706);
--accent-foreground: var(--foreground); --chart-4: oklch(0.6691 0.1569 260.1063);
--chart-5: oklch(0.7058 0 0);
--border: oklch(0.40 0.03 255 / 55%); --sidebar: oklch(0.2011 0.0039 286.0396);
--input: oklch(0.40 0.03 255 / 65%); --sidebar-foreground: oklch(0.9551 0 0);
--ring: oklch(0.65 0.10 255); --sidebar-primary: oklch(0.6132 0.2294 291.7437);
--sidebar-primary-foreground: oklch(1.0000 0 0);
--hover: oklch(28.783% 0.03139 250.817); --sidebar-accent: oklch(0.2940 0.0130 272.9312);
--hover-foreground: var(--foreground); --sidebar-accent-foreground: oklch(0.6132 0.2294 291.7437);
--sidebar-border: oklch(0.3289 0.0092 268.3843);
--sidebar-ring: oklch(0.6132 0.2294 291.7437);
} }
.markdown { .markdown {
@ -260,10 +176,6 @@
@apply line-through text-muted-foreground; @apply line-through text-muted-foreground;
} }
/* div:hover {
border-color: var(--hover-border-color);
} */
@layer base { @layer base {
* { * {
@apply border-border outline-ring/50; @apply border-border outline-ring/50;
@ -276,7 +188,7 @@
} }
.dark body { .dark body {
background-image: background-image:
radial-gradient(1200px 700px at 15% -10%, oklch(0.55 0.14 255 / 16%), transparent 60%), radial-gradient(1200px 700px at 15% -10%, oklch(0.35 0.06 35 / 10%), transparent 60%),
radial-gradient(900px 600px at 85% 0%, oklch(0.50 0.12 110 / 10%), transparent 55%); radial-gradient(900px 600px at 85% 0%, oklch(0.30 0.05 255 / 6%), transparent 55%);
} }
} }

View File

@ -27,9 +27,6 @@ export default function ArtworkTimelapseViewer({
}) { }) {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
// IMPORTANT:
// This assumes your existing `/api/image/[...key]` can stream arbitrary S3 keys.
// If your route expects a different format, adjust this in one place.
const src = `/api/image/${encodeURI(timelapse.s3Key)}`; const src = `/api/image/${encodeURI(timelapse.s3Key)}`;
// Minimal empty captions track (satisfies jsx-a11y/media-has-caption) // Minimal empty captions track (satisfies jsx-a11y/media-has-caption)
@ -46,7 +43,6 @@ export default function ArtworkTimelapseViewer({
<DialogTitle>{title}</DialogTitle> <DialogTitle>{title}</DialogTitle>
</DialogHeader> </DialogHeader>
{/* Only render video when open (prevents unnecessary network / CPU). */}
{open ? ( {open ? (
<div className="space-y-2"> <div className="space-y-2">
<video <video
@ -61,7 +57,7 @@ export default function ArtworkTimelapseViewer({
</video> </video>
<div className="text-xs text-muted-foreground"> <div className="text-xs text-muted-foreground">
{timelapse.fileName ? timelapse.fileName : timelapse.s3Key} {/* {timelapse.fileName ? timelapse.fileName : timelapse.s3Key} */}
</div> </div>
</div> </div>
) : null} ) : null}

View File

@ -13,7 +13,7 @@ const buttonVariants = cva(
destructive: destructive:
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline: outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input dark:border-input dark:hover:bg-input/60",
secondary: secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80", "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: ghost:

View File

@ -14,7 +14,7 @@ function Checkbox({
<CheckboxPrimitive.Root <CheckboxPrimitive.Root
data-slot="checkbox" data-slot="checkbox"
className={cn( className={cn(
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50", "peer border-input dark:bg-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
className className
)} )}
{...props} {...props}

View File

@ -8,7 +8,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
type={type} type={type}
data-slot="input" data-slot="input"
className={cn( className={cn(
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className className

View File

@ -7,7 +7,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
<textarea <textarea
data-slot="textarea" data-slot="textarea"
className={cn( className={cn(
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className className
)} )}
{...props} {...props}