love-ui 1.2.21 → 1.2.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-CH2CHRA7.js +122 -0
- package/dist/index.js +71 -71
- package/dist/mcp-server.js +1 -1
- package/package.json +1 -1
- package/registry/default/blocks/404-2/components/not-found.tsx +1 -1
- package/registry/default/blocks/auth1/components/auth-page.tsx +0 -7
- package/registry/default/blocks/auth1/components/logo.tsx +3 -14
- package/registry/default/blocks/auth2/components/auth.tsx +1 -1
- package/registry/default/blocks/auth2/components/ui/decor-icon.tsx +49 -36
- package/registry/default/blocks/auth3/components/logo.tsx +3 -14
- package/registry/default/blocks/auth3/components/ui/decor-icon.tsx +49 -36
- package/registry/default/blocks/contact5/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/cta-3/components/cta.tsx +1 -1
- package/registry/default/blocks/cta-3/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/cta-5/components/cta.tsx +3 -9
- package/registry/default/blocks/faq-3/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/features1/components/feature-section.tsx +1 -1
- package/registry/default/blocks/features2/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/features2/components/feature-section.tsx +1 -1
- package/registry/default/blocks/features4/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/features4/components/feature-section.tsx +0 -2
- package/registry/default/blocks/features5/components/feature-section.tsx +1 -1
- package/registry/default/blocks/features6/components/feature-section.tsx +5 -21
- package/registry/default/blocks/footer1/components/logo.tsx +3 -14
- package/registry/default/blocks/footer2/components/footer.tsx +1 -1
- package/registry/default/blocks/footer2/components/logo.tsx +3 -14
- package/registry/default/blocks/footer3/components/footer.tsx +2 -2
- package/registry/default/blocks/footer3/components/logo.tsx +3 -14
- package/registry/default/blocks/footer4/components/footer.tsx +1 -1
- package/registry/default/blocks/footer4/components/logo.tsx +3 -14
- package/registry/default/blocks/footer5/components/footer.tsx +27 -30
- package/registry/default/blocks/footer5/components/logo.tsx +3 -14
- package/registry/default/blocks/footer6/components/footer.tsx +3 -3
- package/registry/default/blocks/footer6/components/logo.tsx +3 -14
- package/registry/default/blocks/header1/components/logo.tsx +3 -14
- package/registry/default/blocks/header2/components/logo.tsx +3 -14
- package/registry/default/blocks/header3/components/logo.tsx +3 -14
- package/registry/default/blocks/hero1/components/hero.tsx +7 -7
- package/registry/default/blocks/hero1/components/logo.tsx +3 -14
- package/registry/default/blocks/hero2/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/hero2/components/hero.tsx +4 -5
- package/registry/default/blocks/hero2/components/logo.tsx +3 -14
- package/registry/default/blocks/hero3/components/hero.tsx +2 -3
- package/registry/default/blocks/hero3/components/logo.tsx +3 -14
- package/registry/default/blocks/integrations1/components/integrations.tsx +7 -1
- package/registry/default/blocks/integrations2/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/integrations2/components/integrations.tsx +7 -1
- package/registry/default/blocks/integrations3/components/integrations.tsx +25 -34
- package/registry/default/blocks/integrations4/components/integrations.tsx +2 -5
- package/registry/default/blocks/integrations5/components/integrations.tsx +8 -5
- package/registry/default/blocks/logo-cloud-2/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/logo-cloud-3/app/page.tsx +2 -2
- package/registry/default/blocks/logo-cloud-3/components/logo-cloud.tsx +1 -1
- package/registry/default/blocks/logo-cloud-4/components/logo-cloud.tsx +1 -1
- package/registry/default/blocks/logo-cloud-4/components/progressive-blur.tsx +30 -36
- package/registry/default/blocks/pricing1/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/stats10/components/stats.tsx +1 -9
- package/registry/default/blocks/testimonials1/components/logo.tsx +3 -14
- package/registry/default/blocks/testimonials1/components/testimonials.tsx +1 -1
- package/registry/default/blocks/testimonials2/components/testimonials.tsx +3 -3
- package/registry/default/blocks/testimonials3/components/decor-icon.tsx +49 -36
- package/registry/default/blocks/testimonials3/components/testimonials.tsx +0 -1
- package/registry/default/blocks/testimonials5/components/testimonials.tsx +1 -1
- package/registry/default/blocks/testimonials6/components/testimonials.tsx +1 -1
- package/registry/default/examples/preview-card-profile.tsx +3 -3
- package/registry/default/ui/button.tsx +1 -1
- package/registry/default/ui/toggle.tsx +2 -1
- package/dist/chunk-VDMHIXDM.js +0 -121
- package/registry/default/blocks/auth1/components/particles.tsx +0 -321
|
@@ -19,7 +19,7 @@ type LogoType = {
|
|
|
19
19
|
alt: string;
|
|
20
20
|
isInvertable?: boolean;
|
|
21
21
|
};
|
|
22
|
-
type TileData = {
|
|
22
|
+
type TileData = { x: number; y: number; logo: LogoType };
|
|
23
23
|
|
|
24
24
|
export function Integrations() {
|
|
25
25
|
return (
|
|
@@ -37,19 +37,11 @@ export function Integrations() {
|
|
|
37
37
|
<Button size="sm">Explore LoveUI integrations</Button>
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
|
-
<div className="place-items-
|
|
41
|
-
<div className="relative
|
|
42
|
-
<div
|
|
43
|
-
className={cn(
|
|
44
|
-
"absolute inset-0 size-full",
|
|
45
|
-
"bg-[linear-gradient(to_right,theme(--color-border)_1px,transparent_1px),linear-gradient(to_bottom,theme(--color-border)_1px,transparent_1px)]",
|
|
46
|
-
"bg-size-[64px_64px]",
|
|
47
|
-
"mask-[radial-gradient(ellipse_at_center,black,black,transparent)]"
|
|
48
|
-
)}
|
|
49
|
-
/>
|
|
40
|
+
<div className="place-items-center px-8 py-12">
|
|
41
|
+
<div className="relative h-52 w-full">
|
|
50
42
|
{tiles.map((tile) => (
|
|
51
43
|
<IntegrationCard
|
|
52
|
-
key={String(tile.
|
|
44
|
+
key={String(tile.x) + "_" + String(tile.y)}
|
|
53
45
|
{...tile}
|
|
54
46
|
/>
|
|
55
47
|
))}
|
|
@@ -60,14 +52,17 @@ export function Integrations() {
|
|
|
60
52
|
);
|
|
61
53
|
}
|
|
62
54
|
|
|
63
|
-
function IntegrationCard({
|
|
55
|
+
function IntegrationCard({ x, y, logo }: TileData) {
|
|
64
56
|
return (
|
|
65
57
|
<div
|
|
66
58
|
className={cn(
|
|
67
|
-
"absolute flex size-
|
|
68
|
-
logo ? "bg-
|
|
59
|
+
"absolute z-10 flex size-14 items-center justify-center rounded-md border",
|
|
60
|
+
logo ? "bg-card shadow-xs" : ""
|
|
69
61
|
)}
|
|
70
|
-
style={{
|
|
62
|
+
style={{
|
|
63
|
+
left: `calc(${x}% - 1.75rem)`,
|
|
64
|
+
top: `calc(${y}% - 1.75rem)`,
|
|
65
|
+
}}
|
|
71
66
|
>
|
|
72
67
|
{logo && (
|
|
73
68
|
<LogoAsset
|
|
@@ -91,7 +86,7 @@ function LogoAsset({
|
|
|
91
86
|
return (
|
|
92
87
|
<Component
|
|
93
88
|
aria-label={logo.alt}
|
|
94
|
-
className={cn(className, logo.isInvertable && "
|
|
89
|
+
className={cn(className, logo.isInvertable && "text-foreground")}
|
|
95
90
|
role="img"
|
|
96
91
|
/>
|
|
97
92
|
);
|
|
@@ -99,39 +94,35 @@ function LogoAsset({
|
|
|
99
94
|
|
|
100
95
|
const tiles: TileData[] = [
|
|
101
96
|
{
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
x: 14,
|
|
98
|
+
y: 22,
|
|
104
99
|
logo: { Component: VercelLogo, alt: "Vercel Logo", isInvertable: true },
|
|
105
100
|
},
|
|
106
101
|
{
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
x: 60,
|
|
103
|
+
y: 22,
|
|
109
104
|
logo: { Component: CursorLogo, alt: "Cursor Logo", isInvertable: true },
|
|
110
105
|
},
|
|
111
|
-
{
|
|
112
|
-
{
|
|
113
|
-
{ row: 1, col: 4, logo: { Component: GmailLogo, alt: "Gmail Logo" } },
|
|
106
|
+
{ x: 36, y: 42, logo: { Component: NeonLogo, alt: "Neon Logo" } },
|
|
107
|
+
{ x: 84, y: 42, logo: { Component: GmailLogo, alt: "Gmail Logo" } },
|
|
114
108
|
{
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
x: 14,
|
|
110
|
+
y: 64,
|
|
117
111
|
logo: {
|
|
118
112
|
Component: PlanetscaleLogo,
|
|
119
113
|
alt: "Planetscale Logo",
|
|
120
114
|
isInvertable: true,
|
|
121
115
|
},
|
|
122
116
|
},
|
|
123
|
-
{
|
|
124
|
-
{ row: 3, col: 0 },
|
|
125
|
-
{ row: 3, col: 2, logo: { Component: PolarLogo, alt: "Polar Logo" } },
|
|
117
|
+
{ x: 36, y: 84, logo: { Component: PolarLogo, alt: "Polar Logo" } },
|
|
126
118
|
{
|
|
127
|
-
|
|
128
|
-
|
|
119
|
+
x: 84,
|
|
120
|
+
y: 82,
|
|
129
121
|
logo: { Component: VercelLogo, alt: "Vercel Logo", isInvertable: true },
|
|
130
122
|
},
|
|
131
|
-
{ row: 4, col: 1, logo: { Component: NeonLogo, alt: "Neon Logo" } },
|
|
132
123
|
{
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
x: 60,
|
|
125
|
+
y: 64,
|
|
135
126
|
logo: { Component: CursorLogo, alt: "Cursor Logo", isInvertable: true },
|
|
136
127
|
},
|
|
137
128
|
];
|
|
@@ -32,7 +32,7 @@ export function Integrations() {
|
|
|
32
32
|
</p>
|
|
33
33
|
</div>
|
|
34
34
|
<div className="place-items-end">
|
|
35
|
-
<div className="
|
|
35
|
+
<div className=" relative size-90">
|
|
36
36
|
{tiles.map((tile) => (
|
|
37
37
|
<IntegrationCard
|
|
38
38
|
key={String(tile.row) + "_" + String(tile.col)}
|
|
@@ -76,7 +76,7 @@ function LogoAsset({
|
|
|
76
76
|
return (
|
|
77
77
|
<Component
|
|
78
78
|
aria-label={logo.alt}
|
|
79
|
-
className={cn(className, logo.isInvertable && "
|
|
79
|
+
className={cn(className, logo.isInvertable && "text-foreground")}
|
|
80
80
|
role="img"
|
|
81
81
|
/>
|
|
82
82
|
);
|
|
@@ -93,7 +93,6 @@ const tiles: TileData[] = [
|
|
|
93
93
|
col: 3,
|
|
94
94
|
logo: { Component: CursorLogo, alt: "Cursor Logo", isInvertable: true },
|
|
95
95
|
},
|
|
96
|
-
{ row: 1, col: 0 },
|
|
97
96
|
{ row: 1, col: 2, logo: { Component: NeonLogo, alt: "Neon Logo" } },
|
|
98
97
|
{ row: 1, col: 4, logo: { Component: GmailLogo, alt: "Gmail Logo" } },
|
|
99
98
|
{
|
|
@@ -105,8 +104,6 @@ const tiles: TileData[] = [
|
|
|
105
104
|
isInvertable: true,
|
|
106
105
|
},
|
|
107
106
|
},
|
|
108
|
-
{ row: 2, col: 3 },
|
|
109
|
-
{ row: 3, col: 0 },
|
|
110
107
|
{ row: 3, col: 2, logo: { Component: PolarLogo, alt: "Polar Logo" } },
|
|
111
108
|
{
|
|
112
109
|
row: 3,
|
|
@@ -19,18 +19,17 @@ type Integration = {
|
|
|
19
19
|
Component?: LogoComponent;
|
|
20
20
|
name: string;
|
|
21
21
|
isInvertable?: boolean;
|
|
22
|
+
logoClassName?: string;
|
|
22
23
|
};
|
|
23
24
|
const data: Integration[] = [
|
|
24
|
-
{ name: "Empty 1" },
|
|
25
25
|
{ name: "Vercel", Component: VercelLogo, isInvertable: true },
|
|
26
26
|
{ name: "Cursor", Component: CursorLogo, isInvertable: true },
|
|
27
27
|
{ name: "Neon", Component: NeonLogo },
|
|
28
28
|
{ name: "PlanetScale", Component: PlanetscaleLogo, isInvertable: true },
|
|
29
|
-
{ name: "Notion", Component: NotionLogo },
|
|
29
|
+
{ name: "Notion", Component: NotionLogo, logoClassName: "text-black" },
|
|
30
30
|
{ name: "Gmail", Component: GmailLogo },
|
|
31
31
|
{ name: "Polar", Component: PolarLogo },
|
|
32
32
|
{ name: "Cursor", Component: CursorLogo, isInvertable: true },
|
|
33
|
-
{ name: "Empty 2" },
|
|
34
33
|
];
|
|
35
34
|
|
|
36
35
|
export function Integrations() {
|
|
@@ -45,7 +44,7 @@ export function Integrations() {
|
|
|
45
44
|
</p>
|
|
46
45
|
</div>
|
|
47
46
|
<div className="flex flex-col justify-center rounded-full border bg-secondary dark:bg-secondary/10">
|
|
48
|
-
<div className="
|
|
47
|
+
<div className=" flex items-center justify-center -space-x-2 p-1">
|
|
49
48
|
{data.map((item, index) => (
|
|
50
49
|
<div
|
|
51
50
|
className={cn(
|
|
@@ -88,7 +87,11 @@ function LogoAsset({
|
|
|
88
87
|
return (
|
|
89
88
|
<Component
|
|
90
89
|
aria-label={integration.name}
|
|
91
|
-
className={cn(
|
|
90
|
+
className={cn(
|
|
91
|
+
className,
|
|
92
|
+
integration.isInvertable && "text-foreground",
|
|
93
|
+
integration.logoClassName
|
|
94
|
+
)}
|
|
92
95
|
role="img"
|
|
93
96
|
/>
|
|
94
97
|
);
|
|
@@ -2,44 +2,57 @@ import { cn } from "@/lib/utils";
|
|
|
2
2
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
3
|
|
|
4
4
|
const DecorIconVariants = cva(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
"pointer-events-none absolute z-1 size-4 shrink-0 stroke-1 stroke-muted-foreground transition-transform",
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
position: {
|
|
9
|
+
// We also rotate the SVG inside the variant so the bracket always points inward
|
|
10
|
+
"top-left":
|
|
11
|
+
"top-0 left-0 -translate-x-1/2 -translate-y-1/2",
|
|
12
|
+
"top-right":
|
|
13
|
+
"top-0 right-0 translate-x-1/2 -translate-y-1/2 rotate-90",
|
|
14
|
+
"bottom-right":
|
|
15
|
+
"right-0 bottom-0 translate-x-1/2 translate-y-1/2 rotate-180",
|
|
16
|
+
"bottom-left":
|
|
17
|
+
"bottom-0 left-0 -translate-x-1/2 translate-y-1/2 -rotate-90",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
position: "top-left",
|
|
22
|
+
},
|
|
23
|
+
}
|
|
23
24
|
);
|
|
24
25
|
|
|
25
26
|
type DecorIconProps = React.ComponentProps<"svg"> &
|
|
26
|
-
|
|
27
|
+
VariantProps<typeof DecorIconVariants> & {
|
|
28
|
+
variant?: "bracket" | "dot" | "diagonal";
|
|
29
|
+
};
|
|
27
30
|
|
|
28
|
-
export function DecorIcon({ position, className, ...props }: DecorIconProps) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
export function DecorIcon({ position, variant = "bracket", className, ...props }: DecorIconProps) {
|
|
32
|
+
return (
|
|
33
|
+
<svg
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
className={cn(DecorIconVariants({ position, className }))}
|
|
36
|
+
fill="none"
|
|
37
|
+
stroke="currentColor"
|
|
38
|
+
viewBox="0 0 24 24"
|
|
39
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
40
|
+
{...props}
|
|
41
|
+
>
|
|
42
|
+
{/* OPTION 1: Corner Bracket (Default) */}
|
|
43
|
+
{variant === "bracket" && (
|
|
44
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4H4v8" />
|
|
45
|
+
)}
|
|
46
|
+
|
|
47
|
+
{/* OPTION 2: Minimalist Dot (Change fill to currentColor in class if using this) */}
|
|
48
|
+
{variant === "dot" && (
|
|
49
|
+
<circle cx="12" cy="12" r="3" fill="currentColor" />
|
|
50
|
+
)}
|
|
51
|
+
|
|
52
|
+
{/* OPTION 3: Diagonal Accent Line */}
|
|
53
|
+
{variant === "diagonal" && (
|
|
54
|
+
<path strokeLinecap="round" d="M4 20L20 4" />
|
|
55
|
+
)}
|
|
56
|
+
</svg>
|
|
57
|
+
);
|
|
45
58
|
}
|
|
@@ -9,9 +9,9 @@ export default function Page() {
|
|
|
9
9
|
<br />
|
|
10
10
|
<span className="font-semibold">Used by the leaders.</span>
|
|
11
11
|
</h2>
|
|
12
|
-
<div className="
|
|
12
|
+
<div className=" mx-auto my-5 h-px max-w-sm bg-border" />
|
|
13
13
|
<LogoCloud />
|
|
14
|
-
<div className="
|
|
14
|
+
<div className=" mt-5 h-px bg-border" />
|
|
15
15
|
</section>
|
|
16
16
|
</div>
|
|
17
17
|
);
|
|
@@ -39,7 +39,7 @@ const logos: Logo[] = [
|
|
|
39
39
|
|
|
40
40
|
export function LogoCloud() {
|
|
41
41
|
return (
|
|
42
|
-
<div className="
|
|
42
|
+
<div className=" overflow-hidden py-5">
|
|
43
43
|
<InfiniteSlider gap={56} reverse speed={80} speedOnHover={25}>
|
|
44
44
|
{logos.map((logo) => (
|
|
45
45
|
<LogoAsset
|
|
@@ -42,7 +42,7 @@ const logos: Logo[] = [
|
|
|
42
42
|
|
|
43
43
|
export function LogoCloud() {
|
|
44
44
|
return (
|
|
45
|
-
<div className="relative
|
|
45
|
+
<div className="relative overflow-hidden py-7">
|
|
46
46
|
<InfiniteSlider gap={56} reverse speed={60} speedOnHover={20}>
|
|
47
47
|
{logos.map((logo) => (
|
|
48
48
|
<LogoAsset
|
|
@@ -1,63 +1,57 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import { type HTMLMotionProps, motion } from "motion/react";
|
|
2
|
+
import { motion, type HTMLMotionProps } from "motion/react";
|
|
4
3
|
|
|
5
|
-
export const
|
|
6
|
-
top:
|
|
7
|
-
right:
|
|
8
|
-
bottom:
|
|
9
|
-
left:
|
|
4
|
+
export const BLUR_DIRECTIONS = {
|
|
5
|
+
top: "to bottom",
|
|
6
|
+
right: "to left",
|
|
7
|
+
bottom: "to top",
|
|
8
|
+
left: "to right",
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
export type ProgressiveBlurProps = {
|
|
13
|
-
direction?: keyof typeof
|
|
12
|
+
direction?: keyof typeof BLUR_DIRECTIONS;
|
|
14
13
|
blurLayers?: number;
|
|
15
14
|
className?: string;
|
|
16
15
|
blurIntensity?: number;
|
|
17
16
|
} & HTMLMotionProps<"div">;
|
|
18
17
|
|
|
19
18
|
export function ProgressiveBlur({
|
|
20
|
-
direction = "
|
|
19
|
+
direction = "left",
|
|
21
20
|
blurLayers = 8,
|
|
22
21
|
className,
|
|
23
|
-
blurIntensity =
|
|
22
|
+
blurIntensity = 1,
|
|
23
|
+
style,
|
|
24
24
|
...props
|
|
25
25
|
}: ProgressiveBlurProps) {
|
|
26
|
-
const layers = Math.max(
|
|
27
|
-
const
|
|
26
|
+
const layers = Math.max(1, blurLayers);
|
|
27
|
+
const gradientDirection = BLUR_DIRECTIONS[direction];
|
|
28
28
|
|
|
29
29
|
return (
|
|
30
|
-
<div
|
|
30
|
+
<motion.div
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
className={className}
|
|
33
|
+
style={{ overflow: "hidden", ...style }}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
31
36
|
{Array.from({ length: layers }).map((_, index) => {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
(index + 2) * segmentSize,
|
|
37
|
-
(index + 3) * segmentSize,
|
|
38
|
-
].map(
|
|
39
|
-
(pos, posIndex) =>
|
|
40
|
-
`rgba(255, 255, 255, ${posIndex === 1 || posIndex === 2 ? 1 : 0}) ${pos * 100}%`
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
const gradient = `linear-gradient(${angle}deg, ${gradientStops.join(
|
|
44
|
-
", "
|
|
45
|
-
)})`;
|
|
37
|
+
const blur = (index + 1) * blurIntensity * 2;
|
|
38
|
+
const coverage = ((layers - index) / layers) * 100;
|
|
39
|
+
const fadeEnd = Math.min(coverage + 16, 100);
|
|
40
|
+
const mask = `linear-gradient(${gradientDirection}, black 0%, black ${coverage}%, transparent ${fadeEnd}%)`;
|
|
46
41
|
|
|
47
42
|
return (
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
<div
|
|
44
|
+
key={String(index)}
|
|
45
|
+
className="absolute inset-0"
|
|
51
46
|
style={{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
47
|
+
backdropFilter: `blur(${blur}px)`,
|
|
48
|
+
WebkitBackdropFilter: `blur(${blur}px)`,
|
|
49
|
+
maskImage: mask,
|
|
50
|
+
WebkitMaskImage: mask,
|
|
56
51
|
}}
|
|
57
|
-
{...props}
|
|
58
52
|
/>
|
|
59
53
|
);
|
|
60
54
|
})}
|
|
61
|
-
</div>
|
|
55
|
+
</motion.div>
|
|
62
56
|
);
|
|
63
57
|
}
|
|
@@ -2,44 +2,57 @@ import { cn } from "@/lib/utils";
|
|
|
2
2
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
3
|
|
|
4
4
|
const DecorIconVariants = cva(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
"pointer-events-none absolute z-1 size-4 shrink-0 stroke-1 stroke-muted-foreground transition-transform",
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
position: {
|
|
9
|
+
// We also rotate the SVG inside the variant so the bracket always points inward
|
|
10
|
+
"top-left":
|
|
11
|
+
"top-0 left-0 -translate-x-1/2 -translate-y-1/2",
|
|
12
|
+
"top-right":
|
|
13
|
+
"top-0 right-0 translate-x-1/2 -translate-y-1/2 rotate-90",
|
|
14
|
+
"bottom-right":
|
|
15
|
+
"right-0 bottom-0 translate-x-1/2 translate-y-1/2 rotate-180",
|
|
16
|
+
"bottom-left":
|
|
17
|
+
"bottom-0 left-0 -translate-x-1/2 translate-y-1/2 -rotate-90",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
position: "top-left",
|
|
22
|
+
},
|
|
23
|
+
}
|
|
23
24
|
);
|
|
24
25
|
|
|
25
26
|
type DecorIconProps = React.ComponentProps<"svg"> &
|
|
26
|
-
|
|
27
|
+
VariantProps<typeof DecorIconVariants> & {
|
|
28
|
+
variant?: "bracket" | "dot" | "diagonal";
|
|
29
|
+
};
|
|
27
30
|
|
|
28
|
-
export function DecorIcon({ position, className, ...props }: DecorIconProps) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
export function DecorIcon({ position, variant = "bracket", className, ...props }: DecorIconProps) {
|
|
32
|
+
return (
|
|
33
|
+
<svg
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
className={cn(DecorIconVariants({ position, className }))}
|
|
36
|
+
fill="none"
|
|
37
|
+
stroke="currentColor"
|
|
38
|
+
viewBox="0 0 24 24"
|
|
39
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
40
|
+
{...props}
|
|
41
|
+
>
|
|
42
|
+
{/* OPTION 1: Corner Bracket (Default) */}
|
|
43
|
+
{variant === "bracket" && (
|
|
44
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4H4v8" />
|
|
45
|
+
)}
|
|
46
|
+
|
|
47
|
+
{/* OPTION 2: Minimalist Dot (Change fill to currentColor in class if using this) */}
|
|
48
|
+
{variant === "dot" && (
|
|
49
|
+
<circle cx="12" cy="12" r="3" fill="currentColor" />
|
|
50
|
+
)}
|
|
51
|
+
|
|
52
|
+
{/* OPTION 3: Diagonal Accent Line */}
|
|
53
|
+
{variant === "diagonal" && (
|
|
54
|
+
<path strokeLinecap="round" d="M4 20L20 4" />
|
|
55
|
+
)}
|
|
56
|
+
</svg>
|
|
57
|
+
);
|
|
45
58
|
}
|
|
@@ -138,8 +138,6 @@ export default function Stats10() {
|
|
|
138
138
|
<dl className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 w-full">
|
|
139
139
|
{summary.map((item) => {
|
|
140
140
|
const sanitizedName = sanitizeName(item.name);
|
|
141
|
-
const gradientId = `gradient-${sanitizedName}`;
|
|
142
|
-
|
|
143
141
|
const color =
|
|
144
142
|
item.changeType === "positive" ? "hsl(142.1 76.2% 36.3%)" : "hsl(0 72.2% 50.6%)";
|
|
145
143
|
|
|
@@ -188,17 +186,11 @@ export default function Stats10() {
|
|
|
188
186
|
}}
|
|
189
187
|
>
|
|
190
188
|
<AreaChart data={data}>
|
|
191
|
-
<defs>
|
|
192
|
-
<linearGradient id={gradientId} x1="0" y1="0" x2="0" y2="1">
|
|
193
|
-
<stop offset="5%" stopColor={color} stopOpacity={0.3} />
|
|
194
|
-
<stop offset="95%" stopColor={color} stopOpacity={0} />
|
|
195
|
-
</linearGradient>
|
|
196
|
-
</defs>
|
|
197
189
|
<XAxis dataKey="date" hide={true} />
|
|
198
190
|
<Area
|
|
199
191
|
dataKey={item.name}
|
|
200
192
|
stroke={color}
|
|
201
|
-
fill={
|
|
193
|
+
fill={color}
|
|
202
194
|
fillOpacity={0.4}
|
|
203
195
|
strokeWidth={1.5}
|
|
204
196
|
type="monotone"
|
|
@@ -7,21 +7,10 @@ export const Logo = (props: React.ComponentProps<"svg">) => (
|
|
|
7
7
|
xmlns="http://www.w3.org/2000/svg"
|
|
8
8
|
{...props}
|
|
9
9
|
>
|
|
10
|
-
|
|
11
|
-
<linearGradient id="loveui-blue" x1="0" x2="48" y1="0" y2="48">
|
|
12
|
-
<stop stopColor="#38A3FF" />
|
|
13
|
-
<stop offset="0.55" stopColor="#1266F1" />
|
|
14
|
-
<stop offset="1" stopColor="#0B3FD8" />
|
|
15
|
-
</linearGradient>
|
|
16
|
-
|
|
17
|
-
<linearGradient id="loveui-shine" x1="0" x2="1" y1="0" y2="1">
|
|
18
|
-
<stop stopColor="#FFFFFF" stopOpacity="0.9" />
|
|
19
|
-
<stop offset="1" stopColor="#BBD8FF" stopOpacity="0.4" />
|
|
20
|
-
</linearGradient>
|
|
21
|
-
</defs>
|
|
10
|
+
|
|
22
11
|
|
|
23
12
|
<g transform="translate(0 0)">
|
|
24
|
-
<rect fill="
|
|
13
|
+
<rect fill="#1266F1" height="48" rx="12" width="48" x="0" y="0" />
|
|
25
14
|
|
|
26
15
|
<path
|
|
27
16
|
d="
|
|
@@ -56,7 +45,7 @@ export const Logo = (props: React.ComponentProps<"svg">) => (
|
|
|
56
45
|
H18
|
|
57
46
|
C19.7 29 21 27.7 21 25
|
|
58
47
|
Z"
|
|
59
|
-
fill="
|
|
48
|
+
fill="#BBD8FF"
|
|
60
49
|
opacity="0.5"
|
|
61
50
|
/>
|
|
62
51
|
</g>
|
|
@@ -18,7 +18,7 @@ export function TestimonialsSection() {
|
|
|
18
18
|
control of the code."
|
|
19
19
|
</blockquote>
|
|
20
20
|
|
|
21
|
-
<div className="
|
|
21
|
+
<div className=" mx-auto my-5 h-px w-full max-w-sm bg-border" />
|
|
22
22
|
|
|
23
23
|
<figcaption className="flex flex-col items-center gap-5">
|
|
24
24
|
<div className="space-y-0.5 text-center">
|
|
@@ -16,7 +16,7 @@ export function TestimonialsSection() {
|
|
|
16
16
|
<MaskLine className="top-0 md:w-xl" orientation="horizontal" />
|
|
17
17
|
<MaskLine className="bottom-0 md:w-xl" orientation="horizontal" />
|
|
18
18
|
|
|
19
|
-
<Avatar className="
|
|
19
|
+
<Avatar className=" size-24 rounded-none *:rounded-none md:size-32">
|
|
20
20
|
<AvatarImage
|
|
21
21
|
alt="Connor Love's profile picture"
|
|
22
22
|
src="https://github.com/loveconnor.png"
|
|
@@ -54,9 +54,9 @@ export function MaskLine({
|
|
|
54
54
|
className={cn(
|
|
55
55
|
"absolute bg-foreground/20",
|
|
56
56
|
orientation === "vertical" &&
|
|
57
|
-
"
|
|
57
|
+
" -inset-y-1/2 w-px",
|
|
58
58
|
orientation === "horizontal" &&
|
|
59
|
-
"
|
|
59
|
+
" -inset-x-1/2 h-px",
|
|
60
60
|
className
|
|
61
61
|
)}
|
|
62
62
|
{...props}
|