light mode support for onboarding

This commit is contained in:
Arjun Patel
2026-06-21 11:42:11 -07:00
parent d62d35f25a
commit e6bf024729
7 changed files with 28 additions and 24 deletions
@@ -34,7 +34,7 @@ export function HoldStep({ onAdvance }: { onAdvance: () => void }) {
} }
status={ status={
done ? ( done ? (
<span className="inline-flex items-center gap-1.5 text-emerald-300"> <span className="inline-flex items-center gap-1.5 text-emerald-600 dark:text-emerald-300">
<Check className="size-4" /> Nice. <Check className="size-4" /> Nice.
</span> </span>
) : state === 'holding' ? ( ) : state === 'holding' ? (
@@ -30,20 +30,22 @@ function KeyCap({
className={cn( className={cn(
'relative flex select-none items-center justify-center overflow-hidden rounded-lg border text-sm font-medium', 'relative flex select-none items-center justify-center overflow-hidden rounded-lg border text-sm font-medium',
hero ? 'h-14 w-14 text-xl' : 'h-14', hero ? 'h-14 w-14 text-xl' : 'h-14',
!hero && 'border-white/10 bg-white/5 text-white/30', !hero && 'border-border bg-muted text-muted-foreground/70',
hero && hero &&
state === 'idle' && state === 'idle' &&
'border-white/25 bg-white/10 text-white motion-safe:animate-pulse', 'border-primary/40 bg-primary/10 text-foreground motion-safe:animate-pulse',
hero && state === 'active' && 'border-white/50 bg-white/20 text-white', hero &&
state === 'active' &&
'border-primary/60 bg-primary/20 text-foreground',
hero && hero &&
state === 'success' && state === 'success' &&
'border-emerald-400/50 bg-emerald-500/20 text-emerald-200', 'border-emerald-500/50 bg-emerald-500/15 text-emerald-700 dark:text-emerald-200',
className, className,
)} )}
> >
{hero && state !== 'success' && progress > 0 && ( {hero && state !== 'success' && progress > 0 && (
<span <span
className="pointer-events-none absolute inset-x-0 bottom-0 bg-white/25" className="pointer-events-none absolute inset-x-0 bottom-0 bg-primary/25"
style={{ height: `${progress * 100}%` }} style={{ height: `${progress * 100}%` }}
/> />
)} )}
@@ -62,14 +62,14 @@ export function OnboardingOverlay({ onComplete }: { onComplete: () => void }) {
}, [onComplete, goNext, step, goBack]); }, [onComplete, goNext, step, goBack]);
return ( return (
<div className="flex h-screen flex-col bg-background text-white"> <div className="flex h-screen flex-col bg-background text-foreground">
<div className="drag-region flex items-center justify-between border-b border-white/10 px-3 py-1"> <div className="drag-region flex items-center justify-between border-b border-border px-3 py-1">
<WindowControls /> <WindowControls />
<KeyHint <KeyHint
keys="Esc" keys="Esc"
onClick={onComplete} onClick={onComplete}
title="Skip onboarding (or press Esc)" title="Skip onboarding (or press Esc)"
className="no-drag text-xs text-white/40" className="no-drag text-xs text-muted-foreground"
> >
to skip to skip
</KeyHint> </KeyHint>
@@ -81,7 +81,7 @@ export function OnboardingOverlay({ onComplete }: { onComplete: () => void }) {
tabIndex={-1} tabIndex={-1}
role="dialog" role="dialog"
aria-label="Welcome to llink" aria-label="Welcome to llink"
className="flex w-full max-w-md flex-col items-center gap-8 rounded-2xl border border-white/10 bg-white/5 p-10 outline-none" className="flex w-full max-w-md flex-col items-center gap-8 rounded-2xl border border-border bg-card p-10 outline-none"
> >
{step === 'welcome' && ( {step === 'welcome' && (
<OnboardingStep <OnboardingStep
@@ -103,16 +103,16 @@ export function OnboardingOverlay({ onComplete }: { onComplete: () => void }) {
className={cn( className={cn(
'h-1.5 rounded-full transition-all', 'h-1.5 rounded-full transition-all',
i === index i === index
? 'w-6 bg-white/80' ? 'w-6 bg-foreground'
: i < index : i < index
? 'w-1.5 bg-white/40' ? 'w-1.5 bg-foreground/40'
: 'w-1.5 bg-white/15', : 'w-1.5 bg-foreground/15',
)} )}
/> />
))} ))}
</div> </div>
<div className="flex min-h-5 items-center justify-center gap-4 text-xs text-white/40"> <div className="flex min-h-5 items-center justify-center gap-4 text-xs text-muted-foreground">
{index > 0 && ( {index > 0 && (
<KeyHint <KeyHint
keys="←" keys="←"
@@ -25,17 +25,19 @@ export function OnboardingStep({
return ( return (
<div className="flex flex-col items-center gap-6 text-center"> <div className="flex flex-col items-center gap-6 text-center">
<div className="space-y-2"> <div className="space-y-2">
<h2 className="text-2xl font-semibold tracking-tight text-white"> <h2 className="text-2xl font-semibold tracking-tight text-foreground">
{title} {title}
</h2> </h2>
{subtitle && ( {subtitle && (
<p className="mx-auto max-w-xs text-sm text-white/50">{subtitle}</p> <p className="mx-auto max-w-xs text-sm text-muted-foreground">
{subtitle}
</p>
)} )}
</div> </div>
{children && ( {children && (
<div className="flex flex-col items-center gap-4 py-2">{children}</div> <div className="flex flex-col items-center gap-4 py-2">{children}</div>
)} )}
<p aria-live="polite" className="min-h-5 text-sm text-white/60"> <p aria-live="polite" className="min-h-5 text-sm text-muted-foreground">
{status} {status}
</p> </p>
{footer && ( {footer && (
@@ -28,11 +28,11 @@ export function PermissionStep({ onAdvance }: { onAdvance: () => void }) {
subtitle="llink records audio and video. Grant access once so recording just works." subtitle="llink records audio and video. Grant access once so recording just works."
status={ status={
granted ? ( granted ? (
<span className="inline-flex items-center gap-1.5 text-emerald-300"> <span className="inline-flex items-center gap-1.5 text-emerald-600 dark:text-emerald-300">
<Check className="size-4" /> Access granted. <Check className="size-4" /> Access granted.
</span> </span>
) : denied ? ( ) : denied ? (
<span className="text-white/60"> <span className="text-muted-foreground">
No access yet. You can enable it later in System Settings. No access yet. You can enable it later in System Settings.
</span> </span>
) : null ) : null
@@ -36,11 +36,11 @@ export function TapStep({ onAdvance }: { onAdvance: () => void }) {
} }
status={ status={
satisfied ? ( satisfied ? (
<span className="inline-flex items-center gap-1.5 text-emerald-300"> <span className="inline-flex items-center gap-1.5 text-emerald-600 dark:text-emerald-300">
<Check className="size-4" /> Done. <Check className="size-4" /> Done.
</span> </span>
) : recording ? ( ) : recording ? (
<span className="inline-flex items-center gap-2 text-white/70"> <span className="inline-flex items-center gap-2 text-muted-foreground">
<span className="size-2.5 rounded-full bg-red-500 motion-safe:animate-pulse" /> <span className="size-2.5 rounded-full bg-red-500 motion-safe:animate-pulse" />
Recording Recording
</span> </span>
@@ -41,16 +41,16 @@ export function ToggleStep({ onAdvance }: { onAdvance: () => void }) {
} }
status={ status={
satisfied ? ( satisfied ? (
<span className="inline-flex items-center gap-1.5 text-emerald-300"> <span className="inline-flex items-center gap-1.5 text-emerald-600 dark:text-emerald-300">
<Check className="size-4" />{' '} <Check className="size-4" />{' '}
{isVideo ? 'Back to video.' : 'Audio it is.'} {isVideo ? 'Back to video.' : 'Audio it is.'}
</span> </span>
) : null ) : null
} }
> >
<div className="flex size-32 flex-col items-center justify-center gap-2 rounded-2xl border border-white/10 bg-white/5 text-white"> <div className="flex size-32 flex-col items-center justify-center gap-2 rounded-2xl border border-border bg-muted text-foreground">
{isVideo ? <Video className="size-9" /> : <Mic className="size-9" />} {isVideo ? <Video className="size-9" /> : <Mic className="size-9" />}
<span className="text-sm text-white/70"> <span className="text-sm text-muted-foreground">
{isVideo ? 'Video' : 'Audio'} {isVideo ? 'Video' : 'Audio'}
</span> </span>
</div> </div>