@snow-labs/brutal-ui 0.1.0 → 0.2.0
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/components/brutal/cta-section.d.ts +7 -2
- package/dist/components/brutal/cta-section.js +253 -4
- package/dist/components/brutal/cta-section.js.map +1 -1
- package/dist/components/brutal/faq.d.ts +16 -0
- package/dist/components/brutal/faq.js +166 -0
- package/dist/components/brutal/faq.js.map +1 -0
- package/dist/components/brutal/feature-grid.d.ts +5 -1
- package/dist/components/brutal/feature-grid.js +238 -4
- package/dist/components/brutal/feature-grid.js.map +1 -1
- package/dist/components/brutal/footer.d.ts +14 -1
- package/dist/components/brutal/footer.js +215 -2
- package/dist/components/brutal/footer.js.map +1 -1
- package/dist/components/brutal/hero.d.ts +8 -1
- package/dist/components/brutal/hero.js +197 -4
- package/dist/components/brutal/hero.js.map +1 -1
- package/dist/components/brutal/index.d.ts +7 -2
- package/dist/components/brutal/index.js +1393 -12
- package/dist/components/brutal/index.js.map +1 -1
- package/dist/components/brutal/integration-grid.js +105 -3
- package/dist/components/brutal/integration-grid.js.map +1 -1
- package/dist/components/brutal/logo-cloud.d.ts +17 -0
- package/dist/components/brutal/logo-cloud.js +96 -0
- package/dist/components/brutal/logo-cloud.js.map +1 -0
- package/dist/components/brutal/nav.d.ts +3 -1
- package/dist/components/brutal/nav.js +258 -3
- package/dist/components/brutal/nav.js.map +1 -1
- package/dist/components/brutal/newsletter.d.ts +14 -0
- package/dist/components/brutal/newsletter.js +172 -0
- package/dist/components/brutal/newsletter.js.map +1 -0
- package/dist/components/brutal/pricing-table.d.ts +27 -0
- package/dist/components/brutal/pricing-table.js +254 -0
- package/dist/components/brutal/pricing-table.js.map +1 -0
- package/dist/components/brutal/section-divider.d.ts +14 -0
- package/dist/components/brutal/section-divider.js +70 -0
- package/dist/components/brutal/section-divider.js.map +1 -0
- package/dist/components/brutal/section.d.ts +6 -2
- package/dist/components/brutal/section.js +67 -2
- package/dist/components/brutal/section.js.map +1 -1
- package/dist/components/brutal/stats-bar.d.ts +16 -0
- package/dist/components/brutal/stats-bar.js +130 -0
- package/dist/components/brutal/stats-bar.js.map +1 -0
- package/dist/components/brutal/testimonials.d.ts +11 -3
- package/dist/components/brutal/testimonials.js +192 -3
- package/dist/components/brutal/testimonials.js.map +1 -1
- package/dist/components/brutal/wave-divider.d.ts +2 -12
- package/dist/components/brutal/wave-divider.js +68 -1
- package/dist/components/brutal/wave-divider.js.map +1 -1
- package/dist/components/dashboard/activity-feed.d.ts +18 -0
- package/dist/components/dashboard/activity-feed.js +105 -0
- package/dist/components/dashboard/activity-feed.js.map +1 -0
- package/dist/components/dashboard/app-shell.d.ts +19 -0
- package/dist/components/dashboard/app-shell.js +206 -0
- package/dist/components/dashboard/app-shell.js.map +1 -0
- package/dist/components/dashboard/empty-state.d.ts +14 -0
- package/dist/{chunk-CY2FOBOD.js → components/dashboard/empty-state.js} +36 -5
- package/dist/components/dashboard/empty-state.js.map +1 -0
- package/dist/components/dashboard/file-upload.d.ts +12 -0
- package/dist/components/dashboard/file-upload.js +86 -0
- package/dist/components/dashboard/file-upload.js.map +1 -0
- package/dist/components/dashboard/index.d.ts +10 -0
- package/dist/components/dashboard/index.js +755 -0
- package/dist/components/dashboard/index.js.map +1 -0
- package/dist/components/dashboard/search-bar.d.ts +12 -0
- package/dist/components/dashboard/search-bar.js +49 -0
- package/dist/components/dashboard/search-bar.js.map +1 -0
- package/dist/components/dashboard/sidebar.d.ts +23 -0
- package/dist/components/dashboard/sidebar.js +113 -0
- package/dist/components/dashboard/sidebar.js.map +1 -0
- package/dist/components/dashboard/stat-card.d.ts +13 -0
- package/dist/components/dashboard/stat-card.js +55 -0
- package/dist/components/dashboard/stat-card.js.map +1 -0
- package/dist/components/dashboard/user-menu.d.ts +16 -0
- package/dist/components/dashboard/user-menu.js +179 -0
- package/dist/components/dashboard/user-menu.js.map +1 -0
- package/dist/components/dashboard/view-switcher.d.ts +12 -0
- package/dist/{chunk-OCSYB6YE.js → components/dashboard/view-switcher.js} +57 -5
- package/dist/components/dashboard/view-switcher.js.map +1 -0
- package/dist/components/ui/accordion.js +78 -2
- package/dist/components/ui/accordion.js.map +1 -1
- package/dist/components/ui/alert.js +80 -2
- package/dist/components/ui/alert.js.map +1 -1
- package/dist/components/ui/avatar.js +103 -2
- package/dist/components/ui/avatar.js.map +1 -1
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/badge.js +55 -2
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/breadcrumb.js +122 -2
- package/dist/components/ui/breadcrumb.js.map +1 -1
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/button.js +68 -2
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/card.js +90 -2
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/checkbox.js +36 -2
- package/dist/components/ui/checkbox.js.map +1 -1
- package/dist/components/ui/collapsible.js +15 -1
- package/dist/components/ui/collapsible.js.map +1 -1
- package/dist/components/ui/command.js +399 -7
- package/dist/components/ui/command.js.map +1 -1
- package/dist/components/ui/context-menu.js +232 -2
- package/dist/components/ui/context-menu.js.map +1 -1
- package/dist/components/ui/dialog.js +201 -3
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/drawer.js +118 -2
- package/dist/components/ui/drawer.js.map +1 -1
- package/dist/components/ui/dropdown-menu.js +242 -2
- package/dist/components/ui/dropdown-menu.js.map +1 -1
- package/dist/components/ui/hover-card.js +47 -2
- package/dist/components/ui/hover-card.js.map +1 -1
- package/dist/components/ui/input-group.js +226 -5
- package/dist/components/ui/input-group.js.map +1 -1
- package/dist/components/ui/input.js +26 -2
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/label.js +23 -2
- package/dist/components/ui/label.js.map +1 -1
- package/dist/components/ui/menubar.js +398 -3
- package/dist/components/ui/menubar.js.map +1 -1
- package/dist/components/ui/navigation-menu.js +160 -2
- package/dist/components/ui/navigation-menu.js.map +1 -1
- package/dist/components/ui/pagination.js +185 -3
- package/dist/components/ui/pagination.js.map +1 -1
- package/dist/components/ui/popover.js +80 -2
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/progress.js +80 -2
- package/dist/components/ui/progress.js.map +1 -1
- package/dist/components/ui/radio-group.js +43 -2
- package/dist/components/ui/radio-group.js.map +1 -1
- package/dist/components/ui/scroll-area.js +63 -2
- package/dist/components/ui/scroll-area.js.map +1 -1
- package/dist/components/ui/select.js +190 -2
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/separator.js +29 -2
- package/dist/components/ui/separator.js.map +1 -1
- package/dist/components/ui/sheet.js +185 -3
- package/dist/components/ui/sheet.js.map +1 -1
- package/dist/components/ui/skeleton.js +21 -2
- package/dist/components/ui/skeleton.js.map +1 -1
- package/dist/components/ui/slider.js +62 -2
- package/dist/components/ui/slider.js.map +1 -1
- package/dist/components/ui/switch.js +36 -2
- package/dist/components/ui/switch.js.map +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/components/ui/tabs.js +85 -2
- package/dist/components/ui/tabs.js.map +1 -1
- package/dist/components/ui/textarea.js +24 -2
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/components/ui/toggle-group.js +101 -3
- package/dist/components/ui/toggle-group.js.map +1 -1
- package/dist/components/ui/toggle.js +47 -2
- package/dist/components/ui/toggle.js.map +1 -1
- package/dist/components/ui/tooltip.js +65 -2
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/components/views/calendar-view.d.ts +17 -0
- package/dist/components/views/calendar-view.js +182 -0
- package/dist/components/views/calendar-view.js.map +1 -0
- package/dist/components/views/data-table.d.ts +15 -0
- package/dist/components/views/data-table.js +204 -0
- package/dist/components/views/data-table.js.map +1 -0
- package/dist/components/views/grid-view.d.ts +11 -0
- package/dist/components/views/grid-view.js +31 -0
- package/dist/components/views/grid-view.js.map +1 -0
- package/dist/components/views/index.d.ts +7 -0
- package/dist/components/views/index.js +542 -0
- package/dist/components/views/index.js.map +1 -0
- package/dist/components/views/kanban-board.d.ts +21 -0
- package/dist/components/views/kanban-board.js +153 -0
- package/dist/components/views/kanban-board.js.map +1 -0
- package/dist/components/views/list-view.d.ts +19 -0
- package/dist/components/views/list-view.js +96 -0
- package/dist/components/views/list-view.js.map +1 -0
- package/dist/index.d.ts +27 -3
- package/dist/index.js +4957 -46
- package/dist/index.js.map +1 -1
- package/dist/lib/animations.d.ts +68 -0
- package/dist/lib/animations.js +44 -0
- package/dist/lib/animations.js.map +1 -0
- package/dist/lib/utils.js +10 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/templates/dashboard.d.ts +40 -0
- package/dist/templates/dashboard.js +658 -0
- package/dist/templates/dashboard.js.map +1 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.js +2031 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/saas-launch.d.ts +113 -0
- package/dist/templates/saas-launch.js +1424 -0
- package/dist/templates/saas-launch.js.map +1 -0
- package/dist/templates/studio.d.ts +72 -0
- package/dist/templates/studio.js +1129 -0
- package/dist/templates/studio.js.map +1 -0
- package/dist/theme.css +53 -0
- package/package.json +48 -2
- package/dist/chunk-3HN3QP23.js +0 -44
- package/dist/chunk-3HN3QP23.js.map +0 -1
- package/dist/chunk-4A3EQV6F.js +0 -76
- package/dist/chunk-4A3EQV6F.js.map +0 -1
- package/dist/chunk-53KZXLG4.js +0 -100
- package/dist/chunk-53KZXLG4.js.map +0 -1
- package/dist/chunk-5JCN6EQG.js +0 -60
- package/dist/chunk-5JCN6EQG.js.map +0 -1
- package/dist/chunk-5JEBZUEI.js +0 -20
- package/dist/chunk-5JEBZUEI.js.map +0 -1
- package/dist/chunk-6APJMAO7.js +0 -44
- package/dist/chunk-6APJMAO7.js.map +0 -1
- package/dist/chunk-6UKMYVHC.js +0 -187
- package/dist/chunk-6UKMYVHC.js.map +0 -1
- package/dist/chunk-7FVJ36BQ.js +0 -239
- package/dist/chunk-7FVJ36BQ.js.map +0 -1
- package/dist/chunk-7I7XYB7H.js +0 -44
- package/dist/chunk-7I7XYB7H.js.map +0 -1
- package/dist/chunk-A5KONGTJ.js +0 -49
- package/dist/chunk-A5KONGTJ.js.map +0 -1
- package/dist/chunk-AHUC5AID.js +0 -40
- package/dist/chunk-AHUC5AID.js.map +0 -1
- package/dist/chunk-B6UM5GHF.js +0 -20
- package/dist/chunk-B6UM5GHF.js.map +0 -1
- package/dist/chunk-BAUUM52T.js +0 -234
- package/dist/chunk-BAUUM52T.js.map +0 -1
- package/dist/chunk-BDWCMMEI.js +0 -82
- package/dist/chunk-BDWCMMEI.js.map +0 -1
- package/dist/chunk-BSVJVM2L.js +0 -52
- package/dist/chunk-BSVJVM2L.js.map +0 -1
- package/dist/chunk-CPVH3LD5.js +0 -86
- package/dist/chunk-CPVH3LD5.js.map +0 -1
- package/dist/chunk-CY2FOBOD.js.map +0 -1
- package/dist/chunk-DJTTNICL.js +0 -40
- package/dist/chunk-DJTTNICL.js.map +0 -1
- package/dist/chunk-F2E32OOJ.js +0 -38
- package/dist/chunk-F2E32OOJ.js.map +0 -1
- package/dist/chunk-F7YWBVP6.js +0 -141
- package/dist/chunk-F7YWBVP6.js.map +0 -1
- package/dist/chunk-G7JMADLU.js +0 -167
- package/dist/chunk-G7JMADLU.js.map +0 -1
- package/dist/chunk-GKCLNHVQ.js +0 -124
- package/dist/chunk-GKCLNHVQ.js.map +0 -1
- package/dist/chunk-GQBWKH72.js +0 -33
- package/dist/chunk-GQBWKH72.js.map +0 -1
- package/dist/chunk-H6SOU4UG.js +0 -10
- package/dist/chunk-H6SOU4UG.js.map +0 -1
- package/dist/chunk-HKJJHYFX.js +0 -115
- package/dist/chunk-HKJJHYFX.js.map +0 -1
- package/dist/chunk-IQ5WXHRB.js +0 -16
- package/dist/chunk-IQ5WXHRB.js.map +0 -1
- package/dist/chunk-ISZQ5TSG.js +0 -26
- package/dist/chunk-ISZQ5TSG.js.map +0 -1
- package/dist/chunk-JSYGVDO6.js +0 -41
- package/dist/chunk-JSYGVDO6.js.map +0 -1
- package/dist/chunk-KY6GKED2.js +0 -229
- package/dist/chunk-KY6GKED2.js.map +0 -1
- package/dist/chunk-L5OPCX6F.js +0 -33
- package/dist/chunk-L5OPCX6F.js.map +0 -1
- package/dist/chunk-LLMBKOKT.js +0 -44
- package/dist/chunk-LLMBKOKT.js.map +0 -1
- package/dist/chunk-MKBO4S2O.js +0 -48
- package/dist/chunk-MKBO4S2O.js.map +0 -1
- package/dist/chunk-NMQRI5G5.js +0 -48
- package/dist/chunk-NMQRI5G5.js.map +0 -1
- package/dist/chunk-OCSYB6YE.js.map +0 -1
- package/dist/chunk-OILW3ESA.js +0 -62
- package/dist/chunk-OILW3ESA.js.map +0 -1
- package/dist/chunk-PCVJLIUU.js +0 -125
- package/dist/chunk-PCVJLIUU.js.map +0 -1
- package/dist/chunk-RXSDAOF7.js +0 -45
- package/dist/chunk-RXSDAOF7.js.map +0 -1
- package/dist/chunk-RZD2P2BD.js +0 -77
- package/dist/chunk-RZD2P2BD.js.map +0 -1
- package/dist/chunk-UL52C2UU.js +0 -22
- package/dist/chunk-UL52C2UU.js.map +0 -1
- package/dist/chunk-USFQYYSE.js +0 -118
- package/dist/chunk-USFQYYSE.js.map +0 -1
- package/dist/chunk-UW3CSNPH.js +0 -77
- package/dist/chunk-UW3CSNPH.js.map +0 -1
- package/dist/chunk-V2ORCFEN.js +0 -156
- package/dist/chunk-V2ORCFEN.js.map +0 -1
- package/dist/chunk-WQO7NSII.js +0 -141
- package/dist/chunk-WQO7NSII.js.map +0 -1
- package/dist/chunk-WXHK2EIV.js +0 -75
- package/dist/chunk-WXHK2EIV.js.map +0 -1
- package/dist/chunk-Y6W3YC3K.js +0 -17
- package/dist/chunk-Y6W3YC3K.js.map +0 -1
- package/dist/chunk-ZRVEDPQA.js +0 -59
- package/dist/chunk-ZRVEDPQA.js.map +0 -1
|
@@ -1,6 +1,240 @@
|
|
|
1
|
-
|
|
2
|
-
import '
|
|
3
|
-
import '
|
|
4
|
-
import '
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/lib/utils.ts
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
function Card({
|
|
11
|
+
className,
|
|
12
|
+
...props
|
|
13
|
+
}) {
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
"data-slot": "card",
|
|
18
|
+
className: cn(
|
|
19
|
+
"group/card flex flex-col gap-4 rounded-lg border-brutal border-foreground bg-card p-5 text-card-foreground shadow-brutal transition-all duration-150 hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg",
|
|
20
|
+
className
|
|
21
|
+
),
|
|
22
|
+
...props
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
function CardHeader({ className, ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx(
|
|
28
|
+
"div",
|
|
29
|
+
{
|
|
30
|
+
"data-slot": "card-header",
|
|
31
|
+
className: cn("flex flex-col gap-1", className),
|
|
32
|
+
...props
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function CardTitle({ className, ...props }) {
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
"data-slot": "card-title",
|
|
41
|
+
className: cn("text-lg font-bold leading-snug", className),
|
|
42
|
+
...props
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
function CardDescription({ className, ...props }) {
|
|
47
|
+
return /* @__PURE__ */ jsx(
|
|
48
|
+
"div",
|
|
49
|
+
{
|
|
50
|
+
"data-slot": "card-description",
|
|
51
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
52
|
+
...props
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
function CardContent({ className, ...props }) {
|
|
57
|
+
return /* @__PURE__ */ jsx(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
"data-slot": "card-content",
|
|
61
|
+
className: cn("", className),
|
|
62
|
+
...props
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
var colorMap = {
|
|
67
|
+
white: "bg-background text-foreground",
|
|
68
|
+
brand: "bg-brand",
|
|
69
|
+
"brand-muted": "bg-brand-muted text-foreground",
|
|
70
|
+
blue: "bg-section-blue",
|
|
71
|
+
gray: "bg-section-gray text-foreground",
|
|
72
|
+
cream: "bg-section-cream text-foreground",
|
|
73
|
+
black: "bg-foreground text-background",
|
|
74
|
+
cta: "bg-cta"
|
|
75
|
+
};
|
|
76
|
+
var containerMap = {
|
|
77
|
+
sm: "brutal-container-sm",
|
|
78
|
+
default: "brutal-container",
|
|
79
|
+
lg: "brutal-container-lg"
|
|
80
|
+
};
|
|
81
|
+
var paddingMap = {
|
|
82
|
+
sm: "brutal-section-sm",
|
|
83
|
+
default: "brutal-section",
|
|
84
|
+
lg: "brutal-section py-28 sm:py-36 md:py-44"
|
|
85
|
+
};
|
|
86
|
+
var patternMap = {
|
|
87
|
+
dots: "brutal-dots",
|
|
88
|
+
stripes: "brutal-stripes",
|
|
89
|
+
noise: "brutal-noise",
|
|
90
|
+
grain: "brutal-grain",
|
|
91
|
+
crosshatch: "brutal-crosshatch",
|
|
92
|
+
"grid-dots": "brutal-grid-dots",
|
|
93
|
+
"gradient-mesh": "brutal-gradient-mesh",
|
|
94
|
+
none: ""
|
|
95
|
+
};
|
|
96
|
+
function BrutalSection({
|
|
97
|
+
children,
|
|
98
|
+
color = "white",
|
|
99
|
+
className,
|
|
100
|
+
containerSize = "default",
|
|
101
|
+
padding = "default",
|
|
102
|
+
pattern,
|
|
103
|
+
dots = false,
|
|
104
|
+
stripes = false,
|
|
105
|
+
id
|
|
106
|
+
}) {
|
|
107
|
+
const resolvedPattern = pattern ?? (dots ? "dots" : void 0) ?? (stripes ? "stripes" : void 0) ?? "none";
|
|
108
|
+
return /* @__PURE__ */ jsx(
|
|
109
|
+
"section",
|
|
110
|
+
{
|
|
111
|
+
id,
|
|
112
|
+
className: cn(
|
|
113
|
+
paddingMap[padding],
|
|
114
|
+
colorMap[color],
|
|
115
|
+
patternMap[resolvedPattern],
|
|
116
|
+
className
|
|
117
|
+
),
|
|
118
|
+
children: /* @__PURE__ */ jsx("div", { className: containerMap[containerSize], children })
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
var accentColors = [
|
|
123
|
+
"hsl(var(--brand))",
|
|
124
|
+
"hsl(var(--cta))",
|
|
125
|
+
"hsl(var(--section-blue))",
|
|
126
|
+
"hsl(12 85% 62%)",
|
|
127
|
+
"hsl(260 55% 68%)",
|
|
128
|
+
"hsl(25 75% 48%)"
|
|
129
|
+
];
|
|
130
|
+
var colMap = {
|
|
131
|
+
2: "sm:grid-cols-2",
|
|
132
|
+
3: "sm:grid-cols-2 lg:grid-cols-3",
|
|
133
|
+
4: "sm:grid-cols-2 lg:grid-cols-4"
|
|
134
|
+
};
|
|
135
|
+
function BrutalFeatureGrid({
|
|
136
|
+
variant = "icon-top",
|
|
137
|
+
badge,
|
|
138
|
+
headline,
|
|
139
|
+
description,
|
|
140
|
+
features,
|
|
141
|
+
columns = 3,
|
|
142
|
+
color = "white",
|
|
143
|
+
className
|
|
144
|
+
}) {
|
|
145
|
+
return /* @__PURE__ */ jsxs(BrutalSection, { color, className, children: [
|
|
146
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-12 max-w-2xl", children: [
|
|
147
|
+
badge && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-4 text-muted-foreground", children: badge }),
|
|
148
|
+
/* @__PURE__ */ jsx("h2", { className: "brutal-h2 mb-4", children: headline }),
|
|
149
|
+
description && /* @__PURE__ */ jsx("p", { className: "brutal-body text-muted-foreground", children: description })
|
|
150
|
+
] }),
|
|
151
|
+
/* @__PURE__ */ jsx(
|
|
152
|
+
"div",
|
|
153
|
+
{
|
|
154
|
+
className: cn(
|
|
155
|
+
"grid gap-6",
|
|
156
|
+
variant === "bento" ? "sm:grid-cols-2 lg:grid-cols-3" : colMap[columns]
|
|
157
|
+
),
|
|
158
|
+
children: features.map((feature, i) => /* @__PURE__ */ jsx(
|
|
159
|
+
FeatureCard,
|
|
160
|
+
{
|
|
161
|
+
feature,
|
|
162
|
+
variant,
|
|
163
|
+
index: i,
|
|
164
|
+
accentColor: accentColors[i % accentColors.length]
|
|
165
|
+
},
|
|
166
|
+
feature.title
|
|
167
|
+
))
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
] });
|
|
171
|
+
}
|
|
172
|
+
function FeatureCard({
|
|
173
|
+
feature,
|
|
174
|
+
variant,
|
|
175
|
+
index,
|
|
176
|
+
accentColor
|
|
177
|
+
}) {
|
|
178
|
+
const isBentoFeatured = variant === "bento" && feature.featured;
|
|
179
|
+
if (variant === "icon-left") {
|
|
180
|
+
return /* @__PURE__ */ jsxs(
|
|
181
|
+
"div",
|
|
182
|
+
{
|
|
183
|
+
className: "flex gap-4 border-brutal border-foreground bg-background p-5 shadow-brutal transition-all duration-150 hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg",
|
|
184
|
+
style: { borderLeftColor: accentColor, borderLeftWidth: "4px" },
|
|
185
|
+
children: [
|
|
186
|
+
feature.icon && /* @__PURE__ */ jsx("div", { className: "flex size-12 shrink-0 items-center justify-center border-brutal border-foreground bg-brand-muted text-2xl shadow-brutal-sm", children: feature.icon }),
|
|
187
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
188
|
+
feature.stat && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-1 text-brand", children: feature.stat }),
|
|
189
|
+
/* @__PURE__ */ jsx("h3", { className: "brutal-h4 mb-1", children: feature.title }),
|
|
190
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: feature.description })
|
|
191
|
+
] })
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
if (variant === "numbered") {
|
|
197
|
+
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
198
|
+
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
199
|
+
/* @__PURE__ */ jsx(
|
|
200
|
+
"span",
|
|
201
|
+
{
|
|
202
|
+
className: "brutal-display mb-2 block opacity-15",
|
|
203
|
+
style: { color: accentColor },
|
|
204
|
+
children: String(index + 1).padStart(2, "0")
|
|
205
|
+
}
|
|
206
|
+
),
|
|
207
|
+
feature.stat && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-1 text-brand", children: feature.stat }),
|
|
208
|
+
/* @__PURE__ */ jsx(CardTitle, { children: feature.title })
|
|
209
|
+
] }),
|
|
210
|
+
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(CardDescription, { children: feature.description }) })
|
|
211
|
+
] });
|
|
212
|
+
}
|
|
213
|
+
return /* @__PURE__ */ jsxs(
|
|
214
|
+
Card,
|
|
215
|
+
{
|
|
216
|
+
className: cn(
|
|
217
|
+
isBentoFeatured && "sm:col-span-2 bg-brand-muted"
|
|
218
|
+
),
|
|
219
|
+
children: [
|
|
220
|
+
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
221
|
+
feature.icon && /* @__PURE__ */ jsx(
|
|
222
|
+
"div",
|
|
223
|
+
{
|
|
224
|
+
className: "mb-2 inline-flex size-12 items-center justify-center border-brutal border-foreground bg-brand-muted text-2xl shadow-brutal-sm",
|
|
225
|
+
style: { borderBottomColor: accentColor },
|
|
226
|
+
children: feature.icon
|
|
227
|
+
}
|
|
228
|
+
),
|
|
229
|
+
feature.stat && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-1 text-brand", children: feature.stat }),
|
|
230
|
+
/* @__PURE__ */ jsx(CardTitle, { children: feature.title })
|
|
231
|
+
] }),
|
|
232
|
+
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(CardDescription, { children: feature.description }) })
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export { BrutalFeatureGrid };
|
|
5
239
|
//# sourceMappingURL=feature-grid.js.map
|
|
6
240
|
//# sourceMappingURL=feature-grid.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"feature-grid.js"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/card.tsx","../../../src/components/brutal/section.tsx","../../../src/components/brutal/feature-grid.tsx"],"names":["jsx"],"mappings":"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","file":"feature-grid.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Card({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n \"group/card flex flex-col gap-4 rounded-lg border-brutal border-foreground bg-card p-5 text-card-foreground shadow-brutal transition-all duration-150 hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\"flex flex-col gap-1\", className)}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"text-lg font-bold leading-snug\", className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\"self-start justify-self-end\", className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"\", className)}\n {...props}\n />\n );\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n \"flex items-center border-t-brutal border-foreground pt-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n};\n","import { cn } from \"../../lib/utils\";\n\nexport type SectionColor =\n | \"white\"\n | \"brand\"\n | \"brand-muted\"\n | \"blue\"\n | \"gray\"\n | \"cream\"\n | \"black\"\n | \"cta\";\n\nexport type SectionPattern =\n | \"dots\"\n | \"stripes\"\n | \"noise\"\n | \"grain\"\n | \"crosshatch\"\n | \"grid-dots\"\n | \"gradient-mesh\"\n | \"none\";\n\ninterface BrutalSectionProps {\n children: React.ReactNode;\n color?: SectionColor;\n className?: string;\n containerSize?: \"sm\" | \"default\" | \"lg\";\n padding?: \"sm\" | \"default\" | \"lg\";\n pattern?: SectionPattern;\n /** @deprecated Use pattern=\"dots\" instead */\n dots?: boolean;\n /** @deprecated Use pattern=\"stripes\" instead */\n stripes?: boolean;\n id?: string;\n}\n\nconst colorMap: Record<SectionColor, string> = {\n white: \"bg-background text-foreground\",\n brand: \"bg-brand\",\n \"brand-muted\": \"bg-brand-muted text-foreground\",\n blue: \"bg-section-blue\",\n gray: \"bg-section-gray text-foreground\",\n cream: \"bg-section-cream text-foreground\",\n black: \"bg-foreground text-background\",\n cta: \"bg-cta\",\n};\n\nconst containerMap = {\n sm: \"brutal-container-sm\",\n default: \"brutal-container\",\n lg: \"brutal-container-lg\",\n};\n\nconst paddingMap = {\n sm: \"brutal-section-sm\",\n default: \"brutal-section\",\n lg: \"brutal-section py-28 sm:py-36 md:py-44\",\n};\n\nconst patternMap: Record<SectionPattern, string> = {\n dots: \"brutal-dots\",\n stripes: \"brutal-stripes\",\n noise: \"brutal-noise\",\n grain: \"brutal-grain\",\n crosshatch: \"brutal-crosshatch\",\n \"grid-dots\": \"brutal-grid-dots\",\n \"gradient-mesh\": \"brutal-gradient-mesh\",\n none: \"\",\n};\n\nexport function BrutalSection({\n children,\n color = \"white\",\n className,\n containerSize = \"default\",\n padding = \"default\",\n pattern,\n dots = false,\n stripes = false,\n id,\n}: BrutalSectionProps) {\n const resolvedPattern = pattern\n ?? (dots ? \"dots\" : undefined)\n ?? (stripes ? \"stripes\" : undefined)\n ?? \"none\";\n\n return (\n <section\n id={id}\n className={cn(\n paddingMap[padding],\n colorMap[color],\n patternMap[resolvedPattern],\n className\n )}\n >\n <div className={containerMap[containerSize]}>{children}</div>\n </section>\n );\n}\n","import { cn } from \"../../lib/utils\";\nimport {\n Card,\n CardHeader,\n CardTitle,\n CardDescription,\n CardContent,\n} from \"../ui/card\";\nimport { BrutalSection } from \"./section\";\n\ntype FeatureGridVariant = \"icon-top\" | \"icon-left\" | \"numbered\" | \"bento\";\n\ninterface Feature {\n icon?: React.ReactNode;\n title: string;\n description: string;\n featured?: boolean;\n stat?: string;\n}\n\ninterface BrutalFeatureGridProps {\n variant?: FeatureGridVariant;\n badge?: string;\n headline: string;\n description?: string;\n features: Feature[];\n columns?: 2 | 3 | 4;\n color?: \"white\" | \"brand\" | \"brand-muted\" | \"gray\" | \"cream\";\n className?: string;\n}\n\nconst accentColors = [\n \"hsl(var(--brand))\",\n \"hsl(var(--cta))\",\n \"hsl(var(--section-blue))\",\n \"hsl(12 85% 62%)\",\n \"hsl(260 55% 68%)\",\n \"hsl(25 75% 48%)\",\n];\n\nconst colMap = {\n 2: \"sm:grid-cols-2\",\n 3: \"sm:grid-cols-2 lg:grid-cols-3\",\n 4: \"sm:grid-cols-2 lg:grid-cols-4\",\n};\n\nexport function BrutalFeatureGrid({\n variant = \"icon-top\",\n badge,\n headline,\n description,\n features,\n columns = 3,\n color = \"white\",\n className,\n}: BrutalFeatureGridProps) {\n return (\n <BrutalSection color={color} className={className}>\n <div className=\"mb-12 max-w-2xl\">\n {badge && (\n <p className=\"brutal-label mb-4 text-muted-foreground\">{badge}</p>\n )}\n <h2 className=\"brutal-h2 mb-4\">{headline}</h2>\n {description && (\n <p className=\"brutal-body text-muted-foreground\">{description}</p>\n )}\n </div>\n\n <div\n className={cn(\n \"grid gap-6\",\n variant === \"bento\" ? \"sm:grid-cols-2 lg:grid-cols-3\" : colMap[columns],\n )}\n >\n {features.map((feature, i) => (\n <FeatureCard\n key={feature.title}\n feature={feature}\n variant={variant}\n index={i}\n accentColor={accentColors[i % accentColors.length]}\n />\n ))}\n </div>\n </BrutalSection>\n );\n}\n\nfunction FeatureCard({\n feature,\n variant,\n index,\n accentColor,\n}: {\n feature: Feature;\n variant: FeatureGridVariant;\n index: number;\n accentColor: string;\n}) {\n const isBentoFeatured = variant === \"bento\" && feature.featured;\n\n if (variant === \"icon-left\") {\n return (\n <div\n className=\"flex gap-4 border-brutal border-foreground bg-background p-5 shadow-brutal transition-all duration-150 hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg\"\n style={{ borderLeftColor: accentColor, borderLeftWidth: \"4px\" }}\n >\n {feature.icon && (\n <div className=\"flex size-12 shrink-0 items-center justify-center border-brutal border-foreground bg-brand-muted text-2xl shadow-brutal-sm\">\n {feature.icon}\n </div>\n )}\n <div>\n {feature.stat && (\n <p className=\"brutal-label mb-1 text-brand\">{feature.stat}</p>\n )}\n <h3 className=\"brutal-h4 mb-1\">{feature.title}</h3>\n <p className=\"text-sm text-muted-foreground\">{feature.description}</p>\n </div>\n </div>\n );\n }\n\n if (variant === \"numbered\") {\n return (\n <Card>\n <CardHeader>\n <span\n className=\"brutal-display mb-2 block opacity-15\"\n style={{ color: accentColor }}\n >\n {String(index + 1).padStart(2, \"0\")}\n </span>\n {feature.stat && (\n <p className=\"brutal-label mb-1 text-brand\">{feature.stat}</p>\n )}\n <CardTitle>{feature.title}</CardTitle>\n </CardHeader>\n <CardContent>\n <CardDescription>{feature.description}</CardDescription>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card\n className={cn(\n isBentoFeatured && \"sm:col-span-2 bg-brand-muted\",\n )}\n >\n <CardHeader>\n {feature.icon && (\n <div\n className=\"mb-2 inline-flex size-12 items-center justify-center border-brutal border-foreground bg-brand-muted text-2xl shadow-brutal-sm\"\n style={{ borderBottomColor: accentColor }}\n >\n {feature.icon}\n </div>\n )}\n {feature.stat && (\n <p className=\"brutal-label mb-1 text-brand\">{feature.stat}</p>\n )}\n <CardTitle>{feature.title}</CardTitle>\n </CardHeader>\n <CardContent>\n <CardDescription>{feature.description}</CardDescription>\n </CardContent>\n </Card>\n );\n}\n"]}
|
|
@@ -13,8 +13,21 @@ interface BrutalFooterProps {
|
|
|
13
13
|
columns: FooterColumn[];
|
|
14
14
|
bottomLeft?: string;
|
|
15
15
|
bottomRight?: string;
|
|
16
|
+
variant?: "mega" | "minimal" | "newsletter";
|
|
17
|
+
socials?: {
|
|
18
|
+
twitter?: string;
|
|
19
|
+
github?: string;
|
|
20
|
+
linkedin?: string;
|
|
21
|
+
discord?: string;
|
|
22
|
+
};
|
|
23
|
+
newsletter?: {
|
|
24
|
+
headline?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
placeholder?: string;
|
|
27
|
+
buttonText?: string;
|
|
28
|
+
};
|
|
16
29
|
className?: string;
|
|
17
30
|
}
|
|
18
|
-
declare function BrutalFooter({ logo, tagline, columns, bottomLeft, bottomRight, className, }: BrutalFooterProps): react_jsx_runtime.JSX.Element;
|
|
31
|
+
declare function BrutalFooter({ logo, tagline, columns, bottomLeft, bottomRight, variant, socials, newsletter, className, }: BrutalFooterProps): react_jsx_runtime.JSX.Element;
|
|
19
32
|
|
|
20
33
|
export { BrutalFooter };
|
|
@@ -1,4 +1,217 @@
|
|
|
1
|
-
|
|
2
|
-
import '
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { Button as Button$1 } from '@base-ui/react/button';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import { Input as Input$1 } from '@base-ui/react/input';
|
|
8
|
+
|
|
9
|
+
// src/lib/utils.ts
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return twMerge(clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
var buttonVariants = cva(
|
|
14
|
+
"group/button inline-flex shrink-0 items-center justify-center rounded-lg whitespace-nowrap font-bold transition-all duration-150 select-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
// Primary: Black bg, white text, offset shadow
|
|
19
|
+
default: "border-brutal border-foreground bg-primary text-primary-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
20
|
+
// CTA: Mint green bg — the Bannerbear signature
|
|
21
|
+
cta: "border-brutal border-foreground bg-cta text-cta-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
22
|
+
// Brand: Dynamic brand color bg
|
|
23
|
+
brand: "border-brutal border-foreground bg-brand text-brand-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
24
|
+
// Outline: White bg, black border, offset shadow
|
|
25
|
+
outline: "border-brutal border-foreground bg-background text-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
26
|
+
// Secondary: Light bg, border, smaller shadow
|
|
27
|
+
secondary: "border-brutal border-foreground bg-secondary text-secondary-foreground shadow-brutal-sm hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal active:translate-x-px active:translate-y-px active:shadow-none",
|
|
28
|
+
// Ghost: No border/shadow, subtle hover
|
|
29
|
+
ghost: "hover:bg-secondary hover:text-foreground",
|
|
30
|
+
// Link: Text only
|
|
31
|
+
link: "text-foreground underline-offset-4 hover:underline",
|
|
32
|
+
// Destructive
|
|
33
|
+
destructive: "border-brutal border-destructive bg-destructive text-destructive-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
34
|
+
// Nav: Thin border, no shadow (for nav Sign In buttons)
|
|
35
|
+
nav: "border border-foreground bg-background text-foreground hover:bg-foreground hover:text-background"
|
|
36
|
+
},
|
|
37
|
+
size: {
|
|
38
|
+
xs: "h-7 gap-1 px-2.5 text-xs",
|
|
39
|
+
sm: "h-8 gap-1.5 px-3 text-sm",
|
|
40
|
+
default: "h-10 gap-2 px-5 text-sm",
|
|
41
|
+
lg: "h-12 gap-2 px-7 text-base",
|
|
42
|
+
xl: "h-14 gap-2.5 px-9 text-lg",
|
|
43
|
+
icon: "size-10",
|
|
44
|
+
"icon-sm": "size-8",
|
|
45
|
+
"icon-lg": "size-12"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: {
|
|
49
|
+
variant: "default",
|
|
50
|
+
size: "default"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
function Button({
|
|
55
|
+
className,
|
|
56
|
+
variant = "default",
|
|
57
|
+
size = "default",
|
|
58
|
+
...props
|
|
59
|
+
}) {
|
|
60
|
+
return /* @__PURE__ */ jsx(
|
|
61
|
+
Button$1,
|
|
62
|
+
{
|
|
63
|
+
"data-slot": "button",
|
|
64
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
65
|
+
...props
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function Input({ className, type, ...props }) {
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
Input$1,
|
|
72
|
+
{
|
|
73
|
+
type,
|
|
74
|
+
"data-slot": "input",
|
|
75
|
+
className: cn(
|
|
76
|
+
"h-10 w-full min-w-0 rounded-lg border-brutal border-foreground bg-background px-3 py-2 text-base font-medium shadow-brutal-sm transition-all outline-none placeholder:text-muted-foreground focus:shadow-brutal focus:-translate-x-0.5 focus:-translate-y-0.5 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive md:text-sm",
|
|
77
|
+
className
|
|
78
|
+
),
|
|
79
|
+
...props
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function SocialsRow({
|
|
84
|
+
socials
|
|
85
|
+
}) {
|
|
86
|
+
const items = [
|
|
87
|
+
{ key: "twitter", label: "Twitter", url: socials.twitter },
|
|
88
|
+
{ key: "github", label: "GitHub", url: socials.github },
|
|
89
|
+
{ key: "linkedin", label: "LinkedIn", url: socials.linkedin },
|
|
90
|
+
{ key: "discord", label: "Discord", url: socials.discord }
|
|
91
|
+
].filter((s) => s.url);
|
|
92
|
+
if (items.length === 0) return null;
|
|
93
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4", children: items.map((s) => /* @__PURE__ */ jsx(
|
|
94
|
+
"a",
|
|
95
|
+
{
|
|
96
|
+
href: s.url,
|
|
97
|
+
target: "_blank",
|
|
98
|
+
rel: "noopener noreferrer",
|
|
99
|
+
className: "text-sm font-bold transition-colors hover:text-muted-foreground",
|
|
100
|
+
children: s.label
|
|
101
|
+
},
|
|
102
|
+
s.key
|
|
103
|
+
)) });
|
|
104
|
+
}
|
|
105
|
+
function NewsletterSection({
|
|
106
|
+
newsletter
|
|
107
|
+
}) {
|
|
108
|
+
return /* @__PURE__ */ jsx("div", { className: "mb-10 border-b-brutal border-foreground pb-10", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-lg text-center", children: [
|
|
109
|
+
/* @__PURE__ */ jsx("h3", { className: "brutal-h4 mb-2", children: newsletter.headline || "Stay in the loop" }),
|
|
110
|
+
newsletter.description && /* @__PURE__ */ jsx("p", { className: "brutal-caption mb-4", children: newsletter.description }),
|
|
111
|
+
/* @__PURE__ */ jsxs(
|
|
112
|
+
"form",
|
|
113
|
+
{
|
|
114
|
+
onSubmit: (e) => e.preventDefault(),
|
|
115
|
+
className: "flex gap-2",
|
|
116
|
+
children: [
|
|
117
|
+
/* @__PURE__ */ jsx(
|
|
118
|
+
Input,
|
|
119
|
+
{
|
|
120
|
+
type: "email",
|
|
121
|
+
placeholder: newsletter.placeholder || "you@email.com",
|
|
122
|
+
className: "flex-1"
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
/* @__PURE__ */ jsx(Button, { variant: "default", size: "default", type: "submit", children: newsletter.buttonText || "Subscribe" })
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
] }) });
|
|
130
|
+
}
|
|
131
|
+
function MegaContent({
|
|
132
|
+
logo,
|
|
133
|
+
tagline,
|
|
134
|
+
columns,
|
|
135
|
+
socials
|
|
136
|
+
}) {
|
|
137
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-10 flex flex-col gap-8 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
138
|
+
/* @__PURE__ */ jsxs("div", { className: "max-w-xs", children: [
|
|
139
|
+
/* @__PURE__ */ jsx("div", { className: "mb-2 text-xl font-black", children: logo }),
|
|
140
|
+
tagline && /* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: tagline }),
|
|
141
|
+
socials && /* @__PURE__ */ jsx(SocialsRow, { socials })
|
|
142
|
+
] }),
|
|
143
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-8 sm:grid-cols-3 md:gap-12", children: columns.map((col) => /* @__PURE__ */ jsxs("div", { children: [
|
|
144
|
+
/* @__PURE__ */ jsx("h3", { className: "brutal-label mb-3 text-muted-foreground", children: col.title }),
|
|
145
|
+
/* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2", children: col.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
146
|
+
"a",
|
|
147
|
+
{
|
|
148
|
+
href: link.href,
|
|
149
|
+
className: "text-sm font-medium transition-colors hover:text-muted-foreground",
|
|
150
|
+
children: link.label
|
|
151
|
+
}
|
|
152
|
+
) }, link.href)) })
|
|
153
|
+
] }, col.title)) })
|
|
154
|
+
] });
|
|
155
|
+
}
|
|
156
|
+
function MinimalContent({
|
|
157
|
+
logo,
|
|
158
|
+
columns,
|
|
159
|
+
socials
|
|
160
|
+
}) {
|
|
161
|
+
const allLinks = columns.flatMap((col) => col.links);
|
|
162
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-6 flex flex-col items-center gap-4 sm:flex-row sm:justify-between", children: [
|
|
163
|
+
/* @__PURE__ */ jsx("div", { className: "text-xl font-black", children: logo }),
|
|
164
|
+
/* @__PURE__ */ jsx("nav", { className: "flex flex-wrap items-center justify-center gap-x-6 gap-y-2", children: allLinks.map((link) => /* @__PURE__ */ jsx(
|
|
165
|
+
"a",
|
|
166
|
+
{
|
|
167
|
+
href: link.href,
|
|
168
|
+
className: "text-sm font-medium transition-colors hover:text-muted-foreground",
|
|
169
|
+
children: link.label
|
|
170
|
+
},
|
|
171
|
+
link.href
|
|
172
|
+
)) }),
|
|
173
|
+
socials && /* @__PURE__ */ jsx(SocialsRow, { socials })
|
|
174
|
+
] });
|
|
175
|
+
}
|
|
176
|
+
function BrutalFooter({
|
|
177
|
+
logo,
|
|
178
|
+
tagline,
|
|
179
|
+
columns,
|
|
180
|
+
bottomLeft,
|
|
181
|
+
bottomRight,
|
|
182
|
+
variant = "mega",
|
|
183
|
+
socials,
|
|
184
|
+
newsletter,
|
|
185
|
+
className
|
|
186
|
+
}) {
|
|
187
|
+
return /* @__PURE__ */ jsx(
|
|
188
|
+
"footer",
|
|
189
|
+
{
|
|
190
|
+
className: cn(
|
|
191
|
+
"w-full border-t-4 bg-background px-6 py-12 text-foreground",
|
|
192
|
+
className
|
|
193
|
+
),
|
|
194
|
+
style: { borderTopColor: "hsl(var(--brand))" },
|
|
195
|
+
children: /* @__PURE__ */ jsxs("div", { className: "brutal-container", children: [
|
|
196
|
+
variant === "newsletter" && newsletter && /* @__PURE__ */ jsx(NewsletterSection, { newsletter }),
|
|
197
|
+
variant === "minimal" ? /* @__PURE__ */ jsx(MinimalContent, { logo, columns, socials }) : /* @__PURE__ */ jsx(
|
|
198
|
+
MegaContent,
|
|
199
|
+
{
|
|
200
|
+
logo,
|
|
201
|
+
tagline,
|
|
202
|
+
columns,
|
|
203
|
+
socials
|
|
204
|
+
}
|
|
205
|
+
),
|
|
206
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-t-brutal border-foreground pt-6 font-mono text-xs uppercase tracking-widest text-muted-foreground", children: [
|
|
207
|
+
/* @__PURE__ */ jsx("span", { children: bottomLeft || "Built with care" }),
|
|
208
|
+
/* @__PURE__ */ jsx("span", { children: bottomRight || (/* @__PURE__ */ new Date()).getFullYear() })
|
|
209
|
+
] })
|
|
210
|
+
] })
|
|
211
|
+
}
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export { BrutalFooter };
|
|
3
216
|
//# sourceMappingURL=footer.js.map
|
|
4
217
|
//# sourceMappingURL=footer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"footer.js"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/button.tsx","../../../src/components/ui/input.tsx","../../../src/components/brutal/footer.tsx"],"names":["ButtonPrimitive","jsx","InputPrimitive"],"mappings":"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","file":"footer.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\";\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg whitespace-nowrap font-bold transition-all duration-150 select-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n // Primary: Black bg, white text, offset shadow\n default:\n \"border-brutal border-foreground bg-primary text-primary-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // CTA: Mint green bg — the Bannerbear signature\n cta: \"border-brutal border-foreground bg-cta text-cta-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Brand: Dynamic brand color bg\n brand:\n \"border-brutal border-foreground bg-brand text-brand-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Outline: White bg, black border, offset shadow\n outline:\n \"border-brutal border-foreground bg-background text-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Secondary: Light bg, border, smaller shadow\n secondary:\n \"border-brutal border-foreground bg-secondary text-secondary-foreground shadow-brutal-sm hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal active:translate-x-px active:translate-y-px active:shadow-none\",\n // Ghost: No border/shadow, subtle hover\n ghost: \"hover:bg-secondary hover:text-foreground\",\n // Link: Text only\n link: \"text-foreground underline-offset-4 hover:underline\",\n // Destructive\n destructive:\n \"border-brutal border-destructive bg-destructive text-destructive-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Nav: Thin border, no shadow (for nav Sign In buttons)\n nav: \"border border-foreground bg-background text-foreground hover:bg-foreground hover:text-background\",\n },\n size: {\n xs: \"h-7 gap-1 px-2.5 text-xs\",\n sm: \"h-8 gap-1.5 px-3 text-sm\",\n default: \"h-10 gap-2 px-5 text-sm\",\n lg: \"h-12 gap-2 px-7 text-base\",\n xl: \"h-14 gap-2.5 px-9 text-lg\",\n icon: \"size-10\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-12\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\nimport { Input as InputPrimitive } from \"@base-ui/react/input\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-10 w-full min-w-0 rounded-lg border-brutal border-foreground bg-background px-3 py-2 text-base font-medium shadow-brutal-sm transition-all outline-none placeholder:text-muted-foreground focus:shadow-brutal focus:-translate-x-0.5 focus:-translate-y-0.5 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive md:text-sm\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n","import { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\n\ninterface FooterColumn {\n title: string;\n links: { label: string; href: string }[];\n}\n\ninterface BrutalFooterProps {\n logo: React.ReactNode;\n tagline?: string;\n columns: FooterColumn[];\n bottomLeft?: string;\n bottomRight?: string;\n variant?: \"mega\" | \"minimal\" | \"newsletter\";\n socials?: {\n twitter?: string;\n github?: string;\n linkedin?: string;\n discord?: string;\n };\n newsletter?: {\n headline?: string;\n description?: string;\n placeholder?: string;\n buttonText?: string;\n };\n className?: string;\n}\n\nfunction SocialsRow({\n socials,\n}: {\n socials: NonNullable<BrutalFooterProps[\"socials\"]>;\n}) {\n const items = [\n { key: \"twitter\", label: \"Twitter\", url: socials.twitter },\n { key: \"github\", label: \"GitHub\", url: socials.github },\n { key: \"linkedin\", label: \"LinkedIn\", url: socials.linkedin },\n { key: \"discord\", label: \"Discord\", url: socials.discord },\n ].filter((s) => s.url);\n\n if (items.length === 0) return null;\n\n return (\n <div className=\"flex items-center gap-4\">\n {items.map((s) => (\n <a\n key={s.key}\n href={s.url!}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm font-bold transition-colors hover:text-muted-foreground\"\n >\n {s.label}\n </a>\n ))}\n </div>\n );\n}\n\nfunction NewsletterSection({\n newsletter,\n}: {\n newsletter: NonNullable<BrutalFooterProps[\"newsletter\"]>;\n}) {\n return (\n <div className=\"mb-10 border-b-brutal border-foreground pb-10\">\n <div className=\"mx-auto max-w-lg text-center\">\n <h3 className=\"brutal-h4 mb-2\">\n {newsletter.headline || \"Stay in the loop\"}\n </h3>\n {newsletter.description && (\n <p className=\"brutal-caption mb-4\">{newsletter.description}</p>\n )}\n <form\n onSubmit={(e) => e.preventDefault()}\n className=\"flex gap-2\"\n >\n <Input\n type=\"email\"\n placeholder={newsletter.placeholder || \"you@email.com\"}\n className=\"flex-1\"\n />\n <Button variant=\"default\" size=\"default\" type=\"submit\">\n {newsletter.buttonText || \"Subscribe\"}\n </Button>\n </form>\n </div>\n </div>\n );\n}\n\nfunction MegaContent({\n logo,\n tagline,\n columns,\n socials,\n}: Pick<BrutalFooterProps, \"logo\" | \"tagline\" | \"columns\" | \"socials\">) {\n return (\n <div className=\"mb-10 flex flex-col gap-8 sm:flex-row sm:items-start sm:justify-between\">\n {/* Logo + tagline */}\n <div className=\"max-w-xs\">\n <div className=\"mb-2 text-xl font-black\">{logo}</div>\n {tagline && (\n <p className=\"mb-4 text-sm text-muted-foreground\">{tagline}</p>\n )}\n {socials && <SocialsRow socials={socials} />}\n </div>\n\n {/* Link columns */}\n <div className=\"grid grid-cols-2 gap-8 sm:grid-cols-3 md:gap-12\">\n {columns.map((col) => (\n <div key={col.title}>\n <h3 className=\"brutal-label mb-3 text-muted-foreground\">\n {col.title}\n </h3>\n <ul className=\"flex flex-col gap-2\">\n {col.links.map((link) => (\n <li key={link.href}>\n <a\n href={link.href}\n className=\"text-sm font-medium transition-colors hover:text-muted-foreground\"\n >\n {link.label}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction MinimalContent({\n logo,\n columns,\n socials,\n}: Pick<BrutalFooterProps, \"logo\" | \"columns\" | \"socials\">) {\n const allLinks = columns.flatMap((col) => col.links);\n\n return (\n <div className=\"mb-6 flex flex-col items-center gap-4 sm:flex-row sm:justify-between\">\n <div className=\"text-xl font-black\">{logo}</div>\n <nav className=\"flex flex-wrap items-center justify-center gap-x-6 gap-y-2\">\n {allLinks.map((link) => (\n <a\n key={link.href}\n href={link.href}\n className=\"text-sm font-medium transition-colors hover:text-muted-foreground\"\n >\n {link.label}\n </a>\n ))}\n </nav>\n {socials && <SocialsRow socials={socials} />}\n </div>\n );\n}\n\nexport function BrutalFooter({\n logo,\n tagline,\n columns,\n bottomLeft,\n bottomRight,\n variant = \"mega\",\n socials,\n newsletter,\n className,\n}: BrutalFooterProps) {\n return (\n <footer\n className={cn(\n \"w-full border-t-4 bg-background px-6 py-12 text-foreground\",\n className\n )}\n style={{ borderTopColor: \"hsl(var(--brand))\" }}\n >\n <div className=\"brutal-container\">\n {/* Newsletter section (only for newsletter variant) */}\n {variant === \"newsletter\" && newsletter && (\n <NewsletterSection newsletter={newsletter} />\n )}\n\n {/* Main content */}\n {variant === \"minimal\" ? (\n <MinimalContent logo={logo} columns={columns} socials={socials} />\n ) : (\n <MegaContent\n logo={logo}\n tagline={tagline}\n columns={columns}\n socials={socials}\n />\n )}\n\n {/* Bottom bar */}\n <div className=\"flex items-center justify-between border-t-brutal border-foreground pt-6 font-mono text-xs uppercase tracking-widest text-muted-foreground\">\n <span>{bottomLeft || \"Built with care\"}</span>\n <span>{bottomRight || new Date().getFullYear()}</span>\n </div>\n </div>\n </footer>\n );\n}\n"]}
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { SectionPattern } from './section.js';
|
|
2
3
|
|
|
4
|
+
type HeroVariant = "split" | "centered" | "overlap" | "asymmetric";
|
|
3
5
|
interface BrutalHeroProps {
|
|
6
|
+
variant?: HeroVariant;
|
|
4
7
|
badge?: string;
|
|
8
|
+
badgePosition?: "above" | "inline" | "floating";
|
|
5
9
|
headline: string;
|
|
6
10
|
description: string;
|
|
7
11
|
ctaText: string;
|
|
8
12
|
ctaHref?: string;
|
|
9
13
|
ctaVariant?: "cta" | "brand" | "default";
|
|
14
|
+
secondaryText?: string;
|
|
15
|
+
secondaryHref?: string;
|
|
10
16
|
visual?: React.ReactNode;
|
|
11
17
|
color?: "white" | "brand" | "brand-muted" | "gray";
|
|
18
|
+
pattern?: SectionPattern;
|
|
12
19
|
proof?: string;
|
|
13
20
|
className?: string;
|
|
14
21
|
}
|
|
15
|
-
declare function BrutalHero({ badge, headline, description, ctaText, ctaHref, ctaVariant, visual, color, proof, className, }: BrutalHeroProps): react_jsx_runtime.JSX.Element;
|
|
22
|
+
declare function BrutalHero({ variant, badge, badgePosition, headline, description, ctaText, ctaHref, ctaVariant, secondaryText, secondaryHref, visual, color, pattern, proof, className, }: BrutalHeroProps): react_jsx_runtime.JSX.Element;
|
|
16
23
|
|
|
17
24
|
export { BrutalHero };
|