Some checks failed
Deploy to Cloudflare Workers (OpenNext) / deploy (push) Has been cancelled
Centralize primary, secondary, tertiary, and neutral tokens and apply them across theme variables and UI components. Co-authored-by: Cursor <cursoragent@cursor.com>
117 lines
3.0 KiB
TypeScript
117 lines
3.0 KiB
TypeScript
import { cn } from "@/lib/utils";
|
|
|
|
type FlowProps = {
|
|
className?: string;
|
|
variant?: "divider" | "card" | "section" | "footer";
|
|
inverse?: boolean;
|
|
};
|
|
|
|
/** Small-scale decorative lines (dividers, footer band) — keep subtle */
|
|
export function RiftFlowLines({
|
|
className,
|
|
variant = "divider",
|
|
inverse = false,
|
|
}: FlowProps) {
|
|
const green = inverse ? "rgba(255,255,255,0.35)" : "rgba(26,92,56,0.25)";
|
|
const soft = inverse ? "rgba(255,255,255,0.15)" : "rgba(26,92,56,0.12)";
|
|
|
|
if (variant === "card") {
|
|
return (
|
|
<svg viewBox="0 0 4 40" className={cn("h-8 w-px shrink-0", className)} aria-hidden>
|
|
<path
|
|
d="M2 0 C1 10, 3 20, 2 30 S1 36, 2 40"
|
|
fill="none"
|
|
stroke={green}
|
|
strokeWidth="1"
|
|
strokeLinecap="round"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
if (variant === "section") {
|
|
return (
|
|
<svg
|
|
viewBox="0 0 400 80"
|
|
className={cn("pointer-events-none w-full max-w-xs", className)}
|
|
aria-hidden
|
|
preserveAspectRatio="xMidYMid meet"
|
|
>
|
|
<path
|
|
d="M0 50 Q100 20 200 45 T400 55"
|
|
fill="none"
|
|
stroke={green}
|
|
strokeWidth="1"
|
|
strokeLinecap="round"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
if (variant === "footer") {
|
|
return (
|
|
<svg
|
|
viewBox="0 0 1440 120"
|
|
className={cn("pointer-events-none h-full w-full", className)}
|
|
aria-hidden
|
|
preserveAspectRatio="none"
|
|
>
|
|
<path
|
|
d="M0 65 C180 20 420 40 720 32 S1260 55 1440 38"
|
|
fill="none"
|
|
stroke={inverse ? "rgba(255,255,255,0.28)" : "rgba(255,255,255,0.35)"}
|
|
strokeWidth="1.5"
|
|
strokeLinecap="round"
|
|
/>
|
|
<path
|
|
d="M0 82 C320 98 640 68 960 78 S1320 88 1440 72"
|
|
fill="none"
|
|
stroke={inverse ? "rgba(255,255,255,0.14)" : "rgba(255,255,255,0.2)"}
|
|
strokeWidth="1"
|
|
strokeLinecap="round"
|
|
/>
|
|
<path
|
|
d="M0 48 C240 58 480 22 720 44 S1200 28 1440 52"
|
|
fill="none"
|
|
stroke={inverse ? "rgba(255,179,0,0.18)" : "rgba(255,179,0,0.25)"}
|
|
strokeWidth="0.75"
|
|
strokeLinecap="round"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<svg
|
|
viewBox="0 0 1200 32"
|
|
className={cn("pointer-events-none w-full", className)}
|
|
aria-hidden
|
|
preserveAspectRatio="none"
|
|
>
|
|
<path
|
|
d="M0 16 Q300 8 600 16 T1200 14"
|
|
fill="none"
|
|
stroke={green}
|
|
strokeWidth="1"
|
|
strokeLinecap="round"
|
|
/>
|
|
<path
|
|
d="M0 22 Q400 26 800 18 T1200 20"
|
|
fill="none"
|
|
stroke={soft}
|
|
strokeWidth="1"
|
|
strokeLinecap="round"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Subtle link between ticket card blocks */
|
|
export function RiftCardConnector({ className }: { className?: string }) {
|
|
return (
|
|
<div className={cn("relative flex justify-center py-0.5", className)} aria-hidden>
|
|
<div className="h-6 w-px bg-gradient-to-b from-[#37a47a]/20 via-[#37a47a]/35 to-[#37a47a]/20" />
|
|
</div>
|
|
);
|
|
}
|