107 lines
3.0 KiB
TypeScript
107 lines
3.0 KiB
TypeScript
import { cn } from '@/lib/utils';
|
|
import Image from 'next/image';
|
|
|
|
const BOKEH_ORBS = [
|
|
'top-[20%] left-[10%] size-[min(18vw,140px)] opacity-[0.14]',
|
|
'top-[-18%] right-[-20%] size-[min(42vw,380px)] opacity-[0.1]',
|
|
'bottom-[-17%] left-[-15%] size-[min(34vw,300px)] opacity-[0.12]',
|
|
] as const;
|
|
|
|
const PARTICLES = [
|
|
'top-[30%] left-[45%] opacity-15',
|
|
'top-[43%] right-[20%] opacity-20',
|
|
'top-[57%] left-[10%] opacity-20',
|
|
'bottom-[28%] left-[45%] opacity-20',
|
|
'bottom-[14%] right-[20%] opacity-20',
|
|
] as const;
|
|
|
|
type AuthBackgroundProps = {
|
|
className?: string;
|
|
};
|
|
|
|
export function AuthBackground({ className }: AuthBackgroundProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'relative hidden h-screen w-1/2 shrink-0 overflow-hidden md:block',
|
|
className,
|
|
)}
|
|
aria-hidden
|
|
>
|
|
<div
|
|
className="absolute inset-0"
|
|
style={{
|
|
background:
|
|
'linear-gradient(155deg, color-mix(in oklch, var(--primary) 92%, white 8%) 0%, var(--primary) 32%, color-mix(in oklch, var(--primary) 72%, black 28%) 66%, color-mix(in oklch, var(--primary) 48%, black 52%) 100%)',
|
|
}}
|
|
/>
|
|
|
|
<div
|
|
className="absolute inset-0"
|
|
style={{
|
|
background:
|
|
'radial-gradient(circle at 50% 43%, color-mix(in oklch, var(--primary) 78%, white 22% / 34%), transparent 42%), radial-gradient(circle at 18% 8%, color-mix(in oklch, var(--primary) 70%, white 30% / 26%), transparent 36%)',
|
|
}}
|
|
/>
|
|
|
|
<svg
|
|
className="pointer-events-none absolute inset-0 size-full text-primary-foreground/8"
|
|
viewBox="0 0 100 100"
|
|
preserveAspectRatio="xMidYMid slice"
|
|
>
|
|
{Array.from({ length: 14 }, (_, index) => (
|
|
<circle
|
|
key={index}
|
|
cx="50"
|
|
cy="45"
|
|
r={8 + index * 5.2}
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="0.08"
|
|
/>
|
|
))}
|
|
</svg>
|
|
|
|
{BOKEH_ORBS.map((position, index) => (
|
|
<div
|
|
key={index}
|
|
className={cn(
|
|
'absolute rounded-full bg-primary-foreground/16',
|
|
position,
|
|
)}
|
|
/>
|
|
))}
|
|
|
|
{PARTICLES.map((position, index) => (
|
|
<div
|
|
key={index}
|
|
className={cn(
|
|
'absolute size-1.5 rounded-full bg-primary-foreground/35',
|
|
position,
|
|
)}
|
|
/>
|
|
))}
|
|
|
|
<Image
|
|
src="/logo.svg"
|
|
alt=""
|
|
width={81}
|
|
height={58}
|
|
className="absolute left-10 top-12 h-auto w-16 object-contain"
|
|
priority
|
|
/>
|
|
|
|
<div className="absolute bottom-10 left-10 right-10 text-left text-primary-foreground">
|
|
<p className="text-3xl leading-none tracking-tight">
|
|
<span className="font-semibold">Road</span>
|
|
<span className="font-normal">Monitor</span>
|
|
</p>
|
|
<p className="mt-1 max-w-sm text-xs leading-4 text-primary-foreground/90">
|
|
Map, monitor, and repair road issues with data-driven surface
|
|
intelligence.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|